Title: [276729] trunk
Revision
276729
Author
[email protected]
Date
2021-04-28 12:35:14 -0700 (Wed, 28 Apr 2021)

Log Message

Fine-tune some more selection behaviors in image overlays
https://bugs.webkit.org/show_bug.cgi?id=225121

Reviewed by Tim Horton.

Source/WebCore:

Make some additional minor refinements to selection behaviors in image overlays.

Test:   fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2.html
        DragAndDropTests.DragSelectedTextInImageOverlay

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

Unless `-webkit-user-select: none;` is explicitly set, make each of the text containers under each line have
`-webkit-user-select: all;`, so that text selection snaps to the boundaries of each piece of text.

* page/DragController.cpp:
(WebCore::DragController::startDrag):

Drive-by fix: avoid dragging image overlay text out as rich text.

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

Make an exception for image overlay text, such that we don't select text upon handling a "mousedown" event, even
though the text has `-webkit-user-select: all;`. Also, deploy `RefPtr` in a few places while I'm here.

(WebCore::expandSelectionToRespectSelectOnMouseDown):

Drive-by fix: deploy `RefPtr` in a few places.

Tools:

Add an API test to verify that selected text inside image overlays is dragged out as plain text only.

* TestWebKitAPI/Tests/WebKit/simple-image-overlay.html:
* TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm:
(TEST):

LayoutTests:

Add a new layout test to verify that text selection expands to contain all text underneath selected text
containers.

* fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2-expected.html: Added.
* fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (276728 => 276729)


--- trunk/LayoutTests/ChangeLog	2021-04-28 19:26:04 UTC (rev 276728)
+++ trunk/LayoutTests/ChangeLog	2021-04-28 19:35:14 UTC (rev 276729)
@@ -1,3 +1,16 @@
+2021-04-28  Wenson Hsieh  <[email protected]>
+
+        Fine-tune some more selection behaviors in image overlays
+        https://bugs.webkit.org/show_bug.cgi?id=225121
+
+        Reviewed by Tim Horton.
+
+        Add a new layout test to verify that text selection expands to contain all text underneath selected text
+        containers.
+
+        * fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2-expected.html: Added.
+        * fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2.html: Added.
+
 2021-04-28  Youenn Fablet  <[email protected]>
 
         Set audio transceiver nMax to 1

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


--- trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2-expected.html	2021-04-28 19:35:14 UTC (rev 276729)
@@ -0,0 +1,61 @@
+<!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, [
+        {
+            topLeft : new DOMPointReadOnly(0, 0),
+            topRight : new DOMPointReadOnly(1, 0),
+            bottomRight : new DOMPointReadOnly(1, 0.5),
+            bottomLeft : new DOMPointReadOnly(0, 0.5),
+            children: [
+                {
+                    text : "helloworld1",
+                    topLeft : new DOMPointReadOnly(0, 0),
+                    topRight : new DOMPointReadOnly(0.5, 0),
+                    bottomRight : new DOMPointReadOnly(0.5, 0.5),
+                    bottomLeft : new DOMPointReadOnly(0, 0.5),
+                },
+                {
+                    text : "helloworld2",
+                    topLeft : new DOMPointReadOnly(0.5, 0),
+                    topRight : new DOMPointReadOnly(1, 0),
+                    bottomRight : new DOMPointReadOnly(1, 0.5),
+                    bottomLeft : new DOMPointReadOnly(0.5, 0.5),
+                }
+            ]
+        },
+        {
+            topLeft : new DOMPointReadOnly(0.5, 0.5),
+            topRight : new DOMPointReadOnly(1, 0.5),
+            bottomRight : new DOMPointReadOnly(1, 1),
+            bottomLeft : new DOMPointReadOnly(0.5, 1),
+            children: [
+                {
+                    text : "helloworld3",
+                    topLeft : new DOMPointReadOnly(0.5, 0.5),
+                    topRight : new DOMPointReadOnly(1, 0.5),
+                    bottomRight : new DOMPointReadOnly(1, 1),
+                    bottomLeft : new DOMPointReadOnly(0.5, 1),
+                }
+            ]
+        }
+    ]);
+
+    getSelection().selectAllChildren(internals.shadowRoot(image).querySelector("div#image-overlay"));
+});
+</script>
+</body>
+</html>
\ No newline at end of file

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


--- trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2.html	                        (rev 0)
+++ trunk/LayoutTests/fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2.html	2021-04-28 19:35:14 UTC (rev 276729)
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+img {
+    position: absolute;
+    top: 0;
+    left: 0;
+}
+</style>
+</head>
+<body>
+<img src=""
+<script>
+addEventListener("load", () => {
+    internals.installImageOverlay(document.querySelector("img"), [
+        {
+            topLeft : new DOMPointReadOnly(0, 0),
+            topRight : new DOMPointReadOnly(1, 0),
+            bottomRight : new DOMPointReadOnly(1, 0.5),
+            bottomLeft : new DOMPointReadOnly(0, 0.5),
+            children: [
+                {
+                    text : "helloworld1",
+                    topLeft : new DOMPointReadOnly(0, 0),
+                    topRight : new DOMPointReadOnly(0.5, 0),
+                    bottomRight : new DOMPointReadOnly(0.5, 0.5),
+                    bottomLeft : new DOMPointReadOnly(0, 0.5),
+                },
+                {
+                    text : "helloworld2",
+                    topLeft : new DOMPointReadOnly(0.5, 0),
+                    topRight : new DOMPointReadOnly(1, 0),
+                    bottomRight : new DOMPointReadOnly(1, 0.5),
+                    bottomLeft : new DOMPointReadOnly(0.5, 0.5),
+                }
+            ]
+        },
+        {
+            topLeft : new DOMPointReadOnly(0.5, 0.5),
+            topRight : new DOMPointReadOnly(1, 0.5),
+            bottomRight : new DOMPointReadOnly(1, 1),
+            bottomLeft : new DOMPointReadOnly(0.5, 1),
+            children: [
+                {
+                    text : "helloworld3",
+                    topLeft : new DOMPointReadOnly(0.5, 0.5),
+                    topRight : new DOMPointReadOnly(1, 0.5),
+                    bottomRight : new DOMPointReadOnly(1, 1),
+                    bottomLeft : new DOMPointReadOnly(0.5, 1),
+                }
+            ]
+        }
+    ]);
+
+    eventSender.mouseMoveTo(50, 50);
+    eventSender.mouseDown();
+    eventSender.mouseMoveTo(350, 350);
+    eventSender.mouseUp();
+});
+</script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (276728 => 276729)


--- trunk/Source/WebCore/ChangeLog	2021-04-28 19:26:04 UTC (rev 276728)
+++ trunk/Source/WebCore/ChangeLog	2021-04-28 19:35:14 UTC (rev 276729)
@@ -1,3 +1,36 @@
+2021-04-28  Wenson Hsieh  <[email protected]>
+
+        Fine-tune some more selection behaviors in image overlays
+        https://bugs.webkit.org/show_bug.cgi?id=225121
+
+        Reviewed by Tim Horton.
+
+        Make some additional minor refinements to selection behaviors in image overlays.
+
+        Test:   fast/images/image-extraction/mac/select-image-overlay-with-mouse-drag-2.html
+                DragAndDropTests.DragSelectedTextInImageOverlay
+
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::updateWithImageExtractionResult):
+
+        Unless `-webkit-user-select: none;` is explicitly set, make each of the text containers under each line have
+        `-webkit-user-select: all;`, so that text selection snaps to the boundaries of each piece of text.
+
+        * page/DragController.cpp:
+        (WebCore::DragController::startDrag):
+
+        Drive-by fix: avoid dragging image overlay text out as rich text.
+
+        * page/EventHandler.cpp:
+        (WebCore::nodeToSelectOnMouseDownForNode):
+
+        Make an exception for image overlay text, such that we don't select text upon handling a "mousedown" event, even
+        though the text has `-webkit-user-select: all;`. Also, deploy `RefPtr` in a few places while I'm here.
+
+        (WebCore::expandSelectionToRespectSelectOnMouseDown):
+
+        Drive-by fix: deploy `RefPtr` in a few places.
+
 2021-04-28  Alex Christensen  <[email protected]>
 
         Add SPI to query whether a URL would be upgraded to HTTPS

Modified: trunk/Source/WebCore/html/HTMLElement.cpp (276728 => 276729)


