[iOS DnD] Support DataTransfer.setDragImage when starting a drag on iOS
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Sep 2017 06:59:48 +0000 (06:59 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Sep 2017 06:59:48 +0000 (06:59 +0000)
commit6464dd172f9f3aa3022aa2620b2efa504f527ca3
tree2c780f003e8fc809fda462690efad09c064ad7aa
parentc2d9284c81aba4f93dd78c06473d7251224b5fa6
[iOS DnD] Support DataTransfer.setDragImage when starting a drag on iOS
https://bugs.webkit.org/show_bug.cgi?id=176721
<rdar://problem/34373660>

Reviewed by Tim Horton.

Source/WebCore:

Adds support for setting the drag lift preview frame in the case where DataTransfer.setDragImage is being used
to override the default drag preview. Currently, the frame of the drag preview we supply in this case is the
same as the bounds of the source element in root view coordinates, but this means that any custom drag image
the page supplies will be stretched to fill the frame of the source element. Instead, when handling a DHTML drag,
position the lift and cancel drag previews relative to the event location, respecting any drag offset specified
in setDragImage. The size of this preview matches the size of the drag image source (since this is all in root
view coordinates, this means the drag preview will also enlarge if the user pinches to zoom in). If a
disconnected image source element was provided, then we just fall back to the image size.

Additionally, renames DragItem's elementBounds to dragPreviewFrameInRootViewCoordinates to better reflect the
purpose of this variable. This patch also introduces API test plumbing to grab targeted drag previews from the
drag interaction delegate (i.e. WKContentView), and uses this in a new API test that checks the frame of the
resulting UITargetedDragPreview after initiating a drag in various circumstances (see changes in Tools/ for more
detail).

Test: DataInteractionTests.DragLiftPreviewDataTransferSetDragImage

* dom/DataTransfer.cpp:
(WebCore::DataTransfer::dragImageElement const):
* dom/DataTransfer.h:
* page/DragController.cpp:
(WebCore::dragLocForDHTMLDrag):

The logic to flip the y offset when computing the drag location is only relevant on Mac, but currently, this is
guarded by #if PLATFORM(COCOA), which causes the y offset to shift the drag image in the opposite direction on
iOS. To fix this, simply change the platform define to Mac.

(WebCore::DragController::doSystemDrag):
* platform/DragItem.h:
(WebCore::DragItem::encode const):
(WebCore::DragItem::decode):

Source/WebKit:

Rename elementBounds => dragPreviewFrameInRootViewCoordinates.

* UIProcess/ios/DragDropInteractionState.h:
* UIProcess/ios/DragDropInteractionState.mm:
(WebKit::DragDropInteractionState::previewForDragItem const):
(WebKit::DragDropInteractionState::stageDragItem):

Source/WebKitLegacy/mac:

Rename elementBounds => dragPreviewFrameInRootViewCoordinates. (Note: Unfortunately, _draggedElementBounds in
WebViewPrivate.h can't be renamed yet, due to binary and SDK compatibility with UIKit).

* WebView/WebView.mm:
(-[WebView _startDrag:]):
(-[WebView _draggedElementBounds]):
(-[WebView _endedDataInteraction:global:]):
* WebView/WebViewData.h:

Tools:

In DataInteractionSimulator, ask the UIDragInteractionDelegate (WKContentView) for targeted drag previews after
retrieving UIDragItems during a lift. Remember these previews after the drag and drop simulation is complete, so
API tests (currently, just DragLiftPreviewDataTransferSetDragImage) can verify that the generated drag previews
are as expected.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/DataTransfer-setDragImage.html: Added.

Adds a new test harness containing 5 draggable elements, each generating a drag image using different codepaths.
DragLiftPreviewDataTransferSetDragImage uses this page to check that the frame of the targeted drag preview in
each scenario is as expected.

* TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
(checkCGRectIsEqualToCGRectWithLogging):
(TestWebKitAPI::TEST):
* TestWebKitAPI/ios/DataInteractionSimulator.h:
* TestWebKitAPI/ios/DataInteractionSimulator.mm:
(-[DataInteractionSimulator _resetSimulatedState]):
(-[DataInteractionSimulator _advanceProgress]):
(-[DataInteractionSimulator liftPreviews]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221907 268f45cc-cd09-0410-ab3c-d52691b4dbfc
17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/DataTransfer.cpp
Source/WebCore/dom/DataTransfer.h
Source/WebCore/page/DragController.cpp
Source/WebCore/platform/DragItem.h
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/ios/DragDropInteractionState.h
Source/WebKit/UIProcess/ios/DragDropInteractionState.mm
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebView.mm
Source/WebKitLegacy/mac/WebView/WebViewData.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/DataTransfer-setDragImage.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm
Tools/TestWebKitAPI/ios/DataInteractionSimulator.h
Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm