[iOS DnD] Upstream iOS drag and drop implementation into OpenSource WebKit
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Jun 2017 00:33:23 +0000 (00:33 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Jun 2017 00:33:23 +0000 (00:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=173366
<rdar://problem/32767014>

Reviewed by Tim Horton.

Source/JavaScriptCore:

Introduce ENABLE_DATA_INTERACTION and ENABLE_DRAG_SUPPORT to FeatureDefines.xcconfig.

* Configurations/FeatureDefines.xcconfig:

Source/WebCore:

Moves all drag and drop logic previously hidden behind WebKitAdditions into the open source repository, along
with unit test pages in TestWebKitAPI. Also removes all #includes and #imports of dragging-related files in
WebKitAdditions from the open source repository.

This initial upstreaming phase is only concerned with moving code out of WebKitAdditions, and attempts to
preserve the code as-is, with the exception of trivial style changes so that the open source linter passes.
Future patches will remove the DATA_INTERACTION feature flag altogether and unobscure all variable and function
names referencing "data interaction".

No change in behavior from the internal build.

* Configurations/FeatureDefines.xcconfig:
* page/ios/EventHandlerIOS.mm:
(WebCore::EventHandler::createDraggingDataTransfer):
(WebCore::EventHandler::eventLoopHandleMouseDragged):
(WebCore::EventHandler::tryToBeginDataInteractionAtPoint):
* platform/ios/DragImageIOS.mm:
(WebCore::dragImageSize):
(WebCore::scaleDragImage):
(WebCore::createDragImageFromImage):
(WebCore::deleteDragImage):
(WebCore::createDragImageForLink):
(WebCore::createDragImageIconForCachedImageFilename):
(WebCore::platformAdjustDragImageForDeviceScaleFactor):
(WebCore::createDragImageForSelection):
(WebCore::dissolveDragImageToFraction):
* platform/ios/PasteboardIOS.mm:
(WebCore::Pasteboard::Pasteboard):
(WebCore::Pasteboard::setDragImage):
(WebCore::Pasteboard::createForDragAndDrop):
* platform/mac/DragDataMac.mm:
(WebCore::rtfPasteboardType):
(WebCore::rtfdPasteboardType):
(WebCore::stringPasteboardType):
(WebCore::urlPasteboardType):
(WebCore::htmlPasteboardType):
(WebCore::colorPasteboardType):
(WebCore::pdfPasteboardType):
(WebCore::tiffPasteboardType):
(WebCore::DragData::asFilenames):
(WebCore::DragData::containsURL):
(rtfPasteboardType): Deleted.
(rtfdPasteboardType): Deleted.
(stringPasteboardType): Deleted.
(urlPasteboardType): Deleted.
(htmlPasteboardType): Deleted.
(colorPasteboardType): Deleted.
(pdfPasteboardType): Deleted.
(tiffPasteboardType): Deleted.

Source/WebCore/PAL:

Introduce ENABLE_DATA_INTERACTION and ENABLE_DRAG_SUPPORT to FeatureDefines.xcconfig.

* Configurations/FeatureDefines.xcconfig:

Source/WebKit/mac:

Move pieces of iOS WebKit1 drag and drop implementation into OpenSource. No change in behavior.

* Configurations/FeatureDefines.xcconfig:
* WebCoreSupport/WebDragClient.mm:
(WebDragClient::useLegacyDragClient):
(WebDragClient::willPerformDragDestinationAction):
(WebDragClient::dragSourceActionMaskForPoint):
(WebDragClient::willPerformDragSourceAction):
(WebDragClient::startDrag):
(WebDragClient::beginDrag):
(WebDragClient::declareAndWriteDragImage):
(WebDragClient::declareAndWriteAttachment):
(WebDragClient::didConcludeEditDrag):
* WebView/WebView.mm:
(-[WebView _setDataInteractionData:textIndicator:atClientPosition:anchorPoint:action:]):
(-[WebView _getDataInteractionData]):
(-[WebView dragDataForSession:client:global:operation:]):
(-[WebView _enteredDataInteraction:client:global:operation:]):
(-[WebView _updatedDataInteraction:client:global:operation:]):
(-[WebView _exitedDataInteraction:client:global:operation:]):
(-[WebView _performDataInteraction:client:global:operation:]):
(-[WebView _tryToPerformDataInteraction:client:global:operation:]):
(-[WebView _endedDataInteraction:global:]):
(-[WebView _didConcludeEditDataInteraction]):
(floatRectsForCGRectArray): Deleted.
(-[WebView _createImageWithPlatterForImage:boundingRect:contentScaleFactor:clippingRects:]): Deleted.
* WebView/WebViewData.h:
* WebView/WebViewData.mm:
(-[WebViewPrivate dealloc]):
* WebView/WebViewPrivate.h:

Source/WebKit2:

Move pieces of iOS WebKit2 drag and drop implementation into OpenSource. No change in behavior.

* Configurations/FeatureDefines.xcconfig:
* UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::setDragImage):
(WebKit::WebPageProxy::setPromisedDataForImage):
(WebKit::WebPageProxy::setPromisedDataForAttachment):
(WebKit::WebPageProxy::setDragCaretRect):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(longPressActionDelayAfterLift):
(-[WKContentView webViewUIDelegate]):
(-[WKContentView setupDataInteractionDelegates]):
(-[WKContentView teardownDataInteractionDelegates]):
(-[WKContentView _startDataInteractionWithImage:withIndicatorData:atClientPosition:anchorPoint:action:]):
(-[WKContentView _didHandleStartDataInteractionRequest:]):
(uiImageForImage):
(shouldUseTextIndicatorToCreatePreviewForDragAction):
(-[WKContentView dragPreviewForImage:frameInRootViewCoordinates:clippingRectsInFrameCoordinates:backgroundColor:]):
(-[WKContentView dragPreviewForCurrentDataInteractionState]):
(-[WKContentView performDeferredActionAtDragOrigin]):
(-[WKContentView cancelDeferredActionAtDragOrigin]):
(-[WKContentView computeClientAndGlobalPointsForDropSession:outClientPoint:outGlobalPoint:]):
(dropOperationForWebCoreDragOperation):
(-[WKContentView dragDataForDropSession:dragDestinationAction:]):
(-[WKContentView cleanUpDragSourceSessionState]):
(extractItemProvidersFromDragItems):
(extractItemProvidersFromDropSession):
(-[WKContentView _didConcludeEditDataInteraction:]):
(-[WKContentView _didPerformDataInteractionControllerOperation:]):
(-[WKContentView _transitionDragPreviewToImageIfNecessary:]):
(-[WKContentView _didChangeDataInteractionCaretRect:currentRect:]):
(-[WKContentView _dragDestinationActionForDropSession:]):
(positionInformationMayStartDataInteraction):
(-[WKContentView currentDragOrDropSession]):
(-[WKContentView _dragInteraction:prepareForSession:completion:]):
(-[WKContentView dragInteraction:itemsForBeginningSession:]):
(-[WKContentView _api_dragInteraction:previewForLiftingItem:session:]):
(-[WKContentView dragInteraction:sessionWillBegin:]):
(-[WKContentView _api_dragInteraction:session:didEndWithOperation:]):
(-[WKContentView dragInteraction:previewForCancellingItem:withDefault:]):
(-[WKContentView _api_dragInteraction:item:willAnimateCancelWithAnimator:]):
(-[WKContentView dropInteraction:canHandleSession:]):
(-[WKContentView _api_dropInteraction:sessionDidEnter:]):
(-[WKContentView _api_dropInteraction:sessionDidUpdate:]):
(-[WKContentView dropInteraction:sessionDidExit:]):
(-[WKContentView dropInteraction:performDrop:]):
(-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]):
(-[WKContentView dropInteraction:sessionDidEnd:]):
(-[WKContentView _simulateDataInteractionEntered:]):
(-[WKContentView _simulateDataInteractionUpdated:]):
(-[WKContentView _simulateDataInteractionEnded:]):
(-[WKContentView _simulateDataInteractionPerformOperation:]):
(-[WKContentView _simulateDataInteractionSessionDidEnd:]):
(-[WKContentView _simulateWillBeginDataInteractionWithSession:]):
(-[WKContentView _simulatedItemsForSession:]):
(-[WKContentView _simulatePrepareForDataInteractionSession:completion:]):
* WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:
(WebKit::convertCGImageToBitmap):
(WebKit::WebDragClient::startDrag):
(WebKit::WebDragClient::declareAndWriteDragImage):
(WebKit::WebDragClient::didConcludeEditDrag):
(WebKit::WebDragClient::declareAndWriteAttachment):

Source/WTF:

Define ENABLE_DRAG_SUPPORT as 1 by default and 0 for iOS, and define ENABLE_DATA_INTERACTION as 0 by default.
These are overridden to both be 1 for iOS 11+ in the FeatureDefines.xcconfig within each individual project.

* wtf/Platform.h:

Tools:

Move test pages and pieces of DataInteractionSimulator hidden behind WebKitAdditions into TestWebKitAPI. No
change in behavior.

* TestWebKitAPI/Configurations/FeatureDefines.xcconfig:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/autofocus-contenteditable.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/background-image-link-and-input.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/contenteditable-and-textarea.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/div-and-large-image.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/image-and-contenteditable.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/image-and-textarea.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/link-and-input.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/link-and-target-div.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/prevent-operation.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/prevent-start.html: Added.
* TestWebKitAPI/Tests/WebKit2Cocoa/textarea-to-input.html: Added.
* TestWebKitAPI/ios/DataInteractionSimulator.mm:
(-[MockDragDropSession initWithItems:location:window:]):
(-[MockDragDropSession allowsMoveOperation]):
(-[MockDragDropSession isRestrictedToDraggingApplication]):
(-[MockDragDropSession hasItemsConformingToTypeIdentifiers:]):
(-[MockDragDropSession canLoadObjectsOfClass:]):
(-[MockDragDropSession canLoadObjectsOfClasses:]):
(-[MockDragDropSession items]):
(-[MockDragDropSession setItems:]):
(-[MockDragDropSession locationInView:]):
(-[MockDataOperationSession initWithProviders:location:window:]):
(-[MockDataOperationSession session]):
(-[MockDataOperationSession isLocal]):
(-[MockDataOperationSession progress]):
(-[MockDataOperationSession setProgressIndicatorStyle:]):
(-[MockDataOperationSession progressIndicatorStyle]):
(-[MockDataOperationSession operationMask]):
(-[MockDataOperationSession localDragSession]):
(-[MockDataOperationSession hasItemsConformingToTypeIdentifier:]):
(-[MockDataOperationSession canCreateItemsOfClass:]):
(-[MockDataOperationSession loadObjectsOfClass:completion:]):
(-[MockDataInteractionSession initWithWindow:]):
(-[MockDataInteractionSession localOperationMask]):
(-[MockDataInteractionSession externalOperationMask]):
(-[MockDataInteractionSession session]):
(-[DataInteractionSimulator _advanceProgress]):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@218433 268f45cc-cd09-0410-ab3c-d52691b4dbfc

41 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
Source/WTF/ChangeLog
Source/WTF/wtf/Platform.h
Source/WebCore/ChangeLog
Source/WebCore/Configurations/FeatureDefines.xcconfig
Source/WebCore/PAL/ChangeLog
Source/WebCore/PAL/Configurations/FeatureDefines.xcconfig
Source/WebCore/page/ios/EventHandlerIOS.mm
Source/WebCore/platform/ios/DragImageIOS.mm
Source/WebCore/platform/ios/PasteboardIOS.mm
Source/WebCore/platform/mac/DragDataMac.mm
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Configurations/FeatureDefines.xcconfig
Source/WebKit/mac/WebCoreSupport/WebDragClient.mm
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/mac/WebView/WebViewData.h
Source/WebKit/mac/WebView/WebViewData.mm
Source/WebKit/mac/WebView/WebViewPrivate.h
Source/WebKit2/ChangeLog
Source/WebKit2/Configurations/FeatureDefines.xcconfig
Source/WebKit2/UIProcess/Cocoa/WebPageProxyCocoa.mm
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/autofocus-contenteditable.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/background-image-link-and-input.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/contenteditable-and-textarea.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/div-and-large-image.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/image-and-contenteditable.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/image-and-textarea.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/link-and-input.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/link-and-target-div.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/prevent-operation.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/prevent-start.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/WebKit2Cocoa/textarea-to-input.html [new file with mode: 0644]
Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm

index 977b5d4..c2319c5 100644 (file)
@@ -1,3 +1,15 @@
+2017-06-16  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS DnD] Upstream iOS drag and drop implementation into OpenSource WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=173366
+        <rdar://problem/32767014>
+
+        Reviewed by Tim Horton.
+
+        Introduce ENABLE_DATA_INTERACTION and ENABLE_DRAG_SUPPORT to FeatureDefines.xcconfig.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2017-06-16  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [JSC] Add fast path for Object.assign
index 7847657..efee16e 100644 (file)
@@ -248,4 +248,9 @@ ENABLE_VARIATION_FONTS_IF_NOT_ = $(ENABLE_VARIATION_FONTS_IF_NOT_NO);
 ENABLE_VARIATION_FONTS_IF_NOT_NO = ENABLE_VARIATION_FONTS;
 ENABLE_VARIATION_FONTS_IF_NOT_YES = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+ENABLE_DRAG_SUPPORT[sdk=iphoneos11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DRAG_SUPPORT[sdk=iphonesimulator11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DATA_INTERACTION[sdk=iphoneos11*] = ENABLE_DATA_INTERACTION;
+ENABLE_DATA_INTERACTION[sdk=iphonesimulator11*] = ENABLE_DATA_INTERACTION;
+
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index 7884e03..9596126 100644 (file)
@@ -1,3 +1,16 @@
+2017-06-16  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS DnD] Upstream iOS drag and drop implementation into OpenSource WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=173366
+        <rdar://problem/32767014>
+
+        Reviewed by Tim Horton.
+
+        Define ENABLE_DRAG_SUPPORT as 1 by default and 0 for iOS, and define ENABLE_DATA_INTERACTION as 0 by default.
+        These are overridden to both be 1 for iOS 11+ in the FeatureDefines.xcconfig within each individual project.
+
+        * wtf/Platform.h:
+
 2017-06-15  Chris Dumez  <cdumez@apple.com>
 
         Fix typo in XPCSPI.h
index 1717c36..5004077 100644 (file)
 /* Include feature macros */
 #include <wtf/FeatureDefines.h>
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/AdditionalFeatureDefines.h>)
-#include <WebKitAdditions/AdditionalFeatureDefines.h>
-#endif
-
 #if OS(WINDOWS)
 #define USE_SYSTEM_MALLOC 1
 #endif
index b0e4b25..a608b98 100644 (file)
@@ -1,3 +1,61 @@
+2017-06-16  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS DnD] Upstream iOS drag and drop implementation into OpenSource WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=173366
+        <rdar://problem/32767014>
+
+        Reviewed by Tim Horton.
+
+        Moves all drag and drop logic previously hidden behind WebKitAdditions into the open source repository, along
+        with unit test pages in TestWebKitAPI. Also removes all #includes and #imports of dragging-related files in
+        WebKitAdditions from the open source repository.
+
+        This initial upstreaming phase is only concerned with moving code out of WebKitAdditions, and attempts to
+        preserve the code as-is, with the exception of trivial style changes so that the open source linter passes.
+        Future patches will remove the DATA_INTERACTION feature flag altogether and unobscure all variable and function
+        names referencing "data interaction".
+
+        No change in behavior from the internal build.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * page/ios/EventHandlerIOS.mm:
+        (WebCore::EventHandler::createDraggingDataTransfer):
+        (WebCore::EventHandler::eventLoopHandleMouseDragged):
+        (WebCore::EventHandler::tryToBeginDataInteractionAtPoint):
+        * platform/ios/DragImageIOS.mm:
+        (WebCore::dragImageSize):
+        (WebCore::scaleDragImage):
+        (WebCore::createDragImageFromImage):
+        (WebCore::deleteDragImage):
+        (WebCore::createDragImageForLink):
+        (WebCore::createDragImageIconForCachedImageFilename):
+        (WebCore::platformAdjustDragImageForDeviceScaleFactor):
+        (WebCore::createDragImageForSelection):
+        (WebCore::dissolveDragImageToFraction):
+        * platform/ios/PasteboardIOS.mm:
+        (WebCore::Pasteboard::Pasteboard):
+        (WebCore::Pasteboard::setDragImage):
+        (WebCore::Pasteboard::createForDragAndDrop):
+        * platform/mac/DragDataMac.mm:
+        (WebCore::rtfPasteboardType):
+        (WebCore::rtfdPasteboardType):
+        (WebCore::stringPasteboardType):
+        (WebCore::urlPasteboardType):
+        (WebCore::htmlPasteboardType):
+        (WebCore::colorPasteboardType):
+        (WebCore::pdfPasteboardType):
+        (WebCore::tiffPasteboardType):
+        (WebCore::DragData::asFilenames):
+        (WebCore::DragData::containsURL):
+        (rtfPasteboardType): Deleted.
+        (rtfdPasteboardType): Deleted.
+        (stringPasteboardType): Deleted.
+        (urlPasteboardType): Deleted.
+        (htmlPasteboardType): Deleted.
+        (colorPasteboardType): Deleted.
+        (pdfPasteboardType): Deleted.
+        (tiffPasteboardType): Deleted.
+
 2017-06-16  Youenn Fablet  <youenn@apple.com>
 
         addTransceiver should trigger mid generation in the SDP
index 7847657..efee16e 100644 (file)
@@ -248,4 +248,9 @@ ENABLE_VARIATION_FONTS_IF_NOT_ = $(ENABLE_VARIATION_FONTS_IF_NOT_NO);
 ENABLE_VARIATION_FONTS_IF_NOT_NO = ENABLE_VARIATION_FONTS;
 ENABLE_VARIATION_FONTS_IF_NOT_YES = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+ENABLE_DRAG_SUPPORT[sdk=iphoneos11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DRAG_SUPPORT[sdk=iphonesimulator11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DATA_INTERACTION[sdk=iphoneos11*] = ENABLE_DATA_INTERACTION;
+ENABLE_DATA_INTERACTION[sdk=iphonesimulator11*] = ENABLE_DATA_INTERACTION;
+
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index 57a28e4..c2cd6b5 100644 (file)
@@ -1,3 +1,15 @@
+2017-06-16  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS DnD] Upstream iOS drag and drop implementation into OpenSource WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=173366
+        <rdar://problem/32767014>
+
+        Reviewed by Tim Horton.
+
+        Introduce ENABLE_DATA_INTERACTION and ENABLE_DRAG_SUPPORT to FeatureDefines.xcconfig.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2017-06-10  Dan Bernstein  <mitz@apple.com>
 
         Reverted r218056 because it made the IDE reindex constantly.
index 7847657..efee16e 100644 (file)
@@ -248,4 +248,9 @@ ENABLE_VARIATION_FONTS_IF_NOT_ = $(ENABLE_VARIATION_FONTS_IF_NOT_NO);
 ENABLE_VARIATION_FONTS_IF_NOT_NO = ENABLE_VARIATION_FONTS;
 ENABLE_VARIATION_FONTS_IF_NOT_YES = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+ENABLE_DRAG_SUPPORT[sdk=iphoneos11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DRAG_SUPPORT[sdk=iphonesimulator11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DATA_INTERACTION[sdk=iphoneos11*] = ENABLE_DATA_INTERACTION;
+ENABLE_DATA_INTERACTION[sdk=iphonesimulator11*] = ENABLE_DATA_INTERACTION;
+
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index b09f9e9..9673bc5 100644 (file)
 #import "AXObjectCache.h"
 #import "Chrome.h"
 #import "ChromeClient.h"
+#import "DataTransfer.h"
+#import "DragState.h"
 #import "FocusController.h"
 #import "Frame.h"
 #import "FrameView.h"
 #import "KeyboardEvent.h"
 #import "MouseEventWithHitTestResults.h"
 #import "Page.h"
+#import "Pasteboard.h"
 #import "PlatformEventFactoryIOS.h"
 #import "PlatformKeyboardEvent.h"
 #import "RenderWidget.h"
 #import <wtf/BlockObjCExceptions.h>
 #import <wtf/NeverDestroyed.h>
 #import <wtf/Noncopyable.h>
+#import <wtf/SetForScope.h>
 
 #if ENABLE(IOS_TOUCH_EVENTS)
 #import <WebKitAdditions/EventHandlerIOSTouch.cpp>
 #endif
 
-#if USE(APPLE_INTERNAL_SDK)
-#import <WebKitAdditions/EventHandlerAdditions.mm>
-#endif
-
 namespace WebCore {
 
 static RetainPtr<WebEvent>& currentEventSlot()
@@ -559,4 +559,49 @@ PlatformMouseEvent EventHandler::currentPlatformMouseEvent() const
     return PlatformEventFactory::createPlatformMouseEvent(currentEvent());
 }
 
+#if ENABLE(DRAG_SUPPORT)
+
+Ref<DataTransfer> EventHandler::createDraggingDataTransfer() const
+{
+    Pasteboard("data interaction pasteboard").clear();
+    return DataTransfer::createForDrag();
+}
+
+bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&)
+{
+    return false;
+}
+
+bool EventHandler::tryToBeginDataInteractionAtPoint(const IntPoint& clientPosition, const IntPoint& globalPosition)
+{
+    Ref<Frame> protectedFrame(m_frame);
+
+    PlatformMouseEvent syntheticMousePressEvent(clientPosition, globalPosition, LeftButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime(), 0, NoTap);
+    PlatformMouseEvent syntheticMouseMoveEvent(clientPosition, globalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime(), 0, NoTap);
+
+    HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent);
+    auto documentPoint = protectedFrame->view() ? protectedFrame->view()->windowToContents(syntheticMouseMoveEvent.position()) : syntheticMouseMoveEvent.position();
+    auto hitTestedMouseEvent = m_frame.document()->prepareMouseEvent(request, documentPoint, syntheticMouseMoveEvent);
+
+    RefPtr<Frame> subframe = subframeForHitTestResult(hitTestedMouseEvent);
+    if (subframe && subframe->eventHandler().tryToBeginDataInteractionAtPoint(clientPosition, globalPosition))
+        return true;
+
+    // FIXME: This needs to be refactored, along with handleMousePressEvent and handleMouseMoveEvent, so that state associated only with dragging
+    // lives solely in the DragController, and so that we don't need to pretend that a mouse press and mouse move have already occurred here.
+    m_mouseDownMayStartDrag = eventMayStartDrag(syntheticMousePressEvent);
+    if (!m_mouseDownMayStartDrag)
+        return false;
+
+    SetForScope<bool> mousePressed(m_mousePressed, true);
+    dragState().source = nullptr;
+    dragState().draggedContentRange = nullptr;
+    m_mouseDownPos = protectedFrame->view()->windowToContents(syntheticMouseMoveEvent.position());
+    protectedFrame->document()->updateStyleIfNeeded();
+
+    return handleMouseDraggedEvent(hitTestedMouseEvent, DontCheckDragHysteresis);
+}
+
+#endif
+
 }
index 22abcab..0207247 100644 (file)
 #import "config.h"
 #import "DragImage.h"
 
+#if PLATFORM(IOS)
+
+#import "Document.h"
+#import "Element.h"
+#import "FloatRoundedRect.h"
+#import "FontCascade.h"
+#import "FontPlatformData.h"
+#import "Frame.h"
+#import "GraphicsContext.h"
+#import "Image.h"
+#import "NotImplemented.h"
+#import "Page.h"
+#import "Range.h"
+#import "SoftLinking.h"
+#import "StringTruncator.h"
+#import "TextIndicator.h"
+#import "TextRun.h"
 #import <CoreGraphics/CoreGraphics.h>
+#import <CoreText/CoreText.h>
+#import <UIKit/UIColor.h>
+#import <UIKit/UIFont.h>
+#import <UIKit/UIGraphicsImageRenderer.h>
+#import <UIKit/UIImage.h>
+#import <wtf/NeverDestroyed.h>
 
-#if USE(APPLE_INTERNAL_SDK)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullability-completeness"
 
-#import <WebKitAdditions/DragImageAdditions.mm>
+SOFT_LINK_FRAMEWORK(UIKit)
+SOFT_LINK_CLASS(UIKit, UIFont)
+SOFT_LINK_CLASS(UIKit, UIGraphicsImageRenderer)
+SOFT_LINK(UIKit, UIGraphicsBeginImageContextWithOptions, void, (CGSize size, BOOL opaque, CGFloat scale), (size, opaque, scale))
+SOFT_LINK(UIKit, UIGraphicsGetCurrentContext, CGContextRef, (void), ())
+SOFT_LINK(UIKit, UIGraphicsGetImageFromCurrentImageContext, UIImage *, (void), ())
+SOFT_LINK(UIKit, UIGraphicsEndImageContext, void, (void), ())
 
-#else
+#pragma clang diagnostic pop
 
 namespace WebCore {
 
+#if ENABLE(DRAG_SUPPORT)
+
+IntSize dragImageSize(DragImageRef image)
+{
+    return IntSize(CGImageGetWidth(image.get()), CGImageGetHeight(image.get()));
+}
+
+DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
+{
+    CGSize imageSize = CGSizeMake(scale.width() * CGImageGetWidth(image.get()), scale.height() * CGImageGetHeight(image.get()));
+    CGRect imageRect = { CGPointZero, imageSize };
+
+    RetainPtr<UIGraphicsImageRenderer> render = adoptNS([allocUIGraphicsImageRendererInstance() initWithSize:imageSize]);
+    UIImage *imageCopy = [render.get() imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
+        CGContextRef context = rendererContext.CGContext;
+        CGContextTranslateCTM(context, 0, imageSize.height);
+        CGContextScaleCTM(context, 1, -1);
+        CGContextDrawImage(context, imageRect, image.get());
+    }];
+    return imageCopy.CGImage;
+}
+
+DragImageRef createDragImageFromImage(Image * _Nullable image, ImageOrientationDescription orientation)
+{
+    if (!image)
+        return nil;
+
+    CGSize imageSize(image->size());
+
+    RetainPtr<UIGraphicsImageRenderer> render = adoptNS([allocUIGraphicsImageRendererInstance() initWithSize:imageSize]);
+    UIImage *imageCopy = [render.get() imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
+        GraphicsContext context(rendererContext.CGContext);
+        context.translate(0, imageSize.height);
+        context.scale({ 1, -1 });
+        ImagePaintingOptions paintingOptions;
+        paintingOptions.m_orientationDescription = orientation;
+        context.drawImage(*image, FloatPoint(), paintingOptions);
+    }];
+    return imageCopy.CGImage;
+}
+
+void deleteDragImage(DragImageRef)
+{
+}
+
+static TextIndicatorOptions defaultLinkIndicatorOptions = TextIndicatorOptionTightlyFitContent | TextIndicatorOptionRespectTextColor | TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges | TextIndicatorOptionExpandClipBeyondVisibleRect | TextIndicatorOptionComputeEstimatedBackgroundColor;
+
+DragImageRef createDragImageForLink(Element& linkElement, URL& url, const String& title, TextIndicatorData& indicatorData, FontRenderingMode, float)
+{
+    // FIXME: Most of this can go away once we can use UIURLDragPreviewView unconditionally.
+    static CGFloat dragImagePadding = 10;
+    static LazyNeverDestroyed<FontCascade> titleFontCascade;
+    static LazyNeverDestroyed<FontCascade> urlFontCascade;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^ {
+        UIFont *titleFont = [getUIFontClass() systemFontOfSize:16];
+        UIFont *urlFont = [getUIFontClass() systemFontOfSize:14];
+        titleFontCascade.construct(FontPlatformData(CTFontCreateWithName((CFStringRef)titleFont.fontName, titleFont.pointSize, nil), titleFont.pointSize), AutoSmoothing);
+        urlFontCascade.construct(FontPlatformData(CTFontCreateWithName((CFStringRef)urlFont.fontName, urlFont.pointSize, nil), urlFont.pointSize), AutoSmoothing);
+    });
+
+    String topString(title.stripWhiteSpace());
+    String bottomString([(NSURL *)url absoluteString]);
+    if (topString.isEmpty()) {
+        topString = bottomString;
+        bottomString = emptyString();
+    }
+
+    static CGFloat maxTextWidth = 320;
+    auto truncatedTopString = StringTruncator::rightTruncate(topString, maxTextWidth, titleFontCascade);
+    auto truncatedBottomString = StringTruncator::centerTruncate(bottomString, maxTextWidth, urlFontCascade);
+    CGFloat textWidth = std::max(StringTruncator::width(truncatedTopString, titleFontCascade), StringTruncator::width(truncatedBottomString, urlFontCascade));
+    CGFloat textHeight = truncatedBottomString.isEmpty() ? 22 : 44;
+
+    CGRect imageRect = CGRectMake(0, 0, textWidth + 2 * dragImagePadding, textHeight + 2 * dragImagePadding);
+
+    RetainPtr<UIGraphicsImageRenderer> render = adoptNS([allocUIGraphicsImageRendererInstance() initWithSize:imageRect.size]);
+    UIImage *image = [render.get() imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
+        GraphicsContext context(rendererContext.CGContext);
+        context.translate(0, CGRectGetHeight(imageRect));
+        context.scale({ 1, -1 });
+        context.fillRoundedRect(FloatRoundedRect(imageRect, FloatRoundedRect::Radii(4)), { 255, 255, 255 });
+        titleFontCascade->drawText(context, TextRun(truncatedTopString), FloatPoint(dragImagePadding, 18 + dragImagePadding));
+        if (!truncatedBottomString.isEmpty())
+            urlFontCascade->drawText(context, TextRun(truncatedBottomString), FloatPoint(dragImagePadding, 40 + dragImagePadding));
+    }];
+
+    auto linkRange = rangeOfContents(linkElement);
+    if (auto textIndicator = TextIndicator::createWithRange(linkRange, defaultLinkIndicatorOptions, TextIndicatorPresentationTransition::None, FloatSize()))
+        indicatorData = textIndicator->data();
+
+    return image.CGImage;
+}
+
+DragImageRef createDragImageIconForCachedImageFilename(const String&)
+{
+    notImplemented();
+    return nullptr;
+}
+
+DragImageRef platformAdjustDragImageForDeviceScaleFactor(DragImageRef image, float)
+{
+    // On iOS, we just create the drag image at the right device scale factor, so we don't need to scale it by 1 / deviceScaleFactor later.
+    return image;
+}
+
+static TextIndicatorOptions defaultSelectionDragImageTextIndicatorOptions = TextIndicatorOptionExpandClipBeyondVisibleRect | TextIndicatorOptionPaintAllContent | TextIndicatorOptionUseSelectionRectForSizing | TextIndicatorOptionComputeEstimatedBackgroundColor;
+
+DragImageRef createDragImageForSelection(Frame& frame, TextIndicatorData& indicatorData, bool forceBlackText)
+{
+    if (auto document = frame.document())
+        document->updateLayout();
+
+    TextIndicatorOptions options = defaultSelectionDragImageTextIndicatorOptions;
+    if (!forceBlackText)
+        options |= TextIndicatorOptionRespectTextColor;
+
+    auto textIndicator = TextIndicator::createWithSelectionInFrame(frame, options, TextIndicatorPresentationTransition::None, FloatSize());
+    auto image = textIndicator->contentImage();
+    if (image)
+        indicatorData = textIndicator->data();
+    else
+        return nullptr;
+
+    FloatRect imageRect(0, 0, image->width(), image->height());
+    if (auto page = frame.page())
+        imageRect.scale(1 / page->deviceScaleFactor());
+
+
+    RetainPtr<UIGraphicsImageRenderer> render = adoptNS([allocUIGraphicsImageRendererInstance() initWithSize:imageRect.size()]);
+    UIImage *finalImage = [render.get() imageWithActions:^(UIGraphicsImageRendererContext *rendererContext) {
+        GraphicsContext context(rendererContext.CGContext);
+        context.translate(0, imageRect.height());
+        context.scale({ 1, -1 });
+        context.drawImage(*image, imageRect);
+    }];
+
+    return finalImage.CGImage;
+}
+
+DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
+{
+    notImplemented();
+    return image;
+}
+
+#else
+
 void deleteDragImage(RetainPtr<CGImageRef>)
 {
     // Since this is a RetainPtr, there's nothing additional we need to do to
@@ -46,20 +224,20 @@ void deleteDragImage(RetainPtr<CGImageRef>)
 IntSize dragImageSize(RetainPtr<CGImageRef> image)
 {
     return IntSize(CGImageGetWidth(image.get()), CGImageGetHeight(image.get()));
-    }
+}
 
 RetainPtr<CGImageRef> scaleDragImage(RetainPtr<CGImageRef>, FloatSize)
 {
-    // FIXME: implement for iOS: https://bugs.webkit.org/show_bug.cgi?id=126849
     return nullptr;
 }
 
 RetainPtr<CGImageRef> createDragImageFromImage(Image*, ImageOrientationDescription)
 {
-    // FIXME: implement for iOS: https://bugs.webkit.org/show_bug.cgi?id=126849
     return nullptr;
 }
 
+#endif
+
 } // namespace WebCore
 
-#endif // USE(APPLE_INTERNAL_SDK)
+#endif // PLATFORM(IOS)
index b757a57..6041368 100644 (file)
@@ -29,6 +29,7 @@
 #import "Document.h"
 #import "DocumentFragment.h"
 #import "DocumentLoader.h"
+#import "DragData.h"
 #import "Editing.h"
 #import "Editor.h"
 #import "EditorClient.h"
@@ -39,6 +40,7 @@
 #import "HTMLParserIdioms.h"
 #import "Image.h"
 #import "LegacyWebArchive.h"
+#import "NotImplemented.h"
 #import "PasteboardStrategy.h"
 #import "PlatformStrategies.h"
 #import "RenderImage.h"
 - (BOOL)containsAttachments;
 @end
 