--- trunk/Source/WebCore/html/HTMLElement.cpp	2021-04-28 19:26:04 UTC (rev 276728)
+++ trunk/Source/WebCore/html/HTMLElement.cpp	2021-04-28 19:35:14 UTC (rev 276729)
@@ -1339,6 +1339,7 @@
     static MainThreadNeverDestroyed<const AtomString> imageOverlayLineClass("image-overlay-line", AtomString::ConstructFromLiteral);
     static MainThreadNeverDestroyed<const AtomString> imageOverlayTextClass("image-overlay-text", AtomString::ConstructFromLiteral);
 
+    bool hasUserSelectNone = renderer() && renderer()->style().userSelect() == UserSelect::None;
     IntSize containerSize { offsetWidth(), offsetHeight() };
     for (auto& line : result.lines) {
         auto lineQuad = line.normalizedQuad;
@@ -1431,6 +1432,9 @@
                 (targetSize.height() - sizeBeforeTransform.height()) / 2, "px) "_s,
                 "scale("_s, targetSize.width() / sizeBeforeTransform.width(), ", "_s, targetSize.height() / sizeBeforeTransform.height(), ") "_s
             ));
+
+            if (!hasUserSelectNone || document().isImageDocument())
+                textContainer->setInlineStyleProperty(CSSPropertyWebkitUserSelect, CSSValueAll);
         }
 
         lineContainer->appendChild(HTMLBRElement::create(document()));

Modified: trunk/Source/WebCore/page/DragController.cpp (276728 => 276729)


--- trunk/Source/WebCore/page/DragController.cpp	2021-04-28 19:26:04 UTC (rev 276728)
+++ trunk/Source/WebCore/page/DragController.cpp	2021-04-28 19:35:14 UTC (rev 276729)
@@ -1020,8 +1020,12 @@
             ASSERT(selectionRange);
 
             src.editor().willWriteSelectionToPasteboard(*selectionRange);
+            auto selection = src.selection().selection();
+            bool shouldDragAsPlainText = enclosingTextFormControl(selection.start());
+            if (auto range = selection.range(); range && HTMLElement::isInsideImageOverlay(*range))
+                shouldDragAsPlainText = true;
 
-            if (enclosingTextFormControl(src.selection().selection().start())) {
+            if (shouldDragAsPlainText) {
                 if (mustUseLegacyDragClient)
                     dataTransfer.pasteboard().writePlainText(src.editor().selectedTextForDataTransfer(), Pasteboard::CannotSmartReplace);
                 else {

Modified: trunk/Source/WebCore/page/EventHandler.cpp (276728 => 276729)


--- trunk/Source/WebCore/page/EventHandler.cpp	2021-04-28 19:26:04 UTC (rev 276728)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2021-04-28 19:35:14 UTC (rev 276729)
@@ -436,9 +436,12 @@
 
 static Node* nodeToSelectOnMouseDownForNode(Node& targetNode)
 {
-    if (Node* rootUserSelectAll = Position::rootUserSelectAllForNode(&targetNode))
-        return rootUserSelectAll;
+    if (HTMLElement::isInsideImageOverlay(targetNode))
+        return nullptr;
 
+    if (auto rootUserSelectAll = makeRefPtr(Position::rootUserSelectAllForNode(&targetNode)))
+        return rootUserSelectAll.get();
+
     if (targetNode.shouldSelectOnMouseDown())
         return &targetNode;
 
@@ -447,13 +450,13 @@
 
 static VisibleSelection expandSelectionToRespectSelectOnMouseDown(Node& targetNode, const VisibleSelection& selection)
 {
-    Node* nodeToSelect = nodeToSelectOnMouseDownForNode(targetNode);
+    auto nodeToSelect = makeRefPtr(nodeToSelectOnMouseDownForNode(targetNode));
     if (!nodeToSelect)
         return selection;
 
     VisibleSelection newSelection(selection);
-    newSelection.setBase(positionBeforeNode(nodeToSelect).upstream(CanCrossEditingBoundary));
-    newSelection.setExtent(positionAfterNode(nodeToSelect).downstream(CanCrossEditingBoundary));
+    newSelection.setBase(positionBeforeNode(nodeToSelect.get()).upstream(CanCrossEditingBoundary));
+    newSelection.setExtent(positionAfterNode(nodeToSelect.get()).downstream(CanCrossEditingBoundary));
 
     return newSelection;
 }

Modified: trunk/Tools/ChangeLog (276728 => 276729)


--- trunk/Tools/ChangeLog	2021-04-28 19:26:04 UTC (rev 276728)
+++ trunk/Tools/ChangeLog	2021-04-28 19:35:14 UTC (rev 276729)
@@ -1,3 +1,16 @@
+2021-04-28  Wenson Hsieh  <[email protected]>
+
+        Fine-tune some more selection behaviors in image overlays
+        https://bugs.webkit.org/show_bug.cgi?id=225121
+
+        Reviewed by Tim Horton.
+
+        Add an API test to verify that selected text inside image overlays is dragged out as plain text only.
+
+        * TestWebKitAPI/Tests/WebKit/simple-image-overlay.html:
+        * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm:
+        (TEST):
+
 2021-04-28  Alex Christensen  <[email protected]>
 
         Add SPI to query whether a URL would be upgraded to HTTPS

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit/simple-image-overlay.html (276728 => 276729)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/simple-image-overlay.html	2021-04-28 19:26:04 UTC (rev 276728)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/simple-image-overlay.html	2021-04-28 19:35:14 UTC (rev 276729)
@@ -13,6 +13,11 @@
 }
 </style>
 <script>
+function selectImageOverlay()
+{
+    getSelection().selectAllChildren(internals.shadowRoot(document.querySelector("img")).querySelector("div#image-overlay"));
+}
+
 addEventListener("load", () => {
     if (!window.internals)
         return;

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm (276728 => 276729)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm	2021-04-28 19:26:04 UTC (rev 276728)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm	2021-04-28 19:35:14 UTC (rev 276729)
@@ -33,6 +33,7 @@
 #import "WKWebViewConfigurationExtras.h"
 #import <WebKit/WKPreferencesPrivate.h>
 #import <WebKit/WebArchive.h>
+#import <wtf/RetainPtr.h>
 
 #if PLATFORM(IOS_FAMILY)
 #import <MobileCoreServices/MobileCoreServices.h>
@@ -401,6 +402,36 @@
     EXPECT_TRUE([simulator containsDraggedType:(__bridge NSString *)kUTTypeJPEG]);
 }
 
+TEST(DragAndDropTests, DragSelectedTextInImageOverlay)
+{
+    auto configuration = retainPtr([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]);
+    [[configuration preferences] _setLargeImageAsyncDecodingEnabled:NO];
+
+    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
+    [[simulator webView] synchronouslyLoadTestPageNamed:@"simple-image-overlay"];
+    [[simulator webView] stringByEvaluatingJavaScript:@"selectImageOverlay()"];
+    [[simulator webView] waitForNextPresentationUpdate];
+
+    [simulator runFrom:NSMakePoint(150, 40) to:NSMakePoint(300, 300)];
+
+    EXPECT_TRUE([simulator containsDraggedType:(__bridge NSString *)kUTTypeUTF8PlainText]);
+    EXPECT_FALSE([simulator containsDraggedType:(__bridge NSString *)kUTTypeHTML]);
+    EXPECT_FALSE([simulator containsDraggedType:(__bridge NSString *)kUTTypeRTF]);
+
+    RetainPtr<NSString> draggedText;
+#if USE(APPKIT)
+    draggedText = [[simulator draggingInfo].draggingPasteboard stringForType:(__bridge NSString *)kUTTypeUTF8PlainText];
+#else
+    bool doneLoadingString = false;
+    [[simulator sourceItemProviders].firstObject loadObjectOfClass:NSString.class completionHandler:[&](NSString *string, NSError *error) {
+        draggedText = adoptNS([string copy]);
+        doneLoadingString = true;
+    }];
+    TestWebKitAPI::Util::run(&doneLoadingString);
+#endif
+    EXPECT_WK_STREQ(draggedText.get(), "foobar");
+}
+
 #endif // ENABLE(IMAGE_EXTRACTION)
 
 #endif // ENABLE(DRAG_SUPPORT) && !PLATFORM(MACCATALYST)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to