[iOS] A few drag and drop tests are crashing after r238146
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2018 19:27:29 +0000 (19:27 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2018 19:27:29 +0000 (19:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191617

Reviewed by Dean Jackson.

Source/WebKit:

The notion of temporarily suppressing the selection assistant was introduced during iOS drag and drop
development as a way of allowing both the selection view and dropped content snapshot to fade in simultaneously
during a drop in an editable element. r238146 piggy-backs on this mechanism by changing selection suppression
state when an element is focused, when the selection changes, and when an element is blurred, depending on
whether the currently focused element is transparent.

However, in the case where the selection assistant is suppressed due to a running drop animation, if focus moves
to an element that is not fully transparent, we end up prematurely unsuppressing the text selection assistant.
This subsequently causes selection UI to immediately show up after a drop instead of animating in alongside a
snapshot of the inserted document fragment, if the drop moved focus to an editable element.

A number of drag and drop tests on iOS exercised this codepath by dragging content into editable fields and/or
moving content between editable elements in a web view. These tests began to crash due to selection views and
the accompanying callout bar appearing earlier than usual, which triggers an unrelated UIKit assertion in
<https://webkit.org/b/190401>.

This patch fixes the failing tests by refactoring our selection assistant suppression code. Instead of
maintaining a single `BOOL` flag indicating whether the selection is suppressed, we use an `OptionSet` of
`SuppressSelectionAssistantReason`s, which (at the moment) only include (1) a running drop animation, and (2)
focusing a transparent element. The text selection assistant is considered suppressed when either of the reasons
apply. This allows us to correctly handle a drop animation that occurs simultaneously as an element is focused
without unsuppressing the selection assistant early, and also allows us to handle selection assistant
suppression in more nuanced ways, depending on the suppression reason.

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView cleanupInteraction]):
(-[WKContentView _displayFormNodeInputView]):

Only prevent zooming to the focused element during drop if we're suppressing the selection assistant due to
focusing a transparent element. In the case of a drop, we still want to allow scrolling and zooming.