-#if USE(APPLE_INTERNAL_SDK)
-#import <WebKitAdditions/PasteboardAdditions.mm>
-#endif
-
 namespace WebCore {
 
+#if ENABLE(DRAG_SUPPORT)
+
+Pasteboard::Pasteboard(const String& pasteboardName)
+    : m_pasteboardName(pasteboardName)
+    , m_changeCount(platformStrategies()->pasteboardStrategy()->changeCount(pasteboardName))
+{
+}
+
+void Pasteboard::setDragImage(DragImage, const IntPoint&)
+{
+    notImplemented();
+}
+
+std::unique_ptr<Pasteboard> Pasteboard::createForDragAndDrop()
+{
+    return std::make_unique<Pasteboard>("data interaction pasteboard");
+}
+
+std::unique_ptr<Pasteboard> Pasteboard::createForDragAndDrop(const DragData& dragData)
+{
+    return std::make_unique<Pasteboard>(dragData.pasteboardName());
+}
+
+#endif
+
 static long changeCountForPasteboard(const String& pasteboardName = { })
 {
     return platformStrategies()->pasteboardStrategy()->changeCount(pasteboardName);
index 20d129d..94765a2 100644 (file)
 
 #if ENABLE(DRAG_SUPPORT)
 #import "MIMETypeRegistry.h"
+#import "NotImplemented.h"
 #import "Pasteboard.h"
 #import "PasteboardStrategy.h"
+#import "PlatformPasteboard.h"
 #import "PlatformStrategies.h"
 #import "WebCoreNSURLExtras.h"
 
-#if USE(APPLE_INTERNAL_SDK)
-
-#import <WebKitAdditions/DragDataAdditions.mm>
+#if PLATFORM(IOS)
+#import <MobileCoreServices/MobileCoreServices.h>
+#endif
 
-#else
+namespace WebCore {
 
 static inline String rtfPasteboardType()
 {
+#if PLATFORM(IOS)
+    return String(kUTTypeRTF);
+#else
     return String(NSRTFPboardType);
+#endif
 }
 
 static inline String rtfdPasteboardType()
 {
+#if PLATFORM(IOS)
+    return String(kUTTypeFlatRTFD);
+#else
     return String(NSRTFDPboardType);
+#endif
 }
 
 static inline String stringPasteboardType()
 {
+#if PLATFORM(IOS)
+    return String(kUTTypeText);
+#else
     return String(NSStringPboardType);
+#endif
 }
 
 static inline String urlPasteboardType()
 {
+#if PLATFORM(IOS)
+    return String(kUTTypeURL);
+#else
     return String(NSURLPboardType);
+#endif
 }
 
 static inline String htmlPasteboardType()
 {
+#if PLATFORM(IOS)
+    return String(kUTTypeHTML);
+#else
     return String(NSHTMLPboardType);
+#endif
 }
 
 static inline String colorPasteboardType()
 {
+#if PLATFORM(IOS)
+    return "com.apple.uikit.color";
+#else
     return String(NSColorPboardType);
+#endif
 }
 
 static inline String pdfPasteboardType()
 {
+#if PLATFORM(IOS)
+    return String(kUTTypePDF);
+#else
     return String(NSPDFPboardType);
+#endif
 }
 
 static inline String tiffPasteboardType()
 {
+#if PLATFORM(IOS)
+    return String(kUTTypeTIFF);
+#else
     return String(NSTIFFPboardType);
+#endif
 }
 
-#endif // USE(APPLE_INTERNAL_SDK)
-
-namespace WebCore {
-
 DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation sourceOperationMask, DragApplicationFlags flags, DragDestinationAction destinationAction)
     : m_clientPosition(clientPosition)
     , m_globalPosition(globalPosition)
@@ -154,12 +184,8 @@ void DragData::asFilenames(Vector<String>& result) const
 #if PLATFORM(MAC)
     platformStrategies()->pasteboardStrategy()->getPathnamesForType(result, String(NSFilenamesPboardType), m_pasteboardName);
 #endif
-#if PLATFORM(MAC) || ENABLE(DATA_INTERACTION)
     if (!result.size())
         result = fileNames();
-#else
-    UNUSED_PARAM(result);
-#endif
 }
 
 bool DragData::containsPlainText() const
@@ -231,14 +257,30 @@ bool DragData::containsPromise() const
     return files.size() == 1;
 }
 
-#if !ENABLE(DATA_INTERACTION)
-
 bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const
 {
-    return !asURL(filenamePolicy).isEmpty();
-}
+#if PLATFORM(IOS)
+    UNUSED_PARAM(filenamePolicy);
+    Vector<String> types;
+    platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName);
+    if (!types.contains(urlPasteboardType()))
+        return false;
+
+    auto urlString = platformStrategies()->pasteboardStrategy()->stringForType(urlPasteboardType(), m_pasteboardName);
+    if (urlString.isEmpty()) {
+        // On iOS, we don't get access to the contents of UIItemProviders until we perform the drag operation.
+        // Thus, we consider DragData to contain an URL if it contains the `public.url` UTI type. Later down the
+        // road, when we perform the drag operation, we can then check if the URL's protocol is http or https,
+        // and if it isn't, we bail out of page navigation.
+        return true;
+    }
 
+    URL webcoreURL = [NSURL URLWithString:urlString];
+    return webcoreURL.protocolIs("http") || webcoreURL.protocolIs("https");
+#else
+    return !asURL(filenamePolicy).isEmpty();
 #endif
+}
 
 String DragData::asURL(FilenameConversionPolicy, String* title) const
 {
index 1e01ca2..465d1ab 100644 (file)
@@ -1,3 +1,42 @@
+2017-06-16  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS DnD] Upstream iOS drag and drop implementation into OpenSource WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=173366
+        <rdar://problem/32767014>
+
+        Reviewed by Tim Horton.
+
+        Move pieces of iOS WebKit1 drag and drop implementation into OpenSource. No change in behavior.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * WebCoreSupport/WebDragClient.mm:
+        (WebDragClient::useLegacyDragClient):
+        (WebDragClient::willPerformDragDestinationAction):
+        (WebDragClient::dragSourceActionMaskForPoint):
+        (WebDragClient::willPerformDragSourceAction):
+        (WebDragClient::startDrag):
+        (WebDragClient::beginDrag):
+        (WebDragClient::declareAndWriteDragImage):
+        (WebDragClient::declareAndWriteAttachment):
+        (WebDragClient::didConcludeEditDrag):
+        * WebView/WebView.mm:
+        (-[WebView _setDataInteractionData:textIndicator:atClientPosition:anchorPoint:action:]):
+        (-[WebView _getDataInteractionData]):
+        (-[WebView dragDataForSession:client:global:operation:]):
+        (-[WebView _enteredDataInteraction:client:global:operation:]):
+        (-[WebView _updatedDataInteraction:client:global:operation:]):
+        (-[WebView _exitedDataInteraction:client:global:operation:]):
+        (-[WebView _performDataInteraction:client:global:operation:]):
+        (-[WebView _tryToPerformDataInteraction:client:global:operation:]):
+        (-[WebView _endedDataInteraction:global:]):
+        (-[WebView _didConcludeEditDataInteraction]):
+        (floatRectsForCGRectArray): Deleted.
+        (-[WebView _createImageWithPlatterForImage:boundingRect:contentScaleFactor:clippingRects:]): Deleted.
+        * WebView/WebViewData.h:
+        * WebView/WebViewData.mm:
+        (-[WebViewPrivate dealloc]):
+        * WebView/WebViewPrivate.h:
+
 2017-06-15  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [iOS DnD] [WK1] Dropping links onto UIWebViews should not trigger navigation by default
index 7847657..efee16e 100644 (file)
@@ -248,4 +248,9 @@ ENABLE_VARIATION_FONTS_IF_NOT_ = $(ENABLE_VARIATION_FONTS_IF_NOT_NO);
 ENABLE_VARIATION_FONTS_IF_NOT_NO = ENABLE_VARIATION_FONTS;
 ENABLE_VARIATION_FONTS_IF_NOT_YES = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+ENABLE_DRAG_SUPPORT[sdk=iphoneos11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DRAG_SUPPORT[sdk=iphonesimulator11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DATA_INTERACTION[sdk=iphoneos11*] = ENABLE_DATA_INTERACTION;
+ENABLE_DATA_INTERACTION[sdk=iphonesimulator11*] = ENABLE_DATA_INTERACTION;
+
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index 1bd9b34..115a837 100644 (file)
 
 using namespace WebCore;
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/WebDragClientAdditionsWebKit1.mm>)
-#import <WebKitAdditions/WebDragClientAdditionsWebKit1.mm>
-#endif
-
 WebDragClient::WebDragClient(WebView* webView)
     : m_webView(webView) 
 {
@@ -222,6 +218,55 @@ void WebDragClient::declareAndWriteAttachment(const String&, Element&, const URL
 
 #endif
 
+#if PLATFORM(IOS)
+
+bool WebDragClient::useLegacyDragClient()
+{
+    // FIXME: Move the iOS drag and drop implementation for WebKit1 off of the legacy drag client.
+    return true;
+}
+
+void WebDragClient::willPerformDragDestinationAction(DragDestinationAction, const DragData&)
+{
+}
+
+WebCore::DragSourceAction WebDragClient::dragSourceActionMaskForPoint(const IntPoint&)
+{
+    return DragSourceActionAny;
+}
+
+void WebDragClient::willPerformDragSourceAction(WebCore::DragSourceAction, const IntPoint&, DataTransfer&)
+{
+}
+
+void WebDragClient::startDrag(DragImage dragImage, const IntPoint& point, const IntPoint& eventLocation, const FloatPoint& dragImageAnchor, DataTransfer& dataTransfer, Frame& frame, DragSourceAction dragSourceAction)
+{
+    [m_webView _setDataInteractionData:dragImage.get().get() textIndicator:dragImage.indicatorData() atClientPosition:eventLocation anchorPoint:dragImageAnchor action:dragSourceAction];
+}
+
+void WebDragClient::beginDrag(DragItem, Frame&, const IntPoint&, const IntPoint&, DataTransfer&, DragSourceAction)
+{
+}
+
+void WebDragClient::declareAndWriteDragImage(const String& pasteboardName, Element& element, const URL& url, const String& label, Frame*)
+{
+    if (auto* frame = element.document().frame())
+        frame->editor().writeImageToPasteboard(*Pasteboard::createForDragAndDrop(), element, url, label);
+}
+
+#if ENABLE(ATTACHMENT_ELEMENT)
+void WebDragClient::declareAndWriteAttachment(const String&, Element&, const URL&, const String&, Frame*)
+{
+}
+#endif
+
+void WebDragClient::didConcludeEditDrag()
+{
+    [m_webView _didConcludeEditDataInteraction];
+}
+
+#endif // PLATFORM(IOS)
+
 void WebDragClient::dragControllerDestroyed() 
 {
     delete this;
index 54e3dd3..38a4601 100644 (file)
@@ -1820,7 +1820,8 @@ static void WebKitInitializeGamepadProviderIfNecessary()
 }
 #endif
 
-#if ENABLE(DATA_INTERACTION) && defined(__cplusplus)
+#if ENABLE(DRAG_SUPPORT) && PLATFORM(IOS)
+
 - (BOOL)_requestStartDataInteraction:(CGPoint)clientPosition globalPosition:(CGPoint)globalPosition
 {
     return _private->page->mainFrame().eventHandler().tryToBeginDataInteractionAtPoint(IntPoint(clientPosition), IntPoint(globalPosition));
@@ -1829,9 +1830,9 @@ static void WebKitInitializeGamepadProviderIfNecessary()
 - (void)_setDataInteractionData:(CGImageRef)image textIndicator:(std::optional<TextIndicatorData>)indicatorData atClientPosition:(CGPoint)clientPosition anchorPoint:(CGPoint)anchorPoint action:(uint64_t)action
 {
     if (indicatorData)
-        _private->textIndicatorData = [[[WebUITextIndicatorData alloc] initWithImage:image textIndicatorData:indicatorData.value() scale:_private->page->deviceScaleFactor()] retain];
+        _private->textIndicatorData = adoptNS([[WebUITextIndicatorData alloc] initWithImage:image textIndicatorData:indicatorData.value() scale:_private->page->deviceScaleFactor()]);
     else
-        _private->textIndicatorData = [[[WebUITextIndicatorData alloc] initWithImage:image scale:_private->page->deviceScaleFactor()] retain];
+        _private->textIndicatorData = adoptNS([[WebUITextIndicatorData alloc] initWithImage:image scale:_private->page->deviceScaleFactor()]);
 }
 
 - (CGRect)_dataInteractionCaretRect
@@ -1849,53 +1850,7 @@ static void WebKitInitializeGamepadProviderIfNecessary()
 
 - (WebUITextIndicatorData *)_getDataInteractionData
 {
-    return _private->textIndicatorData;
-}
-
-static Vector<FloatRect> floatRectsForCGRectArray(NSArray<NSValue *> *rectValues)
-{
-    Vector<FloatRect> rects;
-    for (NSValue *rectValue in rectValues)
-        rects.append(rectValue.CGRectValue);
-    return rects;
-}
-
-- (UIImage *)_createImageWithPlatterForImage:(UIImage *)image boundingRect:(CGRect)boundingRect contentScaleFactor:(CGFloat)contentScaleFactor clippingRects:(NSArray<NSValue *> *)clippingRects
-{
-    if (!_private->page)
-        return nil;
-
-    if (!image)
-        return nil;
-
-    CGFloat imageScaleFactor = contentScaleFactor / _private->page->deviceScaleFactor();
-    CGRect imagePaintBounds = CGRectMake(0, 0, CGRectGetWidth(boundingRect) * imageScaleFactor, CGRectGetHeight(boundingRect) * imageScaleFactor);
-    UIGraphicsBeginImageContextWithOptions(imagePaintBounds.size, NO, _private->page->deviceScaleFactor());
-    CGContextRef newContext = UIGraphicsGetCurrentContext();
-
-    auto scaledClippingRects = floatRectsForCGRectArray(clippingRects);
-    for (auto& textBoundingRect : scaledClippingRects)
-        textBoundingRect.scale(imageScaleFactor);
-
-    if (!scaledClippingRects.isEmpty()) {
-        auto webcorePath = PathUtilities::pathWithShrinkWrappedRects(scaledClippingRects, 6 * imageScaleFactor);
-        [[getUIBezierPathClass() bezierPathWithCGPath:webcorePath.ensurePlatformPath()] addClip];
-    }
-
-    // FIXME: This should match the background color of the text, or if the background cannot be captured as a single color, we should fall back
-    // to a default representation, e.g. black text on a white background.
-    CGContextSetFillColorWithColor(newContext, [(UIColor *)[getUIColorClass() whiteColor] CGColor]);
-    for (auto textBoundingRect : scaledClippingRects)
-        CGContextFillRect(newContext, textBoundingRect);
-
-    CGContextTranslateCTM(newContext, 0, CGRectGetHeight(imagePaintBounds));
-    CGContextScaleCTM(newContext, 1, -1);
-    CGContextDrawImage(newContext, imagePaintBounds, image.CGImage);
-
-    UIImage *previewImage = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-
-    return [previewImage retain];
+    return _private->textIndicatorData.get();
 }
 
 - (WebDragDestinationAction)dragDestinationActionMaskForSession:(id <UIDropSession>)session
@@ -1903,65 +1858,67 @@ static Vector<FloatRect> floatRectsForCGRectArray(NSArray<NSValue *> *rectValues
     return [self._UIDelegateForwarder webView:self dragDestinationActionMaskForSession:session];
 }
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/WebViewAdditions.mm>)
-#include <WebKitAdditions/WebViewAdditions.mm>
-#endif
-
-#else
-- (BOOL)_requestStartDataInteraction:(CGPoint)clientPosition globalPosition:(CGPoint)globalPosition
-{
-    return NO;
-}
-- (void)_setDataInteractionData:(CGImageRef)image textIndicator:(TextIndicatorData&)indicatorData atClientPosition:(CGPoint)clientPosition anchorPoint:(CGPoint)anchorPoint action:(uint64_t)action
-{
-}
-- (WebUITextIndicatorData *)_getDataInteractionData
+- (DragData)dragDataForSession:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
 {
-    return nil;
+    auto dragOperationMask = static_cast<DragOperation>(operation);
+    auto dragDestinationMask = static_cast<DragDestinationAction>([self dragDestinationActionMaskForSession:session]);
+    return { session, roundedIntPoint(clientPosition), roundedIntPoint(globalPosition), dragOperationMask, DragApplicationNone, dragDestinationMask };
 }
-- (uint64_t)_enteredDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
+
+- (uint64_t)_enteredDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
 {
-    return 0;
+    WebThreadLock();
+    auto dragData = [self dragDataForSession:session client:clientPosition global:globalPosition operation:operation];
+    return _private->page->dragController().dragEntered(dragData);
 }
 
-- (uint64_t)_updatedDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
+- (uint64_t)_updatedDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
 {
-    return 0;
+    WebThreadLock();
+    auto dragData = [self dragDataForSession:session client:clientPosition global:globalPosition operation:operation];
+    return _private->page->dragController().dragUpdated(dragData);
 }
-- (void)_exitedDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
+- (void)_exitedDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
 {
+    WebThreadLock();
+    auto dragData = [self dragDataForSession:session client:clientPosition global:globalPosition operation:operation];
+    _private->page->dragController().dragExited(dragData);
 }
-- (void)_performDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
+- (void)_performDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
 {
+    [self _tryToPerformDataInteraction:session client:clientPosition global:globalPosition operation:operation];
 }
 
-- (BOOL)_tryToPerformDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
+- (BOOL)_tryToPerformDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation
 {
-    return NO;
+    WebThreadLock();
+    auto dragData = [self dragDataForSession:session client:clientPosition global:globalPosition operation:operation];
+    return _private->page->dragController().performDragOperation(dragData);
 }
 
 - (void)_endedDataInteraction:(CGPoint)clientPosition global:(CGPoint)globalPosition
 {
+    WebThreadLock();
+    _private->page->dragController().dragEnded();
+    _private->dataOperationTextIndicator = nullptr;
 }
 
-- (WebUITextIndicatorData *)_dataOperationTextIndicator
-{
-    return nil;
-}
-
-#if PLATFORM(IOS)
-- (UIImage *)_createImageWithPlatterForImage:(UIImage *)image boundingRect:(CGRect)boundingRect contentScaleFactor:(CGFloat)contentScaleFactor clippingRects:(NSArray<NSValue *> *)clippingRects
+- (void)_didConcludeEditDataInteraction
 {
-    return nil;
-}
+    _private->dataOperationTextIndicator = nullptr;
+    auto* page = _private->page;
+    if (!page)
+        return;
 
-- (CGRect)_dataInteractionCaretRect
-{
-    return CGRectNull;
+    static auto defaultEditDragTextIndicatorOptions = TextIndicatorOptionIncludeSnapshotOfAllVisibleContentWithoutSelection | TextIndicatorOptionExpandClipBeyondVisibleRect | TextIndicatorOptionPaintAllContent | TextIndicatorOptionIncludeMarginIfRangeMatchesSelection | TextIndicatorOptionPaintBackgrounds | TextIndicatorOptionUseSelectionRectForSizing | TextIndicatorOptionIncludeSnapshotWithSelectionHighlight | TextIndicatorOptionRespectTextColor;
+    auto& frame = page->focusController().focusedOrMainFrame();
+    if (auto range = frame.selection().selection().toNormalizedRange()) {
+        if (auto textIndicator = TextIndicator::createWithRange(*range, defaultEditDragTextIndicatorOptions, TextIndicatorPresentationTransition::None, FloatSize()))
+            _private->dataOperationTextIndicator = adoptNS([[WebUITextIndicatorData alloc] initWithImage:nil textIndicatorData:textIndicator->data() scale:page->deviceScaleFactor()]);
+    }
 }
-#endif
 
-#endif // ENABLE(DATA_INTERACTION) && defined(__cplusplus)
+#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(IOS)
 
 static NSMutableSet *knownPluginMIMETypes()
 {
index 23d837d..0e6df27 100644 (file)
@@ -298,7 +298,7 @@ private:
 #endif
     
 #if ENABLE(DATA_INTERACTION)
-    WebUITextIndicatorData *textIndicatorData;
+    RetainPtr<WebUITextIndicatorData> textIndicatorData;
     RetainPtr<WebUITextIndicatorData> dataOperationTextIndicator;
 #endif
 
index b374cb3..779736a 100644 (file)
@@ -213,9 +213,6 @@ WebViewLayerFlushScheduler::WebViewLayerFlushScheduler(LayerFlushController* flu
     [_caretChangeListeners release];
     [_fixedPositionContent release];
 #endif
-#if ENABLE(DATA_INTERACTION)
-    [textIndicatorData release];
-#endif
 
     [super dealloc];
 }
index 4fd075a..09aa702 100644 (file)
@@ -118,6 +118,10 @@ extern NSString *WebQuickLookFileNameKey;
 extern NSString *WebQuickLookUTIKey;
 #endif
 
+#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
+@protocol UIDropSession;
+#endif
+
 extern NSString * const WebViewWillCloseNotification;
 
 #if ENABLE_DASHBOARD_SUPPORT
@@ -464,21 +468,21 @@ Could be worth adding to the API.
 + (void)_releaseMemoryNow;
 
 - (void)_replaceCurrentHistoryItem:(WebHistoryItem *)item;
-#endif // TARGET_OS_IPHONE
 
+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
 - (BOOL)_requestStartDataInteraction:(CGPoint)clientPosition globalPosition:(CGPoint)globalPosition;
 - (WebUITextIndicatorData *)_getDataInteractionData;
 @property (nonatomic, readonly, strong, getter=_dataOperationTextIndicator) WebUITextIndicatorData *dataOperationTextIndicator;
-- (uint64_t)_enteredDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
-- (uint64_t)_updatedDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
-- (void)_exitedDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
-- (void)_performDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
-- (BOOL)_tryToPerformDataInteraction:(id)dataInteraction client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
+- (uint64_t)_enteredDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
+- (uint64_t)_updatedDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
+- (void)_exitedDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
+- (void)_performDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
+- (BOOL)_tryToPerformDataInteraction:(id <UIDropSession>)session client:(CGPoint)clientPosition global:(CGPoint)globalPosition operation:(uint64_t)operation;
 - (void)_endedDataInteraction:(CGPoint)clientPosition global:(CGPoint)clientPosition;
 
-#if TARGET_OS_IPHONE
 @property (nonatomic, readonly, getter=_dataInteractionCaretRect) CGRect dataInteractionCaretRect;
-- (UIImage *)_createImageWithPlatterForImage:(UIImage *)image boundingRect:(CGRect)boundingRect contentScaleFactor:(CGFloat)contentScaleFactor clippingRects:(NSArray<NSValue *> *)clippingRects;
+#endif
+
 // Deprecated. Use -[WebDataSource _quickLookContent] instead.
 - (NSDictionary *)quickLookContentForURL:(NSURL *)url;
 #endif
index 0b3c4c2..24086fd 100644 (file)
@@ -1,3 +1,75 @@
+2017-06-16  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS DnD] Upstream iOS drag and drop implementation into OpenSource WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=173366
+        <rdar://problem/32767014>
+
+        Reviewed by Tim Horton.
+
+        Move pieces of iOS WebKit2 drag and drop implementation into OpenSource. No change in behavior.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * UIProcess/Cocoa/WebPageProxyCocoa.mm:
+        (WebKit::WebPageProxy::setDragImage):
+        (WebKit::WebPageProxy::setPromisedDataForImage):
+        (WebKit::WebPageProxy::setPromisedDataForAttachment):
+        (WebKit::WebPageProxy::setDragCaretRect):
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (longPressActionDelayAfterLift):
+        (-[WKContentView webViewUIDelegate]):
+        (-[WKContentView setupDataInteractionDelegates]):
+        (-[WKContentView teardownDataInteractionDelegates]):
+        (-[WKContentView _startDataInteractionWithImage:withIndicatorData:atClientPosition:anchorPoint:action:]):
+        (-[WKContentView _didHandleStartDataInteractionRequest:]):
+        (uiImageForImage):
+        (shouldUseTextIndicatorToCreatePreviewForDragAction):
+        (-[WKContentView dragPreviewForImage:frameInRootViewCoordinates:clippingRectsInFrameCoordinates:backgroundColor:]):
+        (-[WKContentView dragPreviewForCurrentDataInteractionState]):
+        (-[WKContentView performDeferredActionAtDragOrigin]):
+        (-[WKContentView cancelDeferredActionAtDragOrigin]):
+        (-[WKContentView computeClientAndGlobalPointsForDropSession:outClientPoint:outGlobalPoint:]):
+        (dropOperationForWebCoreDragOperation):
+        (-[WKContentView dragDataForDropSession:dragDestinationAction:]):
+        (-[WKContentView cleanUpDragSourceSessionState]):
+        (extractItemProvidersFromDragItems):
+        (extractItemProvidersFromDropSession):
+        (-[WKContentView _didConcludeEditDataInteraction:]):
+        (-[WKContentView _didPerformDataInteractionControllerOperation:]):
+        (-[WKContentView _transitionDragPreviewToImageIfNecessary:]):
+        (-[WKContentView _didChangeDataInteractionCaretRect:currentRect:]):
+        (-[WKContentView _dragDestinationActionForDropSession:]):
+        (positionInformationMayStartDataInteraction):
+        (-[WKContentView currentDragOrDropSession]):
+        (-[WKContentView _dragInteraction:prepareForSession:completion:]):
+        (-[WKContentView dragInteraction:itemsForBeginningSession:]):
+        (-[WKContentView _api_dragInteraction:previewForLiftingItem:session:]):
+        (-[WKContentView dragInteraction:sessionWillBegin:]):
+        (-[WKContentView _api_dragInteraction:session:didEndWithOperation:]):
+        (-[WKContentView dragInteraction:previewForCancellingItem:withDefault:]):
+        (-[WKContentView _api_dragInteraction:item:willAnimateCancelWithAnimator:]):
+        (-[WKContentView dropInteraction:canHandleSession:]):
+        (-[WKContentView _api_dropInteraction:sessionDidEnter:]):
+        (-[WKContentView _api_dropInteraction:sessionDidUpdate:]):
+        (-[WKContentView dropInteraction:sessionDidExit:]):
+        (-[WKContentView dropInteraction:performDrop:]):
+        (-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]):
+        (-[WKContentView dropInteraction:sessionDidEnd:]):
+        (-[WKContentView _simulateDataInteractionEntered:]):
+        (-[WKContentView _simulateDataInteractionUpdated:]):
+        (-[WKContentView _simulateDataInteractionEnded:]):
+        (-[WKContentView _simulateDataInteractionPerformOperation:]):
+        (-[WKContentView _simulateDataInteractionSessionDidEnd:]):
+        (-[WKContentView _simulateWillBeginDataInteractionWithSession:]):
+        (-[WKContentView _simulatedItemsForSession:]):
+        (-[WKContentView _simulatePrepareForDataInteractionSession:completion:]):
+        * WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:
+        (WebKit::convertCGImageToBitmap):
+        (WebKit::WebDragClient::startDrag):
+        (WebKit::WebDragClient::declareAndWriteDragImage):
+        (WebKit::WebDragClient::didConcludeEditDrag):
+        (WebKit::WebDragClient::declareAndWriteAttachment):
+
 2017-06-16  Youenn Fablet  <youenn@apple.com>
 
         WebRTC sockets should be closed at destruction time if not closed explicitly
index 7847657..efee16e 100644 (file)
@@ -248,4 +248,9 @@ ENABLE_VARIATION_FONTS_IF_NOT_ = $(ENABLE_VARIATION_FONTS_IF_NOT_NO);
 ENABLE_VARIATION_FONTS_IF_NOT_NO = ENABLE_VARIATION_FONTS;
 ENABLE_VARIATION_FONTS_IF_NOT_YES = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+ENABLE_DRAG_SUPPORT[sdk=iphoneos11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DRAG_SUPPORT[sdk=iphonesimulator11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DATA_INTERACTION[sdk=iphoneos11*] = ENABLE_DATA_INTERACTION;
+ENABLE_DATA_INTERACTION[sdk=iphonesimulator11*] = ENABLE_DATA_INTERACTION;
+
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index 8f04454..e4ed0b3 100644 (file)
 #import "APIUIClient.h"
 #import "DataDetectionResult.h"
 #import "LoadParameters.h"
+#import "PageClient.h"
 #import "WebProcessProxy.h"
+#import <WebCore/NotImplemented.h>
 #import <WebCore/SearchPopupMenuCocoa.h>
 #import <WebCore/ValidationBubble.h>
 #import <wtf/cf/TypeCastsCF.h>
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/WebPageProxyAdditions.mm>)
-#import <WebKitAdditions/WebPageProxyAdditions.mm>
-#endif
+using namespace WebCore;
 
 namespace WebKit {
 
@@ -102,4 +102,37 @@ void WebPageProxy::createSandboxExtensionsIfNeeded(const Vector<String>& files,
     }
 }
 
+#if PLATFORM(IOS) && ENABLE(DRAG_SUPPORT)
+
+void WebPageProxy::setDragImage(const IntPoint& clientPosition, const ShareableBitmap::Handle& dragImageHandle, std::optional<TextIndicatorData> textIndicator, const FloatPoint& dragImageAnchor, uint64_t action)
+{
+    m_pageClient.startDataInteractionWithImage(clientPosition, dragImageHandle, textIndicator, dragImageAnchor, action);
+}
+
+void WebPageProxy::setPromisedDataForImage(const String&, const SharedMemory::Handle&, uint64_t, const String&, const String&, const String&, const String&, const String&, const SharedMemory::Handle&, uint64_t)
+{
+    notImplemented();
+}
+
+#if ENABLE(ATTACHMENT_ELEMENT)
+
+void WebPageProxy::setPromisedDataForAttachment(const String&, const String&, const String&, const String&, const String&, const String&)
+{
+    notImplemented();
+}
+
+#endif
+
+void WebPageProxy::setDragCaretRect(const IntRect& dragCaretRect)
+{
+    if (m_currentDragCaretRect == dragCaretRect)
+        return;
+
+    auto previousRect = m_currentDragCaretRect;
+    m_currentDragCaretRect = dragCaretRect;
+    m_pageClient.didChangeDataInteractionCaretRect(previousRect, dragCaretRect);
+}
+
+#endif // PLATFORM(IOS) && ENABLE(DRAG_SUPPORT)
+
 }
index fc94e52..334d580 100644 (file)
 #import "WKSyntheticClickTapGestureRecognizer.h"
 #import <UIKit/UIView.h>
 #import <WebCore/Color.h>
+#import <WebCore/DragActions.h>
 #import <WebCore/FloatQuad.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/Forward.h>
 #import <wtf/Vector.h>
 #import <wtf/text/WTFString.h>
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/WKContentViewInteractionAdditions.h>)
-#import <WebKitAdditions/WKContentViewInteractionAdditions.h>
-#endif
-
 namespace API {
 class OpenPanelParameters;
 }
@@ -76,7 +73,7 @@ class WebPageProxy;
 @class _UIWebHighlightLongPressGestureRecognizer;
 
 #if ENABLE(DATA_INTERACTION)
-@class WKDataInteractionCaretView;
+@class _UITextDragCaretView;
 #endif
 
 typedef void (^UIWKAutocorrectionCompletionHandler)(UIWKAutocorrectionRects *rectsForInput);
@@ -111,6 +108,32 @@ typedef std::pair<WebKit::InteractionInformationRequest, InteractionInformationC
 
 namespace WebKit {
 
+#if ENABLE(DRAG_SUPPORT)
+
+struct WKDataInteractionState {
+    RetainPtr<UIImage> image;
+    std::optional<WebCore::TextIndicatorData> indicatorData;
+    CGPoint gestureOrigin { CGPointZero };
+    CGPoint adjustedOrigin { CGPointZero };
+    CGPoint lastGlobalPosition { CGPointZero };
+    CGRect elementBounds { CGRectZero };
+    BOOL didBeginDragging { NO };
+    BOOL isPerformingOperation { NO };
+    BOOL isAnimatingConcludeEditDrag { NO };
+    RetainPtr<id <UIDragSession>> dragSession;
+    RetainPtr<id <UIDropSession>> dropSession;
+    BlockPtr<void()> dragStartCompletionBlock;
+    WebCore::DragSourceAction sourceAction { WebCore::DragSourceActionNone };
+
+    String linkTitle;
+    WebCore::URL linkURL;
+
+    RetainPtr<UIView> visibleContentViewSnapshot;
+    RetainPtr<_UITextDragCaretView> caretView;
+};
+
+#endif // ENABLE(DRAG_SUPPORT)
+
 struct WKSelectionDrawingInfo {
     enum class SelectionType { None, Plugin, Range };
     WKSelectionDrawingInfo();
@@ -223,8 +246,8 @@ struct WKAutoCorrectionData {
 
 #if ENABLE(DATA_INTERACTION)
     WebKit::WKDataInteractionState _dataInteractionState;
-    RetainPtr<WKDataInteraction> _dataInteraction;
-    RetainPtr<WKDataOperation> _dataOperation;
+    RetainPtr<UIDragInteraction> _dataInteraction;
+    RetainPtr<UIDropInteraction> _dataOperation;
     CGPoint _deferredActionSheetRequestLocation;
 #endif
 }
@@ -233,7 +256,7 @@ struct WKAutoCorrectionData {
 
 @interface WKContentView (WKInteraction) <UIGestureRecognizerDelegate, UIWebTouchEventsGestureRecognizerDelegate, UITextInputPrivate, UIWebFormAccessoryDelegate, UIWKInteractionViewProtocol, WKFileUploadPanelDelegate, WKActionSheetAssistantDelegate
 #if ENABLE(DATA_INTERACTION)
-    , WKDataInteractionDelegate, WKDataOperationDelegate
+    , UIDragInteractionDelegate, UIDropInteractionDelegate
 #endif
 >
 
index b64ab35..88e1c2f 100644 (file)
 #import <WebCore/WebCoreNSURLExtras.h>
 #import <WebCore/WebEvent.h>
 #import <WebKit/WebSelectionRect.h> // FIXME: WK2 should not include WebKit headers!
+#import <wtf/Optional.h>
 #import <wtf/RetainPtr.h>
 #import <wtf/SetForScope.h>
 
-#if ENABLE(DATA_INTERACTION)
+#if ENABLE(DRAG_SUPPORT)
+// FIXME: Move private headers to UIKitSPI.h and add declarations as needed for building on OpenSource against the iOS 11 SDK.
+#import <UIKit/UIDragInteraction.h>
+#import <UIKit/UIDragInteraction_Private.h>
+#import <UIKit/UIDragPreviewParameters.h>
+#import <UIKit/UIDragPreview_Private.h>
+#import <UIKit/UIDragSession.h>
+#import <UIKit/UIDragging.h>
+#import <UIKit/UIDropInteraction.h>
+#import <UIKit/UIPreviewInteraction.h>
+#import <UIKit/UIURLDragPreviewView.h>
+#import <UIKit/_UITextDragCaretView.h>
+#import <WebCore/DragData.h>
 #import <WebCore/PlatformPasteboard.h>
 #import <WebCore/WebItemProviderPasteboard.h>
-#endif
+#endif // ENABLE(DRAG_SUPPORT)
 
 @interface UIEvent(UIEventInternal)
 @property (nonatomic, assign) UIKeyboardInputFlags _inputFlags;
@@ -493,10 +506,6 @@ const CGFloat minimumTapHighlightRadius = 2.0;
 
 @implementation WKContentView (WKInteraction)
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/WKContentViewInteractionAdditions.mm>)
-#import <WebKitAdditions/WKContentViewInteractionAdditions.mm>
-#endif
-
 - (void)_createAndConfigureDoubleTapGestureRecognizer
 {
     _doubleTapGestureRecognizer = adoptNS([[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_doubleTapRecognized:)]);
@@ -4157,6 +4166,654 @@ static bool isAssistableInputType(InputType type)
         completion(nil, nil);
 }
 
+#if ENABLE(DRAG_SUPPORT)
+
+static NSTimeInterval longPressActionDelayAfterLift()
+{
+    return _UIDragInteractionDefaultCompetingLongPressDelay() - _UIDragInteractionDefaultLiftDelay();
+}
+
+- (id <WKUIDelegatePrivate>)webViewUIDelegate
+{
+    return (id <WKUIDelegatePrivate>)[_webView UIDelegate];
+}
+
+- (void)setupDataInteractionDelegates
+{
+    _dataInteraction = adoptNS([[UIDragInteraction alloc] initWithDelegate:self]);
+    _dataOperation = adoptNS([[UIDropInteraction alloc] initWithDelegate:self]);
+    [self addInteraction:_dataInteraction.get()];
+    [self addInteraction:_dataOperation.get()];
+}
+
+- (void)teardownDataInteractionDelegates
+{
+    if (_dataInteraction)
+        [self removeInteraction:_dataInteraction.get()];
+
+    if (_dataOperation)
+        [self removeInteraction:_dataOperation.get()];
+
+    _dataInteraction = nil;
+    _dataOperation = nil;
+
+    [self cleanUpDragSourceSessionState];
+}
+
+- (void)_startDataInteractionWithImage:(RetainPtr<CGImageRef>)image withIndicatorData:(std::optional<TextIndicatorData>)indicatorData atClientPosition:(CGPoint)clientPosition anchorPoint:(CGPoint)anchorPoint action:(uint64_t)action
+{
+    ASSERT(action != DragSourceActionNone);
+    _dataInteractionState.image = adoptNS([[UIImage alloc] initWithCGImage:image.get() scale:_page->deviceScaleFactor() orientation:UIImageOrientationUp]);
+    _dataInteractionState.indicatorData = indicatorData;
+    _dataInteractionState.sourceAction = static_cast<DragSourceAction>(action);
+
+    // As the drag is being recognized, schedule the action sheet to show in 500 ms, if there is an action sheet to be shown.
+    // We will handle showing the action sheet here, instead of going through the long press gesture recognizer.
+    [_longPressGestureRecognizer setEnabled:NO];
+    [_longPressGestureRecognizer setEnabled:YES];
+    [self cancelDeferredActionAtDragOrigin];
+    [self performSelector:@selector(performDeferredActionAtDragOrigin) withObject:nil afterDelay:longPressActionDelayAfterLift()];
+    _deferredActionSheetRequestLocation = _dataInteractionState.gestureOrigin;
+}
+
+- (void)_didHandleStartDataInteractionRequest:(BOOL)started
+{
+    BlockPtr<void()> savedCompletionBlock = _dataInteractionState.dragStartCompletionBlock;
+    _dataInteractionState.dragStartCompletionBlock = nil;
+    ASSERT(savedCompletionBlock);
+
+    if (started) {
+        // Since we're going through with the drag, don't allow the highlight long press gesture recognizer to fire a synthetic click.
+        [self _cancelLongPressGestureRecognizer];
+    } else {
+        // The web process rejected the drag start request, so don't go through with the drag.
+        // By clearing out the source session state, we force -itemsForDragInteraction:session: to return an empty array, which
+        // causes UIKit to bail before beginning the lift animation.
+        [self cleanUpDragSourceSessionState];
+    }
+
+    if (savedCompletionBlock)
+        savedCompletionBlock();
+}
+
+static RetainPtr<UIImage> uiImageForImage(RefPtr<Image> image)
+{
+    if (!image)
+        return nullptr;
+
+    auto cgImage = image->nativeImage();
+    if (!cgImage)
+        return nullptr;
+
+    return adoptNS([[UIImage alloc] initWithCGImage:cgImage.get()]);
+}
+
+static BOOL shouldUseTextIndicatorToCreatePreviewForDragAction(DragSourceAction action)
+{
+    if (action & (DragSourceActionLink | DragSourceActionSelection))
+        return YES;
+
+#if ENABLE(ATTACHMENT_ELEMENT)
+    if (action & DragSourceActionAttachment)
+        return YES;
+#endif
+
+    return NO;
+}
+
+- (RetainPtr<UITargetedDragPreview>)dragPreviewForImage:(UIImage *)image frameInRootViewCoordinates:(const FloatRect&)frame clippingRectsInFrameCoordinates:(const Vector<FloatRect>&)clippingRects backgroundColor:(UIColor *)backgroundColor
+{
+    if (frame.isEmpty() || !image)
+        return nullptr;
+
+    UIView *container = [self unscaledView];
+    FloatRect frameInContainerCoordinates;
+    NSMutableArray *clippingRectValuesInFrameCoordinates = [NSMutableArray arrayWithCapacity:clippingRects.size()];
+
+    frameInContainerCoordinates = [self convertRect:frame toView:container];
+    if (frameInContainerCoordinates.isEmpty())
+        return nullptr;
+
+    float widthScalingRatio = frameInContainerCoordinates.width() / frame.width();
+    float heightScalingRatio = frameInContainerCoordinates.height() / frame.height();
+    for (auto rect : clippingRects) {
+        rect.scale(widthScalingRatio, heightScalingRatio);
+        [clippingRectValuesInFrameCoordinates addObject:[NSValue valueWithCGRect:rect]];
+    }
+
+    auto imageView = adoptNS([[UIImageView alloc] initWithImage:image]);
+    [imageView setFrame:frameInContainerCoordinates];
+
+    RetainPtr<UIDragPreviewParameters> parameters;
+    if (clippingRectValuesInFrameCoordinates.count)
+        parameters = adoptNS([[UIDragPreviewParameters alloc] initWithTextLineRects:clippingRectValuesInFrameCoordinates]);
+    else
+        parameters = adoptNS([[UIDragPreviewParameters alloc] init]);
+
+    if (backgroundColor)
+        [parameters setBackgroundColor:backgroundColor];
+
+    CGPoint centerInContainerCoordinates = { CGRectGetMidX(frameInContainerCoordinates), CGRectGetMidY(frameInContainerCoordinates) };
+    auto target = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:container center:centerInContainerCoordinates]);
+    auto dragPreview = adoptNS([[UITargetedDragPreview alloc] initWithView:imageView.get() parameters:parameters.get() target:target.get()]);
+    return dragPreview;
+}
+
+- (RetainPtr<UITargetedDragPreview>)dragPreviewForCurrentDataInteractionState
+{
+    auto action = _dataInteractionState.sourceAction;
+    if (action & DragSourceActionImage && _dataInteractionState.image) {
+        Vector<FloatRect> emptyClippingRects;
+        return [self dragPreviewForImage:_dataInteractionState.image.get() frameInRootViewCoordinates:_dataInteractionState.elementBounds clippingRectsInFrameCoordinates:emptyClippingRects backgroundColor:nil];
+    }
+
+    if (shouldUseTextIndicatorToCreatePreviewForDragAction(action) && _dataInteractionState.indicatorData) {
+        auto indicator = _dataInteractionState.indicatorData.value();
+        return [self dragPreviewForImage:uiImageForImage(indicator.contentImage).get() frameInRootViewCoordinates:indicator.textBoundingRectInRootViewCoordinates clippingRectsInFrameCoordinates:indicator.textRectsInBoundingRectCoordinates backgroundColor:[UIColor colorWithCGColor:cachedCGColor(indicator.estimatedBackgroundColor)]];
+    }
+
+    return nil;
+}
+
+- (void)performDeferredActionAtDragOrigin
+{
+    auto deferredActionPosition = roundedIntPoint(_deferredActionSheetRequestLocation);
+    [self cancelDeferredActionAtDragOrigin];
+    [self _cancelLongPressGestureRecognizer];
+
+    RetainPtr<WKContentView> retainedSelf(self);
+    [self doAfterPositionInformationUpdate:[retainedSelf] (InteractionInformationAtPosition positionInformation) {
+        if (auto action = [retainedSelf _actionForLongPressFromPositionInformation:positionInformation])
+            [retainedSelf performSelector:action];
+    } forRequest:InteractionInformationRequest(deferredActionPosition)];
+}
+
+- (void)cancelDeferredActionAtDragOrigin
+{
+    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(performDeferredActionAtDragOrigin) object:nil];
+    _deferredActionSheetRequestLocation = CGPointZero;
+}
+
+- (void)computeClientAndGlobalPointsForDropSession:(id <UIDropSession>)session outClientPoint:(CGPoint *)outClientPoint outGlobalPoint:(CGPoint *)outGlobalPoint
+{
+    if (outClientPoint)
+        *outClientPoint = [session locationInView:self];
+
+    if (outGlobalPoint) {
+        UIWindow *window = self.window;
+        *outGlobalPoint = window ? [session locationInView:window] : _dataInteractionState.lastGlobalPosition;
+    }
+}
+
+static UIDropOperation dropOperationForWebCoreDragOperation(DragOperation operation)
+{
+    if (operation & DragOperationMove)
+        return UIDropOperationMove;
+
+    if (operation & DragOperationCopy)
+        return UIDropOperationCopy;
+
+    return UIDropOperationCancel;
+}
+
+- (DragData)dragDataForDropSession:(id <UIDropSession>)session dragDestinationAction:(WKDragDestinationAction)dragDestinationAction
+{
+    CGPoint global;
+    CGPoint client;
+    [self computeClientAndGlobalPointsForDropSession:session outClientPoint:&client outGlobalPoint:&global];
+
+    DragOperation dragOperationMask = static_cast<DragOperation>(session.allowsMoveOperation ? DragOperationEvery : (DragOperationEvery & ~DragOperationMove));
+    return { session, roundedIntPoint(client), roundedIntPoint(global), dragOperationMask, DragApplicationNone, static_cast<DragDestinationAction>(dragDestinationAction) };
+}
+
+- (void)cleanUpDragSourceSessionState
+{
+    if (![[WebItemProviderPasteboard sharedInstance] hasPendingOperation]) {
+        // If we're performing a drag operation, don't clear out the pasteboard yet, since another web view may still require access to it.
+        // The pasteboard will be cleared after the last client is finished performing a drag operation using the item providers.
+        [[WebItemProviderPasteboard sharedInstance] setItemProviders:nil];
+    }
+
+    if (auto completionBlock = _dataInteractionState.dragStartCompletionBlock) {
+        // If the previous drag session is still initializing, we need to ensure that its completion block is called to prevent UIKit from getting out of state.
+        _dataInteractionState.dragStartCompletionBlock = nil;
+        completionBlock();
+    }
+
+    [_dataInteractionState.caretView remove];
+    [_dataInteractionState.visibleContentViewSnapshot removeFromSuperview];
+
+    _dataInteractionState = { };
+}
+
+static NSArray<UIItemProvider *> *extractItemProvidersFromDragItems(NSArray<UIDragItem *> *dragItems)
+{
+    __block NSMutableArray<UIItemProvider *> *providers = [NSMutableArray array];
+    for (UIDragItem *item in dragItems) {
+        RetainPtr<UIItemProvider> provider = item.itemProvider;
+        if (provider)
+            [providers addObject:provider.get()];
+    }
+    return providers;
+}
+
+static NSArray<UIItemProvider *> *extractItemProvidersFromDropSession(id <UIDropSession> session)
+{
+    return extractItemProvidersFromDragItems(session.items);
+}
+
+- (void)_didConcludeEditDataInteraction:(std::optional<TextIndicatorData>)data
+{
+    if (!data)
+        return;
+
+    auto snapshotWithoutSelection = data->contentImageWithoutSelection;
+    if (!snapshotWithoutSelection)
+        return;
+
+    auto unselectedSnapshotImage = snapshotWithoutSelection->nativeImage();
+    if (!unselectedSnapshotImage)
+        return;
+
+    auto dataInteractionUnselectedContentImage = adoptNS([[UIImage alloc] initWithCGImage:unselectedSnapshotImage.get() scale:_page->deviceScaleFactor() orientation:UIImageOrientationUp]);
+    RetainPtr<UIImageView> unselectedContentSnapshot = adoptNS([[UIImageView alloc] initWithImage:dataInteractionUnselectedContentImage.get()]);
+    [unselectedContentSnapshot setFrame:data->contentImageWithoutSelectionRectInRootViewCoordinates];
+
+    RetainPtr<WKContentView> protectedSelf = self;
+    RetainPtr<UIView> visibleContentViewSnapshot = adoptNS(_dataInteractionState.visibleContentViewSnapshot.leakRef());
+
+    _dataInteractionState.isAnimatingConcludeEditDrag = YES;
+    [self insertSubview:unselectedContentSnapshot.get() belowSubview:visibleContentViewSnapshot.get()];
+    [UIView animateWithDuration:0.25 animations:^() {
+        [visibleContentViewSnapshot setAlpha:0];
+    } completion:^(BOOL completed) {
+        [visibleContentViewSnapshot removeFromSuperview];
+        [UIView animateWithDuration:0.25 animations:^() {
+            [protectedSelf setSuppressAssistantSelectionView:NO];
+            [unselectedContentSnapshot setAlpha:0];
+        } completion:^(BOOL completed) {
+            [unselectedContentSnapshot removeFromSuperview];
+        }];
+    }];
+}
+
+- (void)_didPerformDataInteractionControllerOperation:(BOOL)handled
+{
+    [[WebItemProviderPasteboard sharedInstance] decrementPendingOperationCount];
+    RetainPtr<id <UIDropSession>> dropSession = _dataInteractionState.dropSession;
+    if ([self.webViewUIDelegate respondsToSelector:@selector(_webView:dataInteractionOperationWasHandled:forSession:itemProviders:)])
+        [self.webViewUIDelegate _webView:_webView dataInteractionOperationWasHandled:handled forSession:dropSession.get() itemProviders:[WebItemProviderPasteboard sharedInstance].itemProviders];
+
+    if (!_dataInteractionState.isAnimatingConcludeEditDrag)
+        self.suppressAssistantSelectionView = NO;
+
+    CGPoint global;
+    CGPoint client;
+    [self computeClientAndGlobalPointsForDropSession:dropSession.get() outClientPoint:&client outGlobalPoint:&global];
+    [self cleanUpDragSourceSessionState];
+    _page->dragEnded(roundedIntPoint(client), roundedIntPoint(global), _page->currentDragOperation());
+}
+
+- (void)_transitionDragPreviewToImageIfNecessary:(id <UIDragSession>)session
+{
+    if (_dataInteractionState.sourceAction & DragSourceActionImage || !(_dataInteractionState.sourceAction & DragSourceActionLink))
+        return;
+
+    auto linkDraggingCenter = _dataInteractionState.adjustedOrigin;
+    RetainPtr<NSString> title = (NSString *)_dataInteractionState.linkTitle;
+    RetainPtr<NSURL> url = (NSURL *)_dataInteractionState.linkURL;
+    session.items.firstObject.previewProvider = [title, url, linkDraggingCenter] () -> UIDragPreview * {
+        UIURLDragPreviewView *previewView = [UIURLDragPreviewView viewWithTitle:title.get() URL:url.get()];
+        previewView.center = linkDraggingCenter;
+
+        UIDragPreviewParameters *parameters = [[[UIDragPreviewParameters alloc] initWithTextLineRects:@[ [NSValue valueWithCGRect:previewView.bounds] ]] autorelease];
+        return [[[UIDragPreview alloc] initWithView:previewView parameters:parameters] autorelease];
+    };
+}
+
+- (void)_didChangeDataInteractionCaretRect:(CGRect)previousRect currentRect:(CGRect)rect
+{
+    BOOL previousRectIsEmpty = CGRectIsEmpty(previousRect);
+    BOOL currentRectIsEmpty = CGRectIsEmpty(rect);
+    if (previousRectIsEmpty && currentRectIsEmpty)
+        return;
+
+    if (previousRectIsEmpty) {
+        _dataInteractionState.caretView = adoptNS([[_UITextDragCaretView alloc] initWithTextInputView:self]);
+        [_dataInteractionState.caretView insertAtPosition:[WKTextPosition textPositionWithRect:rect]];
+        return;
+    }
+
+    if (currentRectIsEmpty) {
+        [_dataInteractionState.caretView remove];
+        _dataInteractionState.caretView = nil;
+        return;
+    }
+
+    [_dataInteractionState.caretView updateToPosition:[WKTextPosition textPositionWithRect:rect]];
+}
+
+- (WKDragDestinationAction)_dragDestinationActionForDropSession:(id <UIDropSession>)session
+{
+    id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
+    if ([uiDelegate respondsToSelector:@selector(_webView:dragDestinationActionMaskForDraggingInfo:)])
+        return [uiDelegate _webView:_webView dragDestinationActionMaskForDraggingInfo:session];
+
+    return WKDragDestinationActionAny & ~WKDragDestinationActionLoad;
+}
+
+static BOOL positionInformationMayStartDataInteraction(const InteractionInformationAtPosition& positionInformation)
+{
+    return positionInformation.isImage || positionInformation.isLink || positionInformation.isAttachment || positionInformation.hasSelectionAtPosition;
+}
+
+- (id <UIDragDropSession>)currentDragOrDropSession
+{
+    if (_dataInteractionState.dropSession)
+        return _dataInteractionState.dropSession.get();
+    return _dataInteractionState.dragSession.get();
+}
+
+#pragma mark - UIDragInteractionDelegate
+
+- (void)_dragInteraction:(UIDragInteraction *)interaction prepareForSession:(id <UIDragSession>)session completion:(dispatch_block_t)completion
+{
+    if (self.currentDragOrDropSession) {
+        // FIXME: Support multiple simultaneous drag sessions in the future.
+        completion();
+        return;
+    }
+
+    [self cleanUpDragSourceSessionState];
+
+    CGPoint dragOrigin = [session locationInView:self];
+    RetainPtr<WKContentView> retainedSelf(self);
+
+    [self doAfterPositionInformationUpdate:[retainedSelf, session, dragOrigin, capturedBlock = makeBlockPtr(completion)] (InteractionInformationAtPosition positionInformation) {
+        if (!positionInformationMayStartDataInteraction(positionInformation)) {
+            capturedBlock();
+            return;
+        }
+
+        auto& state = retainedSelf->_dataInteractionState;
+        state.dragStartCompletionBlock = capturedBlock;
+        state.gestureOrigin = dragOrigin;
+        state.adjustedOrigin = retainedSelf->_positionInformation.adjustedPointForNodeRespondingToClickEvents;
+        state.elementBounds = retainedSelf->_positionInformation.bounds;
+        state.linkTitle = retainedSelf->_positionInformation.title;
+        state.linkURL = retainedSelf->_positionInformation.url;
+        state.dragSession = session;
+        retainedSelf->_page->requestStartDataInteraction(roundedIntPoint(state.adjustedOrigin), roundedIntPoint([retainedSelf convertPoint:state.adjustedOrigin toView:[retainedSelf window]]));
+    } forRequest:InteractionInformationRequest(roundedIntPoint(dragOrigin))];
+}
+
+- (NSArray<UIDragItem *> *)dragInteraction:(UIDragInteraction *)interaction itemsForBeginningSession:(id <UIDragSession>)session
+{
+    if (_dataInteractionState.dragSession != session)
+        return @[ ];
+
+    WebItemProviderPasteboard *draggingPasteboard = [WebItemProviderPasteboard sharedInstance];
+    ASSERT(interaction == _dataInteraction);
+    NSUInteger numberOfItems = draggingPasteboard.numberOfItems;
+    if (!numberOfItems) {
+        _page->dragCancelled();
+        return @[ ];
+    }
+
+    [UICalloutBar fadeSharedCalloutBar];
+
+    // Give internal clients such as Mail one final chance to augment the contents of each UIItemProvider before sending the drag items off to UIKit.
+    id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
+    if ([uiDelegate respondsToSelector:@selector(_webView:adjustedDataInteractionItemProvidersForItemProvider:representingObjects:additionalData:)]) {
+        NSMutableArray *adjustedItemProviders = [NSMutableArray array];
+        for (NSUInteger itemIndex = 0; itemIndex < numberOfItems; ++itemIndex) {
+            WebItemProviderRegistrationInfoList *infoList = [draggingPasteboard registrationInfoAtIndex:itemIndex];
+            auto representingObjects = adoptNS([[NSMutableArray alloc] init]);
+            auto additionalData = adoptNS([[NSMutableDictionary alloc] init]);
+            [infoList enumerateItems:[representingObjects, additionalData] (WebItemProviderRegistrationInfo *item, NSUInteger) {
+                if (item.representingObject)
+                    [representingObjects addObject:item.representingObject];
+                if (item.typeIdentifier && item.data)
+                    [additionalData setObject:item.data forKey:item.typeIdentifier];
+            }];
+            if (NSArray *replacementItemProviders = [uiDelegate _webView:_webView adjustedDataInteractionItemProvidersForItemProvider:[draggingPasteboard itemProviderAtIndex:itemIndex] representingObjects:representingObjects.get() additionalData:additionalData.get()])
+                [adjustedItemProviders addObjectsFromArray:replacementItemProviders];
+        }
+        draggingPasteboard.itemProviders = adjustedItemProviders;
+    } else if ([uiDelegate respondsToSelector:@selector(_webView:adjustedDataInteractionItemProviders:)])
+        draggingPasteboard.itemProviders = [uiDelegate _webView:_webView adjustedDataInteractionItemProviders:draggingPasteboard.itemProviders];
+
+    __block RetainPtr<NSMutableArray> itemsForDragInteraction = [NSMutableArray array];
+    [draggingPasteboard enumerateItemProvidersWithBlock:^(UIItemProvider *itemProvider, NSUInteger index, BOOL *stop) {
+        [itemsForDragInteraction addObject:[[[UIDragItem alloc] initWithItemProvider:itemProvider] autorelease]];
+    }];
+
+    if (![itemsForDragInteraction count])
+        _page->dragCancelled();
+
+    return itemsForDragInteraction.get();
+}
+
+- (UITargetedDragPreview *)_api_dragInteraction:(UIDragInteraction *)interaction previewForLiftingItem:(UIDragItem *)item session:(id <UIDragSession>)session
+{
+    id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
+    if ([uiDelegate respondsToSelector:@selector(_webView:previewForLiftingItem:session:)]) {
+        UITargetedDragPreview *overridenPreview = [uiDelegate _webView:_webView previewForLiftingItem:item session:session];
+        if (overridenPreview)
+            return overridenPreview;
+    }
+    return self.dragPreviewForCurrentDataInteractionState.autorelease();
+}
+
+- (void)dragInteraction:(UIDragInteraction *)interaction sessionWillBegin:(id <UIDragSession>)session
+{
+    id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
+    if ([uiDelegate respondsToSelector:@selector(_webView:dataInteraction:sessionWillBegin:)])
+        [uiDelegate _webView:_webView dataInteraction:interaction sessionWillBegin:session];
+
+    [self cancelDeferredActionAtDragOrigin];
+    [_actionSheetAssistant cleanupSheet];
+
+    _dataInteractionState.didBeginDragging = YES;
+    [self _transitionDragPreviewToImageIfNecessary:session];
+
+    _page->didStartDrag();
+}
+
+- (void)_api_dragInteraction:(UIDragInteraction *)interaction session:(id <UIDragSession>)session didEndWithOperation:(UIDropOperation)operation
+{
+    id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
+    if ([uiDelegate respondsToSelector:@selector(_webView:dataInteraction:session:didEndWithOperation:)])
+        [uiDelegate _webView:_webView dataInteraction:interaction session:session didEndWithOperation:operation];
+
+    if (_dataInteractionState.isPerformingOperation)
+        return;
+
+    [self cancelDeferredActionAtDragOrigin];
+    [self cleanUpDragSourceSessionState];
+
+    _page->dragEnded(roundedIntPoint(_dataInteractionState.adjustedOrigin), roundedIntPoint([self convertPoint:_dataInteractionState.adjustedOrigin toView:self.window]), operation);
+}
+
+- (UITargetedDragPreview *)dragInteraction:(UIDragInteraction *)interaction previewForCancellingItem:(UIDragItem *)item withDefault:(UITargetedDragPreview *)defaultPreview
+{
+    id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
+    if ([uiDelegate respondsToSelector:@selector(_webView:previewForCancellingItem:withDefault:)]) {
+        UITargetedDragPreview *overridenPreview = [uiDelegate _webView:_webView previewForCancellingItem:item withDefault:defaultPreview];
+        if (overridenPreview)
+            return overridenPreview;
+    }
+    return self.dragPreviewForCurrentDataInteractionState.autorelease();
+}
+
+- (void)_api_dragInteraction:(UIDragInteraction *)interaction item:(UIDragItem *)item willAnimateCancelWithAnimator:(id <UIDragAnimating>)animator
+{
+    [animator addCompletion:[page = _page] (UIViewAnimatingPosition finalPosition) {
+        page->dragCancelled();
+    }];
+}
+
+#pragma mark - UIDropInteractionDelegate
+
+- (BOOL)dropInteraction:(UIDropInteraction *)interaction canHandleSession:(id<UIDropSession>)session
+{
+    // FIXME: Support multiple simultaneous drop sessions in the future.
+    id <UIDragDropSession> dragOrDropSession = self.currentDragOrDropSession;
+    return !dragOrDropSession || session.localDragSession == dragOrDropSession;
+}
+
+- (void)_api_dropInteraction:(UIDropInteraction *)interaction sessionDidEnter:(id <UIDropSession>)session
+{
+    _dataInteractionState.dropSession = session;
+
+    [[WebItemProviderPasteboard sharedInstance] setItemProviders:extractItemProvidersFromDropSession(session)];
+
+    auto dragData = [self dragDataForDropSession:session dragDestinationAction:[self _dragDestinationActionForDropSession:session]];
+
+    _page->dragEntered(dragData, "data interaction pasteboard");
+    _dataInteractionState.lastGlobalPosition = dragData.globalPosition();
+}
+
+- (UIDropProposal *)_api_dropInteraction:(UIDropInteraction *)interaction sessionDidUpdate:(id <UIDropSession>)session
+{
+    [[WebItemProviderPasteboard sharedInstance] setItemProviders:extractItemProvidersFromDropSession(session)];
+
+    auto dragData = [self dragDataForDropSession:session dragDestinationAction:[self _dragDestinationActionForDropSession:session]];
+    _page->dragUpdated(dragData, "data interaction pasteboard");
+    _dataInteractionState.lastGlobalPosition = dragData.globalPosition();
+
+    NSUInteger operation = dropOperationForWebCoreDragOperation(_page->currentDragOperation());
+    if ([self.webViewUIDelegate respondsToSelector:@selector(_webView:willUpdateDataInteractionOperationToOperation:forSession:)])
+        operation = [self.webViewUIDelegate _webView:_webView willUpdateDataInteractionOperationToOperation:operation forSession:session];
+
+    return [[[UIDropProposal alloc] initWithDropOperation:static_cast<UIDropOperation>(operation)] autorelease];
+}
+
+- (void)dropInteraction:(UIDropInteraction *)interaction sessionDidExit:(id <UIDropSession>)session
+{
+    [[WebItemProviderPasteboard sharedInstance] setItemProviders:extractItemProvidersFromDropSession(session)];
+
+    auto dragData = [self dragDataForDropSession:session dragDestinationAction:WKDragDestinationActionAny];
+    _page->dragExited(dragData, "data interaction pasteboard");
+    _page->resetCurrentDragInformation();
+}
+
+- (void)dropInteraction:(UIDropInteraction *)interaction performDrop:(id <UIDropSession>)session
+{
+    NSArray <UIItemProvider *> *itemProviders = extractItemProvidersFromDropSession(session);
+    id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
+    if ([uiDelegate respondsToSelector:@selector(_webView:performDataInteractionOperationWithItemProviders:)]) {
+        if ([uiDelegate _webView:_webView performDataInteractionOperationWithItemProviders:itemProviders])
+            return;
+    }
+
+    if ([uiDelegate respondsToSelector:@selector(_webView:willPerformDropWithSession:)]) {
+        itemProviders = extractItemProvidersFromDragItems([uiDelegate _webView:_webView willPerformDropWithSession:session]);
+        if (!itemProviders.count)
+            return;
+    }
+
+    [[WebItemProviderPasteboard sharedInstance] setItemProviders:itemProviders];
+    [[WebItemProviderPasteboard sharedInstance] incrementPendingOperationCount];
+    _dataInteractionState.isPerformingOperation = YES;
+    auto dragData = [self dragDataForDropSession:session dragDestinationAction:WKDragDestinationActionAny];
+
+    // Always loading content from the item provider ensures that the web process will be allowed to call back in to the UI
+    // process to access pasteboard contents at a later time. Ideally, we only need to do this work if we're over a file input
+    // or the page prevented default on `dragover`, but without this, dropping into a normal editable areas will fail due to
+    // item providers not loading any data.
+    RetainPtr<WKContentView> retainedSelf(self);
+    [[WebItemProviderPasteboard sharedInstance] doAfterLoadingProvidedContentIntoFileURLs:[retainedSelf, capturedDragData = WTFMove(dragData)] (NSArray *fileURLs) mutable {
+        Vector<String> filenames;
+        for (NSURL *fileURL in fileURLs)
+            filenames.append([fileURL path]);
+        capturedDragData.setFileNames(filenames);
+
+        SandboxExtension::Handle sandboxExtensionHandle;
+        SandboxExtension::HandleArray sandboxExtensionForUpload;
+        retainedSelf->_page->createSandboxExtensionsIfNeeded(filenames, sandboxExtensionHandle, sandboxExtensionForUpload);
+        retainedSelf->_page->performDragOperation(capturedDragData, "data interaction pasteboard", sandboxExtensionHandle, sandboxExtensionForUpload);
+
+        retainedSelf->_dataInteractionState.visibleContentViewSnapshot = [retainedSelf snapshotViewAfterScreenUpdates:NO];
+        [retainedSelf setSuppressAssistantSelectionView:YES];
+        [UIView performWithoutAnimation:[retainedSelf] {
+            [retainedSelf->_dataInteractionState.visibleContentViewSnapshot setFrame:[retainedSelf bounds]];
+            [retainedSelf addSubview:retainedSelf->_dataInteractionState.visibleContentViewSnapshot.get()];
+        }];
+    }];
+}
+
+- (UITargetedDragPreview *)dropInteraction:(UIDropInteraction *)interaction previewForDroppingItem:(UIDragItem *)item withDefault:(UITargetedDragPreview *)defaultPreview
+{
+    CGRect caretRect = _page->currentDragCaretRect();
+    if (CGRectIsEmpty(caretRect))
+        return nil;
+
+    // FIXME: <rdar://problem/31074376> [WK2] Performing an edit drag should transition from the initial drag preview to the final drop preview
+    // This is blocked on UIKit support, since we aren't able to update the text clipping rects of a UITargetedDragPreview mid-flight. For now,
+    // just zoom to the center of the caret rect while shrinking the drop preview.
+    auto caretRectInWindowCoordinates = [self convertRect:caretRect toView:[UITextEffectsWindow sharedTextEffectsWindow]];
+    auto caretCenterInWindowCoordinates = CGPointMake(CGRectGetMidX(caretRectInWindowCoordinates), CGRectGetMidY(caretRectInWindowCoordinates));
+    auto target = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:[UITextEffectsWindow sharedTextEffectsWindow] center:caretCenterInWindowCoordinates transform:CGAffineTransformMakeScale(0, 0)]);
+    return [defaultPreview retargetedPreviewWithTarget:target.get()];
+}
+
+- (void)dropInteraction:(UIDropInteraction *)interaction sessionDidEnd:(id <UIDropSession>)session
+{
+    if (_dataInteractionState.isPerformingOperation || _dataInteractionState.didBeginDragging)
+        return;
+
+    CGPoint global;
+    CGPoint client;
+    [self computeClientAndGlobalPointsForDropSession:session outClientPoint:&client outGlobalPoint:&global];
+    [self cleanUpDragSourceSessionState];
+    _page->dragEnded(roundedIntPoint(client), roundedIntPoint(global), UIDragOperationNone);
+}
+
+#pragma mark - Unit testing support
+
+- (void)_simulateDataInteractionEntered:(id)session
+{
+    [self _api_dropInteraction:_dataOperation.get() sessionDidEnter:session];
+}
+
+- (BOOL)_simulateDataInteractionUpdated:(id)session
+{
+    return [self _api_dropInteraction:_dataOperation.get() sessionDidUpdate:session].operation != UIDropOperationCancel;
+}
+
+- (void)_simulateDataInteractionEnded:(id)session
+{
+    [self dropInteraction:_dataOperation.get() sessionDidEnd:session];
+}
+
+- (void)_simulateDataInteractionPerformOperation:(id)session
+{
+    [self dropInteraction:_dataOperation.get() performDrop:session];
+}
+
+- (void)_simulateDataInteractionSessionDidEnd:(id)session
+{
+    [self _api_dragInteraction:_dataInteraction.get() session:session didEndWithOperation:UIDropOperationCopy];
+}
+
+- (void)_simulateWillBeginDataInteractionWithSession:(id)session
+{
+    [self dragInteraction:_dataInteraction.get() sessionWillBegin:session];
+}
+
+- (NSArray *)_simulatedItemsForSession:(id)session
+{
+    return [self dragInteraction:_dataInteraction.get() itemsForBeginningSession:session];
+}
+
+- (void)_simulatePrepareForDataInteractionSession:(id)session completion:(dispatch_block_t)completion
+{
+    [self _dragInteraction:_dataInteraction.get() prepareForSession:session completion:completion];
+}
+
+#endif
+
 @end
 
 @implementation WKContentView (WKTesting)
index c7c2689..7a9825b 100644 (file)
 #import "WebPage.h"
 #import "WebPageProxyMessages.h"
 #import <WebCore/CachedImage.h>
+#import <WebCore/Document.h>
 #import <WebCore/DragController.h>
+#import <WebCore/Editor.h>
+#import <WebCore/Element.h>
 #import <WebCore/Frame.h>
+#import <WebCore/FrameDestructionObserver.h>
 #import <WebCore/FrameView.h>
 #import <WebCore/GraphicsContext.h>
 #import <WebCore/LegacyWebArchive.h>
 #import <WebCore/MainFrame.h>
-#import <WebCore/WebCoreNSURLExtras.h>
+#import <WebCore/NotImplemented.h>
 #import <WebCore/Page.h>
+#import <WebCore/Pasteboard.h>
 #import <WebCore/RenderImage.h>
 #import <WebCore/ResourceHandle.h>
 #import <WebCore/StringTruncator.h>
+#import <WebCore/WebCoreNSURLExtras.h>
 #import <WebKitSystemInterface.h>
 #import <wtf/StdLibExtras.h>
 
+#if PLATFORM(IOS)
+#import "UIKitSPI.h"
+#endif
+
 using namespace WebCore;
 using namespace WebKit;
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/WebDragClientAdditionsWebKit2.mm>)
-#import <WebKitAdditions/WebDragClientAdditionsWebKit2.mm>
-#endif
+namespace WebKit {
 
 #if PLATFORM(MAC)
 
-namespace WebKit {
-
 static RefPtr<ShareableBitmap> convertImageToBitmap(NSImage *image, const IntSize& size, Frame& frame)
 {
     ShareableBitmap::Flags flags = ShareableBitmap::SupportsAlpha;
@@ -184,8 +190,57 @@ void WebDragClient::declareAndWriteDragImage(const String& pasteboardName, Eleme
     m_page->send(Messages::WebPageProxy::SetPromisedDataForImage(pasteboardName, imageHandle, imageSize, filename, extension, title, String([[response URL] absoluteString]), userVisibleString((NSURL *)url), archiveHandle, archiveSize));
 }
 
-} // namespace WebKit
-
 #endif // PLATFORM(MAC)
 
+#if PLATFORM(IOS)
+
+static RefPtr<ShareableBitmap> convertCGImageToBitmap(CGImageRef image, const IntSize& size, Frame& frame)
+{
+    auto bitmap = ShareableBitmap::createShareable(size, ShareableBitmap::SupportsAlpha | ShareableBitmap::SupportsExtendedColor);
+    if (!bitmap)
+        return nullptr;
+
+    auto graphicsContext = bitmap->createGraphicsContext();
+    UIGraphicsPushContext(graphicsContext->platformContext());
+    CGContextDrawImage(graphicsContext->platformContext(), CGRectMake(0, 0, size.width(), size.height()), image);
+    UIGraphicsPopContext();
+    return bitmap;
+}
+
+void WebDragClient::startDrag(DragImage image, const IntPoint& point, const IntPoint& eventLocation, const FloatPoint& dragImageAnchor, DataTransfer& dataTransfer, Frame& frame, DragSourceAction dragSourceAction)
+{
+    IntSize bitmapSize(CGImageGetWidth(image.get().get()), CGImageGetHeight(image.get().get()));
+    auto bitmap = convertCGImageToBitmap(image.get().get(), bitmapSize, frame);
+    ShareableBitmap::Handle handle;
+    if (!bitmap || !bitmap->createHandle(handle))
+        return;
+
+    m_page->willStartDrag();
+    m_page->send(Messages::WebPageProxy::SetDragImage(frame.view()->contentsToWindow(point), handle, image.indicatorData(), dragImageAnchor, dragSourceAction));
+}
+
+void WebDragClient::declareAndWriteDragImage(const String& pasteboardName, Element& element, const URL& url, const String& label, Frame*)
+{
+    if (auto frame = element.document().frame())
+        frame->editor().writeImageToPasteboard(*Pasteboard::createForDragAndDrop(), element, url, label);
+}
+
+void WebDragClient::didConcludeEditDrag()
+{
+    m_page->didConcludeEditDataInteraction();
+}
+
+#if ENABLE(ATTACHMENT_ELEMENT)
+
+void WebDragClient::declareAndWriteAttachment(const String&, Element&, const URL&, const String&, Frame*)
+{
+    notImplemented();
+}
+
+#endif
+
+#endif // PLATFORM(IOS)
+
+} // namespace WebKit
+
 #endif // ENABLE(DRAG_SUPPORT)
index 0d71aa1..734c78a 100644 (file)
@@ -1,3 +1,55 @@
+2017-06-16  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [iOS DnD] Upstream iOS drag and drop implementation into OpenSource WebKit
+        https://bugs.webkit.org/show_bug.cgi?id=173366
+        <rdar://problem/32767014>
+
+        Reviewed by Tim Horton.
+
+        Move test pages and pieces of DataInteractionSimulator hidden behind WebKitAdditions into TestWebKitAPI. No
+        change in behavior.
+
+        * TestWebKitAPI/Configurations/FeatureDefines.xcconfig:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/autofocus-contenteditable.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/background-image-link-and-input.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/contenteditable-and-textarea.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/div-and-large-image.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/image-and-contenteditable.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/image-and-textarea.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/link-and-input.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/link-and-target-div.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/prevent-operation.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/prevent-start.html: Added.
+        * TestWebKitAPI/Tests/WebKit2Cocoa/textarea-to-input.html: Added.
+        * TestWebKitAPI/ios/DataInteractionSimulator.mm:
+        (-[MockDragDropSession initWithItems:location:window:]):
+        (-[MockDragDropSession allowsMoveOperation]):
+        (-[MockDragDropSession isRestrictedToDraggingApplication]):
+        (-[MockDragDropSession hasItemsConformingToTypeIdentifiers:]):
+        (-[MockDragDropSession canLoadObjectsOfClass:]):
+        (-[MockDragDropSession canLoadObjectsOfClasses:]):
+        (-[MockDragDropSession items]):
+        (-[MockDragDropSession setItems:]):
+        (-[MockDragDropSession locationInView:]):
+        (-[MockDataOperationSession initWithProviders:location:window:]):
+        (-[MockDataOperationSession session]):
+        (-[MockDataOperationSession isLocal]):
+        (-[MockDataOperationSession progress]):
+        (-[MockDataOperationSession setProgressIndicatorStyle:]):
+        (-[MockDataOperationSession progressIndicatorStyle]):
+        (-[MockDataOperationSession operationMask]):
+        (-[MockDataOperationSession localDragSession]):
+        (-[MockDataOperationSession hasItemsConformingToTypeIdentifier:]):
+        (-[MockDataOperationSession canCreateItemsOfClass:]):
+        (-[MockDataOperationSession loadObjectsOfClass:completion:]):
+        (-[MockDataInteractionSession initWithWindow:]):
+        (-[MockDataInteractionSession localOperationMask]):
+        (-[MockDataInteractionSession externalOperationMask]):
+        (-[MockDataInteractionSession session]):
+        (-[DataInteractionSimulator _advanceProgress]):
+
 2017-06-16  Alex Christensen  <achristensen@webkit.org>
 
         Show punycode to user if a URL has dotless i or j followed by diacritic dot
index 7847657..efee16e 100644 (file)
@@ -248,4 +248,9 @@ ENABLE_VARIATION_FONTS_IF_NOT_ = $(ENABLE_VARIATION_FONTS_IF_NOT_NO);
 ENABLE_VARIATION_FONTS_IF_NOT_NO = ENABLE_VARIATION_FONTS;
 ENABLE_VARIATION_FONTS_IF_NOT_YES = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+ENABLE_DRAG_SUPPORT[sdk=iphoneos11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DRAG_SUPPORT[sdk=iphonesimulator11*] = ENABLE_DRAG_SUPPORT;
+ENABLE_DATA_INTERACTION[sdk=iphoneos11*] = ENABLE_DATA_INTERACTION;
+ENABLE_DATA_INTERACTION[sdk=iphonesimulator11*] = ENABLE_DATA_INTERACTION;
+
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOSNIFF) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_RTC) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
index 6f9f96a..e59ea33 100644 (file)
                E194E1BD177E53C7009C4D4E /* StopLoadingFromDidReceiveResponse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */; };
                ECA680CE1E68CC0900731D20 /* StringUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = ECA680CD1E68CC0900731D20 /* StringUtilities.mm */; };
                F415086D1DA040C50044BE9B /* play-audio-on-click.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F415086C1DA040C10044BE9B /* play-audio-on-click.html */; };
