Title: [262469] trunk/Source/WebCore
Revision
262469
Author
wenson_hs...@apple.com
Date
2020-06-02 18:50:46 -0700 (Tue, 02 Jun 2020)

Log Message

Add a helper method to populate a DataTransfer before dispatching a "dragstart" event
https://bugs.webkit.org/show_bug.cgi?id=212614
Work towards <rdar://problem/61368402>

Reviewed by Tim Horton.

Add a helper method in DragController to pre-populate the StaticPasteboard-backed DataTransfer before
dispatching the "dragstart" event. There should be no change in behavior yet, since StaticPasteboard doesn't
implement methods for writing data to the pasteboard, which this new method uses.

* page/DragController.cpp:
(WebCore::DragController::prepareForDragStart const):
(WebCore::DragController::hitTestResultForDragStart const):
(WebCore::DragController::startDrag):
* page/DragController.h:
* page/EventHandler.cpp:
(WebCore::EventHandler::dispatchDragStartEventOnSourceElement):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (262468 => 262469)


--- trunk/Source/WebCore/ChangeLog	2020-06-03 01:38:28 UTC (rev 262468)
+++ trunk/Source/WebCore/ChangeLog	2020-06-03 01:50:46 UTC (rev 262469)
@@ -1,3 +1,23 @@
+2020-06-02  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        Add a helper method to populate a DataTransfer before dispatching a "dragstart" event
+        https://bugs.webkit.org/show_bug.cgi?id=212614
+        Work towards <rdar://problem/61368402>
+
+        Reviewed by Tim Horton.
+
+        Add a helper method in DragController to pre-populate the StaticPasteboard-backed DataTransfer before
+        dispatching the "dragstart" event. There should be no change in behavior yet, since StaticPasteboard doesn't
+        implement methods for writing data to the pasteboard, which this new method uses.
+
+        * page/DragController.cpp:
+        (WebCore::DragController::prepareForDragStart const):
+        (WebCore::DragController::hitTestResultForDragStart const):
+        (WebCore::DragController::startDrag):
+        * page/DragController.h:
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::dispatchDragStartEventOnSourceElement):
+
 2020-06-02  Andres Gonzalez  <andresg...@apple.com>
 
         AXIsolatedTree::updateNode should not call nodeForID.

Modified: trunk/Source/WebCore/page/DragController.cpp (262468 => 262469)


--- trunk/Source/WebCore/page/DragController.cpp	2020-06-03 01:38:28 UTC (rev 262468)
+++ trunk/Source/WebCore/page/DragController.cpp	2020-06-03 01:50:46 UTC (rev 262469)
@@ -899,26 +899,76 @@
     return IntPoint(xpos, ypos);
 }
 
-bool DragController::startDrag(Frame& src, const DragState& state, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, HasNonDefaultPasteboardData hasData)
+void DragController::prepareForDragStart(Frame& source, DragSourceAction action, Element& element, DataTransfer& dataTransfer, const IntPoint& dragOrigin) const
 {
-    if (!src.view() || !src.contentRenderer() || !state.source)
-        return false;
+#if !PLATFORM(WIN)
+    Ref<Frame> protector(source);
+    auto hitTestResult = hitTestResultForDragStart(source, element, dragOrigin);
+    if (!hitTestResult)
+        return;
 
-    Ref<Frame> protector(src);
+    auto& pasteboard = dataTransfer.pasteboard();
+    auto& editor = source.editor();
+    if (action == DragSourceActionSelection) {
+        if (enclosingTextFormControl(source.selection().selection().start()))
+            pasteboard.writePlainText(editor.selectedTextForDataTransfer(), Pasteboard::CannotSmartReplace);
+        else
+            editor.writeSelectionToPasteboard(pasteboard);
+        return;
+    }
+
+    auto* image = getImage(element);
+    auto imageURL = hitTestResult->absoluteImageURL();
+    if ((action & DragSourceActionImage) && !imageURL.isEmpty() && image && !image->isNull()) {
+        editor.writeImageToPasteboard(pasteboard, element, imageURL, { });
+        return;
+    }
+
+    auto linkURL = hitTestResult->absoluteLinkURL();
+    if ((action & DragSourceActionLink) && !linkURL.isEmpty() && source.document()->securityOrigin().canDisplay(linkURL))
+        editor.copyURL(linkURL, hitTestResult->textContent().simplifyWhiteSpace(), pasteboard);
+#else
+    // FIXME: Make this work on Windows by implementing Editor::writeSelectionToPasteboard and Editor::writeImageToPasteboard.
+    UNUSED_PARAM(source);
+    UNUSED_PARAM(action);
+    UNUSED_PARAM(element);
+    UNUSED_PARAM(dataTransfer);
+    UNUSED_PARAM(dragOrigin);
+#endif
+}
+
+Optional<HitTestResult> DragController::hitTestResultForDragStart(Frame& source, Element& element, const IntPoint& location) const
+{
+    if (!source.view() || !source.contentRenderer())
+        return WTF::nullopt;
+
     constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::AllowChildFrameContent };
-    HitTestResult hitTestResult = src.eventHandler().hitTestResultAtPoint(dragOrigin, hitType);
+    auto hitTestResult = source.eventHandler().hitTestResultAtPoint(location, hitType);
 
-    bool sourceContainsHitNode = state.source->containsIncludingShadowDOM(hitTestResult.innerNode());
+    bool sourceContainsHitNode = element.containsIncludingShadowDOM(hitTestResult.innerNode());
     if (!sourceContainsHitNode) {
         // The original node being dragged isn't under the drag origin anymore... maybe it was
         // hidden or moved out from under the cursor. Regardless, we don't want to start a drag on
         // something that's not actually under the drag origin.
-        return false;
+        return WTF::nullopt;
     }
 
