Track editable elements on screen
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Apr 2020 22:41:44 +0000 (22:41 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Apr 2020 22:41:44 +0000 (22:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=209888
<rdar://problem/61196886>

Reviewed by Simon Fraser.

Source/JavaScriptCore:

Add feature define to track editable elements on screen (enabled by default on iOS and iOS Simulator).

* Configurations/FeatureDefines.xcconfig:

Source/WebCore:

Amend EventRegion to store a region of all the hit test visible rects of editable elements
on the page. This data will be sent over to the UI process so that it can quickly determine
if a search rect would intersect any editable elements.

An element is considered editable if it has CSS -webkit-user-modify value that isn't read-only.
Note that the value of the HTML content attribute contenteditable is internally converted to
its -webkit-user-modify equivalent (e.g. contenteditable="true" <=> "-webkit-user-modify: read-write").

Tests: editing/editable-region/fixed-and-absolute-contenteditable-scrolled.html
       editing/editable-region/float-contenteditable.html
       editing/editable-region/hit-test-basic.html
       editing/editable-region/hit-test-fixed.html
       editing/editable-region/hit-test-overlap.html
       editing/editable-region/iframe.html
       editing/editable-region/input-basic.html
       editing/editable-region/out-hanging-child-of-contenteditable.html
       editing/editable-region/overflow-scroll-text-field-and-contenteditable.html
       editing/editable-region/relative-inside-fixed-contenteditable-scrolled.html
       editing/editable-region/relative-inside-transformed-contenteditable.html
       editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables.html

* Configurations/FeatureDefines.xcconfig: Add feature define to track editable elements on
screen (enabled by default on iOS and iOS Simulator).
* dom/Document.h:
(WebCore::Document::mayHaveEditableElements const):
(WebCore::Document::setMayHaveEditableElements):
Add some state to each document to track whether it may have an editable element or not. This
value represents a "maybe" because it is only set and never unset. It is set if the style resolver
saw an element with an editable style. This flag is used as a performance optimization to avoid
creating an event region if there are no editable elements on the page.

* page/Frame.cpp:
(WebCore::Frame::invalidateContentEventRegionsIfNeeded): Check if there are any editable elements.
If so, invalidate the event region.
* rendering/EventRegion.cpp:
(WebCore::EventRegion::operator== const): Update for editable region.
(WebCore::EventRegion::unite): If the specified style has a writable CSS user-modify value then
unite the region with the editable region.
(WebCore::EventRegion::translate): Update for editable region.
(WebCore::EventRegion::containsEditableElementsInRect const): Added. Check if the specified rect
intersects the editable region. If it does then that means there are one or more editable elements
whose bounds intersect that rect. Otherwise, there are none.
(WebCore::EventRegion::dump const): Update for editable region.
* rendering/EventRegion.h:
(WebCore::EventRegion::intersects const): Added.
(WebCore::EventRegion::rectsForEditableElements const): Return the rects in the editable region.
(WebCore::EventRegion::encode const): Encode the editable region.
(WebCore::EventRegion::decode): Decode the editable region.
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintObject): Traverse descendants if the page has any editable elements
so that we find all of them.
* rendering/RenderElement.cpp:
(WebCore::RenderElement::styleWillChange): Amend the event region invalidation criterion to look
for a change in writability. If there was a change (e.g. read-only to read-write) then invalidate
the event region to force a re-computation of it.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::invalidateEventRegion): If the document has editable elements then we need
to create an event region.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateEventRegion): Update the region if there are editable elements.
(WebCore::RenderLayerBacking::paintDebugOverlays): Paint the editable elements in the debug overlay.
For now, I piggybacked (like was done for touch-action regions) on the non-fast scrollable region
flag (not shown in the patch). I will look to add a dedicated debug overlay flag in a follow up patch.
* style/StyleTreeResolver.cpp:
(WebCore::Style::TreeResolver::resolveElement): Mark the document as having an editable element if
the style for the element being resolved is writable.

Source/WebCore/PAL:

Add feature define to track editable elements on screen (enabled by default on iOS and iOS Simulator).

* Configurations/FeatureDefines.xcconfig:

Source/WebKit:

Speed up -_requestTextInputContextsInRect when the rect does not intersect any editable
elements by over 4450 times on reddit.com! Another way of saying this is that it reduces
the time from an average of 303.252ms to 0.0680625ms in a Production build.

This speed up is accomplished by having the web process track the rects of the editable
elements on the page and send this information as a region data structure over to the UI
process as part of the EventRegion object. This region is used to determine if there
*may* be an editable element inside the rectangele. It never reports a false negative,
but it can report a false positive: a rectangle is over an editable element when it
actually isn't, (e.g. there is a non-composited element with a higher z-order than the
editable element that intersects the search rect).

* Configurations/FeatureDefines.xcconfig: Add feature define to track editable elements on
screen (enabled by default on iOS and iOS Simulator).
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _mayContainEditableElementsInRect:]): Added.
(-[WKWebView _requestTextInputContextsInRect:completionHandler:]): Checks if the search
rects hits an editable element in a RemoteLayerTree node's editable region. If it does
not hit any then we know there are no editable elements and return immediately. If it
does hit something then we still need to ask the web process to perform a hit test to
find the actual elements, respecting z-ordering (which is lost when these elements' rects
are united to form the editable region).
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h:
* UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
(WebKit::collectDescendantViewsInRect): Added.
(WebKit::mayContainEditableElementsInRect): Added.

Source/WebKitLegacy/mac:

Add feature define to track editable elements on screen (enabled by default on iOS and iOS Simulator).

* Configurations/FeatureDefines.xcconfig:

Tools:

Add more unit tests for -_requestTextInputContextsInRect. Also add test infrastructure to
be able to verify that WebKit::mayContainEditableElementsInRect() works.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::mayContainEditableElementsInRect):
Expose an internal function to test WebKit::mayContainEditableElementsInRect().

* TestWebKitAPI/Configurations/FeatureDefines.xcconfig: Add feature define.
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm:
(webViewLoadHTMLStringAndWaitForAllFramesToPaint): Renamed; formerly webViewLoadHTMLStringAndWaitForDOMLoadEvent.
Also make it wait for the next presentation update after we paint.
(TEST):
(squareCenteredAtPoint): Added.
(webViewLoadHTMLStringAndWaitForDOMLoadEvent): Deleted; renamed webViewLoadHTMLStringAndWaitForAllFramesToPaint().
* TestWebKitAPI/Tests/WebKitCocoa/editable-region-composited-and-non-composited-overlap.html: Added.
* TestWebKitAPI/ios/editable-region-composited-and-non-composited-overlap.html: Added.
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::mayContainEditableElementsInRect): Added.

LayoutTests:

Add some tests. Some of these tests were derived from a torture test page written by Simon Fraser.

* TestExpectations: Skip directory editing/editable-region everywhere. I will unskip this in the iOS TestExpectations file.
* editing/editable-region/fixed-and-absolute-contenteditable-scrolled-expected.txt: Added.
* editing/editable-region/fixed-and-absolute-contenteditable-scrolled.html: Added.
* editing/editable-region/float-contenteditable-expected.txt: Added.
* editing/editable-region/float-contenteditable.html: Added.
* editing/editable-region/hit-test-basic-expected.txt: Added.
* editing/editable-region/hit-test-basic.html: Added.
* editing/editable-region/hit-test-fixed-expected.txt: Added.
* editing/editable-region/hit-test-fixed.html: Added.
* editing/editable-region/hit-test-overlap-expected.txt: Added.
* editing/editable-region/hit-test-overlap.html: Added.
* editing/editable-region/iframe-expected.txt: Added.
* editing/editable-region/iframe.html: Added.
* editing/editable-region/input-basic-expected.txt: Added.
* editing/editable-region/input-basic.html: Added.
* editing/editable-region/out-hanging-child-of-contenteditable-expected.txt: Added.
* editing/editable-region/out-hanging-child-of-contenteditable.html: Added.
* editing/editable-region/overflow-scroll-text-field-and-contenteditable-expected.txt: Added.
* editing/editable-region/overflow-scroll-text-field-and-contenteditable.html: Added.
* editing/editable-region/relative-inside-fixed-contenteditable-scrolled-expected.txt: Added.
* editing/editable-region/relative-inside-fixed-contenteditable-scrolled.html: Added.
* editing/editable-region/relative-inside-transformed-contenteditable-expected.txt: Added.
* editing/editable-region/relative-inside-transformed-contenteditable.html: Added.
* editing/editable-region/resources/hit-test-utilities.js: Added.
(async shouldHaveEditableElementsInRect):
(async shouldNotHaveEditableElementsInRect):
(shouldNotHaveEditableElementsInRectForElement):
* editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables-expected.txt: Added.
* editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables.html: Added.
* platform/ios/TestExpectations: Unskip editing/editable-region.
* resources/ui-helper.js:
(window.UIHelper.mayContainEditableElementsInRect): Added. Convenience function that turns around
and calls the UIScriptController function of the same name and returns a boolean instead of a string.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@259762 268f45cc-cd09-0410-ab3c-d52691b4dbfc

62 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/editing/editable-region/fixed-and-absolute-contenteditable-scrolled-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/fixed-and-absolute-contenteditable-scrolled.html [new file with mode: 0644]
LayoutTests/editing/editable-region/float-contenteditable-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/float-contenteditable.html [new file with mode: 0644]
LayoutTests/editing/editable-region/hit-test-basic-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/hit-test-basic.html [new file with mode: 0644]
LayoutTests/editing/editable-region/hit-test-fixed-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/hit-test-fixed.html [new file with mode: 0644]
LayoutTests/editing/editable-region/hit-test-overlap-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/hit-test-overlap.html [new file with mode: 0644]
LayoutTests/editing/editable-region/iframe-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/iframe.html [new file with mode: 0644]
LayoutTests/editing/editable-region/input-basic-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/input-basic.html [new file with mode: 0644]
LayoutTests/editing/editable-region/out-hanging-child-of-contenteditable-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/out-hanging-child-of-contenteditable.html [new file with mode: 0644]
LayoutTests/editing/editable-region/overflow-scroll-text-field-and-contenteditable-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/overflow-scroll-text-field-and-contenteditable.html [new file with mode: 0644]
LayoutTests/editing/editable-region/relative-inside-fixed-contenteditable-scrolled-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/relative-inside-fixed-contenteditable-scrolled.html [new file with mode: 0644]
LayoutTests/editing/editable-region/relative-inside-transformed-contenteditable-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/relative-inside-transformed-contenteditable.html [new file with mode: 0644]
LayoutTests/editing/editable-region/resources/hit-test-utilities.js [new file with mode: 0644]
LayoutTests/editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables-expected.txt [new file with mode: 0644]
LayoutTests/editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables.html [new file with mode: 0644]
LayoutTests/platform/ios/TestExpectations
LayoutTests/resources/ui-helper.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
Source/WebCore/ChangeLog
Source/WebCore/Configurations/FeatureDefines.xcconfig
Source/WebCore/PAL/ChangeLog
Source/WebCore/PAL/Configurations/FeatureDefines.xcconfig
Source/WebCore/dom/Document.h
Source/WebCore/page/Frame.cpp
Source/WebCore/rendering/EventRegion.cpp
Source/WebCore/rendering/EventRegion.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/style/StyleTreeResolver.cpp
Source/WebKit/ChangeLog
Source/WebKit/Configurations/FeatureDefines.xcconfig
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/Configurations/FeatureDefines.xcconfig
Tools/ChangeLog
Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm
Tools/TestWebKitAPI/Tests/WebKitCocoa/editable-region-composited-and-non-composited-overlap.html [new file with mode: 0644]
Tools/TestWebKitAPI/ios/editable-region-composited-and-non-composited-overlap.html [new file with mode: 0644]
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

