Title: [219271] trunk
Revision
219271
Author
[email protected]
Date
2017-07-07 14:59:25 -0700 (Fri, 07 Jul 2017)

Log Message

[iOS DnD] For cross-app drags, 'drop' event handlers are never invoked if dataTransfer.dropEffect is not set while dragging
https://bugs.webkit.org/show_bug.cgi?id=174219
<rdar://problem/32083177>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Currently, in DragController.cpp, defaultOperationForDrag maps a drag source operation mask of
DragOperationGeneric to DragOperationMove across all platforms. However, on iOS, where cross-app drag moves do
not trigger a drop, this means drop handlers won't fire unless the dropEffect is explicitly set to copy.

To fix this, we introduce DragController::platformGenericDragOperation(), which returns DragOperationCopy on iOS
and DragOperationMove (the existing behavior) elsewhere. defaultOperationForDrag then maps a drag source
operation mask of DragOperationGeneric to platformGenericDragOperation().

Tests:  DataInteractionTests.ExternalSourceHTMLToUploadArea
        DataInteractionTests.ExternalSourceImageAndHTMLToUploadArea
        DataInteractionTests.ExternalSourceMoveOperationNotAllowed

* page/DragController.cpp:
(WebCore::DragController::platformGenericDragOperation):
(WebCore::defaultOperationForDrag):
* page/DragController.h:
* page/mac/DragControllerMac.mm:
(WebCore::DragController::platformGenericDragOperation):

Source/WebKit2:

Tweak some testing SPI to return a drop operation flag instead of whether or not the drop operation was not
UIDropOperationCancel.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _simulateDataInteractionUpdated:]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _simulateDataInteractionUpdated:]):

Tools:

Add plumbing and support to mock the value of -allowsMoveOperation on the simulated UIDragDropSession objects.
Setting the DataInteractionSimulator's shouldAllowMoveOperation property to NO simulates a drag operation coming
in from another app out-of-process, for which move operations won't cause a drop to be performed in the first
place.

Also tweaks 2 existing unit tests regarding file uploads via _javascript_ to simulate items coming in from a
different application, and adds a new test to check that if a drop area specifically requests a MOVE operation,
no action is taken when dropping.

* TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html:
* TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
(TestWebKitAPI::TEST):
* TestWebKitAPI/ios/DataInteractionSimulator.h:
* TestWebKitAPI/ios/DataInteractionSimulator.mm:
(-[MockDragDropSession initWithItems:location:window:allowMove:]):
(-[MockDragDropSession allowsMoveOperation]):
(-[MockDataOperationSession initWithProviders:location:window:allowMove:]):
(-[MockDataInteractionSession initWithWindow:allowMove:]):
(-[DataInteractionSimulator initWithWebView:]):
(-[DataInteractionSimulator runFrom:to:]):
(-[DataInteractionSimulator _advanceProgress]):
(-[MockDragDropSession initWithItems:location:window:]): Deleted.
(-[MockDataOperationSession initWithProviders:location:window:]): Deleted.
(-[MockDataInteractionSession initWithWindow:]): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (219270 => 219271)


--- trunk/Source/WebCore/ChangeLog	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Source/WebCore/ChangeLog	2017-07-07 21:59:25 UTC (rev 219271)
@@ -1,3 +1,30 @@
+2017-07-07  Wenson Hsieh  <[email protected]>
+
+        [iOS DnD] For cross-app drags, 'drop' event handlers are never invoked if dataTransfer.dropEffect is not set while dragging
+        https://bugs.webkit.org/show_bug.cgi?id=174219
+        <rdar://problem/32083177>
+
+        Reviewed by Ryosuke Niwa.
+
+        Currently, in DragController.cpp, defaultOperationForDrag maps a drag source operation mask of
+        DragOperationGeneric to DragOperationMove across all platforms. However, on iOS, where cross-app drag moves do
+        not trigger a drop, this means drop handlers won't fire unless the dropEffect is explicitly set to copy.
+
+        To fix this, we introduce DragController::platformGenericDragOperation(), which returns DragOperationCopy on iOS
+        and DragOperationMove (the existing behavior) elsewhere. defaultOperationForDrag then maps a drag source
+        operation mask of DragOperationGeneric to platformGenericDragOperation().
+
+        Tests:  DataInteractionTests.ExternalSourceHTMLToUploadArea
+                DataInteractionTests.ExternalSourceImageAndHTMLToUploadArea
+                DataInteractionTests.ExternalSourceMoveOperationNotAllowed
+
+        * page/DragController.cpp:
+        (WebCore::DragController::platformGenericDragOperation):
+        (WebCore::defaultOperationForDrag):
+        * page/DragController.h:
+        * page/mac/DragControllerMac.mm:
+        (WebCore::DragController::platformGenericDragOperation):
+
 2017-07-07  Devin Rousso  <[email protected]>
 
         Web Inspector: Show all elements currently using a given CSS Canvas