-    URL linkURL = hitTestResult.absoluteLinkURL();
-    URL imageURL = hitTestResult.absoluteImageURL();
+    return { hitTestResult };
+}
 
+bool DragController::startDrag(Frame& src, const DragState& state, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, HasNonDefaultPasteboardData hasData)
+{
+    if (!state.source)
+        return false;
+
+    Ref<Frame> protector(src);
+    auto hitTestResult = hitTestResultForDragStart(src, *state.source, dragOrigin);
+    if (!hitTestResult)
+        return false;
+
+    auto linkURL = hitTestResult->absoluteLinkURL();
+    auto imageURL = hitTestResult->absoluteImageURL();
+
     IntPoint mouseDraggedPoint = src.view()->windowToContents(dragEvent.position());
 
     m_draggingImageURL = URL();
@@ -1046,13 +1096,13 @@
             if (element.isContentRichlyEditable())
                 selectElement(element);
             if (!attachmentInfo)
-                declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult.altDisplayString());
+                declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult->altDisplayString());
         }
 
         client().willPerformDragSourceAction(DragSourceActionImage, dragOrigin, dataTransfer);
 
         if (!dragImage)
-            doImageDrag(element, dragOrigin, hitTestResult.imageRect(), src, m_dragOffset, state, WTFMove(attachmentInfo));
+            doImageDrag(element, dragOrigin, hitTestResult->imageRect(), src, m_dragOffset, state, WTFMove(attachmentInfo));
         else {
             // DHTML defined drag image
             doSystemDrag(WTFMove(dragImage), dragLoc, dragOrigin, src, state, WTFMove(attachmentInfo));
@@ -1064,7 +1114,7 @@
     if (!linkURL.isEmpty() && (m_dragSourceAction & DragSourceActionLink)) {
         PasteboardWriterData pasteboardWriterData;
 
-        String textContentWithSimplifiedWhiteSpace = hitTestResult.textContent().simplifyWhiteSpace();
+        String textContentWithSimplifiedWhiteSpace = hitTestResult->textContent().simplifyWhiteSpace();
 
         if (hasData == HasNonDefaultPasteboardData::No) {
             // Simplify whitespace so the title put on the dataTransfer resembles what the user sees
@@ -1078,7 +1128,7 @@
             // but don't overwrite more general pasteboard types.
             PasteboardURL pasteboardURL;
             pasteboardURL.url = ""
-            pasteboardURL.title = hitTestResult.textContent();
+            pasteboardURL.title = hitTestResult->textContent();
             dataTransfer.pasteboard().writeTrustworthyWebURLsPboardType(pasteboardURL);
         }
 

Modified: trunk/Source/WebCore/page/DragController.h (262468 => 262469)


--- trunk/Source/WebCore/page/DragController.h	2020-06-03 01:38:28 UTC (rev 262468)
+++ trunk/Source/WebCore/page/DragController.h	2020-06-03 01:50:46 UTC (rev 262469)
@@ -42,6 +42,7 @@
 class FrameSelection;
 class HTMLImageElement;
 class HTMLInputElement;
+class HitTestResult;
 class IntRect;
 class Page;
 class PlatformMouseEvent;
@@ -93,6 +94,7 @@
     WEBCORE_EXPORT void finalizeDroppedImagePlaceholder(HTMLImageElement&);
     WEBCORE_EXPORT void insertDroppedImagePlaceholdersAtCaret(const Vector<IntSize>& imageSizes);
 
+    void prepareForDragStart(Frame& sourceFrame, DragSourceAction, Element& sourceElement, DataTransfer&, const IntPoint& dragOrigin) const;
     bool startDrag(Frame& src, const DragState&, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, HasNonDefaultPasteboardData);
     static const IntSize& maxDragImageSize();
 
@@ -118,6 +120,8 @@
     void mouseMovedIntoDocument(Document*);
     bool shouldUseCachedImageForDragImage(const Image&) const;
 
+    Optional<HitTestResult> hitTestResultForDragStart(Frame&, Element&, const IntPoint&) const;
+
     void doImageDrag(Element&, const IntPoint&, const IntRect&, Frame&, IntPoint&, const DragState&, PromisedAttachmentInfo&&);
     void doSystemDrag(DragImage, const IntPoint&, const IntPoint&, Frame&, const DragState&, PromisedAttachmentInfo&&);
 

Modified: trunk/Source/WebCore/page/EventHandler.cpp (262468 => 262469)


--- trunk/Source/WebCore/page/EventHandler.cpp	2020-06-03 01:38:28 UTC (rev 262468)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2020-06-03 01:50:46 UTC (rev 262469)
@@ -3771,9 +3771,11 @@
 
 bool EventHandler::dispatchDragStartEventOnSourceElement(DataTransfer& dataTransfer)
 {
+    if (auto* page = m_frame.page())
+        page->dragController().prepareForDragStart(m_frame, dragState().type, *dragState().source, dataTransfer, m_mouseDownContentsPosition);
     return !dispatchDragEvent(eventNames().dragstartEvent, *dragState().source, m_mouseDownEvent, dataTransfer) && !m_frame.selection().selection().isInPasswordField();
 }
-    
+
 static bool ExactlyOneBitSet(DragSourceAction n)
 {
     return n && !(n & (n - 1));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to