Title: [261054] trunk
Revision
261054
Author
[email protected]
Date
2020-05-02 14:21:19 -0700 (Sat, 02 May 2020)

Log Message

Page::editableElementsInRect() should return root editable elements
https://bugs.webkit.org/show_bug.cgi?id=211343
<rdar://problem/60015801>

Reviewed by Simon Fraser.

Source/WebCore:

Return the root editable element for each non-text form control editable element
inside the search rect as it may not have been hit itself. This can happen if the
search rect is small enough to intersect only child elements of the root editable
elements.

* page/Page.cpp:
(WebCore::Page::editableElementsInRect const):
(WebCore::isEditableTextInputElement): Deleted.

Tools:

Add some tests.

* TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm:
(TestWebKitAPI::TEST):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (261053 => 261054)


--- trunk/Source/WebCore/ChangeLog	2020-05-02 19:35:03 UTC (rev 261053)
+++ trunk/Source/WebCore/ChangeLog	2020-05-02 21:21:19 UTC (rev 261054)
@@ -1,3 +1,20 @@
+2020-05-02  Daniel Bates  <[email protected]>
+
+        Page::editableElementsInRect() should return root editable elements
+        https://bugs.webkit.org/show_bug.cgi?id=211343
+        <rdar://problem/60015801>
+
+        Reviewed by Simon Fraser.
+
+        Return the root editable element for each non-text form control editable element
+        inside the search rect as it may not have been hit itself. This can happen if the
+        search rect is small enough to intersect only child elements of the root editable
+        elements.
+
+        * page/Page.cpp:
+        (WebCore::Page::editableElementsInRect const):
+        (WebCore::isEditableTextInputElement): Deleted.
+
 2020-05-02  Simon Fraser  <[email protected]>
 
         scrollableAreaForScrollingNodeID() gives the wrong answer for the FrameView

Modified: trunk/Source/WebCore/page/Page.cpp (261053 => 261054)


--- trunk/Source/WebCore/page/Page.cpp	2020-05-02 19:35:03 UTC (rev 261053)
+++ trunk/Source/WebCore/page/Page.cpp	2020-05-02 21:21:19 UTC (rev 261054)
@@ -912,16 +912,6 @@
     });
 }
 
-static bool isEditableTextInputElement(const Element& element)
-{
-    if (is<HTMLTextFormControlElement>(element)) {
-        if (!element.isTextField() && !is<HTMLTextAreaElement>(element))
-            return false;
-        return downcast<HTMLTextFormControlElement>(element).isInnerTextElementEditable();
-    }
-    return element.isRootEditableElement();
-}
-
 Vector<Ref<Element>> Page::editableElementsInRect(const FloatRect& searchRectInRootViewCoordinates) const
 {
     auto frameView = makeRefPtr(mainFrame().view());
@@ -938,16 +928,24 @@
     if (!document->hitTest(hitType, hitTestResult))
         return { };
 
-    Vector<Ref<Element>> result;
+    auto rootEditableElement = [](Node& node) -> Element* {
+        if (is<HTMLTextFormControlElement>(node)) {
+            if (downcast<HTMLTextFormControlElement>(node).isInnerTextElementEditable())
+                return &downcast<Element>(node);
+        } else if (is<Element>(node) && node.hasEditableStyle())
+            return node.rootEditableElement();
+        return nullptr;
+    };
+
+    ListHashSet<Ref<Element>> rootEditableElements;
     auto& nodeSet = hitTestResult.listBasedTestResult();
-    result.reserveInitialCapacity(nodeSet.size());
     for (auto& node : nodeSet) {
-        if (is<Element>(node) && isEditableTextInputElement(downcast<Element>(node.get()))) {
-            ASSERT(searchRectInRootViewCoordinates.intersects(downcast<Element>(node.get()).clientRect()));
-            result.uncheckedAppend(static_reference_cast<Element>(node));
+        if (auto* editableElement = rootEditableElement(node)) {
+            ASSERT(searchRectInRootViewCoordinates.intersects(editableElement->clientRect()));
+            rootEditableElements.add(*editableElement);
         }
     }
-    return result;
+    return WTF::map(rootEditableElements, [](const auto& element) { return element.copyRef(); });
 }
 
 const VisibleSelection& Page::selection() const

Modified: trunk/Tools/ChangeLog (261053 => 261054)


--- trunk/Tools/ChangeLog	2020-05-02 19:35:03 UTC (rev 261053)
+++ trunk/Tools/ChangeLog	2020-05-02 21:21:19 UTC (rev 261054)
@@ -1,3 +1,16 @@
+2020-05-02  Daniel Bates  <[email protected]>
+
+        Page::editableElementsInRect() should return root editable elements
+        https://bugs.webkit.org/show_bug.cgi?id=211343
+        <rdar://problem/60015801>
+
+        Reviewed by Simon Fraser.
+
+        Add some tests.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm:
+        (TestWebKitAPI::TEST):
+
 2020-05-02  Diego Pino Garcia  <[email protected]>
 
         [GTK] Gardening, update API test expectations

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm (261053 => 261054)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm	2020-05-02 19:35:03 UTC (rev 261053)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm	2020-05-02 21:21:19 UTC (rev 261054)
@@ -285,6 +285,33 @@
     EXPECT_EQ(1UL, contexts.count);
 }
 
+TEST(RequestTextInputContext, RectContainsEditableNonRootChild)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView synchronouslyLoadHTMLString:applyStyle(@"<body contenteditable='true' style='width: 500px; height: 500px'><div style='width: 200px; height: 200px; background-color: blue'>Hello World</div></body>")];
+    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(10, 10, 20, 20)];
+    EXPECT_EQ(1UL, contexts.count);
+    EXPECT_EQ(CGRectMake(0, 0, 500, 500), contexts[0].boundingRect);
+}
+
+TEST(RequestTextInputContext, RectContainsNestedEditableNonRootChild)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView synchronouslyLoadHTMLString:applyStyle(@"<body contenteditable='true' style='width: 500px; height: 500px'><div style='width: 200px; height: 200px; background-color: blue'><div style='width: 100px; height: 100px; background-color: yellow' contenteditable='true'>Hello World</div></div></body>")];
+    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(10, 10, 20, 20)];
+    EXPECT_EQ(1UL, contexts.count);
+    EXPECT_EQ(CGRectMake(0, 0, 500, 500), contexts[0].boundingRect);
+}
+
+TEST(RequestTextInputContext, RectContainsInnerEditableNonRootChild)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView synchronouslyLoadHTMLString:applyStyle(@"<body contenteditable='true' style='width: 500px; height: 500px'><div style='width: 200px; height: 200px; background-color: blue' contenteditable='false'><div style='width: 100px; height: 100px; background-color: yellow' contenteditable='true'>Hello World</div></div><p>Body</p></body>")];
+    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(10, 10, 20, 20)];
+    EXPECT_EQ(1UL, contexts.count);
+    EXPECT_EQ(CGRectMake(0, 0, 100, 100), contexts[0].boundingRect);
+}
+
 TEST(RequestTextInputContext, ReadOnlyField)
 {
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to