+               F41AB99F1EF4696B0083FA08 /* autofocus-contenteditable.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB9981EF4692C0083FA08 /* autofocus-contenteditable.html */; };
+               F41AB9A01EF4696B0083FA08 /* background-image-link-and-input.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB9971EF4692C0083FA08 /* background-image-link-and-input.html */; };
+               F41AB9A11EF4696B0083FA08 /* contenteditable-and-textarea.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB99C1EF4692C0083FA08 /* contenteditable-and-textarea.html */; };
+               F41AB9A21EF4696B0083FA08 /* div-and-large-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB99E1EF4692C0083FA08 /* div-and-large-image.html */; };
+               F41AB9A31EF4696B0083FA08 /* file-uploading.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB99B1EF4692C0083FA08 /* file-uploading.html */; };
+               F41AB9A41EF4696B0083FA08 /* image-and-contenteditable.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB9991EF4692C0083FA08 /* image-and-contenteditable.html */; };
+               F41AB9A51EF4696B0083FA08 /* image-and-textarea.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB9931EF4692C0083FA08 /* image-and-textarea.html */; };
+               F41AB9A61EF4696B0083FA08 /* link-and-input.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB9961EF4692C0083FA08 /* link-and-input.html */; };
+               F41AB9A71EF4696B0083FA08 /* link-and-target-div.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB99D1EF4692C0083FA08 /* link-and-target-div.html */; };
+               F41AB9A81EF4696B0083FA08 /* prevent-operation.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB9941EF4692C0083FA08 /* prevent-operation.html */; };
+               F41AB9A91EF4696B0083FA08 /* prevent-start.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB99A1EF4692C0083FA08 /* prevent-start.html */; };
+               F41AB9AA1EF4696B0083FA08 /* textarea-to-input.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F41AB9951EF4692C0083FA08 /* textarea-to-input.html */; };
                F42DA5161D8CEFE400336F40 /* large-input-field-focus-onload.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F42DA5151D8CEFDB00336F40 /* large-input-field-focus-onload.html */; };
                F4451C761EB8FD890020C5DA /* two-paragraph-contenteditable.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4451C751EB8FD7C0020C5DA /* two-paragraph-contenteditable.html */; };
                F4538EF71E8473E600B5C953 /* large-red-square.png in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4538EF01E846B4100B5C953 /* large-red-square.png */; };
                        dstPath = TestWebKitAPI.resources;
                        dstSubfolderSpec = 7;
                        files = (
+                               F41AB99F1EF4696B0083FA08 /* autofocus-contenteditable.html in Copy Resources */,
+                               F41AB9A01EF4696B0083FA08 /* background-image-link-and-input.html in Copy Resources */,
+                               F41AB9A11EF4696B0083FA08 /* contenteditable-and-textarea.html in Copy Resources */,
+                               F41AB9A21EF4696B0083FA08 /* div-and-large-image.html in Copy Resources */,
+                               F41AB9A31EF4696B0083FA08 /* file-uploading.html in Copy Resources */,
+                               F41AB9A41EF4696B0083FA08 /* image-and-contenteditable.html in Copy Resources */,
+                               F41AB9A51EF4696B0083FA08 /* image-and-textarea.html in Copy Resources */,
+                               F41AB9A61EF4696B0083FA08 /* link-and-input.html in Copy Resources */,
+                               F41AB9A71EF4696B0083FA08 /* link-and-target-div.html in Copy Resources */,
+                               F41AB9A81EF4696B0083FA08 /* prevent-operation.html in Copy Resources */,
+                               F41AB9A91EF4696B0083FA08 /* prevent-start.html in Copy Resources */,
+                               F41AB9AA1EF4696B0083FA08 /* textarea-to-input.html in Copy Resources */,
                                CDC9442F1EF205D60059C3C4 /* mediastreamtrack-detached.html in Copy Resources */,
                                F46849C01EEF5EF300B937FE /* rich-and-plain-text.html in Copy Resources */,
                                93E2D2761ED7D53200FA76F6 /* offscreen-iframe-of-media-document.html in Copy Resources */,
                ECA680CD1E68CC0900731D20 /* StringUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringUtilities.mm; sourceTree = "<group>"; };
                F3FC3EE213678B7300126A65 /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; };
                F415086C1DA040C10044BE9B /* play-audio-on-click.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "play-audio-on-click.html"; sourceTree = "<group>"; };
+               F41AB9931EF4692C0083FA08 /* image-and-textarea.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "image-and-textarea.html"; sourceTree = "<group>"; };
+               F41AB9941EF4692C0083FA08 /* prevent-operation.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "prevent-operation.html"; sourceTree = "<group>"; };
+               F41AB9951EF4692C0083FA08 /* textarea-to-input.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "textarea-to-input.html"; sourceTree = "<group>"; };
+               F41AB9961EF4692C0083FA08 /* link-and-input.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "link-and-input.html"; sourceTree = "<group>"; };
+               F41AB9971EF4692C0083FA08 /* background-image-link-and-input.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "background-image-link-and-input.html"; sourceTree = "<group>"; };
+               F41AB9981EF4692C0083FA08 /* autofocus-contenteditable.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "autofocus-contenteditable.html"; sourceTree = "<group>"; };
+               F41AB9991EF4692C0083FA08 /* image-and-contenteditable.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "image-and-contenteditable.html"; sourceTree = "<group>"; };
+               F41AB99A1EF4692C0083FA08 /* prevent-start.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "prevent-start.html"; sourceTree = "<group>"; };
+               F41AB99B1EF4692C0083FA08 /* file-uploading.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "file-uploading.html"; sourceTree = "<group>"; };
+               F41AB99C1EF4692C0083FA08 /* contenteditable-and-textarea.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "contenteditable-and-textarea.html"; sourceTree = "<group>"; };
+               F41AB99D1EF4692C0083FA08 /* link-and-target-div.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "link-and-target-div.html"; sourceTree = "<group>"; };
+               F41AB99E1EF4692C0083FA08 /* div-and-large-image.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "div-and-large-image.html"; sourceTree = "<group>"; };
                F42DA5151D8CEFDB00336F40 /* large-input-field-focus-onload.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = "large-input-field-focus-onload.html"; path = "Tests/WebKit2Cocoa/large-input-field-focus-onload.html"; sourceTree = SOURCE_ROOT; };
                F4451C751EB8FD7C0020C5DA /* two-paragraph-contenteditable.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "two-paragraph-contenteditable.html"; sourceTree = "<group>"; };
                F4538EF01E846B4100B5C953 /* large-red-square.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "large-red-square.png"; sourceTree = "<group>"; };
                A16F66B81C40E9E100BD4D24 /* Resources */ = {
                        isa = PBXGroup;
                        children = (
+                               F41AB9981EF4692C0083FA08 /* autofocus-contenteditable.html */,
+                               F41AB9971EF4692C0083FA08 /* background-image-link-and-input.html */,
+                               F41AB99C1EF4692C0083FA08 /* contenteditable-and-textarea.html */,
+                               F41AB99E1EF4692C0083FA08 /* div-and-large-image.html */,
+                               F41AB99B1EF4692C0083FA08 /* file-uploading.html */,
+                               F41AB9991EF4692C0083FA08 /* image-and-contenteditable.html */,
+                               F41AB9931EF4692C0083FA08 /* image-and-textarea.html */,
+                               F41AB9961EF4692C0083FA08 /* link-and-input.html */,
+                               F41AB99D1EF4692C0083FA08 /* link-and-target-div.html */,
+                               F41AB9941EF4692C0083FA08 /* prevent-operation.html */,
+                               F41AB99A1EF4692C0083FA08 /* prevent-start.html */,
+                               F41AB9951EF4692C0083FA08 /* textarea-to-input.html */,
                                F47D30EB1ED28619000482E1 /* apple.gif */,
                                C25CCA0C1E5140E50026CB8A /* AllAhem.svg */,
                                5C9E593E1D3EB1DE00E3C62E /* ApplicationCache.db */,
                                8DD76F9B0486AA7600D96B5E /* Frameworks */,
                                8DD76F9E0486AA7600D96B5E /* CopyFiles */,
                                BCB9F4FB112384C000A137E0 /* Copy Resources */,
-                               F471CB8B1E565C0F0028055C /* Copy additional resources */,
                        );
                        buildRules = (
                        );
                };
 /* End PBXResourcesBuildPhase section */
 
-/* Begin PBXShellScriptBuildPhase section */
-               F471CB8B1E565C0F0028055C /* Copy additional resources */ = {
-                       isa = PBXShellScriptBuildPhase;
-                       buildActionMask = 2147483647;
-                       files = (
-                       );
-                       inputPaths = (
-                       );
-                       name = "Copy additional resources";
-                       outputPaths = (
-                       );
-                       runOnlyForDeploymentPostprocessing = 0;
-                       shellPath = /bin/sh;
-                       shellScript = "ADDITIONAL_RESOURCES_PATH=\"usr/local/include/WebKitAdditions/Resources/TestWebKitAPI\"\nDESTINATION_PATH=\"$TARGET_BUILD_DIR/TestWebKitAPI.resources\"\nif [ -d $TARGET_BUILD_DIR/$ADDITIONAL_RESOURCES_PATH ]; then\n    cp $TARGET_BUILD_DIR/$ADDITIONAL_RESOURCES_PATH/* $DESTINATION_PATH\nelif [ -d $SDKROOT/$ADDITIONAL_RESOURCES_PATH ]; then\n    cp $SDKROOT/$ADDITIONAL_RESOURCES_PATH/* $DESTINATION_PATH\nfi";
-               };
-/* End PBXShellScriptBuildPhase section */
-
 /* Begin PBXSourcesBuildPhase section */
                7C83DE961D0A590C00FEBCF3 /* Sources */ = {
                        isa = PBXSourcesBuildPhase;
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/autofocus-contenteditable.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/autofocus-contenteditable.html
new file mode 100644 (file)
index 0000000..e03635f
--- /dev/null
@@ -0,0 +1,40 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+        <style>
+        body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        #source, #editor {
+            width: 100%;
+            height: 200px;
+            font-size: 200px;
+            white-space: nowrap;
+        }
+
+        #editor {
+            border: black 1px solid;
+        }
+        </style>
+</head>
+
+<body>
+    <div contenteditable id="source">Hello world</div>
+    <div contenteditable id="editor"></div>
+    <script>
+    function postEventType(event) {
+       webkit.messageHandlers.testHandler.postMessage(event.type);
+    }
+
+    editor.addEventListener("drop", postEventType);
+    editor.addEventListener("dragenter", postEventType);
+    editor.addEventListener("dragover", postEventType);
+    editor.addEventListener("dragleave", postEventType);
+    editor.addEventListener("dragstart", postEventType);
+
+    let text = source.childNodes[0];
+    getSelection().setBaseAndExtent(text, 0, text, text.data.length);
+    </script>
+</body>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/background-image-link-and-input.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/background-image-link-and-input.html
new file mode 100644 (file)
index 0000000..9c98984
--- /dev/null
@@ -0,0 +1,41 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+        <style>
+        body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        a, #editor {
+            width: 100%;
+            height: 200px;
+            font-size: 200px;
+            white-space: nowrap;
+        }
+
+        a {
+            background-image: url(icon.png);
+            background-repeat: no-repeat;
+            display: block;
+        }
+
+        #editor {
+            border: black 1px solid;
+        }
+        </style>
+</head>
+
+<body>
+    <div><a href="https://www.apple.com"></a></div>
+    <div><input id="editor"></input></div>
+    <script>
+    function postEventType(event) {
+       webkit.messageHandlers.testHandler.postMessage(event.type);
+    }
+
+    editor.addEventListener("drop", postEventType);
+    editor.addEventListener("dragenter", postEventType);
+    editor.addEventListener("dragover", postEventType);
+    </script>
+</body>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/contenteditable-and-textarea.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/contenteditable-and-textarea.html
new file mode 100644 (file)
index 0000000..41489fc
--- /dev/null
@@ -0,0 +1,40 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+        <style>
+        body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        #source, #editor {
+            width: 100%;
+            height: 200px;
+            font-size: 200px;
+            white-space: nowrap;
+        }
+
+        #editor {
+            border: black 1px solid;
+        }
+        </style>
+</head>
+
+<body>
+    <div contenteditable id="source">Hello world</div>
+    <textarea contenteditable id="editor"></textarea>
+    <script>
+    function postEventType(event) {
+       webkit.messageHandlers.testHandler.postMessage(event.type);
+    }
+
+    editor.addEventListener("drop", postEventType);
+    editor.addEventListener("dragenter", postEventType);
+    editor.addEventListener("dragover", postEventType);
+    editor.addEventListener("dragleave", postEventType);
+    editor.addEventListener("dragstart", postEventType);
+
+    let text = source.childNodes[0];
+    getSelection().setBaseAndExtent(text, 0, text, text.data.length);
+    </script>
+</body>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/div-and-large-image.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/div-and-large-image.html
new file mode 100644 (file)
index 0000000..4ca019e
--- /dev/null
@@ -0,0 +1,31 @@
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<style>
+html, body {
+    margin: 0;
+    font-size: 1.2em;
+    overflow: scroll;
+    -webkit-overflow-scrolling: touch;
+}
+
+#target {
+    width: 2000px;
+    height: 300px;
+    background-color: gray;
+}
+
+code {
+    color: green;
+}
+</style>
+
+<div id="target"></div>
+<img src="large-red-square.png"></img>
+
+<script>
+target.addEventListener("dragenter", event => event.preventDefault());
+target.addEventListener("dragover", event => event.preventDefault());
+target.addEventListener("drop", event => {
+    target.innerHTML = "<code>PASS</code>";
+    event.preventDefault();
+});
+</script>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html
new file mode 100644 (file)
index 0000000..6774958
--- /dev/null
@@ -0,0 +1,46 @@
+<head>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <style>
+    body, html {
+        width: 100%;
+        height: 100%;
+        margin: 0;
+        font-family: -apple-system;
+    }
+
+    #input, #upload {
+        width: 100%;
+        height: 200px;
+        border: 1px blue dashed;
+    }
+
+    #output {
+        width: 100%;
+        height: 100px;
+        font-size: 1em;
+    }
+    </style>
+</head>
+
+<body>
+    <div><input type="file" id="input"></input></div>
+    <div id="upload"></div>
+    <div><h3>Uploaded file types: </h3><textarea disabled id="output"></textarea></div>
+    <script>
+    input.addEventListener("change", () => {
+        sendUploadedFileTypesToApp(input.files);
+    });
+
+    upload.addEventListener("dragenter", event => event.preventDefault());
+    upload.addEventListener("dragover", event => event.preventDefault());
+    upload.addEventListener("drop", event => {
+        sendUploadedFileTypesToApp(event.dataTransfer.files);
+        event.preventDefault();
+    });
+
+    function sendUploadedFileTypesToApp(files)
+    {
+        output.value = Array.from(files).map(file => file.type).sort().join(", ");
+    }
+    </script>
+</body>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/image-and-contenteditable.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/image-and-contenteditable.html
new file mode 100644 (file)
index 0000000..cc7de73
--- /dev/null
@@ -0,0 +1,35 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+        <style>
+        body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        #source, #editor {
+            width: 200px;
+            height: 200px;
+        }
+
+        #editor {
+            border: black 1px solid;
+        }
+        </style>
+</head>
+
+<body>
+    <div><img id="source" src="icon.png"></img></div>
+    <div contenteditable id="editor"></div>
+    <script>
+    function postEventType(event) {
+        webkit.messageHandlers.testHandler.postMessage(event.type);
+    }
+
+    editor.addEventListener("drop", postEventType);
+    editor.addEventListener("dragenter", postEventType);
+    editor.addEventListener("dragover", postEventType);
+    editor.addEventListener("dragleave", postEventType);
+    editor.addEventListener("dragstart", postEventType);
+    </script>
+</body>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/image-and-textarea.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/image-and-textarea.html
new file mode 100644 (file)
index 0000000..77e6faa
--- /dev/null
@@ -0,0 +1,35 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+        <style>
+        body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        #source, #editor {
+            width: 200px;
+            height: 200px;
+        }
+
+        #editor {
+            border: black 1px solid;
+        }
+        </style>
+</head>
+
+<body>
+    <div><img id="source" src="icon.png"></img></div>
+    <textarea contenteditable id="editor"></textarea>
+    <script>
+    function postEventType(event) {
+        webkit.messageHandlers.testHandler.postMessage(event.type);
+    }
+
+    editor.addEventListener("drop", postEventType);
+    editor.addEventListener("dragenter", postEventType);
+    editor.addEventListener("dragover", postEventType);
+    editor.addEventListener("dragleave", postEventType);
+    editor.addEventListener("dragstart", postEventType);
+    </script>
+</body>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/link-and-input.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/link-and-input.html
new file mode 100644 (file)
index 0000000..0cb931d
--- /dev/null
@@ -0,0 +1,37 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+        <style>
+        body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        a, #editor {
+            width: 100%;
+            height: 200px;
+            font-size: 200px;
+            white-space: nowrap;
+        }
+
+        #editor {
+            border: black 1px solid;
+        }
+        </style>
+</head>
+
+<body>
+    <div><a href="https://www.apple.com">Hello world</a></div>
+    <div><input id="editor"></input></div>
+    <script>
+    function postEventType(event) {
+        webkit.messageHandlers.testHandler.postMessage(event.type);
+    }
+
+    editor.addEventListener("drop", postEventType);
+    editor.addEventListener("dragenter", postEventType);
+    editor.addEventListener("dragover", postEventType);
+    editor.addEventListener("dragleave", postEventType);
+    editor.addEventListener("dragstart", postEventType);
+    </script>
+</body>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/link-and-target-div.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/link-and-target-div.html
new file mode 100644 (file)
index 0000000..6fad669
--- /dev/null
@@ -0,0 +1,33 @@
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<style>
+body {
+    width: 100%;
+    height: 100%;
+    margin: 0;
+}
+
+a, #target {
+    width: 100%;
+    height: 200px;
+    font-size: 200px;
+    white-space: nowrap;
+}
+
+#target {
+    border: black 1px solid;
+}
+
+code {
+    color: green;
+}
+</style>
+<div><a href="https://www.apple.com">Hello world</a></div>
+<div id="target"></div>
+<script>
+target.addEventListener("dragenter", event => event.preventDefault());
+target.addEventListener("dragover", event => event.preventDefault());
+target.addEventListener("drop", event => {
+    target.innerHTML = "<code>PASS</code>";
+    event.preventDefault();
+});
+</script>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/prevent-operation.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/prevent-operation.html
new file mode 100644 (file)
index 0000000..f376e67
--- /dev/null
@@ -0,0 +1,37 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+        <style>
+        body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        a, #editor {
+            width: 100%;
+            height: 200px;
+            font-size: 200px;
+            white-space: nowrap;
+        }
+
+        #editor {
+            border: black 1px solid;
+        }
+        </style>
+</head>
+
+<body>
+    <div><a href="https://www.apple.com">Hello world</a></div>
+    <div><textarea ondrop="return false" id="editor"></textarea></div>
+    <script>
+    function postEventType(event) {
+        webkit.messageHandlers.testHandler.postMessage(event.type);
+    }
+
+    editor.addEventListener("drop", postEventType);
+    editor.addEventListener("dragenter", postEventType);
+    editor.addEventListener("dragover", postEventType);
+    editor.addEventListener("dragleave", postEventType);
+    editor.addEventListener("dragstart", postEventType);
+    </script>
+</body>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/prevent-start.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/prevent-start.html
new file mode 100644 (file)
index 0000000..f405201
--- /dev/null
@@ -0,0 +1,37 @@
+<head>
+    <meta name="viewport" content="width=device-width">
+        <style>
+        body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        a, #editor {
+            width: 100%;
+            height: 200px;
+            font-size: 200px;
+            white-space: nowrap;
+        }
+
+        #editor {
+            border: black 1px solid;
+        }
+        </style>
+</head>
+
+<body>
+    <div><a ondragstart="return false" href="https://www.apple.com">Hello world</a></div>
+    <div><textarea id="editor"></textarea></div>
+    <script>
+    function postEventType(event) {
+        webkit.messageHandlers.testHandler.postMessage(event.type);
+    }
+
+    editor.addEventListener("drop", postEventType);
+    editor.addEventListener("dragenter", postEventType);
+    editor.addEventListener("dragover", postEventType);
+    editor.addEventListener("dragleave", postEventType);
+    editor.addEventListener("dragstart", postEventType);
+    </script>
+</body>
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/textarea-to-input.html b/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/textarea-to-input.html
new file mode 100644 (file)
index 0000000..33b8f9c
--- /dev/null
@@ -0,0 +1,39 @@
+<head>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <style>
+        body {
+            width: 100%;
+            height: 100%;
+            margin: 0;
+        }
+
+        #source, #editor {
+            width: 100%;
+            height: 200px;
+            font-size: 200px;
+            white-space: nowrap;
+        }
+
+        #editor {
+            border: black 1px solid;
+        }
+        </style>
+</head>
+
+<body>
+    <textarea id="source">Hello world</textarea>
+    <input id="editor"></input>
+    <script>
+    function postEventType(event) {
+        webkit.messageHandlers.testHandler.postMessage(event.type);
+    }
+
+    editor.addEventListener("drop", postEventType);
+    editor.addEventListener("dragenter", postEventType);
+    editor.addEventListener("dragover", postEventType);
+    editor.addEventListener("dragleave", postEventType);
+    editor.addEventListener("dragstart", postEventType);
+    source.selectionStart = 0;
+    source.selectionEnd = source.value.length;
+    </script>
+</body>
index 7090f7b..9c9be47 100644 (file)
 
 #import "InstanceMethodSwizzler.h"
 #import "PlatformUtilities.h"
