Title: [274420] trunk
Revision
274420
Author
wenson_hs...@apple.com
Date
2021-03-15 06:36:50 -0700 (Mon, 15 Mar 2021)

Log Message

[macOS] Selecting text via mouse drag in image documents shouldn't trigger click events
https://bugs.webkit.org/show_bug.cgi?id=223075
<rdar://problem/75334611>

Reviewed by Tim Horton.

Source/WebCore:

Improve image overlay support in image documents, by setting `-webkit-user-select: text;` on the image overlay
container and `cursor: text;` on each of the text children. Additionally, make it so that text selection in
image overlays doesn't trigger a click event, so that attempting to select text doesn't trigger click events.

Tests: fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click.html
       fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag.html

* html/HTMLElement.cpp:
(WebCore::HTMLElement::isImageOverlayText):

Make a slight adjustment here to handle the case where the host element's shadow root is not installed by the
user agent, and also so that we return `true` for all nodes underneath the image overlay container as well (not
just text nodes). See `DragController` change below for more details.

(WebCore::HTMLElement::updateWithImageExtractionResult):
* page/DragController.cpp:
(WebCore::DragController::draggableElement const):

Make another adjustment to `DragController::draggableElement`, such that we don't initiate image drags when
dragging over text inside the image overlay. Note that this does not prevent drag start when the text is
selected, since that does not result in an image drag (i.e., `DragSourceAction::Image`).

* page/EventHandler.cpp:
(WebCore::EventHandler::updateSelectionForMouseDrag):

LayoutTests:

Add a couple of new layout tests to exercise the new behavior.

* fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click-expected.txt: Added.
* fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click.html: Added.
* fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-expected-mismatch.html: Added.
* fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (274419 => 274420)


--- trunk/LayoutTests/ChangeLog	2021-03-15 13:18:25 UTC (rev 274419)
+++ trunk/LayoutTests/ChangeLog	2021-03-15 13:36:50 UTC (rev 274420)
@@ -1,3 +1,18 @@
+2021-03-15  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [macOS] Selecting text via mouse drag in image documents shouldn't trigger click events
+        https://bugs.webkit.org/show_bug.cgi?id=223075
+        <rdar://problem/75334611>
+
+        Reviewed by Tim Horton.
+
+        Add a couple of new layout tests to exercise the new behavior.
+
+        * fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click-expected.txt: Added.
+        * fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click.html: Added.
+        * fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-expected-mismatch.html: Added.
+        * fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag.html: Added.
+
 2021-03-15  Rob Buis  <rb...@igalia.com>
 
         Treat min-intrinsic like *-content

Added: trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click-expected.txt (0 => 274420)


--- trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click-expected.txt	2021-03-15 13:36:50 UTC (rev 274420)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click.html (0 => 274420)


--- trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click.html	2021-03-15 13:36:50 UTC (rev 274420)
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+img {
+    position: absolute;
+    top: 0;
+    left: 0;
+}
+</style>
+</head>
+<body>
+<img src=""
+<script>
+addEventListener("load", () => {
+    let image = document.querySelector("img");
+    internals.installImageOverlay(image, [{
+        text : "hello",
+        topLeft : new DOMPointReadOnly(0, 0.5),
+        topRight : new DOMPointReadOnly(1, 0.5),
+        bottomRight : new DOMPointReadOnly(1, 1),
+        bottomLeft : new DOMPointReadOnly(0, 1),
+    }]);
+
+    image.addEventListener("click", event => {
+        testFailed("Observed click.");
+    });
+
+    eventSender.mouseMoveTo(50, 300);
+    eventSender.mouseDown();
+    eventSender.mouseMoveTo(350, 300);
+    eventSender.mouseUp();
+});
+</script>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-expected-mismatch.html (0 => 274420)


--- trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-expected-mismatch.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-expected-mismatch.html	2021-03-15 13:36:50 UTC (rev 274420)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+img {
+    position: absolute;
+    top: 0;
+    left: 0;
+}
+</style>
+</head>
+<body>
+<img src=""
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag.html (0 => 274420)


--- trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag.html	2021-03-15 13:36:50 UTC (rev 274420)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+img {
+    position: absolute;
+    top: 0;
+    left: 0;
+}
+</style>
+</head>
+<body>
+<img src=""
+<script>
+addEventListener("load", () => {
+    let image = document.querySelector("img");
+    internals.installImageOverlay(image, [{
+        text : "hello",
+        topLeft : new DOMPointReadOnly(0, 0.5),
+        topRight : new DOMPointReadOnly(1, 0.5),
+        bottomRight : new DOMPointReadOnly(1, 1),
+        bottomLeft : new DOMPointReadOnly(0, 1),
+    }]);
+
+    eventSender.mouseMoveTo(50, 300);
+    eventSender.mouseDown();
+    eventSender.mouseMoveTo(350, 300);
+    eventSender.mouseUp();
+});
+</script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (274419 => 274420)


--- trunk/Source/WebCore/ChangeLog	2021-03-15 13:18:25 UTC (rev 274419)
+++ trunk/Source/WebCore/ChangeLog	2021-03-15 13:36:50 UTC (rev 274420)
@@ -1,3 +1,36 @@
+2021-03-15  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [macOS] Selecting text via mouse drag in image documents shouldn't trigger click events
+        https://bugs.webkit.org/show_bug.cgi?id=223075
+        <rdar://problem/75334611>
+
+        Reviewed by Tim Horton.
+
+        Improve image overlay support in image documents, by setting `-webkit-user-select: text;` on the image overlay
+        container and `cursor: text;` on each of the text children. Additionally, make it so that text selection in
+        image overlays doesn't trigger a click event, so that attempting to select text doesn't trigger click events.
+
+        Tests: fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-does-not-fire-click.html
+               fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag.html
+
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::isImageOverlayText):
+
+        Make a slight adjustment here to handle the case where the host element's shadow root is not installed by the
+        user agent, and also so that we return `true` for all nodes underneath the image overlay container as well (not
+        just text nodes). See `DragController` change below for more details.
+
+        (WebCore::HTMLElement::updateWithImageExtractionResult):
+        * page/DragController.cpp:
+        (WebCore::DragController::draggableElement const):
+
+        Make another adjustment to `DragController::draggableElement`, such that we don't initiate image drags when
+        dragging over text inside the image overlay. Note that this does not prevent drag start when the text is
+        selected, since that does not result in an image drag (i.e., `DragSourceAction::Image`).
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::updateSelectionForMouseDrag):
+
 2021-03-15  Rob Buis  <rb...@igalia.com>
 
         Treat min-intrinsic like *-content

Modified: trunk/Source/WebCore/html/HTMLElement.cpp (274419 => 274420)


--- trunk/Source/WebCore/html/HTMLElement.cpp	2021-03-15 13:18:25 UTC (rev 274419)
+++ trunk/Source/WebCore/html/HTMLElement.cpp	2021-03-15 13:36:50 UTC (rev 274420)
@@ -1236,22 +1236,17 @@
 
 bool HTMLElement::isImageOverlayText(const Node& node)
 {
-    if (!is<Text>(node))
-        return false;
-
     auto shadowHost = node.shadowHost();
     if (!shadowHost)
         return false;
 
-    auto userAgentShadowRoot = shadowHost->userAgentShadowRoot();
-    if (!userAgentShadowRoot) {
-        ASSERT_NOT_REACHED();
+    auto shadowRoot = shadowHost->shadowRoot();
+    if (!shadowRoot || shadowRoot->mode() != ShadowRootMode::UserAgent || shadowRoot != node.containingShadowRoot())
         return false;
-    }
 
-    for (auto& child : childrenOfType<HTMLDivElement>(*userAgentShadowRoot)) {
+    for (auto& child : childrenOfType<HTMLDivElement>(*shadowRoot)) {
         if (child.getIdAttribute() == imageOverlayElementIdentifier())
-            return child.contains(&node);
+            return node.isDescendantOf(&child);
     }
 
     return false;
@@ -1280,6 +1275,8 @@
 
     auto container = HTMLDivElement::create(document());
     container->setIdAttribute(imageOverlayElementIdentifier());
+    if (document().isImageDocument())
+        container->setInlineStyleProperty(CSSPropertyWebkitUserSelect, CSSValueText);
     shadowRoot->appendChild(container);
 
     static MainThreadNeverDestroyed<const AtomString> imageOverlayTextClass("image-overlay-text", AtomString::ConstructFromLiteral);
@@ -1312,6 +1309,9 @@
             rotationTransformationAsText,
             "scale("_s, scale.width(), ", "_s, scale.height(), ") "_s
         ));
+
+        if (document().isImageDocument())
+            child->setInlineStyleProperty(CSSPropertyCursor, CSSValueText);
     }
 
     if (auto frame = makeRefPtr(document().frame()))

Modified: trunk/Source/WebCore/page/DragController.cpp (274419 => 274420)


--- trunk/Source/WebCore/page/DragController.cpp	2021-03-15 13:18:25 UTC (rev 274419)
+++ trunk/Source/WebCore/page/DragController.cpp	2021-03-15 13:36:50 UTC (rev 274420)
@@ -798,6 +798,7 @@
         if (dragMode == UserDrag::Auto) {
             if ((m_dragSourceAction.contains(DragSourceAction::Image))
                 && is<HTMLImageElement>(*element)
+                && !HTMLElement::isImageOverlayText(*startElement)
                 && imageElementIsDraggable(downcast<HTMLImageElement>(*element), *sourceFrame)) {
                 state.type.add(DragSourceAction::Image);
                 return element;

Modified: trunk/Source/WebCore/page/EventHandler.cpp (274419 => 274420)


--- trunk/Source/WebCore/page/EventHandler.cpp	2021-03-15 13:18:25 UTC (rev 274419)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2021-03-15 13:36:50 UTC (rev 274420)
@@ -999,6 +999,10 @@
 
     m_frame.selection().setSelectionByMouseIfDifferent(newSelection, m_frame.selection().granularity(),
         FrameSelection::EndPointsAdjustmentMode::AdjustAtBidiBoundary);
+
+    if (newSelection.start().containerNode() && HTMLElement::isImageOverlayText(*newSelection.start().containerNode())
+        && newSelection.end().containerNode() && HTMLElement::isImageOverlayText(*newSelection.end().containerNode()))
+        invalidateClick();
 }
 #endif // ENABLE(DRAG_SUPPORT)
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to