Changeset 275546 in webkit


Ignore:
Timestamp:
Apr 6, 2021 1:39:10 PM (3 years ago)
Author:
Wenson Hsieh
Message:

REGRESSION (r274610): Unable to drag images when image extraction is enabled
https://bugs.webkit.org/show_bug.cgi?id=224211
<rdar://problem/76229563>

Reviewed by Tim Horton.

Source/WebKit:

r274610 introduced a new deferring gesture recognizer intended to prevent several text interaction gestures from
recognizing during pending image extraction. However, this also causes dragging on iOS to fail, since the
gesture used to initiate dragging is excluded by the new deferring gesture recognizer. To fix this, allow the
new deferring gesture to recognize simultaneously alongside all gestures with the exception of only the gestures
it is intended to defer (i.e. text interaction gestures).

Test: fast/events/ios/dragstart-on-image-by-long-pressing.html

  • UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
  • UIProcess/API/ios/WKWebViewTestingIOS.mm:

(-[WKWebView _isAnimatingDragCancel]):

  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[UIGestureRecognizer _wk_isTapAndAHalf]):

Add a WebKit category method that returns whether or not a gesture recognizer is a tap-and-a-half gesture.

(-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):

Allow the image extraction deferring gesture to recognize alongside all other gestures, with the exception of
the text interaction gestures determined by -shouldDeferGestureDueToImageExtraction:. This limits the impact
of this new deferring gesture, such that it only affects the text interaction gestures it is intended to defer.

(-[WKContentView shouldDeferGestureDueToImageExtraction:]):

Add a helper method to determine whether or not a gesture recognizer should be deferred, due to pending image
extraction. We pull this logic behind a helper method because it's now consulted from two call sites.

(-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]):
(-[WKContentView dragInteraction:item:willAnimateCancelWithAnimator:]):
(-[WKContentView isAnimatingDragCancel]):

Add a testing hook to return whether or not the drag cancel animation is running. See Tools/ChangeLog and the
new layout test for more detail.

(tapAndAHalfRecognizerClass): Deleted.

Tools:

Add support for some new testing infrastructure; see below for more details.

  • TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
  • TestRunnerShared/UIScriptContext/UIScriptController.h:

(WTR::UIScriptController::isAnimatingDragCancel const):

Add a new testing hook to return whether or not the web view's drag interaction is currently animating a drag
cancel (i.e., the drag preview is animating back to its original frame).

  • WebKitTestRunner/TestOptions.cpp:

(WTR::TestOptions::defaults):
(WTR::TestOptions::keyTypeMapping):

  • WebKitTestRunner/TestOptions.h:

(WTR::TestOptions::dragInteractionPolicy const):

Add a test option that allows tests to override the drag interaction policy to "always-allow",
"always-disallow", and the default value. This option allows us to force drag and drop to be enabled when
testing on iPhone simulator.

  • WebKitTestRunner/ios/TestControllerIOS.mm:

(WTR::dragInteractionPolicy):
(WTR::TestController::platformResetStateToConsistentValues):

  • WebKitTestRunner/ios/UIScriptControllerIOS.h:
  • WebKitTestRunner/ios/UIScriptControllerIOS.mm:

(WTR::UIScriptControllerIOS::isAnimatingDragCancel const):

LayoutTests:

Add a new layout test that initiates dragging on an image using a synthesized event stream, and verifies that
"dragstart" and "dragend" events are dispatched on the image.

  • fast/events/ios/dragstart-on-image-by-long-pressing-expected.txt: Added.
  • fast/events/ios/dragstart-on-image-by-long-pressing.html: Added.
  • resources/ui-helper.js:

(window.UIHelper.isAnimatingDragCancel):

Add a UIHelper method that returns whether or not the dragging animation is being cancelled. The new test uses
this hook to wait for the drag cancel animation to end before proceeding to the next test.