+#import <UIKit/UIDragInteraction.h>
+#import <UIKit/UIDragItem.h>
+#import <UIKit/UIDragSession.h>
+#import <UIKit/UIDragging.h>
 #import <UIKit/UIItemProvider_Private.h>
 #import <WebCore/SoftLinking.h>
 #import <WebKit/WKWebViewPrivate.h>
@@ -42,9 +46,191 @@ SOFT_LINK(UIKit, UIApplicationInstantiateSingleton, void, (Class singletonClass)
 
 using namespace TestWebKitAPI;
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/DataInteractionSimulatorAdditions.mm>)
-#include <WebKitAdditions/DataInteractionSimulatorAdditions.mm>
-#endif
+@interface MockDragDropSession : NSObject <UIDragDropSession> {
+@private
+    RetainPtr<NSArray> _mockItems;
+    RetainPtr<UIWindow> _window;
+}
+@property (nonatomic) CGPoint mockLocationInWindow;
+@end
+
+@implementation MockDragDropSession
+
+- (instancetype)initWithItems:(NSArray <UIDragItem *>*)items location:(CGPoint)locationInWindow window:(UIWindow *)window
+{
+    if (self = [super init]) {
+        _mockItems = items;
+        _mockLocationInWindow = locationInWindow;
+        _window = window;
+    }
+    return self;
+}
+
+- (BOOL)allowsMoveOperation
+{
+    return YES;
+}
+
+- (BOOL)isRestrictedToDraggingApplication
+{
+    return NO;
+}
+
+- (BOOL)hasItemsConformingToTypeIdentifiers:(NSArray<NSString *> *)typeIdentifiers
+{
+    for (NSString *typeIdentifier in typeIdentifiers) {
+        BOOL hasItemConformingToType = NO;
+        for (UIDragItem *item in self.items)
+            hasItemConformingToType |= [[item.itemProvider registeredTypeIdentifiers] containsObject:typeIdentifier];
+        if (!hasItemConformingToType)
+            return NO;
+    }
+    return YES;
+}
+
+- (BOOL)canLoadObjectsOfClass:(Class<UIItemProviderReading>)aClass
+{
+    for (UIDragItem *item in self.items) {
+        if ([item.itemProvider canLoadObjectOfClass:aClass])
+            return YES;
+    }
+    return NO;
+}
+
+- (BOOL)canLoadObjectsOfClasses:(NSArray<Class<UIItemProviderReading>> *)classes
+{
+    for (Class<UIItemProviderReading> aClass in classes) {
+        BOOL canLoad = NO;
+        for (UIDragItem *item in self.items)
+            canLoad |= [item.itemProvider canLoadObjectOfClass:aClass];
+        if (!canLoad)
+            return NO;
+    }
+    return YES;
+}
+
+- (NSArray<UIDragItem *> *)items
+{
+    return _mockItems.get();
+}
+
+- (void)setItems:(NSArray<UIDragItem *> *)items
+{
+    _mockItems = items;
+}
+
+- (CGPoint)locationInView:(UIView *)view
+{
+    return [_window convertPoint:_mockLocationInWindow toView:view];
+}
+
+@end
+
+NSString * const DataInteractionEnterEventName = @"dragenter";
+NSString * const DataInteractionOverEventName = @"dragover";
+NSString * const DataInteractionPerformOperationEventName = @"drop";
+NSString * const DataInteractionLeaveEventName = @"dragleave";
+NSString * const DataInteractionStartEventName = @"dragstart";
+
+@interface MockDataOperationSession : MockDragDropSession <UIDropSession>
+@property (nonatomic, strong) id localContext;
+@end
+
+@implementation MockDataOperationSession
+
+- (instancetype)initWithProviders:(NSArray<UIItemProvider *> *)providers location:(CGPoint)locationInWindow window:(UIWindow *)window
+{
+    auto items = adoptNS([[NSMutableArray alloc] init]);
+    for (UIItemProvider *itemProvider in providers)
+        [items addObject:[[[UIDragItem alloc] initWithItemProvider:itemProvider] autorelease]];
+
+    return [super initWithItems:items.get() location:locationInWindow window:window];
+}
+
+- (UIDraggingSession *)session
+{
+    return nil;
+}
+
+- (BOOL)isLocal
+{
+    return YES;
+}
+
+- (NSProgress *)progress
+{
+    return [NSProgress discreteProgressWithTotalUnitCount:100];
+}
+
+- (void)setProgressIndicatorStyle:(UIDropSessionProgressIndicatorStyle)progressIndicatorStyle
+{
+}
+
+- (UIDropSessionProgressIndicatorStyle)progressIndicatorStyle
+{
+    return UIDropSessionProgressIndicatorStyleNone;
+}
+
+- (NSUInteger)operationMask
+{
+    return 0;
+}
+
+- (id <UIDragSession>)localDragSession
+{
+    return nil;
+}
+
+- (BOOL)hasItemsConformingToTypeIdentifier:(NSString *)typeIdentifier
+{
+    ASSERT_NOT_REACHED();
+    return NO;
+}
+
+- (BOOL)canCreateItemsOfClass:(Class<UIItemProviderReading>)aClass
+{
+    ASSERT_NOT_REACHED();
+    return NO;
+}
+
+- (NSProgress *)loadObjectsOfClass:(Class<NSItemProviderReading>)aClass completion:(void(^)(NSArray<__kindof id <NSItemProviderReading>> *objects))completion
+{
+    ASSERT_NOT_REACHED();
+    return nil;
+}
+
+@end
+
+@interface MockDataInteractionSession : MockDragDropSession <UIDragSession>
+@property (nonatomic, strong) id localContext;
+@property (nonatomic, strong) id context;
+@end
+
+@implementation MockDataInteractionSession
+
+- (instancetype)initWithWindow:(UIWindow *)window
+{
+    return [super initWithItems:@[ ] location:CGPointZero window:window];
+}
+
+- (NSUInteger)localOperationMask
+{
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+- (NSUInteger)externalOperationMask
+{
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+- (id)session
+{
+    return nil;
+}
+
+@end
 
 static double progressIncrementStep = 0.033;
 static double progressTimeStep = 0.016;
@@ -212,7 +398,7 @@ static NSArray *dataInteractionEventNames()
             return;
         }
 
-        for (WKDataInteractionItem *item in items)
+        for (UIDragItem *item in items)
             [itemProviders addObject:item.itemProvider];
 
         _dataOperationSession = adoptNS([[MockDataOperationSession alloc] initWithProviders:itemProviders location:self._currentLocation window:[_webView window]]);