index 954eaf8..da73043 100644 (file)
@@ -1,5 +1,49 @@
 2020-04-08  Daniel Bates  <dabates@apple.com>
 
+        Track editable elements on screen
+        https://bugs.webkit.org/show_bug.cgi?id=209888
+        <rdar://problem/61196886>
+
+        Reviewed by Simon Fraser.
+
+        Add some tests. Some of these tests were derived from a torture test page written by Simon Fraser.
+
+        * TestExpectations: Skip directory editing/editable-region everywhere. I will unskip this in the iOS TestExpectations file.
+        * editing/editable-region/fixed-and-absolute-contenteditable-scrolled-expected.txt: Added.
+        * editing/editable-region/fixed-and-absolute-contenteditable-scrolled.html: Added.
+        * editing/editable-region/float-contenteditable-expected.txt: Added.
+        * editing/editable-region/float-contenteditable.html: Added.
+        * editing/editable-region/hit-test-basic-expected.txt: Added.
+        * editing/editable-region/hit-test-basic.html: Added.
+        * editing/editable-region/hit-test-fixed-expected.txt: Added.
+        * editing/editable-region/hit-test-fixed.html: Added.
+        * editing/editable-region/hit-test-overlap-expected.txt: Added.
+        * editing/editable-region/hit-test-overlap.html: Added.
+        * editing/editable-region/iframe-expected.txt: Added.
+        * editing/editable-region/iframe.html: Added.
+        * editing/editable-region/input-basic-expected.txt: Added.
+        * editing/editable-region/input-basic.html: Added.
+        * editing/editable-region/out-hanging-child-of-contenteditable-expected.txt: Added.
+        * editing/editable-region/out-hanging-child-of-contenteditable.html: Added.
+        * editing/editable-region/overflow-scroll-text-field-and-contenteditable-expected.txt: Added.
+        * editing/editable-region/overflow-scroll-text-field-and-contenteditable.html: Added.
+        * editing/editable-region/relative-inside-fixed-contenteditable-scrolled-expected.txt: Added.
+        * editing/editable-region/relative-inside-fixed-contenteditable-scrolled.html: Added.
+        * editing/editable-region/relative-inside-transformed-contenteditable-expected.txt: Added.
+        * editing/editable-region/relative-inside-transformed-contenteditable.html: Added.
+        * editing/editable-region/resources/hit-test-utilities.js: Added.
+        (async shouldHaveEditableElementsInRect):
+        (async shouldNotHaveEditableElementsInRect):
+        (shouldNotHaveEditableElementsInRectForElement):
+        * editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables-expected.txt: Added.
+        * editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables.html: Added.
+        * platform/ios/TestExpectations: Unskip editing/editable-region.
+        * resources/ui-helper.js:
+        (window.UIHelper.mayContainEditableElementsInRect): Added. Convenience function that turns around
+        and calls the UIScriptController function of the same name and returns a boolean instead of a string.
+
+2020-04-08  Daniel Bates  <dabates@apple.com>
+
         Should find touch-action elements inside non-composited iframes
         https://bugs.webkit.org/show_bug.cgi?id=210041
         <rdar://problem/61323558>
index c1d34cb..915051f 100644 (file)
@@ -17,6 +17,7 @@ accessibility/win [ Skip ]
 displaylists [ Skip ]
 editing/mac [ Skip ]
 editing/caret/ios [ Skip ]
+editing/editable-region [ Skip ]
 editing/input/ios [ Skip ]
 editing/find [ Skip ]
 editing/pasteboard/gtk [ Skip ]
