⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 284889 in webkit


Ignore:
Timestamp:
Oct 26, 2021, 12:44:14 PM (5 years ago)
Author:
Wenson Hsieh
Message:

REGRESSION (r281054): [iOS] Context menu presents from wrong location when long pressing a link in Mail
https://bugs.webkit.org/show_bug.cgi?id=232287
rdar://82671325

Reviewed by Tim Horton.

In the case where the WebKit client isn't overriding the context menu configuration via WebKit context menu UI
delegate methods, _contextMenuElementInfo on WKContentView will end up being nil while presenting the context
menu via long press.

After the changes in r281054, this means that when the last view is removed from our WKTargetedPreviewContainer,
we'll unparent WKTargetedPreviewContainer too early, since _contextMenuElementInfo won't prevent us from
bailing in -_removeContextMenuHintContainerIfPossible. To fix this, we add a boolean flag to track when the
context menu presentation animation is running, and avoid unparenting the preview container if the flag is set.

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

(-[WKContentView setUpInteraction]):
(-[WKContentView _removeContextMenuHintContainerIfPossible]):
(-[WKContentView _contentsOfUserInterfaceItem:]):
(-[WKContentView contextMenuInteraction:willDisplayMenuForConfiguration:animator:]):

To test this change, add an assertion that fires if the context menu preview hint container has already been
unparented by the time we've presented the context menu. This assertion already fires during the extant layout
test fast/events/touch/ios/long-press-on-link.html, which technically exhibits the bug (albeit in a more subtle
way).

(-[WKContentView contextMenuInteraction:willEndForConfiguration:animator:]):

Location:
trunk/Source/WebKit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r284887 r284889  
     12021-10-26  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        REGRESSION (r281054): [iOS] Context menu presents from wrong location when long pressing a link in Mail
     4        https://bugs.webkit.org/show_bug.cgi?id=232287
     5        rdar://82671325
     6
     7        Reviewed by Tim Horton.
     8
     9        In the case where the WebKit client isn't overriding the context menu configuration via WebKit context menu UI
     10        delegate methods, `_contextMenuElementInfo` on WKContentView will end up being nil while presenting the context
     11        menu via long press.
     12
     13        After the changes in r281054, this means that when the last view is removed from our WKTargetedPreviewContainer,
     14        we'll unparent WKTargetedPreviewContainer too early, since `_contextMenuElementInfo` won't prevent us from
     15        bailing in `-_removeContextMenuHintContainerIfPossible`. To fix this, we add a boolean flag to track when the
     16        context menu presentation animation is running, and avoid unparenting the preview container if the flag is set.
     17
     18        * UIProcess/ios/WKContentViewInteraction.h:
     19        * UIProcess/ios/WKContentViewInteraction.mm:
     20        (-[WKContentView setUpInteraction]):
     21        (-[WKContentView _removeContextMenuHintContainerIfPossible]):
     22        (-[WKContentView _contentsOfUserInterfaceItem:]):
     23        (-[WKContentView contextMenuInteraction:willDisplayMenuForConfiguration:animator:]):
     24
     25        To test this change, add an assertion that fires if the context menu preview hint container has already been
     26        unparented by the time we've presented the context menu. This assertion already fires during the extant layout
     27        test fast/events/touch/ios/long-press-on-link.html, which technically exhibits the bug (albeit in a more subtle
     28        way).
     29
     30        (-[WKContentView contextMenuInteraction:willEndForConfiguration:animator:]):
     31
    1322021-10-26  Brady Eidson  <beidson@apple.com>
    233
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r284122 r284889  
    351351    BOOL _contextMenuHasRequestedLegacyData;
    352352    BOOL _contextMenuActionProviderDelegateNeedsOverride;
     353    BOOL _isDisplayingContextMenuWithAnimation;
    353354#endif
    354355    RetainPtr<UIPreviewItemController> _previewItemController;
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r284843 r284889  
    10291029    _isChangingFocus = NO;
    10301030    _isBlurringFocusedElement = NO;
     1031#if USE(UICONTEXTMENU)
     1032    _isDisplayingContextMenuWithAnimation = NO;
     1033#endif
    10311034
    10321035#if USE(UICONTEXTMENU) && ENABLE(IMAGE_ANALYSIS)
     
    86268629        return;
    86278630#endif
     8631    if (_isDisplayingContextMenuWithAnimation)
     8632        return;
    86288633#if ENABLE(DATA_DETECTION)
    86298634    // We are also using this container for the action sheet assistant...
     
    1052510530#if HAVE(LINK_PREVIEW)
    1052610531    if ([userInterfaceItem isEqualToString:@"contextMenu"]) {
    10527         if (self._shouldUseContextMenus)
     10532        if (self._shouldUseContextMenus) {
    1052810533            return @{ userInterfaceItem: @{
    1052910534                @"url": _positionInformation.url.isValid() ? WTF::userVisibleString(_positionInformation.url) : @"",
     
    1053210537                @"imageURL": _positionInformation.imageURL.isValid() ? WTF::userVisibleString(_positionInformation.imageURL) : @""
    1053310538            } };
     10539        }
    1053410540        NSString *url = [_previewItemController previewData][UIPreviewDataLink];
    1053510541        return @{ userInterfaceItem: @{
     
    1113311139    if (!_webView)
    1113411140        return;
     11141
     11142    _isDisplayingContextMenuWithAnimation = YES;
     11143    [animator addCompletion:[weakSelf = WeakObjCPtr<WKContentView>(self)] {
     11144        if (auto strongSelf = weakSelf.get()) {
     11145            ASSERT_IMPLIES(strongSelf->_isDisplayingContextMenuWithAnimation, [strongSelf->_contextMenuHintContainerView window]);
     11146            strongSelf->_isDisplayingContextMenuWithAnimation = NO;
     11147        }
     11148    }];
     11149
    1113511150    auto uiDelegate = static_cast<id<WKUIDelegatePrivate>>(self.webView.UIDelegate);
    1113611151    if (!uiDelegate)
    1113711152        return;
     11153
    1113811154    if ([uiDelegate respondsToSelector:@selector(webView:contextMenuWillPresentForElement:)])
    1113911155        [uiDelegate webView:self.webView contextMenuWillPresentForElement:_contextMenuElementInfo.get()];
     
    1129411310        if (!strongSelf)
    1129511311            return;
     11312
     11313        strongSelf->_isDisplayingContextMenuWithAnimation = NO;
    1129611314        [strongSelf _removeContextMenuHintContainerIfPossible];
    1129711315        [strongSelf->_webView _didDismissContextMenu];
Note: See TracChangeset for help on using the changeset viewer.