Changeset 246912 in webkit


Ignore:
Timestamp:
Jun 27, 2019 6:06:38 PM (5 years ago)
Author:
dino@apple.com
Message:

Provide overrides for UIKit's suggested actions in UIContextMenuInteraction
https://bugs.webkit.org/show_bug.cgi?id=199301
<rdar://problem/52297380>

Reviewed by Tim Horton.

We were previously wrapping the actionMenuProvider with our own block
in order to ensure the correct suggestedActions were passed to the provider.
UIKit added API for us to override the actions separately.

Unfortunately we can't quite yet get rid of our access into the
UIContextMenuConfiguration, because we still need to override the preview
handler in the case where the user does not want link previews.

  • Platform/spi/ios/UIKitSPI.h:
  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView continueContextMenuInteraction:]):
(-[WKContentView _contextMenuInteraction:overrideSuggestedActionsForConfiguration:]):
Implement the new delegate SPI to provide our own actions.

Location:
trunk/Source/WebKit
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r246908 r246912  
     12019-06-27  Dean Jackson  <dino@apple.com>
     2
     3        Provide overrides for UIKit's suggested actions in UIContextMenuInteraction
     4        https://bugs.webkit.org/show_bug.cgi?id=199301
     5        <rdar://problem/52297380>
     6
     7        Reviewed by Tim Horton.
     8
     9        We were previously wrapping the actionMenuProvider with our own block
     10        in order to ensure the correct suggestedActions were passed to the provider.
     11        UIKit added API for us to override the actions separately.
     12
     13        Unfortunately we can't quite yet get rid of our access into the
     14        UIContextMenuConfiguration, because we still need to override the preview
     15        handler in the case where the user does not want link previews.
     16
     17        * Platform/spi/ios/UIKitSPI.h:
     18        * UIProcess/ios/WKContentViewInteraction.h:
     19        * UIProcess/ios/WKContentViewInteraction.mm:
     20        (-[WKContentView continueContextMenuInteraction:]):
     21        (-[WKContentView _contextMenuInteraction:overrideSuggestedActionsForConfiguration:]):
     22        Implement the new delegate SPI to provide our own actions.
     23
    1242019-06-27  Daniel Bates  <dabates@apple.com>
    225
  • trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h

    r246892 r246912  
    9090#import <UIKit/UIPreviewAction_Private.h>
    9191#import <UIKit/UIPreviewItemController.h>
     92#if USE(UICONTEXTMENU)
     93#import <UIKit/UIContextMenuInteraction_ForWebKitOnly.h>
     94#endif
    9295#endif
    9396
     
    11861189
    11871190#if HAVE(LINK_PREVIEW) && USE(UICONTEXTMENU)
    1188 @interface UIContextMenuConfiguration (NeededUntil51288435Fixed)
     1191@interface UIContextMenuConfiguration (Radar52295535)
    11891192@property (nonatomic, copy) id <NSCopying> identifier;
    11901193@property (nonatomic, copy) UIContextMenuContentPreviewProvider previewProvider;
     
    11981201
    11991202@class _UIClickPresentationInteraction;
    1200 @interface UIContextMenuInteraction (Radar51288435)
     1203@interface UIContextMenuInteraction (Radar52298310)
    12011204@property (nonatomic, strong) _UIClickPresentationInteraction *presentationInteraction;
    12021205@end
     
    12071210@interface _UIClickPresentationInteraction : NSObject <UIInteraction>
    12081211@end
    1209 @interface _UIClickPresentationInteraction (NeededUntil51288435Fixed)
     1212@interface _UIClickPresentationInteraction (Radar52298310)
    12101213@property (nonatomic, strong) _UIClickInteraction *previewClickInteraction;
    12111214@end
    12121215
    1213 @interface _UIClickInteraction (Radar51288435)
     1216@interface _UIClickInteraction (Radar52298310)
    12141217@property (nonatomic, strong) id<_UIClickInteractionDriving> driver;
    12151218@end
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r246892 r246912  
    255255    RetainPtr<UIMenu> _contextMenuLegacyMenu;
    256256    BOOL _contextMenuHasRequestedLegacyData;
     257    BOOL _contextMenuActionProviderDelegateNeedsOverride;
    257258    RetainPtr<UITargetedPreview> _contextMenuInteractionTargetedPreview;
    258259#endif
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r246908 r246912  
    77777777        _contextMenuLegacyMenu = nullptr;
    77787778        _contextMenuHasRequestedLegacyData = NO;
    7779 
    7780         UIContextMenuActionProvider actionMenuProvider = [weakSelf = WeakObjCPtr<WKContentView>(self)] (NSArray<UIMenuElement *> *suggestedActions) -> UIMenu * {
     7779        _contextMenuActionProviderDelegateNeedsOverride = NO;
     7780
     7781        UIContextMenuActionProvider actionMenuProvider = [weakSelf = WeakObjCPtr<WKContentView>(self)] (NSArray<UIMenuElement *> *) -> UIMenu * {
    77817782            auto strongSelf = weakSelf.get();
    77827783            if (!strongSelf)
     
    78087809            return completion(nil);
    78097810
    7810         if (!configurationFromWKUIDelegate) {
    7811 
    7812             strongSelf->_contextMenuElementInfo = nil;
    7813 
    7814             // At this point we have an object we might want to show a context menu for, but the
    7815             // client was unable to handle it. Before giving up, we ask DataDetectors.
     7811        if (configurationFromWKUIDelegate) {
     7812            strongSelf->_contextMenuActionProviderDelegateNeedsOverride = YES;
     7813            completion(configurationFromWKUIDelegate);
     7814            return;
     7815        }
     7816
     7817        // At this point we have an object we might want to show a context menu for, but the
     7818        // client was unable to handle it. Before giving up, we ask DataDetectors.
     7819
     7820        strongSelf->_contextMenuElementInfo = nil;
    78167821
    78177822#if ENABLE(DATA_DETECTION)
    7818             // FIXME: Support JavaScript urls here. But make sure they don't show a preview.
    7819             // <rdar://problem/50572283>
    7820             if (!linkURL.protocolIsInHTTPFamily() && !WebCore::DataDetection::canBePresentedByDataDetectors(linkURL))
    7821                 return completion(nil);
    7822 
    7823             BEGIN_BLOCK_OBJC_EXCEPTIONS;
    7824             auto ddContextMenuActionClass = getDDContextMenuActionClass();
    7825             if ([ddContextMenuActionClass respondsToSelector:@selector(contextMenuConfigurationWithURL:inView:context:menuIdentifier:)]) {
    7826                 NSDictionary *context = [strongSelf dataDetectionContextForPositionInformation:strongSelf->_positionInformation];
    7827                 UIContextMenuConfiguration *configurationFromDD = [ddContextMenuActionClass contextMenuConfigurationForURL:linkURL identifier:strongSelf->_positionInformation.dataDetectorIdentifier selectedText:[strongSelf selectedText] results:strongSelf->_positionInformation.dataDetectorResults.get() inView:strongSelf.get() context:context menuIdentifier:nil];
    7828                 if (strongSelf->_showLinkPreviews)
    7829                     return completion(configurationFromDD);
    7830                 return completion([UIContextMenuConfiguration configurationWithIdentifier:[configurationFromDD identifier] previewProvider:[configurationFromDD previewProvider] actionProvider:[configurationFromDD actionProvider]]);
    7831             }
    7832             END_BLOCK_OBJC_EXCEPTIONS;
    7833 #endif
     7823        // FIXME: Support JavaScript urls here. But make sure they don't show a preview.
     7824        // <rdar://problem/50572283>
     7825        if (!linkURL.protocolIsInHTTPFamily() && !WebCore::DataDetection::canBePresentedByDataDetectors(linkURL))
    78347826            return completion(nil);
     7827
     7828        BEGIN_BLOCK_OBJC_EXCEPTIONS;
     7829        auto ddContextMenuActionClass = getDDContextMenuActionClass();
     7830        if ([ddContextMenuActionClass respondsToSelector:@selector(contextMenuConfigurationWithURL:inView:context:menuIdentifier:)]) {
     7831            NSDictionary *context = [strongSelf dataDetectionContextForPositionInformation:strongSelf->_positionInformation];
     7832            UIContextMenuConfiguration *configurationFromDD = [ddContextMenuActionClass contextMenuConfigurationForURL:linkURL identifier:strongSelf->_positionInformation.dataDetectorIdentifier selectedText:[strongSelf selectedText] results:strongSelf->_positionInformation.dataDetectorResults.get() inView:strongSelf.get() context:context menuIdentifier:nil];
     7833            strongSelf->_contextMenuActionProviderDelegateNeedsOverride = YES;
     7834            if (strongSelf->_showLinkPreviews)
     7835                return completion(configurationFromDD);
     7836            return completion([UIContextMenuConfiguration configurationWithIdentifier:[configurationFromDD identifier] previewProvider:nil actionProvider:[configurationFromDD actionProvider]]);
    78357837        }
    7836 
    7837         id<NSCopying> identifier = [configurationFromWKUIDelegate identifier];
    7838         UIContextMenuContentPreviewProvider contentPreviewProvider = [configurationFromWKUIDelegate previewProvider];
    7839         UIContextMenuActionProvider actionMenuProvider = [configurationFromWKUIDelegate actionProvider];
    7840 
    7841         auto actionProviderWrapper = [actionProviderFromUIDelegate = makeBlockPtr(actionMenuProvider), weakSelf = WTFMove(weakSelf)] (NSArray<UIMenuElement *> *suggestedActions) -> UIMenu * {
    7842             auto strongSelf = weakSelf.get();
    7843             if (!strongSelf)
    7844                 return nil;
    7845 
    7846             auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithInteractionInformationAtPosition:strongSelf->_positionInformation]);
    7847             RetainPtr<NSArray<_WKElementAction *>> defaultActionsFromAssistant = strongSelf->_positionInformation.isLink ? [strongSelf->_actionSheetAssistant defaultActionsForLinkSheet:elementInfo.get()] : [strongSelf->_actionSheetAssistant defaultActionsForImageSheet:elementInfo.get()];
    7848 
    7849             auto menuElements = menuElementsFromDefaultActions(defaultActionsFromAssistant, elementInfo);
    7850 
    7851             if (actionProviderFromUIDelegate)
    7852                 return actionProviderFromUIDelegate(menuElements);
    7853 
    7854             auto title = titleForMenu(strongSelf->_positionInformation.isLink, strongSelf->_showLinkPreviews, strongSelf->_positionInformation.url, strongSelf->_positionInformation.title);
    7855             return [UIMenu menuWithTitle:title children:menuElements];
    7856         };
    7857 
    7858         completion([UIContextMenuConfiguration configurationWithIdentifier:identifier previewProvider:contentPreviewProvider actionProvider:actionProviderWrapper]);
     7838        END_BLOCK_OBJC_EXCEPTIONS;
     7839#endif
     7840        return completion(nil);
    78597841    });
    78607842
     7843    _contextMenuActionProviderDelegateNeedsOverride = NO;
    78617844    _contextMenuElementInfo = wrapper(API::ContextMenuElementInfo::create(_positionInformation));
    78627845    if ([uiDelegate respondsToSelector:@selector(_webView:contextMenuConfigurationForElement:completionHandler:)]) {
     
    78787861    } else
    78797862        completionBlock(nil);
     7863}
     7864
     7865- (NSArray<UIMenuElement *> *)_contextMenuInteraction:(UIContextMenuInteraction *)interaction overrideSuggestedActionsForConfiguration:(UIContextMenuConfiguration *)configuration
     7866{
     7867    if (_contextMenuActionProviderDelegateNeedsOverride) {
     7868        auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithInteractionInformationAtPosition:_positionInformation]);
     7869        RetainPtr<NSArray<_WKElementAction *>> defaultActionsFromAssistant = _positionInformation.isLink ? [_actionSheetAssistant defaultActionsForLinkSheet:elementInfo.get()] : [_actionSheetAssistant defaultActionsForImageSheet:elementInfo.get()];
     7870        return menuElementsFromDefaultActions(defaultActionsFromAssistant, elementInfo);
     7871    }
     7872    // If we're here we're in the legacy path, which ignores the suggested actions anyway.
     7873    return nil;
    78807874}
    78817875
Note: See TracChangeset for help on using the changeset viewer.