Modified: trunk/Source/WebCore/page/DragController.cpp (219270 => 219271)


--- trunk/Source/WebCore/page/DragController.cpp	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Source/WebCore/page/DragController.cpp	2017-07-07 21:59:25 UTC (rev 219271)
@@ -184,6 +184,15 @@
     return nullptr;
 }
 
+#if !PLATFORM(IOS)
+
+DragOperation DragController::platformGenericDragOperation()
+{
+    return DragOperationMove;
+}
+
+#endif
+
 bool DragController::dragIsMove(FrameSelection& selection, const DragData& dragData)
 {
     const VisibleSelection& visibleSelection = selection.selection();
@@ -666,8 +675,10 @@
         return DragOperationCopy;
     if (srcOpMask == DragOperationNone)
         return DragOperationNone;
-    if (srcOpMask & DragOperationMove || srcOpMask & DragOperationGeneric)
+    if (srcOpMask & DragOperationMove)
         return DragOperationMove;
+    if (srcOpMask & DragOperationGeneric)
+        return DragController::platformGenericDragOperation();
     if (srcOpMask & DragOperationCopy)
         return DragOperationCopy;
     if (srcOpMask & DragOperationLink)

Modified: trunk/Source/WebCore/page/DragController.h (219270 => 219271)


--- trunk/Source/WebCore/page/DragController.h	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Source/WebCore/page/DragController.h	2017-07-07 21:59:25 UTC (rev 219271)
@@ -55,6 +55,7 @@
         ~DragController();
 
         static std::unique_ptr<DragController> create(Page&, DragClient&);
+        static DragOperation platformGenericDragOperation();
 
         DragClient& client() const { return m_client; }
 

Modified: trunk/Source/WebCore/page/mac/DragControllerMac.mm (219270 => 219271)


--- trunk/Source/WebCore/page/mac/DragControllerMac.mm	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Source/WebCore/page/mac/DragControllerMac.mm	2017-07-07 21:59:25 UTC (rev 219271)
@@ -106,6 +106,13 @@
 
 #if ENABLE(DATA_INTERACTION)
 
+DragOperation DragController::platformGenericDragOperation()
+{
+    // On iOS, UIKit skips the -performDrop invocation altogether if MOVE is forbidden.
+    // Thus, if MOVE is not allowed in the drag source operation mask, fall back to only other allowable action, COPY.
+    return DragOperationCopy;
+}
+
 void DragController::updateSupportedTypeIdentifiersForDragHandlingMethod(DragHandlingMethod dragHandlingMethod, const DragData& dragData) const
 {
     Vector<String> supportedTypes;

Modified: trunk/Source/WebKit2/ChangeLog (219270 => 219271)


--- trunk/Source/WebKit2/ChangeLog	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Source/WebKit2/ChangeLog	2017-07-07 21:59:25 UTC (rev 219271)
@@ -1,3 +1,21 @@
+2017-07-07  Wenson Hsieh  <[email protected]>
+
+        [iOS DnD] For cross-app drags, 'drop' event handlers are never invoked if dataTransfer.dropEffect is not set while dragging
+        https://bugs.webkit.org/show_bug.cgi?id=174219
+        <rdar://problem/32083177>
+
+        Reviewed by Ryosuke Niwa.
+
+        Tweak some testing SPI to return a drop operation flag instead of whether or not the drop operation was not
+        UIDropOperationCancel.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _simulateDataInteractionUpdated:]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _simulateDataInteractionUpdated:]):
+
 2017-07-07  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r219238, r219239, and r219241.

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (219270 => 219271)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2017-07-07 21:59:25 UTC (rev 219271)
@@ -5628,12 +5628,12 @@
 #endif
 }
 
