Changeset 246865 in webkit


Ignore:
Timestamp:
Jun 26, 2019 6:04:48 PM (5 years ago)
Author:
dino@apple.com
Message:

Expose UIAction identifiers for _WKElementActions
https://bugs.webkit.org/show_bug.cgi?id=199246
<rdar://problem/52218950>

Reviewed by Tim Horton.

In order for clients to create a contextual menu, they are given
a set of suggested UIActions, created from _WKElementActions.
By associating identifiers (strings) with the UIActions, clients
can inspect the suggestions and make a decision on whether or
not to include them in the final menu.

  • UIProcess/API/Cocoa/_WKElementAction.h: Typedef UIActionIdentifier,

add a method to create a UIAction from an _WKElementAction, and a
helper to map between identifiers and types.

  • UIProcess/API/Cocoa/_WKElementAction.mm:

(elementActionTypeToUIActionIdentifier): Helper to convert between the two types.
(uiActionIdentifierToElementActionType): The inverse of above.
(+[_WKElementAction elementActionTypeForUIActionIdentifier:]): A client given
a UIAction object can use this helper method to see what _WKElementActionType it
corresponds to.
(-[_WKElementAction uiActionForElementInfo:]): Used by WKContentViewInteraction to
create a UIAction from this _WKElementAction.

  • UIProcess/ios/WKContentViewInteraction.mm:

(uiActionForLegacyPreviewAction): Renamed to make it clear this is a legacy approach.
(menuFromLegacyPreviewOrDefaultActions): Split these functions to separate the legacy
and non-legacy approach.
(-[WKContentView assignLegacyDataForContextMenuInteraction]):
(-[WKContentView continueContextMenuInteraction:]):
(uiActionForPreviewAction): Deleted.
(menuFromPreviewOrDefaults): Deleted.