diff --git a/LayoutTests/editing/editable-region/fixed-and-absolute-contenteditable-scrolled-expected.txt b/LayoutTests/editing/editable-region/fixed-and-absolute-contenteditable-scrolled-expected.txt
new file mode 100644 (file)
index 0000000..0193ad9
--- /dev/null
@@ -0,0 +1,40 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 4117.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 4117.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=4117)
+      )
+      (children 2
+        (GraphicsLayer
+          (position 8.00 1037.00)
+          (bounds 792.00 42.00)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=802 height=42)
+          (editable region
+            (rect (0,0) width=802 height=42)
+          )
+          )
+        )
+        (GraphicsLayer
+          (position 200.00 1000.00)
+          (bounds 258.00 258.00)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=258 height=258)
+          (editable region
+            (rect (0,0) width=258 height=258)
+          )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/editing/editable-region/fixed-and-absolute-contenteditable-scrolled.html b/LayoutTests/editing/editable-region/fixed-and-absolute-contenteditable-scrolled.html
new file mode 100644 (file)
index 0000000..3b35dbd
--- /dev/null
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<body style="height: 4096px">
+<div style="position: fixed; border: 1px solid black; width: 100%; height: 40px" contenteditable="true"></div>
+<div style="position: absolute; border: 1px solid black; height: 256px; width: 256px; top: 1000px; left: 200px" contenteditable="true"></div>
+<pre id="results"></pre>
+<script>
+window.scrollTo(0, 1024);
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/float-contenteditable-expected.txt b/LayoutTests/editing/editable-region/float-contenteditable-expected.txt
new file mode 100644 (file)
index 0000000..c2dd59e
--- /dev/null
@@ -0,0 +1,19 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=600)
+      (editable region
+        (rect (740,13) width=52 height=42)
+      )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/editing/editable-region/float-contenteditable.html b/LayoutTests/editing/editable-region/float-contenteditable.html
new file mode 100644 (file)
index 0000000..d37334d
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="float: right; border: 1px solid black; width: 50px; height: 40px" contenteditable="true"></div>
+<pre id="results"></pre>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/hit-test-basic-expected.txt b/LayoutTests/editing/editable-region/hit-test-basic-expected.txt
new file mode 100644 (file)
index 0000000..5117c80
--- /dev/null
@@ -0,0 +1,11 @@
+Hit tests for editable elements inside the black outlined rectangle.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS (x = 100, y = 100, width = 202, height = 202) contains editable elements.
+PASS (x = 0, y = 0, width = 50, height = 50) does not contain editable elements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/editable-region/hit-test-basic.html b/LayoutTests/editing/editable-region/hit-test-basic.html
new file mode 100644 (file)
index 0000000..be4c37c
--- /dev/null
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<script src="resources/hit-test-utilities.js"></script>
+<style>
+#test-container {
+    position: absolute;
+    top: 100px;
+    left: 100px;
+    border: 1px solid black;
+    width: 200px;
+    height: 200px;
+}
+</style>
+</head>
+<body>
+<div id="test-container">
+    <input>
+</div>
+<script>
+window.jsTestIsAsync = true;
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+async function runTest()
+{
+    if (!window.testRunner) {
+        testFailed("Must be run in WebKitTestRunner.");
+        return;
+    }
+
+    let testContainer = document.getElementById("test-container");
+    await shouldHaveEditableElementsInRectForElement(testContainer);
+    await shouldNotHaveEditableElementsInRect(0, 0, 50, 50);
+
+    document.body.removeChild(testContainer);
+    finishJSTest();
+}
+
+description("Hit tests for editable elements inside the black outlined rectangle.");
+runTest();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/hit-test-fixed-expected.txt b/LayoutTests/editing/editable-region/hit-test-fixed-expected.txt
new file mode 100644 (file)
index 0000000..844530d
--- /dev/null
@@ -0,0 +1,12 @@
+Hit test fixed positioned editable element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS (x = 0, y = 0, width = 200, height = 40) contains editable elements.
+PASS (x = 0, y = 100, width = 50, height = 50) does not contain editable elements.
+PASS (x = 0, y = 0, width = 200, height = 40) contains editable elements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/editable-region/hit-test-fixed.html b/LayoutTests/editing/editable-region/hit-test-fixed.html
new file mode 100644 (file)
index 0000000..b43e367
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<script src="resources/hit-test-utilities.js"></script>
+<style>
+#test-container {
+    height: 100px;
+}
+</style>
+</head>
+<body style="height: 4096px">
+<div id="test-container">
+    <div style="position: fixed; border: 1px solid black; width: 100%; height: 40px" contenteditable="true"></div>
+</div>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+window.jsTestIsAsync = true;
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+async function runTest()
+{
+    if (!window.testRunner) {
+        testFailed("Must be run in WebKitTestRunner.");
+        return;
+    }
+
+    await shouldHaveEditableElementsInRect(0, 0, 200, 40);
+    await shouldNotHaveEditableElementsInRect(0, 100, 50, 50);
+
+    window.scrollTo(0, 200);
+
+    await shouldHaveEditableElementsInRect(0, 0, 200, 40);
+
+    let testContainer = document.getElementById("test-container");
+    document.body.removeChild(testContainer);
+    finishJSTest();
+}
+
+description("Hit test fixed positioned editable element.");
+runTest();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/hit-test-overlap-expected.txt b/LayoutTests/editing/editable-region/hit-test-overlap-expected.txt
new file mode 100644 (file)
index 0000000..9e5b9d8
--- /dev/null
@@ -0,0 +1,18 @@
+Hit test editable elements that are overlapped by another element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Non-Composited overlap:
+PASS (x = 29, y = 71, width = 251, height = 201) contains editable elements.
+PASS (x = 270, y = 150, width = 10, height = 10) contains editable elements.
+PASS (x = 281, y = 69, width = 249, height = 201) contains editable elements.
+
+Composited overlap:
+PASS (x = 29, y = 343, width = 251, height = 201) does not contain editable elements.
+PASS (x = 270, y = 400, width = 10, height = 10) does not contain editable elements.
+PASS (x = 281, y = 343, width = 249, height = 201) contains editable elements.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/editable-region/hit-test-overlap.html b/LayoutTests/editing/editable-region/hit-test-overlap.html
new file mode 100644 (file)
index 0000000..29a522a
--- /dev/null
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<script src="resources/hit-test-utilities.js"></script>
+<style>
+#test-container {
+    height: 500px;
+}
+
+.container {
+    position: relative;
+    width: 500px;
+    height: 200px;
+    margin: 20px;
+    border: 1px solid black;
+}
+
+.editable {
+    -webkit-user-modify: read-write;
+    background-color: aquamarine;
+    border: 2px solid green;
+}
+
+.overlapper {
+    position: absolute;
+    top: 0;
+    height: 100%;
+    width: 50%;
+    background-color: rgba(255, 255, 255, 0.75);
+    border: 1px solid black;
+    z-index: 1;
+    box-shadow: 0 0 10px black;
+}
+
+.tap-point {
+    position: absolute;
+    height: 10px;
+    width: 10px;
+    border-radius: 50%;
+    background-color: red;
+    z-index: 1;
+}
+</style>
+</head>
+<body style="height: 4096px">
+<div id="test-container">
+    <h2>Non-composited overlap</h2>
+    <div id="non-composited-container" class="container">
+        <div class="editable" style="margin: 10px; height: 100px"></div>
+        <div class="overlapper"></div>
+    </div>
+
+    <h2>Composited overlap</h2>
+    <div id="composited-container" class="container">
+        <div class="editable" style="margin: 10px; height: 100px"></div>
+        <div class="overlapper" style="transform: translateZ(0)"></div>
+    </div>
+
+    <div id="first-tap-point" class="tap-point" style="top: 150px; left: 270px"></div>
+    <div id="second-tap-point" class="tap-point" style="top: 400px; left: 270px"></div>
+</div>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+window.jsTestIsAsync = true;
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+async function runTest()
+{
+    if (!window.testRunner) {
+        testFailed("Must be run in WebKitTestRunner.");
+        return;
+    }
+
+    debug("Non-Composited overlap:");
+    let container = document.getElementById("non-composited-container");
+    let containerComputedStyle = window.getComputedStyle(container);
+    let overlapper = container.querySelector(".overlapper");
+    let borderLength = parseInt(containerComputedStyle.borderLeftWidth, 10); // Assumes uniform border width
+    await shouldHaveEditableElementsInRect(container.offsetLeft + borderLength, container.offsetTop + borderLength, overlapper.offsetWidth - borderLength, container.offsetHeight - borderLength);
+    await shouldHaveEditableElementsInRectForElement(document.getElementById("first-tap-point"));
+    await shouldHaveEditableElementsInRect(container.offsetLeft + overlapper.offsetWidth + borderLength, container.offsetTop - borderLength, container.offsetWidth - overlapper.offsetWidth - borderLength, container.offsetHeight - borderLength);
+
+    debug("<br>Composited overlap:");
+    container = document.getElementById("composited-container");
+    containerComputedStyle = window.getComputedStyle(container);
+    overlapper = container.querySelector(".overlapper");
+    borderLength = parseInt(containerComputedStyle.borderLeftWidth, 10); // Assumes uniform border width
+    await shouldNotHaveEditableElementsInRect(container.offsetLeft + borderLength, container.offsetTop + borderLength, overlapper.offsetWidth - borderLength, container.offsetHeight - borderLength);
+    await shouldNotHaveEditableElementsInRectForElement(document.getElementById("second-tap-point"));
+    await shouldHaveEditableElementsInRect(container.offsetLeft + overlapper.offsetWidth + borderLength, container.offsetTop + borderLength, container.offsetWidth - overlapper.offsetWidth - borderLength, container.offsetHeight - borderLength);
+
+    let testContainer = document.getElementById("test-container");
+    document.body.removeChild(testContainer);
+    finishJSTest();
+}
+
+description("Hit test editable elements that are overlapped by another element.");
+runTest();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/iframe-expected.txt b/LayoutTests/editing/editable-region/iframe-expected.txt
new file mode 100644 (file)
index 0000000..26d0129
--- /dev/null
@@ -0,0 +1,61 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 4112.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 4112.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 304.00 304.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (position 2.00 2.00)
+              (children 1
+                (GraphicsLayer
+                  (bounds origin 0.00 200.00)
+                  (anchor 0.00 0.00)
+                  (bounds 300.00 300.00)
+                  (children 1
+                    (GraphicsLayer
+                      (anchor 0.00 0.00)
+                      (children 1
+                        (GraphicsLayer
+                          (anchor 0.00 0.00)
+                          (bounds 310.00 670.00)
+                          (children 1
+                            (GraphicsLayer
+                              (bounds 310.00 670.00)
+                              (drawsContent 1)
+                              (event region
+                                (rect (0,0) width=300 height=670)
+                              (editable region
+                                (rect (8,286) width=284 height=24)
+                                (rect (9,431) width=285 height=24)
+                              )
+                              )
+                              (children 1
+                                (GraphicsLayer
+                                )
+                              )
+                            )
+                          )
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/editing/editable-region/iframe.html b/LayoutTests/editing/editable-region/iframe.html
new file mode 100644 (file)
index 0000000..8708491
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<body style="height: 4096px">
+<iframe id="testFrame" height="300" srcdoc="
+<style>
+.scroller {
+    margin-top: 400px;
+    width: 300px;
+    height: 300px;
+    overflow: scroll;
+    border: 1px solid black;
+}
+.contents {
+    width: 500px;
+    height: 500px;
+}
+.editable {
+    -webkit-user-modify: read-write;
+    border: 2px solid blue;
+}   
+</style>
+<p>iframe</p>
+<div class='editable box' style='margin-top: 250px;'>
+</div>
+<div class='scroller' style='margin-top: 50px;'>
+    <div class='contents'>
+        Overflow scroll in iframe
+        <div class='editable box' style='margin-top: 50px;'>
+        </div>
+    </div>
+</div>
+<script>
+window.parent.scrollIFrameAndDumpRegions();
+</script>
+">
+</iframe>
+<pre id="results"></pre>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+if (window.internals)
+    internals.settings.setAsyncFrameScrollingEnabled(true);
+
+function scrollIFrameAndDumpRegions()
+{
+    testFrame.contentWindow.scrollTo(0, 200);
+    if (window.internals)
+       results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+   if (window.testRunner)
+        testRunner.notifyDone();
+}
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/input-basic-expected.txt b/LayoutTests/editing/editable-region/input-basic-expected.txt
new file mode 100644 (file)
index 0000000..fc69ed9
--- /dev/null
@@ -0,0 +1,20 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=600)
+      (editable region
+        (rect (16,13) width=123 height=14)
+      )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/editing/editable-region/input-basic.html b/LayoutTests/editing/editable-region/input-basic.html
new file mode 100644 (file)
index 0000000..84a8019
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+<input type="text">
+<pre id="results"></pre>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/out-hanging-child-of-contenteditable-expected.txt b/LayoutTests/editing/editable-region/out-hanging-child-of-contenteditable-expected.txt
new file mode 100644 (file)
index 0000000..3958923
--- /dev/null
@@ -0,0 +1,21 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=600)
+      (editable region
+        (rect (48,40) width=226 height=101)
+        (rect (48,141) width=397 height=68)
+        (rect (48,209) width=226 height=33)
+      )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/editing/editable-region/out-hanging-child-of-contenteditable.html b/LayoutTests/editing/editable-region/out-hanging-child-of-contenteditable.html
new file mode 100644 (file)
index 0000000..92c3579
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.container {
+    background-color: silver;
+    margin: 20px;
+    border-radius: 20px;
+    padding: 20px;
+}
+.positioned-child {
+    position: relative;
+    height: 200px;
+    width: 14em;
+    border: 1px solid blue;
+}
+.absolute-positioned-child {
+    position: absolute;
+    top: 100px;
+    left: 200px;
+    width: 12em;
+    height: 4em;
+    border: 2px solid blue;
+}
+</style>
+</head>
+<body>
+<div class="container">
+    <div class="positioned-child" contenteditable="true">
+        <div class="absolute-positioned-child"></div>
+    </div>
+</div>
+<pre id="results"></pre>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/overflow-scroll-text-field-and-contenteditable-expected.txt b/LayoutTests/editing/editable-region/overflow-scroll-text-field-and-contenteditable-expected.txt
new file mode 100644 (file)
index 0000000..8f8056d
--- /dev/null
@@ -0,0 +1,21 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=600)
+      (editable region
+        (rect (17,206) width=123 height=14)
+        (rect (19,451) width=275 height=35)
+      )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/editing/editable-region/overflow-scroll-text-field-and-contenteditable.html b/LayoutTests/editing/editable-region/overflow-scroll-text-field-and-contenteditable.html
new file mode 100644 (file)
index 0000000..ad29458
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scroller {
+    margin-top: 200px;
+    width: 300px;
+    height: 300px;
+    overflow: scroll;
+    border: 1px solid black;
+}
+.contents {
+    width: 500px;
+    height: 500px;
+}
+</style>
+</head>
+<body>
+<div class="scroller">
+    <div class="contents">
+        <input type="text">
+        <div style="margin-top: 225px; margin-left: 10px; border: 1px solid blue; width: 300px; height: 100px;" contenteditable="true"></div>
+    </div>
+</div>
+<pre id="results"></pre>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/relative-inside-fixed-contenteditable-scrolled-expected.txt b/LayoutTests/editing/editable-region/relative-inside-fixed-contenteditable-scrolled-expected.txt
new file mode 100644 (file)
index 0000000..042cafd
--- /dev/null
@@ -0,0 +1,30 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 4117.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 4117.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=4117)
+      )
+      (children 1
+        (GraphicsLayer
+          (position 8.00 1037.00)
+          (bounds 792.00 143.00)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=802 height=42)
+            (rect (21,121) width=800 height=22)
+          (editable region
+            (rect (21,121) width=800 height=22)
+          )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/editing/editable-region/relative-inside-fixed-contenteditable-scrolled.html b/LayoutTests/editing/editable-region/relative-inside-fixed-contenteditable-scrolled.html
new file mode 100644 (file)
index 0000000..197af32
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<body style="height: 4096px">
+<div style="position: fixed; border: 1px solid black; width: 100%; height: 40px">
+    <div style="position: relative; top: 120px; left: 20px; border: 1px solid blue" contenteditable="true"></div>
+</div>
+<pre id="results"></pre>
+<script>
+window.scrollTo(0, 1024);
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/relative-inside-transformed-contenteditable-expected.txt b/LayoutTests/editing/editable-region/relative-inside-transformed-contenteditable-expected.txt
new file mode 100644 (file)
index 0000000..76c3069
--- /dev/null
@@ -0,0 +1,31 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=600)
+      )
+      (children 1
+        (GraphicsLayer
+          (offsetFromRenderer width=-28 height=-28)
+          (position -20.00 -20.00)
+          (bounds 366.00 138.00)
+          (drawsContent 1)
+          (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [20.00 100.00 1.00 1.00])
+          (event region
+            (rect (28,28) width=310 height=82)
+          (editable region
+            (rect (78,58) width=250 height=22)
+          )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/editing/editable-region/relative-inside-transformed-contenteditable.html b/LayoutTests/editing/editable-region/relative-inside-transformed-contenteditable.html
new file mode 100644 (file)
index 0000000..519f299
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.transformed {
+    box-shadow: 0 0 20px black;
+    background-color: rgba(255, 255, 255, 0.75);
+    transform: translate3d(20px, 100px, 1px);
+    width: 250px;
+    padding: 30px;
+}
+</style>
+</head>
+<body>
+<div class="transformed">
+    <div style="position: relative; left: 20px; border: 1px solid blue" contenteditable="true"></div>
+</div>
+<pre id="results"></pre>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/editable-region/resources/hit-test-utilities.js b/LayoutTests/editing/editable-region/resources/hit-test-utilities.js
new file mode 100644 (file)
index 0000000..31719fa
--- /dev/null
@@ -0,0 +1,25 @@
+async function shouldHaveEditableElementsInRect(x, y, width, height)
+{
+    if (await UIHelper.mayContainEditableElementsInRect(x, y, width, height))
+        testPassed(`(x = ${x}, y = ${y}, width = ${width}, height = ${height}) contains editable elements.`);
+    else
+        testFailed(`(x = ${x}, y = ${y}, width = ${width}, height = ${height}) should contain editable elements, but did not.`);
+}
+
+async function shouldNotHaveEditableElementsInRect(x, y, width, height)
+{
+    if (!await UIHelper.mayContainEditableElementsInRect(x, y, width, height))
+        testPassed(`(x = ${x}, y = ${y}, width = ${width}, height = ${height}) does not contain editable elements.`);
+    else
+        testFailed(`(x = ${x}, y = ${y}, width = ${width}, height = ${height}) should not contain editable elements, but did.`);
+}
+
+function shouldHaveEditableElementsInRectForElement(element)
+{
+    return shouldHaveEditableElementsInRect(element.offsetLeft, element.offsetTop, element.offsetWidth, element.offsetHeight);
+}
+
+function shouldNotHaveEditableElementsInRectForElement(element)
+{
+    return shouldNotHaveEditableElementsInRect(element.offsetLeft, element.offsetTop, element.offsetWidth, element.offsetHeight);
+}
diff --git a/LayoutTests/editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables-expected.txt b/LayoutTests/editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables-expected.txt
new file mode 100644 (file)
index 0000000..78665c1
--- /dev/null
@@ -0,0 +1,42 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 4112.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 4112.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=4112)
+      )
+      (children 2
+        (GraphicsLayer
+          (position 8.00 128.00)
+          (bounds 792.00 42.00)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=802 height=42)
+          (editable region
+            (rect (0,0) width=802 height=42)
+          )
+          )
+        )
+        (GraphicsLayer
+          (offsetFromRenderer width=-28 height=-28)
+          (position -20.00 -20.00)
+          (bounds 366.00 138.00)
+          (drawsContent 1)
+          (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [20.00 100.00 1.00 1.00])
+          (event region
+            (rect (28,28) width=310 height=82)
+          (editable region
+            (rect (78,58) width=250 height=22)
+          )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables.html b/LayoutTests/editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables.html
new file mode 100644 (file)
index 0000000..bbc7ff9
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.transformed {
+    box-shadow: 0 0 20px black;
+    background-color: rgba(255, 255, 255, 0.75);
+    transform: translate3d(20px, 100px, 1px);
+    width: 250px;
+    padding: 30px;
+}
+</style>
+</head>
+<body style="height: 4096px">
+<div style="position: fixed; border: 1px solid black; width: 100%; height: 40px" contenteditable="true"></div>
+<div class="transformed">
+    <div style="position: relative; left: 20px; border: 1px solid blue" contenteditable="true"></div>
+</div>
+<pre id="results"></pre>
+<script>
+window.scrollTo(0, 120);
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+</script>
+</body>
+</html>
index 24c2f5a..6039091 100644 (file)
@@ -8,6 +8,7 @@
 
 accessibility/ios-simulator [ Pass ]
 displaylists [ Pass ]
+editing/editable-region [ Pass ]
 editing/deleting/ios [ Pass ]
 http/tests/quicklook [ Pass ]
 media/ios [ Pass ]
index b4485c9..e28c022 100644 (file)
@@ -1169,6 +1169,21 @@ window.UIHelper = class UIHelper {
                 })();`, resolve);
         });
     }
+
+    static mayContainEditableElementsInRect(x, y, width, height)
+    {
+        if (!this.isWebKit2() || !this.isIOSFamily())
+            return Promise.resolve(false);
+
+        return new Promise(resolve => {
+            testRunner.runUIScript(`
+                (function() {
+                    uiController.doAfterPresentationUpdate(function() {
+                        uiController.uiScriptComplete(uiController.mayContainEditableElementsInRect(${x}, ${y}, ${width}, ${height}));
+                    })
+                })();`, result => resolve(result === "true"));
+        });
+    }
 }
 
 UIHelper.EventStreamBuilder = class {
index 87297a0..1531e1e 100644 (file)
@@ -1,3 +1,15 @@
+2020-04-08  Daniel Bates  <dabates@apple.com>
+
+        Track editable elements on screen
+        https://bugs.webkit.org/show_bug.cgi?id=209888
+        <rdar://problem/61196886>
+
+        Reviewed by Simon Fraser.
+
+        Add feature define to track editable elements on screen (enabled by default on iOS and iOS Simulator).
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2020-04-08  Yusuke Suzuki  <ysuzuki@apple.com>
 
         [JSC] Threading JSGlobalObject in RegExp::match properly
index effc72b..a74b4a6 100644 (file)
@@ -145,6 +145,10 @@ ENABLE_DRAG_SUPPORT_iphoneos = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_iphonesimulator = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_maccatalyst = ENABLE_DRAG_SUPPORT;
 
+ENABLE_EDITABLE_REGION = $(ENABLE_EDITABLE_REGION_$(WK_PLATFORM_NAME));
+ENABLE_EDITABLE_REGION_iphoneos = ENABLE_EDITABLE_REGION;
+ENABLE_EDITABLE_REGION_iphonesimulator = ENABLE_EDITABLE_REGION;
+
 ENABLE_ENCRYPTED_MEDIA = $(ENABLE_ENCRYPTED_MEDIA_$(WK_PLATFORM_NAME));
 ENABLE_ENCRYPTED_MEDIA_iphoneos = ENABLE_ENCRYPTED_MEDIA;
 ENABLE_ENCRYPTED_MEDIA_iphonesimulator = ENABLE_ENCRYPTED_MEDIA;
@@ -417,4 +421,4 @@ ENABLE_WIRELESS_PLAYBACK_TARGET = ENABLE_WIRELESS_PLAYBACK_TARGET;
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_EDITABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index e9e68d9..45b9a54 100644 (file)
@@ -1,5 +1,80 @@
 2020-04-08  Daniel Bates  <dabates@apple.com>
 
+        Track editable elements on screen
+        https://bugs.webkit.org/show_bug.cgi?id=209888
+        <rdar://problem/61196886>
+
+        Reviewed by Simon Fraser.
+
+        Amend EventRegion to store a region of all the hit test visible rects of editable elements
+        on the page. This data will be sent over to the UI process so that it can quickly determine
+        if a search rect would intersect any editable elements. 
+
+        An element is considered editable if it has CSS -webkit-user-modify value that isn't read-only.
+        Note that the value of the HTML content attribute contenteditable is internally converted to
+        its -webkit-user-modify equivalent (e.g. contenteditable="true" <=> "-webkit-user-modify: read-write").
+
+        Tests: editing/editable-region/fixed-and-absolute-contenteditable-scrolled.html
+               editing/editable-region/float-contenteditable.html
+               editing/editable-region/hit-test-basic.html
+               editing/editable-region/hit-test-fixed.html
+               editing/editable-region/hit-test-overlap.html
+               editing/editable-region/iframe.html
+               editing/editable-region/input-basic.html
+               editing/editable-region/out-hanging-child-of-contenteditable.html
+               editing/editable-region/overflow-scroll-text-field-and-contenteditable.html
+               editing/editable-region/relative-inside-fixed-contenteditable-scrolled.html
+               editing/editable-region/relative-inside-transformed-contenteditable.html
+               editing/editable-region/transformed-scrolled-on-top-of-fixed-contenteditables.html
+
+        * Configurations/FeatureDefines.xcconfig: Add feature define to track editable elements on
+        screen (enabled by default on iOS and iOS Simulator).
+        * dom/Document.h:
+        (WebCore::Document::mayHaveEditableElements const):
+        (WebCore::Document::setMayHaveEditableElements):
+        Add some state to each document to track whether it may have an editable element or not. This
+        value represents a "maybe" because it is only set and never unset. It is set if the style resolver
+        saw an element with an editable style. This flag is used as a performance optimization to avoid
+        creating an event region if there are no editable elements on the page.
+
+        * page/Frame.cpp:
+        (WebCore::Frame::invalidateContentEventRegionsIfNeeded): Check if there are any editable elements.
+        If so, invalidate the event region.
+        * rendering/EventRegion.cpp:
+        (WebCore::EventRegion::operator== const): Update for editable region.
+        (WebCore::EventRegion::unite): If the specified style has a writable CSS user-modify value then
+        unite the region with the editable region.
+        (WebCore::EventRegion::translate): Update for editable region.
+        (WebCore::EventRegion::containsEditableElementsInRect const): Added. Check if the specified rect
+        intersects the editable region. If it does then that means there are one or more editable elements
+        whose bounds intersect that rect. Otherwise, there are none.
+        (WebCore::EventRegion::dump const): Update for editable region.
+        * rendering/EventRegion.h:
+        (WebCore::EventRegion::intersects const): Added.
+        (WebCore::EventRegion::rectsForEditableElements const): Return the rects in the editable region.
+        (WebCore::EventRegion::encode const): Encode the editable region.
+        (WebCore::EventRegion::decode): Decode the editable region.
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintObject): Traverse descendants if the page has any editable elements
+        so that we find all of them.
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::styleWillChange): Amend the event region invalidation criterion to look
+        for a change in writability. If there was a change (e.g. read-only to read-write) then invalidate
+        the event region to force a re-computation of it.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::invalidateEventRegion): If the document has editable elements then we need
+        to create an event region.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateEventRegion): Update the region if there are editable elements.
+        (WebCore::RenderLayerBacking::paintDebugOverlays): Paint the editable elements in the debug overlay.
+        For now, I piggybacked (like was done for touch-action regions) on the non-fast scrollable region
+        flag (not shown in the patch). I will look to add a dedicated debug overlay flag in a follow up patch.
+        * style/StyleTreeResolver.cpp:
+        (WebCore::Style::TreeResolver::resolveElement): Mark the document as having an editable element if
+        the style for the element being resolved is writable.
+
+2020-04-08  Daniel Bates  <dabates@apple.com>
+
         Should find touch-action elements inside non-composited iframes
         https://bugs.webkit.org/show_bug.cgi?id=210041
         <rdar://problem/61323558>
index effc72b..a74b4a6 100644 (file)
@@ -145,6 +145,10 @@ ENABLE_DRAG_SUPPORT_iphoneos = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_iphonesimulator = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_maccatalyst = ENABLE_DRAG_SUPPORT;
 
+ENABLE_EDITABLE_REGION = $(ENABLE_EDITABLE_REGION_$(WK_PLATFORM_NAME));
+ENABLE_EDITABLE_REGION_iphoneos = ENABLE_EDITABLE_REGION;
+ENABLE_EDITABLE_REGION_iphonesimulator = ENABLE_EDITABLE_REGION;
+
 ENABLE_ENCRYPTED_MEDIA = $(ENABLE_ENCRYPTED_MEDIA_$(WK_PLATFORM_NAME));
 ENABLE_ENCRYPTED_MEDIA_iphoneos = ENABLE_ENCRYPTED_MEDIA;
 ENABLE_ENCRYPTED_MEDIA_iphonesimulator = ENABLE_ENCRYPTED_MEDIA;
@@ -417,4 +421,4 @@ ENABLE_WIRELESS_PLAYBACK_TARGET = ENABLE_WIRELESS_PLAYBACK_TARGET;
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_EDITABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index 5badaab..8bf1ef4 100644 (file)
@@ -1,3 +1,15 @@
+2020-04-08  Daniel Bates  <dabates@apple.com>
+
+        Track editable elements on screen
+        https://bugs.webkit.org/show_bug.cgi?id=209888
+        <rdar://problem/61196886>
+
+        Reviewed by Simon Fraser.
+
+        Add feature define to track editable elements on screen (enabled by default on iOS and iOS Simulator).
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2020-04-08  Adrian Perez de Castro  <aperez@igalia.com>
 
         [GTK4] Make PAL::systemBeep() work
index effc72b..a74b4a6 100644 (file)
@@ -145,6 +145,10 @@ ENABLE_DRAG_SUPPORT_iphoneos = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_iphonesimulator = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_maccatalyst = ENABLE_DRAG_SUPPORT;
 
+ENABLE_EDITABLE_REGION = $(ENABLE_EDITABLE_REGION_$(WK_PLATFORM_NAME));
+ENABLE_EDITABLE_REGION_iphoneos = ENABLE_EDITABLE_REGION;
+ENABLE_EDITABLE_REGION_iphonesimulator = ENABLE_EDITABLE_REGION;
+
 ENABLE_ENCRYPTED_MEDIA = $(ENABLE_ENCRYPTED_MEDIA_$(WK_PLATFORM_NAME));
 ENABLE_ENCRYPTED_MEDIA_iphoneos = ENABLE_ENCRYPTED_MEDIA;
 ENABLE_ENCRYPTED_MEDIA_iphonesimulator = ENABLE_ENCRYPTED_MEDIA;
@@ -417,4 +421,4 @@ ENABLE_WIRELESS_PLAYBACK_TARGET = ENABLE_WIRELESS_PLAYBACK_TARGET;
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_EDITABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index c5ad3df..34fd00e 100644 (file)
@@ -1251,6 +1251,10 @@ public:
     bool mayHaveElementsWithNonAutoTouchAction() const { return m_mayHaveElementsWithNonAutoTouchAction; }
     void setMayHaveElementsWithNonAutoTouchAction() { m_mayHaveElementsWithNonAutoTouchAction = true; }
 #endif
+#if ENABLE(EDITABLE_REGION)
+    bool mayHaveEditableElements() const { return m_mayHaveEditableElements; }
+    void setMayHaveEditableElements() { m_mayHaveEditableElements = true; }
+#endif
 
     void didAddTouchEventHandler(Node&);
     void didRemoveTouchEventHandler(Node&, EventHandlerRemoval = EventHandlerRemoval::One);
@@ -1863,6 +1867,9 @@ private:
 #if PLATFORM(IOS_FAMILY)
     bool m_mayHaveElementsWithNonAutoTouchAction { false };
 #endif
+#if ENABLE(EDITABLE_REGION)
+    bool m_mayHaveEditableElements { false };
+#endif
     std::unique_ptr<EventTargetSet> m_wheelEventTargets;
 
     MonotonicTime m_lastHandledUserGestureTimestamp;
index 93138f3..385e37a 100644 (file)
@@ -309,10 +309,16 @@ void Frame::invalidateContentEventRegionsIfNeeded()
 {
     if (!m_page || !m_doc || !m_doc->renderView())
         return;
+    bool hasTouchActionElements = false;
+    bool hasEditableElements = false;
 #if PLATFORM(IOS)
-    if (!m_doc->mayHaveElementsWithNonAutoTouchAction())
-        return;
+    hasTouchActionElements = m_doc->mayHaveElementsWithNonAutoTouchAction();
+#endif
+#if ENABLE(EDITABLE_REGION)
+    hasEditableElements = m_doc->mayHaveEditableElements();
 #endif
+    if (!hasTouchActionElements && !hasEditableElements)
+        return;
     if (!m_doc->renderView()->compositor().viewNeedsToInvalidateEventRegionOfEnclosingCompositingLayerForRepaint())
         return;
     if (m_ownerElement)
index a4848de..ede0a6d 100644 (file)
@@ -100,6 +100,10 @@ bool EventRegion::operator==(const EventRegion& other) const
 {
     if (m_touchActionRegions != other.m_touchActionRegions)
         return false;
+#if ENABLE(EDITABLE_REGION)
+    if (m_editableRegion != other.m_editableRegion)
+        return false;
+#endif
     return m_region == other.m_region;
 }
 
@@ -108,6 +112,11 @@ void EventRegion::unite(const Region& region, const RenderStyle& style)
     m_region.unite(region);
 
     uniteTouchActions(region, style.effectiveTouchActions());
+
+#if ENABLE(EDITABLE_REGION)
+    if (style.userModify() != UserModify::ReadOnly)
+        m_editableRegion.unite(region);
+#endif
 }
 
 void EventRegion::translate(const IntSize& offset)
@@ -116,6 +125,10 @@ void EventRegion::translate(const IntSize& offset)
 
     for (auto& touchActionRegion : m_touchActionRegions)
         touchActionRegion.translate(offset);
+
+#if ENABLE(EDITABLE_REGION)
+    m_editableRegion.translate(offset);
+#endif
 }
 
 static inline unsigned toIndex(TouchAction touchAction)
@@ -205,6 +218,15 @@ OptionSet<TouchAction> EventRegion::touchActionsForPoint(const IntPoint& point)
     return actions;
 }
 
+#if ENABLE(EDITABLE_REGION)
+
+bool EventRegion::containsEditableElementsInRect(const IntRect& rect) const
+{
+    return m_editableRegion.intersects(rect);
+}
+
+#endif
+
 void EventRegion::dump(TextStream& ts) const
 {
     ts << m_region;
@@ -222,6 +244,13 @@ void EventRegion::dump(TextStream& ts) const
         }
         ts << indent << ")\n";
     }
+
+#if ENABLE(EDITABLE_REGION)
+    if (!m_editableRegion.isEmpty()) {
+        ts << indent << "(editable region" << m_editableRegion;
+        ts << indent << ")\n";
+    }
+#endif
 }
 
 TextStream& operator<<(TextStream& ts, TouchAction touchAction)
index 58c496b..f7fbe26 100644 (file)
@@ -70,6 +70,7 @@ public:
 
     bool contains(const IntPoint& point) const { return m_region.contains(point); }
     bool contains(const IntRect& rect) const { return m_region.contains(rect); }
+    bool intersects(const IntRect& rect) const { return m_region.intersects(rect); }
 
     const Region& region() const { return m_region; }
 
@@ -78,6 +79,11 @@ public:
 
     const Region* regionForTouchAction(TouchAction) const;
 
+#if ENABLE(EDITABLE_REGION)
+    WEBCORE_EXPORT bool containsEditableElementsInRect(const IntRect&) const;
+    Vector<IntRect, 1> rectsForEditableElements() const { return m_editableRegion.rects(); }
+#endif
+
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static Optional<EventRegion> decode(Decoder&);
     // FIXME: Remove legacy decode.
@@ -90,6 +96,9 @@ private:
 
     Region m_region;
     Vector<Region> m_touchActionRegions;
+#if ENABLE(EDITABLE_REGION)
+    Region m_editableRegion;
+#endif
 };
 
 WEBCORE_EXPORT TextStream& operator<<(TextStream&, const EventRegion&);
@@ -99,6 +108,9 @@ void EventRegion::encode(Encoder& encoder) const
 {
     encoder << m_region;
     encoder << m_touchActionRegions;
+#if ENABLE(EDITABLE_REGION)
+    encoder << m_editableRegion;
+#endif
 }
 
 template<class Decoder>
@@ -119,6 +131,14 @@ Optional<EventRegion> EventRegion::decode(Decoder& decoder)
 
     eventRegion.m_touchActionRegions = WTFMove(*touchActionRegions);
 
+#if ENABLE(EDITABLE_REGION)
+    Optional<Region> editableRegion;
+    decoder >> editableRegion;
+    if (!editableRegion)
+        return WTF::nullopt;
+    eventRegion.m_editableRegion = WTFMove(*editableRegion);
+#endif
+
     return eventRegion;
 }
 
index f2b2fd3..20d9df5 100644 (file)
@@ -1257,7 +1257,10 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs
 
         bool needsTraverseDescendants = hasVisualOverflow() || containsFloats() || !paintInfo.eventRegionContext->contains(enclosingIntRect(borderRect)) || view().needsEventRegionUpdateForNonCompositedFrame();
 #if PLATFORM(IOS_FAMILY)
-        needsTraverseDescendants = needsTraverseDescendants || document().mayHaveElementsWithNonAutoTouchAction();
+        needsTraverseDescendants |= document().mayHaveElementsWithNonAutoTouchAction();
+#endif
+#if ENABLE(EDITABLE_REGION)
+        needsTraverseDescendants |= document().mayHaveEditableElements();
 #endif
         if (!needsTraverseDescendants)
             return;
index 5ea09a5..0ef3b7f 100644 (file)
@@ -739,6 +739,12 @@ void RenderElement::styleWillChange(StyleDifference diff, const RenderStyle& new
                 return true;
             if (m_style.effectiveTouchActions() != newStyle.effectiveTouchActions())
                 return true;
+#if ENABLE(EDITABLE_REGION)
+            bool wasEditable = m_style.userModify() != UserModify::ReadOnly;
+            bool isEditable = newStyle.userModify() != UserModify::ReadOnly;
+            if (wasEditable != isEditable)
+                return true;
+#endif
             return false;
         };
 
index b9b7adf..f23331f 100644 (file)
@@ -7020,6 +7020,11 @@ bool RenderLayer::invalidateEventRegion(EventRegionInvalidationReason reason)
         // UI side touch-action resolution.
         if (renderer().document().mayHaveElementsWithNonAutoTouchAction())
             return true;
+#if ENABLE(EDITABLE_REGION)
+        // UI side editable elements resolution.
+        if (renderer().document().mayHaveEditableElements())
+            return true;
+#endif
         return false;
     };
 
index ff89f5e..843e069 100644 (file)
@@ -1620,10 +1620,14 @@ void RenderLayerBacking::updateEventRegion()
 
     bool needsEventRegionUpdateForNonCompositedFrame = renderer().view().needsEventRegionUpdateForNonCompositedFrame();
     bool hasTouchActionElements = false;
+    bool hasEditableElements = false;
 #if PLATFORM(IOS_FAMILY)
     hasTouchActionElements = renderer().document().mayHaveElementsWithNonAutoTouchAction();
 #endif
-    if (!hasTouchActionElements && !needsEventRegionUpdateForNonCompositedFrame) {
+#if ENABLE(EDITABLE_REGION)
+    hasEditableElements = renderer().document().mayHaveEditableElements();
+#endif
+    if (!hasTouchActionElements && !hasEditableElements && !needsEventRegionUpdateForNonCompositedFrame) {
         if (m_owningLayer.isRenderViewLayer())
             return;
 
@@ -3068,6 +3072,7 @@ void RenderLayerBacking::paintDebugOverlays(const GraphicsLayer* graphicsLayer,
     context.translate(-contentOffset);
 
     // The interactive part.
+    // Paint rects for touch action.
     auto& eventRegion = graphicsLayer->eventRegion();
     Color regionColor(0, 0, 255, 50);
     context.setFillColor(regionColor);
@@ -3095,6 +3100,13 @@ void RenderLayerBacking::paintDebugOverlays(const GraphicsLayer* graphicsLayer,
         for (auto rect : actionRegion->rects())
             context.fillRect(rect);
     }
+
+#if ENABLE(EDITABLE_REGION)
+    // Paint rects for editable elements.
+    context.setFillColor({ 128, 0, 128, 50 });
+    for (auto rect : eventRegion.rectsForEditableElements())
+        context.fillRect(rect);
+#endif
 }
 
 // Up-call from compositing layer drawing callback.
index 2a2285b..9f3500d 100644 (file)
@@ -249,6 +249,10 @@ ElementUpdates TreeResolver::resolveElement(Element& element)
     if (update.style->touchActions() != TouchAction::Auto && !m_document.quirks().shouldDisablePointerEventsQuirk())
         m_document.setMayHaveElementsWithNonAutoTouchAction();
 #endif
+#if ENABLE(EDITABLE_REGION)
+    if (update.style->userModify() != UserModify::ReadOnly)
+        m_document.setMayHaveEditableElements();
+#endif
 
     return { WTFMove(update), descendantsToResolve, WTFMove(beforeUpdate), WTFMove(afterUpdate) };
 }
index 5de4159..0dcc1d6 100644 (file)
@@ -1,5 +1,41 @@
 2020-04-08  Daniel Bates  <dabates@apple.com>
 
+        Track editable elements on screen
+        https://bugs.webkit.org/show_bug.cgi?id=209888
+        <rdar://problem/61196886>
+
+        Reviewed by Simon Fraser.
+
+        Speed up -_requestTextInputContextsInRect when the rect does not intersect any editable
+        elements by over 4450 times on reddit.com! Another way of saying this is that it reduces
+        the time from an average of 303.252ms to 0.0680625ms in a Production build.
+
+        This speed up is accomplished by having the web process track the rects of the editable
+        elements on the page and send this information as a region data structure over to the UI
+        process as part of the EventRegion object. This region is used to determine if there
+        *may* be an editable element inside the rectangele. It never reports a false negative,
+        but it can report a false positive: a rectangle is over an editable element when it
+        actually isn't, (e.g. there is a non-composited element with a higher z-order than the
+        editable element that intersects the search rect).
+
+        * Configurations/FeatureDefines.xcconfig: Add feature define to track editable elements on
+        screen (enabled by default on iOS and iOS Simulator).
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _mayContainEditableElementsInRect:]): Added.
+        (-[WKWebView _requestTextInputContextsInRect:completionHandler:]): Checks if the search
+        rects hits an editable element in a RemoteLayerTree node's editable region. If it does
+        not hit any then we know there are no editable elements and return immediately. If it
+        does hit something then we still need to ask the web process to perform a hit test to
+        find the actual elements, respecting z-ordering (which is lost when these elements' rects
+        are united to form the editable region).
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h:
+        * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
+        (WebKit::collectDescendantViewsInRect): Added.
+        (WebKit::mayContainEditableElementsInRect): Added.
+
+2020-04-08  Daniel Bates  <dabates@apple.com>
+
         Should find touch-action elements inside non-composited iframes
         https://bugs.webkit.org/show_bug.cgi?id=210041
         <rdar://problem/61323558>
index effc72b..a74b4a6 100644 (file)
@@ -145,6 +145,10 @@ ENABLE_DRAG_SUPPORT_iphoneos = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_iphonesimulator = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_maccatalyst = ENABLE_DRAG_SUPPORT;
 
+ENABLE_EDITABLE_REGION = $(ENABLE_EDITABLE_REGION_$(WK_PLATFORM_NAME));
+ENABLE_EDITABLE_REGION_iphoneos = ENABLE_EDITABLE_REGION;
+ENABLE_EDITABLE_REGION_iphonesimulator = ENABLE_EDITABLE_REGION;
+
 ENABLE_ENCRYPTED_MEDIA = $(ENABLE_ENCRYPTED_MEDIA_$(WK_PLATFORM_NAME));
 ENABLE_ENCRYPTED_MEDIA_iphoneos = ENABLE_ENCRYPTED_MEDIA;
 ENABLE_ENCRYPTED_MEDIA_iphonesimulator = ENABLE_ENCRYPTED_MEDIA;
@@ -417,4 +421,4 @@ ENABLE_WIRELESS_PLAYBACK_TARGET = ENABLE_WIRELESS_PLAYBACK_TARGET;
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_EDITABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index aef675d..5e1da5f 100644 (file)
 
 #if PLATFORM(IOS_FAMILY)
 #import "RemoteLayerTreeDrawingAreaProxy.h"
+#import "RemoteLayerTreeViews.h"
 #import "RemoteScrollingCoordinatorProxy.h"
 #import "UIKitSPI.h"
 #import "WKContentViewInteraction.h"
@@ -2091,6 +2092,20 @@ static RetainPtr<NSMutableArray> wkTextManipulationErrors(NSArray<_WKTextManipul
 #endif
 }
 
+- (BOOL)_mayContainEditableElementsInRect:(CGRect)rect
+{
+#if ENABLE(EDITABLE_REGION)
+#if PLATFORM(IOS_FAMILY)
+    if (![self usesStandardContentView])
+        return NO;
+#endif
+    CGRect rectInRootViewCoordinates = [self _convertRectToRootViewCoordinates:rect];
+    return WebKit::mayContainEditableElementsInRect(_contentView.get(), rectInRootViewCoordinates);
+#else
+    return NO;
+#endif
+}
+
 - (void)_requestTextInputContextsInRect:(CGRect)rectInWebViewCoordinates completionHandler:(void(^)(NSArray<_WKTextInputContext *> *))completionHandler
 {
 #if PLATFORM(IOS_FAMILY)
@@ -2099,8 +2114,15 @@ static RetainPtr<NSMutableArray> wkTextManipulationErrors(NSArray<_WKTextManipul
         return;
     }
 #endif
+#if ENABLE(EDITABLE_REGION)
+    if (![self _mayContainEditableElementsInRect:rectInWebViewCoordinates]) {
+        completionHandler(@[]);
+        return;
+    }
+#endif
 
     CGRect rectInRootViewCoordinates = [self _convertRectToRootViewCoordinates:rectInWebViewCoordinates];
+
     auto weakSelf = WeakObjCPtr<WKWebView>(self);
     _page->textInputContextsInRect(rectInRootViewCoordinates, [weakSelf, capturedCompletionHandler = makeBlockPtr(completionHandler)] (const Vector<WebCore::ElementContext>& contexts) {
         RetainPtr<NSMutableArray> elements = adoptNS([[NSMutableArray alloc] initWithCapacity:contexts.size()]);
index 1d08757..cd62343 100644 (file)
@@ -335,6 +335,7 @@ for this property.
 - (void)_resumeAllMediaPlayback;
 - (void)_closeAllMediaPresentations;
 
+- (BOOL)_mayContainEditableElementsInRect:(CGRect)rect;
 - (void)_requestTextInputContextsInRect:(CGRect)rect completionHandler:(void(^)(NSArray<_WKTextInputContext *> *))completionHandler WK_API_AVAILABLE(macos(10.15), ios(13.0));
 - (void)_focusTextInputContext:(_WKTextInputContext *)textInputElement completionHandler:(void(^)(BOOL))completionHandler WK_API_AVAILABLE(macos(10.15), ios(13.0));
 
index f3234b6..87a415a 100644 (file)
@@ -81,6 +81,10 @@ namespace WebKit {
 OptionSet<WebCore::TouchAction> touchActionsForPoint(UIView *rootView, const WebCore::IntPoint&);
 UIScrollView *findActingScrollParent(UIScrollView *, const RemoteLayerTreeHost&);
 
+#if ENABLE(EDITABLE_REGION)
+bool mayContainEditableElementsInRect(UIView *rootView, const WebCore::FloatRect&);
+#endif
+
 }
 
 #endif // PLATFORM(IOS_FAMILY)
index 449ec20..60112d8 100644 (file)
@@ -76,6 +76,62 @@ static void collectDescendantViewsAtPoint(Vector<UIView *, 16>& viewsAtPoint, UI
     };
 }
 
+#if ENABLE(EDITABLE_REGION)
+
+static void collectDescendantViewsInRect(Vector<UIView *, 16>& viewsInRect, UIView *parent, CGRect rect)
+{
+    if (parent.clipsToBounds && !CGRectIntersectsRect(parent.bounds, rect))
+        return;
+
+    for (UIView *view in parent.subviews) {
+        CGRect subviewRect = [view convertRect:rect fromView:parent];
+
+        auto intersectsRect = [&] {
+            // FIXME: isUserInteractionEnabled is mostly redundant with event regions for web content layers.
+            //        It is currently only needed for scroll views.
+            if (!view.isUserInteractionEnabled)
+                return false;
+
+            if (CGRectIsEmpty(view.frame))
+                return false;
+
+            if (!CGRectIntersectsRect(subviewRect, view.bounds))
+                return false;
+
+            if (![view isKindOfClass:WKCompositingView.class])
+                return true;
+            auto* node = RemoteLayerTreeNode::forCALayer(view.layer);
+            return node->eventRegion().intersects(WebCore::IntRect { subviewRect });
+        }();
+
+        if (intersectsRect)
+            viewsInRect.append(view);
+
+        if (!view.subviews)
+            return;
+
+        collectDescendantViewsInRect(viewsInRect, view, subviewRect);
+    };
+}
+
+bool mayContainEditableElementsInRect(UIView *rootView, const WebCore::FloatRect& rect)
+{
+    Vector<UIView *, 16> viewsInRect;
+    collectDescendantViewsInRect(viewsInRect, rootView, rect);
+    if (viewsInRect.isEmpty())
+        return false;
+    for (auto *view : WTF::makeReversedRange(viewsInRect)) {
+        if (![view isKindOfClass:WKCompositingView.class])
+            continue;
+        WebCore::IntRect rectToTest { [view convertRect:rect fromView:rootView] };
+        if (auto* node = RemoteLayerTreeNode::forCALayer(view.layer); node && node->eventRegion().containsEditableElementsInRect(rectToTest))
+            return true;
+    }
+    return false;
+}
+
+#endif // ENABLE(EDITABLE_REGION)
+
 static bool isScrolledBy(WKChildScrollView* scrollView, UIView *hitView)
 {
     auto scrollLayerID = RemoteLayerTreeNode::layerID(scrollView.layer);
index 582c04e..604b159 100644 (file)
@@ -1,3 +1,15 @@
+2020-04-08  Daniel Bates  <dabates@apple.com>
+
+        Track editable elements on screen
+        https://bugs.webkit.org/show_bug.cgi?id=209888
+        <rdar://problem/61196886>
+
+        Reviewed by Simon Fraser.
+
+        Add feature define to track editable elements on screen (enabled by default on iOS and iOS Simulator).
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2020-04-08  Truitt Savell  <tsavell@apple.com>
 
         Unreviewed, reverting r259708.
index effc72b..a74b4a6 100644 (file)
@@ -145,6 +145,10 @@ ENABLE_DRAG_SUPPORT_iphoneos = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_iphonesimulator = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_maccatalyst = ENABLE_DRAG_SUPPORT;
 
+ENABLE_EDITABLE_REGION = $(ENABLE_EDITABLE_REGION_$(WK_PLATFORM_NAME));
+ENABLE_EDITABLE_REGION_iphoneos = ENABLE_EDITABLE_REGION;
+ENABLE_EDITABLE_REGION_iphonesimulator = ENABLE_EDITABLE_REGION;
+
 ENABLE_ENCRYPTED_MEDIA = $(ENABLE_ENCRYPTED_MEDIA_$(WK_PLATFORM_NAME));
 ENABLE_ENCRYPTED_MEDIA_iphoneos = ENABLE_ENCRYPTED_MEDIA;
 ENABLE_ENCRYPTED_MEDIA_iphonesimulator = ENABLE_ENCRYPTED_MEDIA;
@@ -417,4 +421,4 @@ ENABLE_WIRELESS_PLAYBACK_TARGET = ENABLE_WIRELESS_PLAYBACK_TARGET;
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_EDITABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index 326a06e..0180fcc 100644 (file)
@@ -1,3 +1,33 @@
+2020-04-08  Daniel Bates  <dabates@apple.com>
+
+        Track editable elements on screen
+        https://bugs.webkit.org/show_bug.cgi?id=209888
+        <rdar://problem/61196886>
+
+        Reviewed by Simon Fraser.
+
+        Add more unit tests for -_requestTextInputContextsInRect. Also add test infrastructure to
+        be able to verify that WebKit::mayContainEditableElementsInRect() works.
+
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        (WTR::UIScriptController::mayContainEditableElementsInRect):
+        Expose an internal function to test WebKit::mayContainEditableElementsInRect().
+
+        * TestWebKitAPI/Configurations/FeatureDefines.xcconfig: Add feature define.
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm:
+        (webViewLoadHTMLStringAndWaitForAllFramesToPaint): Renamed; formerly webViewLoadHTMLStringAndWaitForDOMLoadEvent.
+        Also make it wait for the next presentation update after we paint.
+        (TEST):
+        (squareCenteredAtPoint): Added.
+        (webViewLoadHTMLStringAndWaitForDOMLoadEvent): Deleted; renamed webViewLoadHTMLStringAndWaitForAllFramesToPaint().
+        * TestWebKitAPI/Tests/WebKitCocoa/editable-region-composited-and-non-composited-overlap.html: Added.
+        * TestWebKitAPI/ios/editable-region-composited-and-non-composited-overlap.html: Added.
+        * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptControllerIOS::mayContainEditableElementsInRect): Added.
+
 2020-04-08  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Remove a workaround that allows many API tests to pass on iOS 13.2
index 4547ff4..cf12347 100644 (file)
@@ -308,6 +308,8 @@ interface UIScriptController {
 
     readonly attribute DOMString scrollingTreeAsText;
 
+    boolean mayContainEditableElementsInRect(unsigned long x, unsigned long y, unsigned long width, unsigned long height);
+
     object propertiesOfLayerWithID(unsigned long long layerID);
 
     void retrieveSpeakSelectionContent(object callback);
index 492b2f9..74c220c 100644 (file)
@@ -119,6 +119,10 @@ public:
 
     virtual void installTapGestureOnWindow(JSValueRef) { notImplemented(); }
 
+    // Editable region
+
+    virtual bool mayContainEditableElementsInRect(unsigned, unsigned, unsigned, unsigned) { notImplemented(); return false; }
+
     // Compositing
 
     virtual JSObjectRef propertiesOfLayerWithID(uint64_t layerID) const { notImplemented(); return nullptr; }
index effc72b..a74b4a6 100644 (file)
@@ -145,6 +145,10 @@ ENABLE_DRAG_SUPPORT_iphoneos = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_iphonesimulator = ENABLE_DRAG_SUPPORT;
 ENABLE_DRAG_SUPPORT_maccatalyst = ENABLE_DRAG_SUPPORT;
 
+ENABLE_EDITABLE_REGION = $(ENABLE_EDITABLE_REGION_$(WK_PLATFORM_NAME));
+ENABLE_EDITABLE_REGION_iphoneos = ENABLE_EDITABLE_REGION;
+ENABLE_EDITABLE_REGION_iphonesimulator = ENABLE_EDITABLE_REGION;
+
 ENABLE_ENCRYPTED_MEDIA = $(ENABLE_ENCRYPTED_MEDIA_$(WK_PLATFORM_NAME));
 ENABLE_ENCRYPTED_MEDIA_iphoneos = ENABLE_ENCRYPTED_MEDIA;
 ENABLE_ENCRYPTED_MEDIA_iphonesimulator = ENABLE_ENCRYPTED_MEDIA;
@@ -417,4 +421,4 @@ ENABLE_WIRELESS_PLAYBACK_TARGET = ENABLE_WIRELESS_PLAYBACK_TARGET;
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLE_PAY_SESSION_V9) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_EDITABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_GPU_PROCESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INSPECTOR_TELEMETRY) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFSCREEN_CANVAS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEBXR) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index ddf9326..1a072f7 100644 (file)
                CEBCA1391E3A807A00C73293 /* page-with-csp-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CEBCA1341E3A803400C73293 /* page-with-csp-iframe.html */; };
                CEBCA13A1E3A807A00C73293 /* page-without-csp.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CEBCA1371E3A803400C73293 /* page-without-csp.html */; };
                CEBCA13B1E3A807A00C73293 /* page-without-csp-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CEBCA1361E3A803400C73293 /* page-without-csp-iframe.html */; };
+               CEDA12412437C9FB00C28A9E /* editable-region-composited-and-non-composited-overlap.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CEDA12402437C9EA00C28A9E /* editable-region-composited-and-non-composited-overlap.html */; };
                D34E08761E4E42E1005FF14A /* WKWebViewGetContents.mm in Sources */ = {isa = PBXBuildFile; fileRef = D3BE5E341E4CE85E00FD563A /* WKWebViewGetContents.mm */; };
                DF4B273921A47728009BD1CA /* WKNSDictionaryEmptyDictionaryCrash.mm in Sources */ = {isa = PBXBuildFile; fileRef = DF4B273821A47727009BD1CA /* WKNSDictionaryEmptyDictionaryCrash.mm */; };
                E1220DCA155B28AA0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */; };
                                A155022C1E050D0300A24C57 /* duplicate-completion-handler-calls.html in Copy Resources */,
                                9984FACE1CFFB090008D198C /* editable-body.html in Copy Resources */,
                                F4D9818F2196B920008230FC /* editable-nested-lists.html in Copy Resources */,
+                               CEDA12412437C9FB00C28A9E /* editable-region-composited-and-non-composited-overlap.html in Copy Resources */,
                                F44D06451F395C26001A0E29 /* editor-state-test-harness.html in Copy Resources */,
                                51C8E1A91F27F49600BF731B /* EmptyGrandfatheredResourceLoadStatistics.plist in Copy Resources */,
                                A14AAB651E78DC5400C1ADC2 /* encrypted.pdf in Copy Resources */,
                CEBCA1351E3A803400C73293 /* page-with-csp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "page-with-csp.html"; sourceTree = "<group>"; };
                CEBCA1361E3A803400C73293 /* page-without-csp-iframe.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "page-without-csp-iframe.html"; sourceTree = "<group>"; };
                CEBCA1371E3A803400C73293 /* page-without-csp.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "page-without-csp.html"; sourceTree = "<group>"; };
+               CEDA12402437C9EA00C28A9E /* editable-region-composited-and-non-composited-overlap.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = "editable-region-composited-and-non-composited-overlap.html"; path = "ios/editable-region-composited-and-non-composited-overlap.html"; sourceTree = SOURCE_ROOT; };
                D3BE5E341E4CE85E00FD563A /* WKWebViewGetContents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewGetContents.mm; sourceTree = "<group>"; };
                DC69AA621CF77C6500C6272F /* ScopedLambda.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScopedLambda.cpp; sourceTree = "<group>"; };
                DF4B273821A47727009BD1CA /* WKNSDictionaryEmptyDictionaryCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKNSDictionaryEmptyDictionaryCrash.mm; sourceTree = "<group>"; };
                        isa = PBXGroup;
                        children = (
                                0F16BED72304A1D100B4A167 /* composited.html */,
+                               CEDA12402437C9EA00C28A9E /* editable-region-composited-and-non-composited-overlap.html */,
                                CE6D0EE22426B8ED002AD901 /* insert-text.html */,
                                0F340777230382540060A1A0 /* overflow-scroll.html */,
                                A1C4FB721BACD1B7003742D0 /* pages.pages */,
index 0a804f5..bfaa985 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2019-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -151,13 +151,14 @@ TEST(RequestTextInputContext, Simple)
 }
 
 // Consider moving this to TestWKWebView if it could be useful to other tests.
-static void webViewLoadHTMLStringAndWaitForDOMLoadEvent(TestWKWebView *webView, NSString *htmlString)
+static void webViewLoadHTMLStringAndWaitForAllFramesToPaint(TestWKWebView *webView, NSString *htmlString)
 {
     ASSERT(webView); // Make passing a nil web view a more obvious failure than a hang.
     bool didFireDOMLoadEvent = false;
     [webView performAfterLoading:[&] { didFireDOMLoadEvent = true; }];
     [webView loadHTMLString:htmlString baseURL:nil];
     TestWebKitAPI::Util::run(&didFireDOMLoadEvent);
+    [webView waitForNextPresentationUpdate];
 }
 
 TEST(RequestTextInputContext, Iframe)
@@ -167,22 +168,67 @@ TEST(RequestTextInputContext, Iframe)
 
     NSArray<_WKTextInputContext *> *contexts;
 
-    webViewLoadHTMLStringAndWaitForDOMLoadEvent(webView.get(), applyIframe(@"<input type='text' style='width: 50px; height: 50px;'>"));
+    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), applyIframe(@"<input type='text' style='width: 50px; height: 50px;'>"));
     contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
     EXPECT_EQ(1UL, contexts.count);
     EXPECT_EQ(CGRectMake(0, 200, 50, 50), contexts[0].boundingRect);
 
-    webViewLoadHTMLStringAndWaitForDOMLoadEvent(webView.get(), applyIframe(@"<textarea style='width: 100px; height: 100px;'></textarea>"));
+    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), applyIframe(@"<textarea style='width: 100px; height: 100px;'></textarea>"));
     contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
     EXPECT_EQ(1UL, contexts.count);
     EXPECT_EQ(CGRectMake(0, 200, 100, 100), contexts[0].boundingRect);
 
-    webViewLoadHTMLStringAndWaitForDOMLoadEvent(webView.get(), applyIframe(@"<div contenteditable style='width: 100px; height: 100px;'></div>"));
+    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), applyIframe(@"<div contenteditable style='width: 100px; height: 100px;'></div>"));
     contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
     EXPECT_EQ(1UL, contexts.count);
     EXPECT_EQ(CGRectMake(0, 200, 100, 100), contexts[0].boundingRect);
 }
 
+static CGRect squareCenteredAtPoint(float x, float y, float length)
+{
+    return CGRectMake(x - length / 2, y - length / 2, length, length);
+}
+
+TEST(RequestTextInputContext, NonCompositedOverlap)
+{
+    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    NSArray<_WKTextInputContext *> *contexts;
+
+    [webView synchronouslyLoadTestPageNamed:@"editable-region-composited-and-non-composited-overlap"];
+
+    // Search rect fully contained in non-composited <div>.
+    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(270, 150, 10, 10)];
+    EXPECT_EQ(0UL, contexts.count);
+    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(170, 150, 10, 10)];
+    EXPECT_EQ(0UL, contexts.count);
+
+    // Search rect overlaps both the non-composited <div> and the editable element.
+    contexts = [webView synchronouslyRequestTextInputContextsInRect:squareCenteredAtPoint(270, 150, 200)];
+    EXPECT_EQ(1UL, contexts.count);
+}
+
+TEST(RequestTextInputContext, CompositedOverlap)
+{
+    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    NSArray<_WKTextInputContext *> *contexts;
+
+    [webView synchronouslyLoadTestPageNamed:@"editable-region-composited-and-non-composited-overlap"];
+
+    // Search rect fully contained in composited <div>.
+    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(270, 400, 10, 10)];
+    EXPECT_EQ(0UL, contexts.count);
+    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(170, 400, 10, 10)];
+    EXPECT_EQ(0UL, contexts.count);
+
+    // Search rect overlaps both the composited <div> and the editable element.
+    contexts = [webView synchronouslyRequestTextInputContextsInRect:squareCenteredAtPoint(270, 400, 200)];
+    EXPECT_EQ(1UL, contexts.count);
+}
+
 TEST(RequestTextInputContext, DISABLED_FocusTextInputContext)
 {
     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/editable-region-composited-and-non-composited-overlap.html b/Tools/TestWebKitAPI/Tests/WebKitCocoa/editable-region-composited-and-non-composited-overlap.html
new file mode 100644 (file)
index 0000000..a31ea9d
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta name="viewport" content="width=device-width">
+    <style>
+        .container {
+            position: relative;
+            width: 500px;
+            height: 200px;
+            margin: 20px;
+            border: 1px solid black;
+        }
+
+        .editable {
+            -webkit-user-modify: read-write;
+            background-color: aquamarine;
+            border: 2px solid green;
+        }
+        
+        .overlapper {
+            position: absolute;
+            top: 0;
+            height: 100%;
+            width: 50%;
+            background-color: rgba(255, 255, 255, 0.75);
+            border: 1px solid black;
+            z-index: 1;
+            box-shadow: 0 0 10px black;
+        }
+        
+        .tap-point {
+            position: absolute;
+            height: 10px;
+            width: 10px;
+            border-radius: 50%;
+            background-color: red;
+            z-index: 1;
+        }
+    </style>
+    
+</head>
+<body>
+    <h2>Non-composited overlap</h2>
+    <div class="container">
+        <div class="editable" style="margin: 10px; height: 100px">
+        </div>
+        <div class="overlapper">
+        </div>
+    </div>
+
+    <h2>Composited overlap</h2>
+    <div class="container">
+        <div class="editable" style="margin: 10px; height: 100px">
+        </div>
+        <div class="overlapper" style="transform: translateZ(0)">
+        </div>
+    </div>
+    
+    <div class="tap-point" style="top: 150px; left: 270px"></div>
+    <div class="tap-point" style="top: 400px; left: 270px"></div>
+    <p>Tap near the red dots</p>
+</body>
+</html>
diff --git a/Tools/TestWebKitAPI/ios/editable-region-composited-and-non-composited-overlap.html b/Tools/TestWebKitAPI/ios/editable-region-composited-and-non-composited-overlap.html
new file mode 100644 (file)
index 0000000..a4c680e
--- /dev/null
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="viewport" content="width=device-width">
+<style>
+.container {
+    position: relative;
+    width: 500px;
+    height: 200px;
+    margin: 20px;
+    border: 1px solid black;
+}
+
+.editable {
+    -webkit-user-modify: read-write;
+    background-color: aquamarine;
+    border: 2px solid green;
+}
+
+.overlapper {
+    position: absolute;
+    top: 0;
+    height: 100%;
+    width: 50%;
+    background-color: rgba(255, 255, 255, 0.75);
+    border: 1px solid black;
+    z-index: 1;
+    box-shadow: 0 0 10px black;
+}
+
+.tap-point {
+    position: absolute;
+    height: 10px;
+    width: 10px;
+    border-radius: 50%;
+    background-color: red;
+    z-index: 1;
+}
+</style>
+</head>
+<body>
+<h2>Non-composited overlap</h2>
+<div class="container">
+    <div class="editable" style="margin: 10px; height: 100px"></div>
+    <div class="overlapper"></div>
+</div>
+
+<h2>Composited overlap</h2>
+<div class="container">
+    <div class="editable" style="margin: 10px; height: 100px"></div>
+    <div class="overlapper" style="transform: translateZ(0)"></div>
+</div>
+
+<div class="tap-point" style="top: 150px; left: 270px"></div>
+<div class="tap-point" style="top: 400px; left: 270px"></div>
+<p>Tap near the red dots</p>
+</body>
+</html>
index 2f731ec..566c389 100644 (file)
@@ -142,6 +142,8 @@ public:
     void copyText(JSStringRef) override;
     void installTapGestureOnWindow(JSValueRef) override;
 
+    bool mayContainEditableElementsInRect(unsigned x, unsigned y, unsigned width, unsigned height) override;
+
     void setDidStartFormControlInteractionCallback(JSValueRef) override;
     void setDidEndFormControlInteractionCallback(JSValueRef) override;
     void setDidShowContextMenuCallback(JSValueRef) override;
index bb7a248..0ed2b77 100644 (file)
@@ -836,6 +836,11 @@ JSObjectRef UIScriptControllerIOS::propertiesOfLayerWithID(uint64_t layerID) con
     return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:[webView() _propertiesOfLayerWithID:layerID] inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
+bool UIScriptControllerIOS::mayContainEditableElementsInRect(unsigned x, unsigned y, unsigned width, unsigned height)
+{
+    return [webView() _mayContainEditableElementsInRect:CGRectMake(x, y, width, height)];
+}
+
 static UIDeviceOrientation toUIDeviceOrientation(DeviceOrientation* orientation)
 {
     if (!orientation)