-- (BOOL)_simulateDataInteractionUpdated:(id)info
+- (NSUInteger)_simulateDataInteractionUpdated:(id)info
 {
 #if ENABLE(DATA_INTERACTION)
     return [_contentView _simulateDataInteractionUpdated:info];
 #else
-    return NO;
+    return 0;
 #endif
 }
 

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (219270 => 219271)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h	2017-07-07 21:59:25 UTC (rev 219271)
@@ -352,7 +352,7 @@
 - (NSDictionary *)_propertiesOfLayerWithID:(unsigned long long)layerID WK_API_AVAILABLE(ios(WK_IOS_TBA));
 
 - (void)_simulateDataInteractionEntered:(id)info WK_API_AVAILABLE(ios(WK_IOS_TBA));
-- (BOOL)_simulateDataInteractionUpdated:(id)info WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (NSUInteger)_simulateDataInteractionUpdated:(id)info WK_API_AVAILABLE(ios(WK_IOS_TBA));
 - (void)_simulateDataInteractionPerformOperation:(id)info WK_API_AVAILABLE(ios(WK_IOS_TBA));
 - (void)_simulateDataInteractionEnded:(id)info WK_API_AVAILABLE(ios(WK_IOS_TBA));
 - (void)_simulateDataInteractionSessionDidEnd:(id)session WK_API_AVAILABLE(ios(WK_IOS_TBA));

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h (219270 => 219271)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h	2017-07-07 21:59:25 UTC (rev 219271)
@@ -342,7 +342,7 @@
 - (void)_didChangeDataInteractionCaretRect:(CGRect)previousRect currentRect:(CGRect)rect;
 
 - (void)_simulateDataInteractionEntered:(id)info;
-- (BOOL)_simulateDataInteractionUpdated:(id)info;
+- (NSUInteger)_simulateDataInteractionUpdated:(id)info;
 - (void)_simulateDataInteractionPerformOperation:(id)info;
 - (void)_simulateDataInteractionEnded:(id)info;
 - (void)_simulateDataInteractionSessionDidEnd:(id)session;

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (219270 => 219271)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2017-07-07 21:59:25 UTC (rev 219271)
@@ -4858,9 +4858,9 @@
     [self dropInteraction:_dataOperation.get() sessionDidEnter:session];
 }
 
-- (BOOL)_simulateDataInteractionUpdated:(id)session
+- (NSUInteger)_simulateDataInteractionUpdated:(id)session
 {
-    return [self dropInteraction:_dataOperation.get() sessionDidUpdate:session].operation != UIDropOperationCancel;
+    return [self dropInteraction:_dataOperation.get() sessionDidUpdate:session].operation;
 }
 
 - (void)_simulateDataInteractionEnded:(id)session

Modified: trunk/Tools/ChangeLog (219270 => 219271)


--- trunk/Tools/ChangeLog	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Tools/ChangeLog	2017-07-07 21:59:25 UTC (rev 219271)
@@ -1,3 +1,36 @@
+2017-07-07  Wenson Hsieh  <[email protected]>
+
+        [iOS DnD] For cross-app drags, 'drop' event handlers are never invoked if dataTransfer.dropEffect is not set while dragging
+        https://bugs.webkit.org/show_bug.cgi?id=174219
+        <rdar://problem/32083177>
+
+        Reviewed by Ryosuke Niwa.
+
+        Add plumbing and support to mock the value of -allowsMoveOperation on the simulated UIDragDropSession objects.
+        Setting the DataInteractionSimulator's shouldAllowMoveOperation property to NO simulates a drag operation coming
+        in from another app out-of-process, for which move operations won't cause a drop to be performed in the first
+        place.
+
+        Also tweaks 2 existing unit tests regarding file uploads via _javascript_ to simulate items coming in from a
+        different application, and adds a new test to check that if a drop area specifically requests a MOVE operation,
+        no action is taken when dropping.
+
+        * TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html:
+        * TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/ios/DataInteractionSimulator.h:
+        * TestWebKitAPI/ios/DataInteractionSimulator.mm:
+        (-[MockDragDropSession initWithItems:location:window:allowMove:]):
+        (-[MockDragDropSession allowsMoveOperation]):
+        (-[MockDataOperationSession initWithProviders:location:window:allowMove:]):
+        (-[MockDataInteractionSession initWithWindow:allowMove:]):
+        (-[DataInteractionSimulator initWithWebView:]):
+        (-[DataInteractionSimulator runFrom:to:]):
+        (-[DataInteractionSimulator _advanceProgress]):
+        (-[MockDragDropSession initWithItems:location:window:]): Deleted.
+        (-[MockDataOperationSession initWithProviders:location:window:]): Deleted.
+        (-[MockDataInteractionSession initWithWindow:]): Deleted.
+
 2017-07-07  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r219238, r219239, and r219241.

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html (219270 => 219271)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/file-uploading.html	2017-07-07 21:59:25 UTC (rev 219271)
@@ -31,8 +31,18 @@
         sendUploadedFileTypesToApp(input.files);
     });
 
