[iOS WK2] Support tapping to add items to the current drag session in web content
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Sep 2017 02:09:28 +0000 (02:09 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Sep 2017 02:09:28 +0000 (02:09 +0000)
commita07b66180df50e7338b3fb1c556987ce1bf0d0cf
tree6e66c8cd936d0163b9cd9aa92c092a2477621f99
parenta026540557a22b26c1953acfecbd2cd73ba75986
[iOS WK2] Support tapping to add items to the current drag session in web content
https://bugs.webkit.org/show_bug.cgi?id=176421
<rdar://problem/31144674>

Reviewed by Tim Horton.

Source/WebCore:

Refactors some drag initiation logic to handle starting a drag when data has already been written to the
pasteboard (in the case of iOS, WebItemProviderPasteboard). See annotated comments below for more detail.

Tests: DataInteractionTests.AdditionalLinkAndImageIntoContentEditable

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

Add a HasNonDefaultPasteboardData argument here, and replace checks for !dataTransfer.pasteboard().hasData()
with checks for whether the argument is HasNonDefaultPasteboardData::No. These checks for Pasteboard::hasData()
currently prevent us from overwriting custom pasteboard data, in the case that the page has written pasteboard
data using the event's DataTransfer. However, in the case of adding additional drag items to the session, we
will already have pasteboard data, so these checks will prevent us from writing default data to the pasteboard.
See EventHandler::handleDrag for more detail.

* page/DragController.h:
* page/DragState.h:

Remove the draggedContentRange member from DragState. See below.

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

Simplify the handling of dragged content range markers. Instead of storing the DOM Range being dragged and
removing/repainting the range after dragging ends, just repaint the contentRenderer of the frame being dragged.
When the dragging session has completely ended, remove all dragged content ranges from the page's mainframe and
all of its subframes, and repaint everything.

(WebCore::EventHandler::dragCancelled):
(WebCore::EventHandler::didStartDrag):
(WebCore::EventHandler::dragSourceEndedAt):

Add a MayExtendDragSession argument, indicating whether or not the web process will attempt to continue the drag
session, in which case EventHandler::dragSourceEndedAt should not remove any existing dragged content range
document markers.

(WebCore::EventHandler::dispatchDragStartEvent):

Helper method to dispatch a `dragstart` event, return whether or not to proceed with the drag, and also compute
(as an outparam) whether or not custom pasteboard data was written during the event.

(WebCore::EventHandler::handleDrag):

If custom data was written during `dragstart`, pass along HasNonDefaultPasteboardData::Yes when calling
DragController::startDrag.

(WebCore::repaintContentsOfRange): Deleted.
* page/EventHandler.h:
* page/ios/EventHandlerIOS.mm:
(WebCore::EventHandler::tryToBeginDataInteractionAtPoint):
* platform/Pasteboard.h:
* platform/ios/PasteboardIOS.mm:
(WebCore::Pasteboard::changeCount const):
* platform/ios/WebItemProviderPasteboard.mm:
(-[WebItemProviderPasteboard setItemProviders:]):

Stop clearing out the staged item provider registration list when setting item providers. After refactoring in
r221595, staged registration lists are now automatically cleared out when (1) the drag-and-drop interaction
state is cleared out in the UI process, or (2) when the registration list is taken by WKContentView (see
-takeRegistrationList) when generating an item provider.

* platform/mac/PasteboardMac.mm:
(WebCore::Pasteboard::changeCount const):

Add a changeCount method to Pasteboard on Cocoa platforms (Mac, iOS) which support changeCount natively. In
theory, there's no reason Windows, GTK and WPE ports can't also implement a similar mechanism in
PlatformPasteboard, but this isn't needed for anything yet. Upon dragstart, it is safe to assume that the
pasteboard has been cleared on these platforms, so checking for Pasteboard::hasData (as we do for all platforms
currently) is sufficient.

Source/WebKit:

To request additional drag items, end the current drag in the web page and try to begin a drag at the new
location. This process is transparent to the UI process, which still maintains the same UIDragSession with the
old drag source.

As opposed to firing a new event (for instance: `adddragitem`), this approach is taken to ensure that if the
page wants to preventDefault() on `dragstart`, it would also prevent the user from adding it as an additional
drag item. Using the new event approach, dealing with this case would either require the page to listen for a
new event and call preventDefault(), which would break compatibility with pages that only preventDefault() on
`dragstart`, or it would require the default behavior of this new event to be _not_ adding a drag item, in which
case this approach would require pages to adopt the new event in some form.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::requestAdditionalItemsForDragSession):

Tools:

Adds a new drag and drop test that begins a drag on a text selection, adds an image and a link, and then drops
into a contenteditable area. This verifies that the text, link and image are inserted into the editable area
upon drop.

* TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221900 268f45cc-cd09-0410-ab3c-d52691b4dbfc
16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/page/DragActions.h
Source/WebCore/page/DragController.cpp
Source/WebCore/page/DragController.h
Source/WebCore/page/DragState.h
Source/WebCore/page/EventHandler.cpp
Source/WebCore/page/EventHandler.h
Source/WebCore/page/ios/EventHandlerIOS.mm
Source/WebCore/platform/Pasteboard.h
Source/WebCore/platform/ios/PasteboardIOS.mm
Source/WebCore/platform/ios/WebItemProviderPasteboard.mm
Source/WebCore/platform/mac/PasteboardMac.mm
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm