Changeset 262469 in webkit


Ignore:
Timestamp:
Jun 2, 2020 6:50:46 PM (4 years ago)
Author:
Wenson Hsieh
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):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r262463 r262469  
     12020-06-02  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Add a helper method to populate a DataTransfer before dispatching a "dragstart" event
     4        https://bugs.webkit.org/show_bug.cgi?id=212614
     5        Work towards <rdar://problem/61368402>
     6
     7        Reviewed by Tim Horton.
     8
     9        Add a helper method in DragController to pre-populate the StaticPasteboard-backed DataTransfer before
     10        dispatching the "dragstart" event. There should be no change in behavior yet, since StaticPasteboard doesn't
     11        implement methods for writing data to the pasteboard, which this new method uses.
     12
     13        * page/DragController.cpp:
     14        (WebCore::DragController::prepareForDragStart const):
     15        (WebCore::DragController::hitTestResultForDragStart const):
     16        (WebCore::DragController::startDrag):
     17        * page/DragController.h:
     18        * page/EventHandler.cpp:
     19        (WebCore::EventHandler::dispatchDragStartEventOnSourceElement):
     20
    1212020-06-02  Andres Gonzalez  <andresg_22@apple.com>
    222
  • trunk/Source/WebCore/page/DragController.cpp

    r262190 r262469  
    900900}
    901901
    902 bool DragController::startDrag(Frame& src, const DragState& state, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, HasNonDefaultPasteboardData hasData)
    903 {
    904     if (!src.view() || !src.contentRenderer() || !state.source)
    905         return false;
    906 
    907     Ref<Frame> protector(src);
     902void DragController::prepareForDragStart(Frame& source, DragSourceAction action, Element& element, DataTransfer& dataTransfer, const IntPoint& dragOrigin) const
     903{
     904#if !PLATFORM(WIN)
     905    Ref<Frame> protector(source);
     906    auto hitTestResult = hitTestResultForDragStart(source, element, dragOrigin);
     907    if (!hitTestResult)
     908        return;
     909
     910    auto& pasteboard = dataTransfer.pasteboard();
     911    auto& editor = source.editor();
     912    if (action == DragSourceActionSelection) {
     913        if (enclosingTextFormControl(source.selection().selection().start()))
     914            pasteboard.writePlainText(editor.selectedTextForDataTransfer(), Pasteboard::CannotSmartReplace);
     915        else
     916            editor.writeSelectionToPasteboard(pasteboard);
     917        return;
     918    }
     919
     920    auto* image = getImage(element);
     921    auto imageURL = hitTestResult->absoluteImageURL();
     922    if ((action & DragSourceActionImage) && !imageURL.isEmpty() && image && !image->isNull()) {
     923        editor.writeImageToPasteboard(pasteboard, element, imageURL, { });
     924        return;
     925    }
     926
     927    auto linkURL = hitTestResult->absoluteLinkURL();
     928    if ((action & DragSourceActionLink) && !linkURL.isEmpty() && source.document()->securityOrigin().canDisplay(linkURL))
     929        editor.copyURL(linkURL, hitTestResult->textContent().simplifyWhiteSpace(), pasteboard);
     930#else
     931    // FIXME: Make this work on Windows by implementing Editor::writeSelectionToPasteboard and Editor::writeImageToPasteboard.
     932    UNUSED_PARAM(source);
     933    UNUSED_PARAM(action);
     934    UNUSED_PARAM(element);
     935    UNUSED_PARAM(dataTransfer);
     936    UNUSED_PARAM(dragOrigin);
     937#endif
     938}
     939
     940Optional<HitTestResult> DragController::hitTestResultForDragStart(Frame& source, Element& element, const IntPoint& location) const
     941{
     942    if (!source.view() || !source.contentRenderer())
     943        return WTF::nullopt;
     944
    908945    constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::AllowChildFrameContent };
    909     HitTestResult hitTestResult = src.eventHandler().hitTestResultAtPoint(dragOrigin, hitType);
    910 
    911     bool sourceContainsHitNode = state.source->containsIncludingShadowDOM(hitTestResult.innerNode());
     946    auto hitTestResult = source.eventHandler().hitTestResultAtPoint(location, hitType);
     947
     948    bool sourceContainsHitNode = element.containsIncludingShadowDOM(hitTestResult.innerNode());
    912949    if (!sourceContainsHitNode) {
    913950        // The original node being dragged isn't under the drag origin anymore... maybe it was
    914951        // hidden or moved out from under the cursor. Regardless, we don't want to start a drag on
    915952        // something that's not actually under the drag origin.
    916         return false;
    917     }
    918 
    919     URL linkURL = hitTestResult.absoluteLinkURL();
    920     URL imageURL = hitTestResult.absoluteImageURL();
     953        return WTF::nullopt;
     954    }
     955
     956    return { hitTestResult };
     957}
     958
     959bool DragController::startDrag(Frame& src, const DragState& state, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, HasNonDefaultPasteboardData hasData)
     960{
     961    if (!state.source)
     962        return false;
     963
     964    Ref<Frame> protector(src);
     965    auto hitTestResult = hitTestResultForDragStart(src, *state.source, dragOrigin);
     966    if (!hitTestResult)
     967        return false;
     968
     969    auto linkURL = hitTestResult->absoluteLinkURL();
     970    auto imageURL = hitTestResult->absoluteImageURL();
    921971
    922972    IntPoint mouseDraggedPoint = src.view()->windowToContents(dragEvent.position());
     
    10471097                selectElement(element);
    10481098            if (!attachmentInfo)
    1049                 declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult.altDisplayString());
     1099                declareAndWriteDragImage(dataTransfer, element, !linkURL.isEmpty() ? linkURL : imageURL, hitTestResult->altDisplayString());
    10501100        }
    10511101
     
    10531103
    10541104        if (!dragImage)
    1055             doImageDrag(element, dragOrigin, hitTestResult.imageRect(), src, m_dragOffset, state, WTFMove(attachmentInfo));
     1105            doImageDrag(element, dragOrigin, hitTestResult->imageRect(), src, m_dragOffset, state, WTFMove(attachmentInfo));
    10561106        else {
    10571107            // DHTML defined drag image
     
    10651115        PasteboardWriterData pasteboardWriterData;
    10661116
    1067         String textContentWithSimplifiedWhiteSpace = hitTestResult.textContent().simplifyWhiteSpace();
     1117        String textContentWithSimplifiedWhiteSpace = hitTestResult->textContent().simplifyWhiteSpace();
    10681118
    10691119        if (hasData == HasNonDefaultPasteboardData::No) {
     
    10791129            PasteboardURL pasteboardURL;
    10801130            pasteboardURL.url = linkURL;
    1081             pasteboardURL.title = hitTestResult.textContent();
     1131            pasteboardURL.title = hitTestResult->textContent();
    10821132            dataTransfer.pasteboard().writeTrustworthyWebURLsPboardType(pasteboardURL);
    10831133        }
  • trunk/Source/WebCore/page/DragController.h

    r262367 r262469  
    4343class HTMLImageElement;
    4444class HTMLInputElement;
     45class HitTestResult;
    4546class IntRect;
    4647class Page;
     
    9495    WEBCORE_EXPORT void insertDroppedImagePlaceholdersAtCaret(const Vector<IntSize>& imageSizes);
    9596
     97    void prepareForDragStart(Frame& sourceFrame, DragSourceAction, Element& sourceElement, DataTransfer&, const IntPoint& dragOrigin) const;
    9698    bool startDrag(Frame& src, const DragState&, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, HasNonDefaultPasteboardData);
    9799    static const IntSize& maxDragImageSize();
     
    118120    void mouseMovedIntoDocument(Document*);
    119121    bool shouldUseCachedImageForDragImage(const Image&) const;
     122
     123    Optional<HitTestResult> hitTestResultForDragStart(Frame&, Element&, const IntPoint&) const;
    120124
    121125    void doImageDrag(Element&, const IntPoint&, const IntRect&, Frame&, IntPoint&, const DragState&, PromisedAttachmentInfo&&);
  • trunk/Source/WebCore/page/EventHandler.cpp

    r262051 r262469  
    37723772bool EventHandler::dispatchDragStartEventOnSourceElement(DataTransfer& dataTransfer)
    37733773{
     3774    if (auto* page = m_frame.page())
     3775        page->dragController().prepareForDragStart(m_frame, dragState().type, *dragState().source, dataTransfer, m_mouseDownContentsPosition);
    37743776    return !dispatchDragEvent(eventNames().dragstartEvent, *dragState().source, m_mouseDownEvent, dataTransfer) && !m_frame.selection().selection().isInPasswordField();
    37753777}
    3776    
     3778
    37773779static bool ExactlyOneBitSet(DragSourceAction n)
    37783780{
Note: See TracChangeset for help on using the changeset viewer.