Location:
trunk/Source/WebKit
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r246859 r246865  
     12019-06-26  Dean Jackson  <dino@apple.com>
     2
     3        Expose UIAction identifiers for _WKElementActions
     4        https://bugs.webkit.org/show_bug.cgi?id=199246
     5        <rdar://problem/52218950>
     6
     7        Reviewed by Tim Horton.
     8
     9        In order for clients to create a contextual menu, they are given
     10        a set of suggested UIActions, created from _WKElementActions.
     11        By associating identifiers (strings) with the UIActions, clients
     12        can inspect the suggestions and make a decision on whether or
     13        not to include them in the final menu.
     14
     15        * UIProcess/API/Cocoa/_WKElementAction.h: Typedef UIActionIdentifier,
     16        add a method to create a UIAction from an _WKElementAction, and a
     17        helper to map between identifiers and types.
     18
     19        * UIProcess/API/Cocoa/_WKElementAction.mm:
     20        (elementActionTypeToUIActionIdentifier): Helper to convert between the two types.
     21        (uiActionIdentifierToElementActionType): The inverse of above.
     22        (+[_WKElementAction elementActionTypeForUIActionIdentifier:]): A client given
     23        a UIAction object can use this helper method to see what _WKElementActionType it
     24        corresponds to.
     25        (-[_WKElementAction uiActionForElementInfo:]): Used by WKContentViewInteraction to
     26        create a UIAction from this _WKElementAction.
     27
     28        * UIProcess/ios/WKContentViewInteraction.mm:
     29        (uiActionForLegacyPreviewAction): Renamed to make it clear this is a legacy approach.
     30        (menuFromLegacyPreviewOrDefaultActions): Split these functions to separate the legacy
     31        and non-legacy approach.
     32        (-[WKContentView assignLegacyDataForContextMenuInteraction]):
     33        (-[WKContentView continueContextMenuInteraction:]):
     34        (uiActionForPreviewAction): Deleted.
     35        (menuFromPreviewOrDefaults): Deleted.
     36
    1372019-06-26  Wenson Hsieh  <wenson_hsieh@apple.com>
    238
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.h

    r244941 r246865  
    3131#import <WebKit/_WKActivatedElementInfo.h>
    3232
     33@class UIAction;
    3334@class UIImage;
     35
     36typedef NSString *UIActionIdentifier;
    3437
    3538typedef void (^WKElementActionHandler)(_WKActivatedElementInfo *);
     
    4346#if !defined(TARGET_OS_IOS) || TARGET_OS_IOS
    4447    _WKElementActionTypeAddToReadingList,
    45     _WKElementActionTypeOpenInDefaultBrowser WK_API_AVAILABLE(ios(9_0)),
    46     _WKElementActionTypeOpenInExternalApplication WK_API_AVAILABLE(ios(9_0)),
     48    _WKElementActionTypeOpenInDefaultBrowser WK_API_AVAILABLE(ios(9.0)),
     49    _WKElementActionTypeOpenInExternalApplication WK_API_AVAILABLE(ios(9.0)),
    4750#endif
    4851    _WKElementActionTypeShare WK_API_AVAILABLE(macos(10.12), ios(10.0)),
     
    6063+ (instancetype)elementActionWithTitle:(NSString *)title actionHandler:(WKElementActionHandler)handler;
    6164
    62 + (UIImage *)imageForElementActionType:(_WKElementActionType)actionType WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     65+ (UIImage *)imageForElementActionType:(_WKElementActionType)actionType WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(13.0));
     66+ (_WKElementActionType)elementActionTypeForUIActionIdentifier:(UIActionIdentifier)identifier WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(13.0));
    6367
    64 - (void)runActionWithElementInfo:(_WKActivatedElementInfo *)info WK_API_AVAILABLE(ios(9_0));
     68- (void)runActionWithElementInfo:(_WKActivatedElementInfo *)info WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(9.0));
     69
     70- (UIAction *)uiActionForElementInfo:(_WKActivatedElementInfo *)elementInfo WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(13.0));
    6571
    6672@property (nonatomic, readonly) _WKElementActionType type;
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm

    r244941 r246865  
    5151typedef void (^WKElementActionHandlerInternal)(WKActionSheetAssistant *, _WKActivatedElementInfo *);
    5252
     53static UIActionIdentifier const WKElementActionTypeCustomIdentifier = @"WKElementActionTypeCustom";
     54static UIActionIdentifier const WKElementActionTypeOpenIdentifier = @"WKElementActionTypeOpen";
     55static UIActionIdentifier const WKElementActionTypeCopyIdentifier = @"WKElementActionTypeCopy";
     56static UIActionIdentifier const WKElementActionTypeSaveImageIdentifier = @"WKElementActionTypeSaveImage";
     57#if !defined(TARGET_OS_IOS) || TARGET_OS_IOS
     58static UIActionIdentifier const WKElementActionTypeAddToReadingListIdentifier = @"WKElementActionTypeAddToReadingList";
     59static UIActionIdentifier const WKElementActionTypeOpenInDefaultBrowserIdentifier = @"WKElementActionTypeOpenInDefaultBrowser";
     60static UIActionIdentifier const WKElementActionTypeOpenInExternalApplicationIdentifier = @"WKElementActionTypeOpenInExternalApplication";
     61#endif
     62static UIActionIdentifier const WKElementActionTypeShareIdentifier = @"WKElementActionTypeShare";
     63static UIActionIdentifier const WKElementActionTypeOpenInNewTabIdentifier = @"WKElementActionTypeOpenInNewTab";
     64static UIActionIdentifier const WKElementActionTypeOpenInNewWindowIdentifier = @"WKElementActionTypeOpenInNewWindow";
     65static UIActionIdentifier const WKElementActionTypeDownloadIdentifier = @"WKElementActionTypeDownload";
     66
    5367@implementation _WKElementAction  {
    5468    RetainPtr<NSString> _title;
     
    189203#endif
    190204
     205#if USE(UICONTEXTMENU)
     206static UIActionIdentifier elementActionTypeToUIActionIdentifier(_WKElementActionType actionType)
     207{
     208    switch (actionType) {
     209    case _WKElementActionTypeCustom:
     210        return WKElementActionTypeCustomIdentifier;
     211    case _WKElementActionTypeOpen:
     212        return WKElementActionTypeOpenIdentifier;
     213    case _WKElementActionTypeCopy:
     214        return WKElementActionTypeCopyIdentifier;
     215    case _WKElementActionTypeSaveImage:
     216        return WKElementActionTypeSaveImageIdentifier;
     217#if !defined(TARGET_OS_IOS) || TARGET_OS_IOS
     218    case _WKElementActionTypeAddToReadingList:
     219        return WKElementActionTypeAddToReadingListIdentifier;
     220    case _WKElementActionTypeOpenInDefaultBrowser:
     221        return WKElementActionTypeOpenInDefaultBrowserIdentifier;
     222    case _WKElementActionTypeOpenInExternalApplication:
     223        return WKElementActionTypeOpenInExternalApplicationIdentifier;
     224#endif
     225    case _WKElementActionTypeShare:
     226        return WKElementActionTypeShareIdentifier;
     227    case _WKElementActionTypeOpenInNewTab:
     228        return WKElementActionTypeOpenInNewTabIdentifier;
     229    case _WKElementActionTypeOpenInNewWindow:
     230        return WKElementActionTypeOpenInNewWindowIdentifier;
     231    case _WKElementActionTypeDownload:
     232        return WKElementActionTypeDownloadIdentifier;
     233    }
     234}
     235
     236static _WKElementActionType uiActionIdentifierToElementActionType(UIActionIdentifier identifier)
     237{
     238    if ([identifier isEqualToString:WKElementActionTypeCustomIdentifier])
     239        return _WKElementActionTypeCustom;
     240    if ([identifier isEqualToString:WKElementActionTypeOpenIdentifier])
     241        return _WKElementActionTypeOpen;
     242    if ([identifier isEqualToString:WKElementActionTypeCopyIdentifier])
     243        return _WKElementActionTypeCopy;
     244    if ([identifier isEqualToString:WKElementActionTypeSaveImageIdentifier])
     245        return _WKElementActionTypeSaveImage;
     246#if !defined(TARGET_OS_IOS) || TARGET_OS_IOS
     247    if ([identifier isEqualToString:WKElementActionTypeAddToReadingListIdentifier])
     248        return _WKElementActionTypeAddToReadingList;
     249    if ([identifier isEqualToString:WKElementActionTypeOpenInDefaultBrowserIdentifier])
     250        return _WKElementActionTypeOpenInDefaultBrowser;
     251    if ([identifier isEqualToString:WKElementActionTypeOpenInExternalApplicationIdentifier])
     252        return _WKElementActionTypeOpenInExternalApplication;
     253#endif
     254    if ([identifier isEqualToString:WKElementActionTypeShareIdentifier])
     255        return _WKElementActionTypeShare;
     256    if ([identifier isEqualToString:WKElementActionTypeOpenInNewTabIdentifier])
     257        return _WKElementActionTypeOpenInNewTab;
     258    if ([identifier isEqualToString:WKElementActionTypeOpenInNewWindowIdentifier])
     259        return _WKElementActionTypeOpenInNewWindow;
     260    if ([identifier isEqualToString:WKElementActionTypeDownloadIdentifier])
     261        return _WKElementActionTypeDownload;
     262
     263    return _WKElementActionTypeCustom;
     264}
     265
     266+ (_WKElementActionType)elementActionTypeForUIActionIdentifier:(UIActionIdentifier)identifier
     267{
     268    return uiActionIdentifierToElementActionType(identifier);
     269}
     270
     271- (UIAction *)uiActionForElementInfo:(_WKActivatedElementInfo *)elementInfo
     272{
     273    UIImage *image = [_WKElementAction imageForElementActionType:self.type];
     274    UIActionIdentifier identifier = elementActionTypeToUIActionIdentifier(self.type);
     275
     276    return [UIAction actionWithTitle:self.title image:image identifier:identifier handler:[weakSelf = WeakObjCPtr<_WKElementAction>(self), weakElementInfo = WeakObjCPtr<_WKActivatedElementInfo>(elementInfo)] (UIAction *) {
     277        auto strongSelf = weakSelf.get();
     278        if (!strongSelf)
     279            return;
     280        auto strongElementInfo = weakElementInfo.get();
     281        if (!strongElementInfo)
     282            return;
     283        [strongSelf runActionWithElementInfo:strongElementInfo.get()];
     284    }];
     285}
     286#else
     287+ (_WKElementActionType)elementActionTypeForUIActionIdentifier:(UIActionIdentifier)identifier
     288{
     289    return _WKElementActionTypeCustom;
     290}
     291
     292- (UIAction *)uiActionForElementInfo:(_WKActivatedElementInfo *)elementInfo
     293{
     294    return nil;
     295}
     296#endif
     297
    191298@end
    192299
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r246859 r246865  
    75317531
    75327532ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    7533 static NSArray<WKPreviewAction *> *wkPreviewActionsFromElementActions(NSArray<_WKElementAction *> *elementActions, _WKActivatedElementInfo *elementInfo)
     7533static NSArray<WKPreviewAction *> *wkLegacyPreviewActionsFromElementActions(NSArray<_WKElementAction *> *elementActions, _WKActivatedElementInfo *elementInfo)
    75347534{
    75357535    NSMutableArray<WKPreviewAction *> *previewActions = [NSMutableArray arrayWithCapacity:[elementActions count]];
     
    75447544}
    75457545
    7546 static UIAction *uiActionForPreviewAction(UIPreviewAction *previewAction, UIViewController *previewViewController)
     7546static UIAction *uiActionForLegacyPreviewAction(UIPreviewAction *previewAction, UIViewController *previewViewController)
    75477547{
    75487548    // UIPreviewActionItem.image is SPI, so no external clients will be able
     
    75567556ALLOW_DEPRECATED_DECLARATIONS_END
    75577557
    7558 static NSArray<UIMenuElement *> *menuElementsFromPreviewOrDefaults(UIViewController *previewViewController, const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo)
    7559 {
     7558static NSArray<UIMenuElement *> *menuElementsFromLegacyPreview(UIViewController *previewViewController)
     7559{
     7560    if (previewViewController)
     7561        return nil;
     7562
     7563    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
     7564    NSArray<id<UIPreviewActionItem>> *previewActions = previewViewController.previewActionItems;
     7565    if (!previewActions || ![previewActions count])
     7566        return nil;
     7567
     7568    auto actions = [NSMutableArray arrayWithCapacity:previewActions.count];
     7569
     7570    for (UIPreviewAction *previewAction in previewActions)
     7571        [actions addObject:uiActionForLegacyPreviewAction(previewAction, previewViewController)];
     7572    ALLOW_DEPRECATED_DECLARATIONS_END
     7573
     7574    return actions;
     7575}
     7576
     7577static NSArray<UIMenuElement *> *menuElementsFromDefaultActions(const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo)
     7578{
     7579    if (!defaultElementActions || !defaultElementActions.get().count)
     7580        return nil;
     7581
    75607582    auto actions = [NSMutableArray arrayWithCapacity:defaultElementActions.get().count];
    75617583
    7562     // One of the delegates may have provided a UIViewController with a previewActionItems array. If so,
    7563     // we need to convert each UIPreviewActionItem into a UIAction.
    7564     if (previewViewController) {
    7565         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    7566         NSArray<id<UIPreviewActionItem>> *previewActions = previewViewController.previewActionItems;
    7567         for (UIPreviewAction *previewAction in previewActions)
    7568             [actions addObject:uiActionForPreviewAction(previewAction, previewViewController)];
    7569         ALLOW_DEPRECATED_DECLARATIONS_END
    7570     }
    7571 
    7572     if (![actions count]) {
    7573         // We either didn't get a custom preview UIViewController, or it didn't provide any actions
    7574         // so we should use the default set.
    7575         for (_WKElementAction *elementAction in defaultElementActions.get()) {
    7576             UIImage *image = [_WKElementAction imageForElementActionType:elementAction.type];
    7577 
    7578             [actions addObject:[UIAction actionWithTitle:elementAction.title image:image identifier:nil handler:^(UIAction *) {
    7579                 [elementAction runActionWithElementInfo:elementInfo.get()];
    7580             }]];
    7581         }
    7582     }
     7584    for (_WKElementAction *elementAction in defaultElementActions.get())
     7585        [actions addObject:[elementAction uiActionForElementInfo:elementInfo.get()]];
    75837586
    75847587    return actions;
    75857588}
    75867589
    7587 static UIMenu *menuFromPreviewOrDefaults(UIViewController *previewViewController, const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo, NSString *title)
    7588 {
    7589     auto actions = menuElementsFromPreviewOrDefaults(previewViewController, defaultElementActions, elementInfo);
     7590static UIMenu *menuFromLegacyPreviewOrDefaultActions(UIViewController *previewViewController, const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo, NSString *title)
     7591{
     7592    auto actions = menuElementsFromLegacyPreview(previewViewController);
     7593    if (!actions)
     7594        actions = menuElementsFromDefaultActions(defaultElementActions, elementInfo);
     7595
    75907596    return [UIMenu menuWithTitle:title children:actions];
    75917597}
     
    76357641        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    76367642        if ([uiDelegate respondsToSelector:@selector(webView:previewingViewControllerForElement:defaultActions:)]) {
    7637             auto defaultActions = wkPreviewActionsFromElementActions(defaultActionsFromAssistant.get(), elementInfo.get());
     7643            auto defaultActions = wkLegacyPreviewActionsFromElementActions(defaultActionsFromAssistant.get(), elementInfo.get());
    76387644            auto previewElementInfo = adoptNS([[WKPreviewElementInfo alloc] _initWithLinkURL:url]);
    76397645            previewViewController = [uiDelegate webView:_webView previewingViewControllerForElement:previewElementInfo.get() defaultActions:defaultActions];
     
    76567662                    _contextMenuLegacyPreviewController = dataDetectorsResult.get().previewProvider();
    76577663                if (dataDetectorsResult && dataDetectorsResult.get().actionProvider) {
    7658                     auto menuElements = menuElementsFromPreviewOrDefaults(nil, defaultActionsFromAssistant, elementInfo);
     7664                    auto menuElements = menuElementsFromDefaultActions(defaultActionsFromAssistant, elementInfo);
    76597665                    _contextMenuLegacyMenu = dataDetectorsResult.get().actionProvider(menuElements);
    76607666                }
     
    76667672
    76677673        auto menuTitle = titleForMenu(true, _showLinkPreviews, url, _positionInformation.title);
    7668         _contextMenuLegacyMenu = menuFromPreviewOrDefaults(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle);
     7674        _contextMenuLegacyMenu = menuFromLegacyPreviewOrDefaultActions(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle);
    76697675
    76707676    } else if (_positionInformation.isImage) {
     
    76947700
    76957701        auto menuTitle = titleForMenu(false, _showLinkPreviews, url, _positionInformation.title);
    7696         _contextMenuLegacyMenu = menuFromPreviewOrDefaults(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle);
     7702        _contextMenuLegacyMenu = menuFromLegacyPreviewOrDefaultActions(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle);
    76977703    }
    76987704
     
    78407846            RetainPtr<NSArray<_WKElementAction *>> defaultActionsFromAssistant = strongSelf->_positionInformation.isLink ? [strongSelf->_actionSheetAssistant defaultActionsForLinkSheet:elementInfo.get()] : [strongSelf->_actionSheetAssistant defaultActionsForImageSheet:elementInfo.get()];
    78417847
    7842             auto menuElements = menuElementsFromPreviewOrDefaults(nil, defaultActionsFromAssistant, elementInfo);
     7848            auto menuElements = menuElementsFromDefaultActions(defaultActionsFromAssistant, elementInfo);
    78437849
    78447850            if (actionProviderFromUIDelegate)
Note: See TracChangeset for help on using the changeset viewer.