Location:
trunk
Files:
2 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r275543 r275546  
     12021-04-06  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        REGRESSION (r274610): Unable to drag images when image extraction is enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=224211
     5        <rdar://problem/76229563>
     6
     7        Reviewed by Tim Horton.
     8
     9        Add a new layout test that initiates dragging on an image using a synthesized event stream, and verifies that
     10        "dragstart" and "dragend" events are dispatched on the image.
     11
     12        * fast/events/ios/dragstart-on-image-by-long-pressing-expected.txt: Added.
     13        * fast/events/ios/dragstart-on-image-by-long-pressing.html: Added.
     14        * resources/ui-helper.js:
     15        (window.UIHelper.isAnimatingDragCancel):
     16
     17        Add a `UIHelper` method that returns whether or not the dragging animation is being cancelled. The new test uses
     18        this hook to wait for the drag cancel animation to end before proceeding to the next test.
     19
    1202021-04-06  Ryosuke Niwa  <rniwa@webkit.org>
    221
  • trunk/LayoutTests/resources/ui-helper.js

    r274581 r275546  
    368368        return new Promise(resolve => {
    369369            testRunner.runUIScript(`uiController.keyboardIsAutomaticallyShifted`, result => resolve(result === "true"));
     370        });
     371    }
     372
     373    static isAnimatingDragCancel()
     374    {
     375        return new Promise(resolve => {
     376            testRunner.runUIScript(`uiController.isAnimatingDragCancel`, result => resolve(result === "true"));
    370377        });
    371378    }
  • trunk/Source/WebKit/ChangeLog

    r275540 r275546  
     12021-04-06  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        REGRESSION (r274610): Unable to drag images when image extraction is enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=224211
     5        <rdar://problem/76229563>
     6
     7        Reviewed by Tim Horton.
     8
     9        r274610 introduced a new deferring gesture recognizer intended to prevent several text interaction gestures from
     10        recognizing during pending image extraction. However, this also causes dragging on iOS to fail, since the
     11        gesture used to initiate dragging is excluded by the new deferring gesture recognizer. To fix this, allow the
     12        new deferring gesture to recognize simultaneously alongside all gestures with the exception of only the gestures
     13        it is intended to defer (i.e. text interaction gestures).
     14
     15        Test: fast/events/ios/dragstart-on-image-by-long-pressing.html
     16
     17        * UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
     18        * UIProcess/API/ios/WKWebViewTestingIOS.mm:
     19        (-[WKWebView _isAnimatingDragCancel]):
     20        * UIProcess/ios/WKContentViewInteraction.h:
     21        * UIProcess/ios/WKContentViewInteraction.mm:
     22        (-[UIGestureRecognizer _wk_isTapAndAHalf]):
     23
     24        Add a WebKit category method that returns whether or not a gesture recognizer is a tap-and-a-half gesture.
     25
     26        (-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
     27
     28        Allow the image extraction deferring gesture to recognize alongside all other gestures, with the exception of
     29        the text interaction gestures determined by `-shouldDeferGestureDueToImageExtraction:`. This limits the impact
     30        of this new deferring gesture, such that it only affects the text interaction gestures it is intended to defer.
     31
     32        (-[WKContentView shouldDeferGestureDueToImageExtraction:]):
     33
     34        Add a helper method to determine whether or not a gesture recognizer should be deferred, due to pending image
     35        extraction. We pull this logic behind a helper method because it's now consulted from two call sites.
     36
     37        (-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]):
     38        (-[WKContentView dragInteraction:item:willAnimateCancelWithAnimator:]):
     39        (-[WKContentView isAnimatingDragCancel]):
     40
     41        Add a testing hook to return whether or not the drag cancel animation is running. See Tools/ChangeLog and the
     42        new layout test for more detail.
     43
     44        (tapAndAHalfRecognizerClass): Deleted.
     45
    1462021-04-06  Alex Christensen  <achristensen@webkit.org>
    247
  • trunk/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h

    r274581 r275546  
    4343@property (nonatomic, readonly) NSNumber *_stableStateOverride;
    4444@property (nonatomic, readonly) CGRect _dragCaretRect;
     45@property (nonatomic, readonly, getter=_isAnimatingDragCancel) BOOL _animatingDragCancel;
    4546
    4647- (void)keyboardAccessoryBarNext;
  • trunk/Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm

    r274581 r275546  
    314314}
    315315
     316- (BOOL)_isAnimatingDragCancel
     317{
     318#if ENABLE(DRAG_SUPPORT)
     319    return [_contentView isAnimatingDragCancel];
     320#else
     321    return NO;
     322#endif
     323}
     324
    316325- (void)_simulateElementAction:(_WKElementActionType)actionType atLocation:(CGPoint)location
    317326{
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r275270 r275546  
    439439    RetainPtr<UIDragInteraction> _dragInteraction;
    440440    RetainPtr<UIDropInteraction> _dropInteraction;
     441    BOOL _isAnimatingDragCancel;
    441442    BOOL _shouldRestoreCalloutBarAfterDrop;
    442443    RetainPtr<UIView> _visibleContentViewSnapshot;
     
    736737@property (nonatomic, readonly) WKDateTimeInputControl *dateTimeInputControl;
    737738@property (nonatomic, readonly) WKFormSelectControl *selectControl;
     739#if ENABLE(DRAG_SUPPORT)
     740@property (nonatomic, readonly, getter=isAnimatingDragCancel) BOOL animatingDragCancel;
     741#endif
    738742
    739743@end
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r275397 r275546  
    682682}
    683683
     684- (BOOL)_wk_isTapAndAHalf
     685{
     686    static dispatch_once_t onceToken;
     687    static Class tapAndAHalfGestureRecognizerClass;
     688    dispatch_once(&onceToken, ^{
     689        tapAndAHalfGestureRecognizerClass = NSClassFromString(@"UITapAndAHalfRecognizer");
     690    });
     691    return [self isKindOfClass:tapAndAHalfGestureRecognizerClass];
     692}
     693
    684694@end
    685695
     
    22272237}
    22282238
    2229 static Class tapAndAHalfRecognizerClass()
    2230 {
    2231     static dispatch_once_t onceToken;
    2232     static Class theClass;
    2233     dispatch_once(&onceToken, ^{
    2234         theClass = NSClassFromString(@"UITapAndAHalfRecognizer");
    2235     });
    2236     return theClass;
    2237 }
    2238 
    22392239- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer
    22402240{
     
    22462246    if ([gestureRecognizer isKindOfClass:WKDeferringGestureRecognizer.class] && [otherGestureRecognizer isKindOfClass:WKDeferringGestureRecognizer.class])
    22472247        return YES;
     2248
     2249#if ENABLE(IMAGE_EXTRACTION)
     2250    if (gestureRecognizer == _imageExtractionDeferringGestureRecognizer)
     2251        return ![self shouldDeferGestureDueToImageExtraction:otherGestureRecognizer];
     2252
     2253    if (otherGestureRecognizer == _imageExtractionDeferringGestureRecognizer)
     2254        return ![self shouldDeferGestureDueToImageExtraction:gestureRecognizer];
     2255#endif
    22482256
    22492257    if (isSamePair(gestureRecognizer, otherGestureRecognizer, _highlightLongPressGestureRecognizer.get(), _longPressGestureRecognizer.get()))
     
    22752283            return YES;
    22762284
    2277         if ([gestureRecognizer isKindOfClass:tapAndAHalfRecognizerClass()] || [otherGestureRecognizer isKindOfClass:tapAndAHalfRecognizerClass()])
     2285        if (gestureRecognizer._wk_isTapAndAHalf || otherGestureRecognizer._wk_isTapAndAHalf)
    22782286            return YES;
    22792287    }
     
    75147522}
    75157523
     7524#if ENABLE(IMAGE_EXTRACTION)
     7525
     7526- (BOOL)shouldDeferGestureDueToImageExtraction:(UIGestureRecognizer *)gesture
     7527{
     7528    return gesture == [_textInteractionAssistant loupeGesture] || gesture._wk_isTapAndAHalf || gesture == [_textInteractionAssistant forcePressGesture];
     7529}
     7530
     7531#endif // ENABLE(IMAGE_EXTRACTION)
     7532
    75167533#if HAVE(PASTEBOARD_DATA_OWNER)
    75177534
     
    76607677        return NO;
    76617678
    7662     BOOL isLoupeGesture = gestureRecognizer == [_textInteractionAssistant loupeGesture];
    7663     BOOL isTapAndAHalfGesture = [gestureRecognizer isKindOfClass:tapAndAHalfRecognizerClass()];
    7664 
    76657679#if ENABLE(IMAGE_EXTRACTION)
    76667680    if (deferringGestureRecognizer == _imageExtractionDeferringGestureRecognizer)
    7667         return isLoupeGesture || isTapAndAHalfGesture || gestureRecognizer == [_textInteractionAssistant forcePressGesture];
     7681        return [self shouldDeferGestureDueToImageExtraction:gestureRecognizer];
    76687682#endif
    76697683
     
    76797693#endif
    76807694
    7681         if (isTapAndAHalfGesture)
     7695        if (gestureRecognizer._wk_isTapAndAHalf)
    76827696            return YES;
    76837697
    7684         if (isLoupeGesture)
     7698        if (gestureRecognizer == [_textInteractionAssistant loupeGesture])
    76857699            return YES;
    76867700
     
    86868700- (void)dragInteraction:(UIDragInteraction *)interaction item:(UIDragItem *)item willAnimateCancelWithAnimator:(id <UIDragAnimating>)animator
    86878701{
     8702    _isAnimatingDragCancel = YES;
    86888703    RELEASE_LOG(DragAndDrop, "Drag interaction willAnimateCancelWithAnimator");
    86898704    [animator addCompletion:[protectedSelf = retainPtr(self), page = _page] (UIViewAnimatingPosition finalPosition) {
     
    86918706        page->dragCancelled();
    86928707        if (auto completion = protectedSelf->_dragDropInteractionState.takeDragCancelSetDownBlock()) {
    8693             page->callAfterNextPresentationUpdate([completion] (WebKit::CallbackBase::Error) {
     8708            page->callAfterNextPresentationUpdate([completion, protectedSelf] (WebKit::CallbackBase::Error) {
    86948709                completion();
     8710                protectedSelf->_isAnimatingDragCancel = NO;
    86958711            });
    86968712        }
     
    95439559    return nil;
    95449560}
     9561
     9562#if ENABLE(DRAG_SUPPORT)
     9563
     9564- (BOOL)isAnimatingDragCancel
     9565{
     9566    return _isAnimatingDragCancel;
     9567}
     9568
     9569#endif // ENABLE(DRAG_SUPPORT)
    95459570
    95469571- (void)_simulateTextEntered:(NSString *)text
  • trunk/Tools/ChangeLog

    r275542 r275546  
     12021-04-06  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        REGRESSION (r274610): Unable to drag images when image extraction is enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=224211
     5        <rdar://problem/76229563>
     6
     7        Reviewed by Tim Horton.
     8
     9        Add support for some new testing infrastructure; see below for more details.
     10
     11        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
     12        * TestRunnerShared/UIScriptContext/UIScriptController.h:
     13        (WTR::UIScriptController::isAnimatingDragCancel const):
     14
     15        Add a new testing hook to return whether or not the web view's drag interaction is currently animating a drag
     16        cancel (i.e., the drag preview is animating back to its original frame).
     17
     18        * WebKitTestRunner/TestOptions.cpp:
     19        (WTR::TestOptions::defaults):
     20        (WTR::TestOptions::keyTypeMapping):
     21        * WebKitTestRunner/TestOptions.h:
     22        (WTR::TestOptions::dragInteractionPolicy const):
     23
     24        Add a test option that allows tests to override the drag interaction policy to "always-allow",
     25        "always-disallow", and the default value. This option allows us to force drag and drop to be enabled when
     26        testing on iPhone simulator.
     27
     28        * WebKitTestRunner/ios/TestControllerIOS.mm:
     29        (WTR::dragInteractionPolicy):
     30        (WTR::TestController::platformResetStateToConsistentValues):
     31        * WebKitTestRunner/ios/UIScriptControllerIOS.h:
     32        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
     33        (WTR::UIScriptControllerIOS::isAnimatingDragCancel const):
     34
    1352021-04-06  Yusuke Suzuki  <ysuzuki@apple.com>
    236
  • trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl

    r274581 r275546  
    9090    undefined rawKeyDown(DOMString key);
    9191    undefined rawKeyUp(DOMString key);
     92
     93    readonly attribute boolean isAnimatingDragCancel;
    9294
    9395    // eventsJSON describes a series of user events in JSON form. For the keys, see HIDEventGenerator.mm.
  • trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h

    r274581 r275546  
    177177    }
    178178
     179    virtual bool isAnimatingDragCancel() const
     180    {
     181        notImplemented();
     182        return false;
     183    }
     184
    179185    virtual void rawKeyDown(JSStringRef) { notImplemented(); }
    180186    virtual void rawKeyUp(JSStringRef) { notImplemented(); }
  • trunk/Tools/WebKitTestRunner/TestOptions.cpp

    r272304 r275546  
    114114            { "applicationManifest", { } },
    115115            { "contentMode", { } },
     116            { "dragInteractionPolicy", { } },
    116117            { "jscOptions", { } },
    117118            { "standaloneWebApplicationURL", { } },
     
    162163        { "applicationManifest", TestHeaderKeyType::StringRelativePathTestRunner },
    163164        { "contentMode", TestHeaderKeyType::StringTestRunner },
     165        { "dragInteractionPolicy", TestHeaderKeyType::StringTestRunner },
    164166        { "jscOptions", TestHeaderKeyType::StringTestRunner },
    165167        { "standaloneWebApplicationURL", TestHeaderKeyType::StringURLTestRunner },
  • trunk/Tools/WebKitTestRunner/TestOptions.h

    r270446 r275546  
    7979    std::string applicationManifest() const { return stringTestRunnerFeatureValue("applicationManifest"); }
    8080    std::string contentMode() const { return stringTestRunnerFeatureValue("contentMode"); }
     81    std::string dragInteractionPolicy() const { return stringTestRunnerFeatureValue("dragInteractionPolicy"); }
    8182    std::string jscOptions() const { return stringTestRunnerFeatureValue("jscOptions"); }
    8283    std::string standaloneWebApplicationURL() const { return stringTestRunnerFeatureValue("standaloneWebApplicationURL"); }
  • trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm

    r273730 r275546  
    155155}
    156156
     157static _WKDragInteractionPolicy dragInteractionPolicy(const TestOptions& options)
     158{
     159    auto policy = options.dragInteractionPolicy();
     160    if (policy == "always-enable")
     161        return _WKDragInteractionPolicyAlwaysEnable;
     162    if (policy == "always-disable")
     163        return _WKDragInteractionPolicyAlwaysDisable;
     164    return _WKDragInteractionPolicyDefault;
     165}
     166
    157167bool TestController::platformResetStateToConsistentValues(const TestOptions& options)
    158168{
     
    213223        [webView resetCustomMenuAction];
    214224        [webView setAllowedMenuActions:nil];
     225        webView._dragInteractionPolicy = dragInteractionPolicy(options);
    215226
    216227        UIScrollView *scrollView = webView.scrollView;
  • trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h

    r274581 r275546  
    135135    void toggleCapsLock(JSValueRef) override;
    136136    bool keyboardIsAutomaticallyShifted() const override;
     137    bool isAnimatingDragCancel() const override;
    137138    JSObjectRef attachmentInfo(JSStringRef) override;
    138139    UIView *platformContentView() const override;
  • trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

    r274581 r275546  
    11711171}
    11721172
     1173bool UIScriptControllerIOS::isAnimatingDragCancel() const
     1174{
     1175    return webView()._animatingDragCancel;
     1176}
     1177
    11731178JSObjectRef UIScriptControllerIOS::attachmentInfo(JSStringRef jsAttachmentIdentifier)
    11741179{
Note: See TracChangeset for help on using the changeset viewer.