(-[WKContentView canShowNonEmptySelectionView]):
(-[WKContentView hasSelectablePositionAtPoint:]):
(-[WKContentView pointIsNearMarkedText:]):
(-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):
(-[WKContentView _startAssistingKeyboard]):
(-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
(-[WKContentView _stopAssistingNode]):
(-[WKContentView _updateChangedSelection:]):
(-[WKContentView _shouldSuppressSelectionCommands]):
(-[WKContentView _beginSuppressingSelectionAssistantForReason:]):
(-[WKContentView _stopSuppressingSelectionAssistantForReason:]):

Add helper methods for adding or removing selection assistant suppression reasons. When the last selection
assistant suppression reason is removed, we activate the selection assistant, and conversely, when the first
suppression reason is added, we deactivate the selection assistant.

(-[WKContentView _didConcludeEditDataInteraction:]):
(-[WKContentView _didPerformDragOperation:]):
(-[WKContentView dropInteraction:performDrop:]):
(-[WKContentView suppressAssistantSelectionView]): Deleted.
(-[WKContentView setSuppressAssistantSelectionView:]): Deleted.

Tools:

Augment these crashing tests to verify that selection commands are suppressed during drop over editable elements
via more robust means. These tests currently hit an assertion when revealing the callout bar too early, because
TestWebKitAPI is not a UI application (see <https://webkit.org/b/190401>).

Instead of relying on this other bug, directly ask the text input whether it is suppressing selection commands
during a drop, and remember the answer via DragAndDropSimulator.

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

Add to the existing tests that started failing after r238146.

* TestWebKitAPI/cocoa/DragAndDropSimulator.h:
* TestWebKitAPI/cocoa/TestWKWebView.h:
* TestWebKitAPI/cocoa/TestWKWebView.mm:
(-[TestWKWebView textInputContentView]):
* TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
(-[DragAndDropSimulator _resetSimulatedState]):
(-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]):
* TestWebKitAPI/ios/UIKitSPI.h:

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm
Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h
Tools/TestWebKitAPI/cocoa/TestWKWebView.h
Tools/TestWebKitAPI/cocoa/TestWKWebView.mm
Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm
Tools/TestWebKitAPI/ios/UIKitSPI.h

index 19aa1bc..f0c1ec5 100644 (file)
@@ -1,5 +1,66 @@
 2018-11-14  Wenson Hsieh  <wenson_hsieh@apple.com>
 
+        [iOS] A few drag and drop tests are crashing after r238146
+        https://bugs.webkit.org/show_bug.cgi?id=191617
+
+        Reviewed by Dean Jackson.
+
+        The notion of temporarily suppressing the selection assistant was introduced during iOS drag and drop
+        development as a way of allowing both the selection view and dropped content snapshot to fade in simultaneously
+        during a drop in an editable element. r238146 piggy-backs on this mechanism by changing selection suppression
+        state when an element is focused, when the selection changes, and when an element is blurred, depending on
+        whether the currently focused element is transparent.
+
+        However, in the case where the selection assistant is suppressed due to a running drop animation, if focus moves
+        to an element that is not fully transparent, we end up prematurely unsuppressing the text selection assistant.
+        This subsequently causes selection UI to immediately show up after a drop instead of animating in alongside a
+        snapshot of the inserted document fragment, if the drop moved focus to an editable element.
+
+        A number of drag and drop tests on iOS exercised this codepath by dragging content into editable fields and/or
+        moving content between editable elements in a web view. These tests began to crash due to selection views and
+        the accompanying callout bar appearing earlier than usual, which triggers an unrelated UIKit assertion in
+        <https://webkit.org/b/190401>.
+
+        This patch fixes the failing tests by refactoring our selection assistant suppression code. Instead of
+        maintaining a single `BOOL` flag indicating whether the selection is suppressed, we use an `OptionSet` of
+        `SuppressSelectionAssistantReason`s, which (at the moment) only include (1) a running drop animation, and (2)
+        focusing a transparent element. The text selection assistant is considered suppressed when either of the reasons
+        apply. This allows us to correctly handle a drop animation that occurs simultaneously as an element is focused
+        without unsuppressing the selection assistant early, and also allows us to handle selection assistant
+        suppression in more nuanced ways, depending on the suppression reason.
+
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView cleanupInteraction]):
+        (-[WKContentView _displayFormNodeInputView]):
+
+        Only prevent zooming to the focused element during drop if we're suppressing the selection assistant due to
+        focusing a transparent element. In the case of a drop, we still want to allow scrolling and zooming.
+
+        (-[WKContentView canShowNonEmptySelectionView]):
+        (-[WKContentView hasSelectablePositionAtPoint:]):
+        (-[WKContentView pointIsNearMarkedText:]):
+        (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):
+        (-[WKContentView _startAssistingKeyboard]):
+        (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
+        (-[WKContentView _stopAssistingNode]):
+        (-[WKContentView _updateChangedSelection:]):
+        (-[WKContentView _shouldSuppressSelectionCommands]):
+        (-[WKContentView _beginSuppressingSelectionAssistantForReason:]):
+        (-[WKContentView _stopSuppressingSelectionAssistantForReason:]):
+
+        Add helper methods for adding or removing selection assistant suppression reasons. When the last selection
+        assistant suppression reason is removed, we activate the selection assistant, and conversely, when the first
+        suppression reason is added, we deactivate the selection assistant.
+
+        (-[WKContentView _didConcludeEditDataInteraction:]):
+        (-[WKContentView _didPerformDragOperation:]):
+        (-[WKContentView dropInteraction:performDrop:]):
+        (-[WKContentView suppressAssistantSelectionView]): Deleted.
+        (-[WKContentView setSuppressAssistantSelectionView:]): Deleted.
+
+2018-11-14  Wenson Hsieh  <wenson_hsieh@apple.com>
+
         [Cocoa] [WebKit2] Hook up some more editing actions (-_pasteAndMatchStyle:, -makeTextWritingDirectionNatural:)
         https://bugs.webkit.org/show_bug.cgi?id=191605
         <rdar://problem/45813991>
index de058f2..3bd1e25 100644 (file)
@@ -50,6 +50,7 @@
 #import <WebCore/FloatQuad.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/Forward.h>
+#import <wtf/OptionSet.h>
 #import <wtf/Vector.h>
 #import <wtf/WeakObjCPtr.h>
 #import <wtf/text/WTFString.h>
@@ -156,6 +157,11 @@ typedef std::pair<WebKit::InteractionInformationRequest, InteractionInformationC
 
 namespace WebKit {
 
+enum SuppressSelectionAssistantReason : uint8_t {
+    FocusedElementIsTransparent = 1 << 0,
+    DropAnimationIsRunning = 1 << 1
+};
+
 struct WKSelectionDrawingInfo {
     enum class SelectionType { None, Plugin, Range };
     WKSelectionDrawingInfo();
@@ -209,7 +215,7 @@ struct WKAutoCorrectionData {
 #endif
 
     RetainPtr<UIWKTextInteractionAssistant> _textSelectionAssistant;
-    BOOL _suppressAssistantSelectionView;
+    OptionSet<WebKit::SuppressSelectionAssistantReason> _suppressSelectionAssistantReasons;
 
     RetainPtr<UITextInputTraits> _traits;
     RetainPtr<UIWebFormAccessory> _formAccessoryView;
@@ -337,7 +343,6 @@ struct WKAutoCorrectionData {
 @property (nonatomic, readonly) const WebKit::WKAutoCorrectionData& autocorrectionData;
 @property (nonatomic, readonly) const WebKit::AssistedNodeInformation& assistedNodeInformation;
 @property (nonatomic, readonly) UIWebFormAccessory *formAccessoryView;
-@property (nonatomic) BOOL suppressAssistantSelectionView;
 @property (nonatomic, readonly) UITextInputAssistantItem *inputAssistantItemForWebView;
 
 #if ENABLE(DATALIST_ELEMENT)
index 508e1ea..52cba4f 100644 (file)
@@ -822,6 +822,7 @@ static inline bool hasAssistedNode(WebKit::AssistedNodeInformation assistedNodeI
 #endif
 
     _hasSetUpInteractions = NO;
+    _suppressSelectionAssistantReasons = { };
 }
 
 - (void)_removeDefaultGestureRecognizers
@@ -1342,7 +1343,7 @@ static NSValue *nsSizeForTapHighlightBorderRadius(WebCore::IntSize borderRadius,
 
 - (void)_displayFormNodeInputView
 {
-    if (!self.suppressAssistantSelectionView) {
+    if (!_suppressSelectionAssistantReasons.contains(FocusedElementIsTransparent)) {
         // In case user scaling is force enabled, do not use that scaling when zooming in with an input field.
         // Zooming above the page's default scale factor should only happen when the user performs it.
         [self _zoomToFocusRect:_assistedNodeInformation.elementRect
@@ -1736,7 +1737,7 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
 
 - (BOOL)canShowNonEmptySelectionView
 {
-    if (self.suppressAssistantSelectionView)
+    if (_suppressSelectionAssistantReasons)
         return NO;
 
     auto& state = _page->editorState();
@@ -1748,7 +1749,7 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
     if (!_webView.configuration._textInteractionGesturesEnabled)
         return NO;
 
-    if (self.suppressAssistantSelectionView)
+    if (_suppressSelectionAssistantReasons)
         return NO;
 
     if (_inspectorNodeSearchEnabled)
@@ -1774,7 +1775,7 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
     if (!_webView.configuration._textInteractionGesturesEnabled)
         return NO;
 
-    if (self.suppressAssistantSelectionView)
+    if (_suppressSelectionAssistantReasons)
         return NO;
 
     InteractionInformationRequest request(roundedIntPoint(point));
@@ -1788,7 +1789,7 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
     if (!_webView.configuration._textInteractionGesturesEnabled)
         return NO;
 
-    if (self.suppressAssistantSelectionView)
+    if (_suppressSelectionAssistantReasons)
         return NO;
 
     InteractionInformationRequest request(roundedIntPoint(point));
@@ -4199,7 +4200,7 @@ static NSString *contentTypeFromFieldName(WebCore::AutofillFieldName fieldName)
 {
     [self setUpTextSelectionAssistant];
     
-    if (self.isFirstResponder && !self.suppressAssistantSelectionView)
+    if (self.isFirstResponder && !_suppressSelectionAssistantReasons)
         [_textSelectionAssistant activateSelection];
 
 #if !PLATFORM(WATCHOS)
@@ -4285,7 +4286,10 @@ static bool isAssistableInputType(InputType type)
     if ([inputDelegate respondsToSelector:@selector(_webView:decidePolicyForFocusedElement:)])
         startInputSessionPolicy = [inputDelegate _webView:_webView decidePolicyForFocusedElement:focusedElementInfo.get()];
 
-    self.suppressAssistantSelectionView = information.elementIsTransparent;
+    if (information.elementIsTransparent)
+        [self _beginSuppressingSelectionAssistantForReason:FocusedElementIsTransparent];
+    else
+        [self _stopSuppressingSelectionAssistantForReason:FocusedElementIsTransparent];
 
     switch (startInputSessionPolicy) {
     case _WKFocusStartsInputSessionPolicyAuto:
@@ -4430,7 +4434,7 @@ static bool isAssistableInputType(InputType type)
 
     [_webView didEndFormControlInteraction];
 
-    self.suppressAssistantSelectionView = NO;
+    [self _stopSuppressingSelectionAssistantForReason:FocusedElementIsTransparent];
 }
 
 - (void)updateCurrentAssistedNodeInformation:(Function<void(bool didUpdate)>&&)callback
@@ -4768,8 +4772,12 @@ static bool isAssistableInputType(InputType type)
         return;
 
     auto& postLayoutData = state.postLayoutData();
-    if (hasAssistedNode(_assistedNodeInformation))
-        self.suppressAssistantSelectionView = postLayoutData.elementIsTransparent;
+    if (hasAssistedNode(_assistedNodeInformation)) {
+        if (postLayoutData.elementIsTransparent)
+            [self _beginSuppressingSelectionAssistantForReason:FocusedElementIsTransparent];
+        else
+            [self _stopSuppressingSelectionAssistantForReason:FocusedElementIsTransparent];
+    }
 
     WKSelectionDrawingInfo selectionDrawingInfo(_page->editorState());
     if (force || selectionDrawingInfo != _lastSelectionDrawingInfo) {
@@ -4794,7 +4802,7 @@ static bool isAssistableInputType(InputType type)
     if (postLayoutData.isStableStateUpdate && _needsDeferredEndScrollingSelectionUpdate && _page->inStableState()) {
         [[self selectionInteractionAssistant] showSelectionCommands];
 
-        if (!self.suppressAssistantSelectionView)
+        if (!_suppressSelectionAssistantReasons)
             [_textSelectionAssistant activateSelection];
 
         [_textSelectionAssistant didEndScrollingOverflow];
@@ -4805,26 +4813,24 @@ static bool isAssistableInputType(InputType type)
 
 - (BOOL)_shouldSuppressSelectionCommands
 {
-    return _suppressAssistantSelectionView;
+    return !!_suppressSelectionAssistantReasons;
 }
 
-- (BOOL)suppressAssistantSelectionView
+- (void)_beginSuppressingSelectionAssistantForReason:(SuppressSelectionAssistantReason)reason
 {
-    return _suppressAssistantSelectionView;
+    bool wasSuppressingSelectionAssistant = !!_suppressSelectionAssistantReasons;
+    _suppressSelectionAssistantReasons.add(reason);
+
+    if (!wasSuppressingSelectionAssistant)
+        [_textSelectionAssistant deactivateSelection];
 }
 
-- (void)setSuppressAssistantSelectionView:(BOOL)suppressAssistantSelectionView
+- (void)_stopSuppressingSelectionAssistantForReason:(SuppressSelectionAssistantReason)reason
 {
-    if (_suppressAssistantSelectionView == suppressAssistantSelectionView)
-        return;
+    bool wasSuppressingSelectionAssistant = !!_suppressSelectionAssistantReasons;
+    _suppressSelectionAssistantReasons.remove(reason);
 
-    _suppressAssistantSelectionView = suppressAssistantSelectionView;
-    if (!_textSelectionAssistant)
-        return;
-
-    if (suppressAssistantSelectionView)
-        [_textSelectionAssistant deactivateSelection];
-    else
+    if (wasSuppressingSelectionAssistant && !_suppressSelectionAssistantReasons)
         [_textSelectionAssistant activateSelection];
 }
 
@@ -5336,7 +5342,7 @@ static NSArray<UIItemProvider *> *extractItemProvidersFromDropSession(id <UIDrop
     } completion:^(BOOL completed) {
         [visibleContentViewSnapshot removeFromSuperview];
         [UIView animateWithDuration:0.25 animations:^() {
-            [protectedSelf setSuppressAssistantSelectionView:NO];
+            [protectedSelf _stopSuppressingSelectionAssistantForReason:DropAnimationIsRunning];
             [unselectedContentSnapshot setAlpha:0];
         } completion:^(BOOL completed) {
             [unselectedContentSnapshot removeFromSuperview];
@@ -5353,7 +5359,7 @@ static NSArray<UIItemProvider *> *extractItemProvidersFromDropSession(id <UIDrop
         [self.webViewUIDelegate _webView:_webView dataInteractionOperationWasHandled:handled forSession:dropSession itemProviders:[WebItemProviderPasteboard sharedInstance].itemProviders];
 
     if (!_isAnimatingConcludeEditDrag)
-        self.suppressAssistantSelectionView = NO;
+        [self _stopSuppressingSelectionAssistantForReason:DropAnimationIsRunning];
 
     CGPoint global;
     CGPoint client;
@@ -5802,7 +5808,7 @@ static NSArray<UIItemProvider *> *extractItemProvidersFromDropSession(id <UIDrop
         retainedSelf->_page->performDragOperation(capturedDragData, "data interaction pasteboard", WTFMove(sandboxExtensionHandle), WTFMove(sandboxExtensionForUpload));
 
         retainedSelf->_visibleContentViewSnapshot = [retainedSelf snapshotViewAfterScreenUpdates:NO];
-        [retainedSelf setSuppressAssistantSelectionView:YES];
+        [retainedSelf _beginSuppressingSelectionAssistantForReason:DropAnimationIsRunning];
         [UIView performWithoutAnimation:[retainedSelf] {
             [retainedSelf->_visibleContentViewSnapshot setFrame:[retainedSelf bounds]];
             [retainedSelf addSubview:retainedSelf->_visibleContentViewSnapshot.get()];
index cc2651f..6b1295d 100644 (file)
@@ -1,5 +1,33 @@
 2018-11-14  Wenson Hsieh  <wenson_hsieh@apple.com>
 
+        [iOS] A few drag and drop tests are crashing after r238146
+        https://bugs.webkit.org/show_bug.cgi?id=191617
+
+        Reviewed by Dean Jackson.
+
+        Augment these crashing tests to verify that selection commands are suppressed during drop over editable elements
+        via more robust means. These tests currently hit an assertion when revealing the callout bar too early, because
+        TestWebKitAPI is not a UI application (see <https://webkit.org/b/190401>).
+
+        Instead of relying on this other bug, directly ask the text input whether it is suppressing selection commands
+        during a drop, and remember the answer via DragAndDropSimulator.
+
+        * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
+        (TestWebKitAPI::TEST):
+
+        Add to the existing tests that started failing after r238146.
+
+        * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+        * TestWebKitAPI/cocoa/TestWKWebView.h:
+        * TestWebKitAPI/cocoa/TestWKWebView.mm:
+        (-[TestWKWebView textInputContentView]):
+        * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+        (-[DragAndDropSimulator _resetSimulatedState]):
+        (-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]):
+        * TestWebKitAPI/ios/UIKitSPI.h:
+
+2018-11-14  Wenson Hsieh  <wenson_hsieh@apple.com>
+
         [Cocoa] [WebKit2] Hook up some more editing actions (-pasteAndMatchStyle:, -makeTextWritingDirectionNatural:)
         https://bugs.webkit.org/show_bug.cgi?id=191605
         <rdar://problem/45813991>
index 1d86b06..b903edc 100644 (file)
@@ -346,6 +346,7 @@ TEST(DragAndDropTests, ContentEditableToContentEditable)
     [simulator waitForInputSession];
     [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
 
+    EXPECT_TRUE([simulator suppressedSelectionCommandsDuringDrop]);
     EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL);
     EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String);
 
@@ -366,6 +367,7 @@ TEST(DragAndDropTests, ContentEditableToTextarea)
     [simulator waitForInputSession];
     [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
 
+    EXPECT_TRUE([simulator suppressedSelectionCommandsDuringDrop]);
     EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL);
     EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String);
 
@@ -401,6 +403,7 @@ TEST(DragAndDropTests, ContentEditableMoveParagraphs)
     NSUInteger firstParagraphOffset = [finalTextContent rangeOfString:@"This is the first paragraph"].location;
     NSUInteger secondParagraphOffset = [finalTextContent rangeOfString:@"This is the second paragraph"].location;
 
+    EXPECT_TRUE([simulator suppressedSelectionCommandsDuringDrop]);
     EXPECT_FALSE(firstParagraphOffset == NSNotFound);
     EXPECT_FALSE(secondParagraphOffset == NSNotFound);
     EXPECT_GT(firstParagraphOffset, secondParagraphOffset);
@@ -427,6 +430,7 @@ TEST(DragAndDropTests, TextAreaToInput)
     [simulator waitForInputSession];
     [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
 
+    EXPECT_TRUE([simulator suppressedSelectionCommandsDuringDrop]);
     EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL);
     EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String);
     checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 990, 232) ], [simulator finalSelectionRects]);
@@ -444,6 +448,8 @@ TEST(DragAndDropTests, SinglePlainTextWordTypeIdentifiers)
     [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"];
     [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
 
+    EXPECT_TRUE([simulator suppressedSelectionCommandsDuringDrop]);
+
     NSItemProvider *itemProvider = [simulator sourceItemProviders].firstObject;
     NSArray *registeredTypes = [itemProvider registeredTypeIdentifiers];
     EXPECT_EQ(1UL, registeredTypes.count);
@@ -465,6 +471,8 @@ TEST(DragAndDropTests, SinglePlainTextURLTypeIdentifiers)
     [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"];
     [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
 
+    EXPECT_TRUE([simulator suppressedSelectionCommandsDuringDrop]);
+
     NSItemProvider *itemProvider = [simulator sourceItemProviders].firstObject;
     NSArray *registeredTypes = [itemProvider registeredTypeIdentifiers];
     EXPECT_EQ(2UL, registeredTypes.count);
index 1d0e2e6..b912da3 100644 (file)
@@ -107,6 +107,7 @@ typedef NSDictionary<NSNumber *, NSValue *> *ProgressToCGPointValueMap;
 @property (nonatomic, readonly) NSArray *finalSelectionRects;
 @property (nonatomic, readonly) CGRect lastKnownDragCaretRect;
 @property (nonatomic, readonly) NSArray<UITargetedDragPreview *> *liftPreviews;
+@property (nonatomic, readonly) BOOL suppressedSelectionCommandsDuringDrop;
 
 #endif // PLATFORM(IOS_FAMILY)
 
index 6ee17d7..de52291 100644 (file)
@@ -33,6 +33,7 @@
 #if PLATFORM(IOS_FAMILY)
 @class _WKActivatedElementInfo;
 @protocol UITextInputMultiDocument;
+@protocol UITextInputPrivate;
 #endif
 
 @interface WKWebView (AdditionalDeclarations)
@@ -76,7 +77,7 @@
 
 #if PLATFORM(IOS_FAMILY)
 @interface TestWKWebView (IOSOnly)
-@property (nonatomic, readonly) UIView <UITextInput, UITextInputMultiDocument> *textInputContentView;
+@property (nonatomic, readonly) UIView <UITextInputPrivate, UITextInputMultiDocument> *textInputContentView;
 @property (nonatomic, readonly) RetainPtr<NSArray> selectionRectsAfterPresentationUpdate;
 @property (nonatomic, readonly) CGRect caretViewRectInContentCoordinates;
 @property (nonatomic, readonly) NSArray<NSValue *> *selectionViewRectsInContentCoordinates;
index 67e36d1..6294de1 100644 (file)
@@ -351,9 +351,9 @@ NSEventMask __simulated_forceClickAssociatedEventsMask(id self, SEL _cmd)
 
 @implementation TestWKWebView (IOSOnly)
 
-- (UIView <UITextInput, UITextInputMultiDocument> *)textInputContentView
+- (UIView <UITextInputPrivate, UITextInputMultiDocument> *)textInputContentView
 {
-    return (UIView <UITextInput, UITextInputMultiDocument> *)[self valueForKey:@"_currentContentView"];
+    return (UIView <UITextInputPrivate, UITextInputMultiDocument> *)[self valueForKey:@"_currentContentView"];
 }
 
 - (RetainPtr<NSArray>)selectionRectsAfterPresentationUpdate
index d482962..745547d 100644 (file)
@@ -315,6 +315,7 @@ static NSArray *dragAndDropEventNames()
     bool _isDoneWithCurrentRun;
     DragAndDropPhase _phase;
 
+    BOOL _suppressedSelectionCommandsDuringDrop;
     RetainPtr<UIDropProposal> _currentDropProposal;
 }
 
@@ -357,6 +358,7 @@ static NSArray *dragAndDropEventNames()
 
 - (void)_resetSimulatedState
 {
+    _suppressedSelectionCommandsDuringDrop = NO;
     _phase = DragAndDropPhaseBeginning;
     _currentProgress = 0;
     _isDoneWithCurrentRun = false;
@@ -650,6 +652,7 @@ static NSArray *dragAndDropEventNames()
 
 - (void)_webView:(WKWebView *)webView dataInteractionOperationWasHandled:(BOOL)handled forSession:(id)session itemProviders:(NSArray<UIItemProvider *> *)itemProviders
 {
+    _suppressedSelectionCommandsDuringDrop = [_webView textInputContentView]._shouldSuppressSelectionCommands;
     _isDoneWithCurrentRun = true;
 
     if (self.dropCompletionBlock)
index 64a6e59..f28d00e 100644 (file)
@@ -79,6 +79,7 @@ WTF_EXTERN_C_END
 - (UITextInputTraits *)textInputTraits;
 - (void)insertTextSuggestion:(UITextSuggestion *)textSuggestion;
 - (void)handleKeyWebEvent:(WebEvent *)theEvent withCompletionHandler:(void (^)(WebEvent *, BOOL))completionHandler;
+- (BOOL)_shouldSuppressSelectionCommands;
 @end
 
 @protocol UITextInputMultiDocument <NSObject>