-    upload.addEventListener("dragenter", event => event.preventDefault());
-    upload.addEventListener("dragover", event => event.preventDefault());
+    upload.addEventListener("dragenter", event => {
+        event.preventDefault();
+        if (upload.dropEffect)
+            event.dataTransfer.dropEffect = upload.dropEffect;
+    });
+
+    upload.addEventListener("dragover", event => {
+        event.preventDefault();
+        if (upload.dropEffect)
+            event.dataTransfer.dropEffect = upload.dropEffect;
+    });
+
     upload.addEventListener("drop", event => {
         sendUploadedFileTypesToApp(event.dataTransfer.files);
         event.preventDefault();

Modified: trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm (219270 => 219271)


--- trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm	2017-07-07 21:59:25 UTC (rev 219271)
@@ -496,14 +496,15 @@
 
 TEST(DataInteractionTests, ExternalSourceHTMLToUploadArea)
 {
-    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
 
-    RetainPtr<UIItemProvider> simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
+    auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
     NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
     [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
 
-    RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+    auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+    [dataInteractionSimulator setShouldAllowMoveOperation:NO];
     [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get() ]];
     [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
 
@@ -511,6 +512,24 @@
     EXPECT_WK_STREQ("text/html", outputValue.UTF8String);
 }
 
+TEST(DataInteractionTests, ExternalSourceMoveOperationNotAllowed)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
+    [webView stringByEvaluatingJavaScript:@"upload.dropEffect = 'move'"];
+
+    auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
+    NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
+    [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
+
+    auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+    [dataInteractionSimulator setShouldAllowMoveOperation:NO];
+    [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get() ]];
+    [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
+
+    EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"output.value"]);
+}
+
 TEST(DataInteractionTests, ExternalSourceZIPArchiveAndURLToSingleFileInput)
 {
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
@@ -591,22 +610,23 @@
 
 TEST(DataInteractionTests, ExternalSourceImageAndHTMLToUploadArea)
 {
-    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
     [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
 
-    RetainPtr<UIItemProvider> simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
+    auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
     NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
     [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
 
-    RetainPtr<UIItemProvider> firstSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
+    auto firstSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
     NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
     [firstSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData];
 
-    RetainPtr<UIItemProvider> secondSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
+    auto secondSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
     NSData *secondHTMLData = [@"<html><body>hello world</body></html>" dataUsingEncoding:NSUTF8StringEncoding];
     [secondSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:secondHTMLData];
 
-    RetainPtr<DataInteractionSimulator> dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+    auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+    [dataInteractionSimulator setShouldAllowMoveOperation:NO];
     [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), firstSimulatedHTMLItemProvider.get(), secondSimulatedHTMLItemProvider.get() ]];
     [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
 

Modified: trunk/Tools/TestWebKitAPI/ios/DataInteractionSimulator.h (219270 => 219271)


--- trunk/Tools/TestWebKitAPI/ios/DataInteractionSimulator.h	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Tools/TestWebKitAPI/ios/DataInteractionSimulator.h	2017-07-07 21:59:25 UTC (rev 219271)
@@ -75,6 +75,7 @@
 
 @property (nonatomic) BOOL allowsFocusToStartInputSession;
 @property (nonatomic) BOOL shouldEnsureUIApplication;
+@property (nonatomic) BOOL shouldAllowMoveOperation;
 @property (nonatomic) BlockPtr<BOOL(_WKActivatedElementInfo *)> showCustomActionSheetBlock;
 @property (nonatomic) BlockPtr<NSArray *(UIItemProvider *, NSArray *, NSDictionary *)> convertItemProvidersBlock;
 @property (nonatomic) BlockPtr<NSArray *(id <UIDropSession>)> overridePerformDropBlock;

Modified: trunk/Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm (219270 => 219271)


--- trunk/Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm	2017-07-07 21:44:18 UTC (rev 219270)
+++ trunk/Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm	2017-07-07 21:59:25 UTC (rev 219271)
@@ -52,16 +52,18 @@
     RetainPtr<UIWindow> _window;
 }
 @property (nonatomic) CGPoint mockLocationInWindow;
+@property (nonatomic) BOOL allowMove;
 @end
 
 @implementation MockDragDropSession
 
-- (instancetype)initWithItems:(NSArray <UIDragItem *>*)items location:(CGPoint)locationInWindow window:(UIWindow *)window
+- (instancetype)initWithItems:(NSArray <UIDragItem *>*)items location:(CGPoint)locationInWindow window:(UIWindow *)window allowMove:(BOOL)allowMove
 {
     if (self = [super init]) {
         _mockItems = items;
         _mockLocationInWindow = locationInWindow;
         _window = window;
+        _allowMove = allowMove;
     }
     return self;
 }
@@ -68,7 +70,7 @@
 
 - (BOOL)allowsMoveOperation
 {
-    return YES;
+    return _allowMove;
 }
 
 - (BOOL)isRestrictedToDraggingApplication
@@ -138,13 +140,13 @@
 
 @implementation MockDataOperationSession
 
-- (instancetype)initWithProviders:(NSArray<UIItemProvider *> *)providers location:(CGPoint)locationInWindow window:(UIWindow *)window
+- (instancetype)initWithProviders:(NSArray<UIItemProvider *> *)providers location:(CGPoint)locationInWindow window:(UIWindow *)window allowMove:(BOOL)allowMove
 {
     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];
+    return [super initWithItems:items.get() location:locationInWindow window:window allowMove:allowMove];
 }
 
 - (UIDraggingSession *)session
@@ -208,9 +210,9 @@
 
 @implementation MockDataInteractionSession
 
-- (instancetype)initWithWindow:(UIWindow *)window
+- (instancetype)initWithWindow:(UIWindow *)window allowMove:(BOOL)allowMove
 {
-    return [super initWithItems:@[ ] location:CGPointZero window:window];
+    return [super initWithItems:@[ ] location:CGPointZero window:window allowMove:allowMove];
 }
 
 - (NSUInteger)localOperationMask
@@ -263,6 +265,7 @@
     if (self = [super init]) {
         _webView = webView;
         _shouldEnsureUIApplication = NO;
+        _shouldAllowMoveOperation = YES;
         _isDoneWaitingForInputSession = true;
         [_webView setUIDelegate:self];
         [_webView _setInputDelegate:self];
@@ -331,11 +334,11 @@
     _endLocation = endLocation;
 
     if (self.externalItemProviders.count) {
-        _dataOperationSession = adoptNS([[MockDataOperationSession alloc] initWithProviders:self.externalItemProviders location:_startLocation window:[_webView window]]);
+        _dataOperationSession = adoptNS([[MockDataOperationSession alloc] initWithProviders:self.externalItemProviders location:_startLocation window:[_webView window] allowMove:self.shouldAllowMoveOperation]);
         _phase = DataInteractionBegan;
         [self _advanceProgress];
     } else {
-        _dataInteractionSession = adoptNS([[MockDataInteractionSession alloc] initWithWindow:[_webView window]]);
+        _dataInteractionSession = adoptNS([[MockDataInteractionSession alloc] initWithWindow:[_webView window] allowMove:self.shouldAllowMoveOperation]);
         [_dataInteractionSession setMockLocationInWindow:_startLocation];
         [_webView _simulatePrepareForDataInteractionSession:_dataInteractionSession.get() completion:^() {
             DataInteractionSimulator *weakSelf = strongSelf.get();
@@ -404,7 +407,7 @@
         for (UIDragItem *item in items)
             [itemProviders addObject:item.itemProvider];
 
-        _dataOperationSession = adoptNS([[MockDataOperationSession alloc] initWithProviders:itemProviders location:self._currentLocation window:[_webView window]]);
+        _dataOperationSession = adoptNS([[MockDataOperationSession alloc] initWithProviders:itemProviders location:self._currentLocation window:[_webView window] allowMove:self.shouldAllowMoveOperation]);
         [_dataInteractionSession setItems:items];
         _sourceItemProviders = itemProviders;
         if (self.showCustomActionSheetBlock) {
@@ -428,9 +431,11 @@
         [_webView _simulateDataInteractionEntered:_dataOperationSession.get()];
         _phase = DataInteractionEntered;
         break;
-    case DataInteractionEntered:
-        _shouldPerformOperation = [_webView _simulateDataInteractionUpdated:_dataOperationSession.get()];
+    case DataInteractionEntered: {
+        auto operation = static_cast<UIDropOperation>([_webView _simulateDataInteractionUpdated:_dataOperationSession.get()]);
+        _shouldPerformOperation = operation == UIDropOperationCopy || ([_dataOperationSession allowsMoveOperation] && operation != UIDropOperationCancel);
         break;
+    }
     default:
         break;
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to