WebKit Bugzilla
Attachment 372976 Details for
Bug 199246
: Expose UIAction identifiers for _WKElementActions
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-199246-20190627104234.patch (text/plain), 19.36 KB, created by
Dean Jackson
on 2019-06-26 17:42:35 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Dean Jackson
Created:
2019-06-26 17:42:35 PDT
Size:
19.36 KB
patch
obsolete
>Subversion Revision: 246800 >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 7851cddbff8e5e4187d7e0d0db5e621d206b86a4..490e67199fd73fe1b6de47162f9c6211a043bf5f 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,40 @@ >+2019-06-26 Dean Jackson <dino@apple.com> >+ >+ Expose UIAction identifiers for _WKElementActions >+ https://bugs.webkit.org/show_bug.cgi?id=199246 >+ <rdar://problem/52218950> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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. >+ >+ > 2019-06-25 Wenson Hsieh <wenson_hsieh@apple.com> > > [iOS] Occasional crash under -[UIPreviewTarget initWithContainer:center:transform:] when generating a drag preview >diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.h b/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.h >index 454dc6a13a26e5ac18bad2984ae09783de86d51c..9d0ab462ce399eaab5fe3e9e54d172f3f84b00fd 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.h >+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.h >@@ -30,8 +30,11 @@ > #import <WebKit/WKBase.h> > #import <WebKit/_WKActivatedElementInfo.h> > >+@class UIAction; > @class UIImage; > >+typedef NSString *UIActionIdentifier; >+ > typedef void (^WKElementActionHandler)(_WKActivatedElementInfo *); > typedef BOOL (^WKElementActionDismissalHandler)(void); > >@@ -42,8 +45,8 @@ typedef NS_ENUM(NSInteger, _WKElementActionType) { > _WKElementActionTypeSaveImage, > #if !defined(TARGET_OS_IOS) || TARGET_OS_IOS > _WKElementActionTypeAddToReadingList, >- _WKElementActionTypeOpenInDefaultBrowser WK_API_AVAILABLE(ios(9_0)), >- _WKElementActionTypeOpenInExternalApplication WK_API_AVAILABLE(ios(9_0)), >+ _WKElementActionTypeOpenInDefaultBrowser WK_API_AVAILABLE(ios(9.0)), >+ _WKElementActionTypeOpenInExternalApplication WK_API_AVAILABLE(ios(9.0)), > #endif > _WKElementActionTypeShare WK_API_AVAILABLE(macos(10.12), ios(10.0)), > _WKElementActionTypeOpenInNewTab WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)), >@@ -59,9 +62,12 @@ WK_CLASS_AVAILABLE(macos(10.10), ios(8.0)) > + (instancetype)elementActionWithType:(_WKElementActionType)type customTitle:(NSString *)title; > + (instancetype)elementActionWithTitle:(NSString *)title actionHandler:(WKElementActionHandler)handler; > >-+ (UIImage *)imageForElementActionType:(_WKElementActionType)actionType WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); >++ (UIImage *)imageForElementActionType:(_WKElementActionType)actionType WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(13.0)); >++ (_WKElementActionType)elementActionTypeForUIActionIdentifier:(UIActionIdentifier)identifier WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(13.0)); >+ >+- (void)runActionWithElementInfo:(_WKActivatedElementInfo *)info WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(9.0)); > >-- (void)runActionWithElementInfo:(_WKActivatedElementInfo *)info WK_API_AVAILABLE(ios(9_0)); >+- (UIAction *)uiActionForElementInfo:(_WKActivatedElementInfo *)elementInfo WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(13.0)); > > @property (nonatomic, readonly) _WKElementActionType type; > @property (nonatomic, readonly) NSString* title; >diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm >index c44493f930bcd0e75e3f29a7d029d0239b285596..5cc2adcf3bdca84a34f7348ae4eb63dc6d8cc1b2 100644 >--- a/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm >+++ b/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm >@@ -50,6 +50,20 @@ SOFT_LINK_CLASS(SafariServices, SSReadingList); > > typedef void (^WKElementActionHandlerInternal)(WKActionSheetAssistant *, _WKActivatedElementInfo *); > >+static UIActionIdentifier const WKElementActionTypeCustomIdentifier = @"WKElementActionTypeCustom"; >+static UIActionIdentifier const WKElementActionTypeOpenIdentifier = @"WKElementActionTypeOpen"; >+static UIActionIdentifier const WKElementActionTypeCopyIdentifier = @"WKElementActionTypeCopy"; >+static UIActionIdentifier const WKElementActionTypeSaveImageIdentifier = @"WKElementActionTypeSaveImage"; >+#if !defined(TARGET_OS_IOS) || TARGET_OS_IOS >+static UIActionIdentifier const WKElementActionTypeAddToReadingListIdentifier = @"WKElementActionTypeAddToReadingList"; >+static UIActionIdentifier const WKElementActionTypeOpenInDefaultBrowserIdentifier = @"WKElementActionTypeOpenInDefaultBrowser"; >+static UIActionIdentifier const WKElementActionTypeOpenInExternalApplicationIdentifier = @"WKElementActionTypeOpenInExternalApplication"; >+#endif >+static UIActionIdentifier const WKElementActionTypeShareIdentifier = @"WKElementActionTypeShare"; >+static UIActionIdentifier const WKElementActionTypeOpenInNewTabIdentifier = @"WKElementActionTypeOpenInNewTab"; >+static UIActionIdentifier const WKElementActionTypeOpenInNewWindowIdentifier = @"WKElementActionTypeOpenInNewWindow"; >+static UIActionIdentifier const WKElementActionTypeDownloadIdentifier = @"WKElementActionTypeDownload"; >+ > @implementation _WKElementAction { > RetainPtr<NSString> _title; > WKElementActionHandlerInternal _actionHandler; >@@ -188,6 +202,99 @@ static void addToReadingList(NSURL *targetURL, NSString *title) > } > #endif > >+#if USE(UICONTEXTMENU) >+static UIActionIdentifier elementActionTypeToUIActionIdentifier(_WKElementActionType actionType) >+{ >+ switch (actionType) { >+ case _WKElementActionTypeCustom: >+ return WKElementActionTypeCustomIdentifier; >+ case _WKElementActionTypeOpen: >+ return WKElementActionTypeOpenIdentifier; >+ case _WKElementActionTypeCopy: >+ return WKElementActionTypeCopyIdentifier; >+ case _WKElementActionTypeSaveImage: >+ return WKElementActionTypeSaveImageIdentifier; >+#if !defined(TARGET_OS_IOS) || TARGET_OS_IOS >+ case _WKElementActionTypeAddToReadingList: >+ return WKElementActionTypeAddToReadingListIdentifier; >+ case _WKElementActionTypeOpenInDefaultBrowser: >+ return WKElementActionTypeOpenInDefaultBrowserIdentifier; >+ case _WKElementActionTypeOpenInExternalApplication: >+ return WKElementActionTypeOpenInExternalApplicationIdentifier; >+#endif >+ case _WKElementActionTypeShare: >+ return WKElementActionTypeShareIdentifier; >+ case _WKElementActionTypeOpenInNewTab: >+ return WKElementActionTypeOpenInNewTabIdentifier; >+ case _WKElementActionTypeOpenInNewWindow: >+ return WKElementActionTypeOpenInNewWindowIdentifier; >+ case _WKElementActionTypeDownload: >+ return WKElementActionTypeDownloadIdentifier; >+ } >+} >+ >+static _WKElementActionType uiActionIdentifierToElementActionType(UIActionIdentifier identifier) >+{ >+ if ([identifier isEqualToString:WKElementActionTypeCustomIdentifier]) >+ return _WKElementActionTypeCustom; >+ if ([identifier isEqualToString:WKElementActionTypeOpenIdentifier]) >+ return _WKElementActionTypeOpen; >+ if ([identifier isEqualToString:WKElementActionTypeCopyIdentifier]) >+ return _WKElementActionTypeCopy; >+ if ([identifier isEqualToString:WKElementActionTypeSaveImageIdentifier]) >+ return _WKElementActionTypeSaveImage; >+#if !defined(TARGET_OS_IOS) || TARGET_OS_IOS >+ if ([identifier isEqualToString:WKElementActionTypeAddToReadingListIdentifier]) >+ return _WKElementActionTypeAddToReadingList; >+ if ([identifier isEqualToString:WKElementActionTypeOpenInDefaultBrowserIdentifier]) >+ return _WKElementActionTypeOpenInDefaultBrowser; >+ if ([identifier isEqualToString:WKElementActionTypeOpenInExternalApplicationIdentifier]) >+ return _WKElementActionTypeOpenInExternalApplication; >+#endif >+ if ([identifier isEqualToString:WKElementActionTypeShareIdentifier]) >+ return _WKElementActionTypeShare; >+ if ([identifier isEqualToString:WKElementActionTypeOpenInNewTabIdentifier]) >+ return _WKElementActionTypeOpenInNewTab; >+ if ([identifier isEqualToString:WKElementActionTypeOpenInNewWindowIdentifier]) >+ return _WKElementActionTypeOpenInNewWindow; >+ if ([identifier isEqualToString:WKElementActionTypeDownloadIdentifier]) >+ return _WKElementActionTypeDownload; >+ >+ return _WKElementActionTypeCustom; >+} >+ >++ (_WKElementActionType)elementActionTypeForUIActionIdentifier:(UIActionIdentifier)identifier >+{ >+ return uiActionIdentifierToElementActionType(identifier); >+} >+ >+- (UIAction *)uiActionForElementInfo:(_WKActivatedElementInfo *)elementInfo >+{ >+ UIImage *image = [_WKElementAction imageForElementActionType:self.type]; >+ UIActionIdentifier identifier = elementActionTypeToUIActionIdentifier(self.type); >+ >+ return [UIAction actionWithTitle:self.title image:image identifier:identifier handler:[weakSelf = WeakObjCPtr<_WKElementAction>(self), weakElementInfo = WeakObjCPtr<_WKActivatedElementInfo>(elementInfo)] (UIAction *) { >+ auto strongSelf = weakSelf.get(); >+ if (!strongSelf) >+ return; >+ auto strongElementInfo = weakElementInfo.get(); >+ if (!strongElementInfo) >+ return; >+ [strongSelf runActionWithElementInfo:strongElementInfo.get()]; >+ }]; >+} >+#else >++ (_WKElementActionType)elementActionTypeForUIActionIdentifier:(UIActionIdentifier)identifier >+{ >+ return _WKElementActionTypeCustom; >+} >+ >+- (UIAction *)uiActionForElementInfo:(_WKActivatedElementInfo *)elementInfo >+{ >+ return nil; >+} >+#endif >+ > @end > > #endif // PLATFORM(IOS_FAMILY) >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >index 4d42f0b01eaa1e15e64ad49ac41a7d8d5702c6e9..b5d0b6639db59be92642414886ae38cd01a10111 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >@@ -7528,7 +7528,7 @@ static bool needsDeprecatedPreviewAPI(id<WKUIDelegate> delegate) > } > > ALLOW_DEPRECATED_DECLARATIONS_BEGIN >-static NSArray<WKPreviewAction *> *wkPreviewActionsFromElementActions(NSArray<_WKElementAction *> *elementActions, _WKActivatedElementInfo *elementInfo) >+static NSArray<WKPreviewAction *> *wkLegacyPreviewActionsFromElementActions(NSArray<_WKElementAction *> *elementActions, _WKActivatedElementInfo *elementInfo) > { > NSMutableArray<WKPreviewAction *> *previewActions = [NSMutableArray arrayWithCapacity:[elementActions count]]; > for (_WKElementAction *elementAction in elementActions) { >@@ -7541,7 +7541,7 @@ static NSArray<WKPreviewAction *> *wkPreviewActionsFromElementActions(NSArray<_W > return previewActions; > } > >-static UIAction *uiActionForPreviewAction(UIPreviewAction *previewAction, UIViewController *previewViewController) >+static UIAction *uiActionForLegacyPreviewAction(UIPreviewAction *previewAction, UIViewController *previewViewController) > { > // UIPreviewActionItem.image is SPI, so no external clients will be able > // to provide glyphs for actions <rdar://problem/50151855>. >@@ -7553,38 +7553,44 @@ static UIAction *uiActionForPreviewAction(UIPreviewAction *previewAction, UIView > } > ALLOW_DEPRECATED_DECLARATIONS_END > >-static NSArray<UIMenuElement *> *menuElementsFromPreviewOrDefaults(UIViewController *previewViewController, const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo) >+static NSArray<UIMenuElement *> *menuElementsFromLegacyPreview(UIViewController *previewViewController) > { >- auto actions = [NSMutableArray arrayWithCapacity:defaultElementActions.get().count]; >+ if (previewViewController) >+ return nil; > >- // One of the delegates may have provided a UIViewController with a previewActionItems array. If so, >- // we need to convert each UIPreviewActionItem into a UIAction. >- if (previewViewController) { >- ALLOW_DEPRECATED_DECLARATIONS_BEGIN >- NSArray<id<UIPreviewActionItem>> *previewActions = previewViewController.previewActionItems; >- for (UIPreviewAction *previewAction in previewActions) >- [actions addObject:uiActionForPreviewAction(previewAction, previewViewController)]; >- ALLOW_DEPRECATED_DECLARATIONS_END >- } >+ ALLOW_DEPRECATED_DECLARATIONS_BEGIN >+ NSArray<id<UIPreviewActionItem>> *previewActions = previewViewController.previewActionItems; >+ if (!previewActions || ![previewActions count]) >+ return nil; > >- if (![actions count]) { >- // We either didn't get a custom preview UIViewController, or it didn't provide any actions >- // so we should use the default set. >- for (_WKElementAction *elementAction in defaultElementActions.get()) { >- UIImage *image = [_WKElementAction imageForElementActionType:elementAction.type]; >+ auto actions = [NSMutableArray arrayWithCapacity:previewActions.count]; > >- [actions addObject:[UIAction actionWithTitle:elementAction.title image:image identifier:nil handler:^(UIAction *) { >- [elementAction runActionWithElementInfo:elementInfo.get()]; >- }]]; >- } >- } >+ for (UIPreviewAction *previewAction in previewActions) >+ [actions addObject:uiActionForLegacyPreviewAction(previewAction, previewViewController)]; >+ ALLOW_DEPRECATED_DECLARATIONS_END > > return actions; > } > >-static UIMenu *menuFromPreviewOrDefaults(UIViewController *previewViewController, const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo, NSString *title) >+static NSArray<UIMenuElement *> *menuElementsFromDefaultActions(const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo) > { >- auto actions = menuElementsFromPreviewOrDefaults(previewViewController, defaultElementActions, elementInfo); >+ if (!defaultElementActions || !defaultElementActions.get().count) >+ return nil; >+ >+ auto actions = [NSMutableArray arrayWithCapacity:defaultElementActions.get().count]; >+ >+ for (_WKElementAction *elementAction in defaultElementActions.get()) >+ [actions addObject:[elementAction uiActionForElementInfo:elementInfo.get()]]; >+ >+ return actions; >+} >+ >+static UIMenu *menuFromLegacyPreviewOrDefaultActions(UIViewController *previewViewController, const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo, NSString *title) >+{ >+ auto actions = menuElementsFromLegacyPreview(previewViewController); >+ if (!actions) >+ actions = menuElementsFromDefaultActions(defaultElementActions, elementInfo); >+ > return [UIMenu menuWithTitle:title children:actions]; > } > >@@ -7632,7 +7638,7 @@ static NSString *titleForMenu(bool isLink, bool showLinkPreviews, const URL& url > > ALLOW_DEPRECATED_DECLARATIONS_BEGIN > if ([uiDelegate respondsToSelector:@selector(webView:previewingViewControllerForElement:defaultActions:)]) { >- auto defaultActions = wkPreviewActionsFromElementActions(defaultActionsFromAssistant.get(), elementInfo.get()); >+ auto defaultActions = wkLegacyPreviewActionsFromElementActions(defaultActionsFromAssistant.get(), elementInfo.get()); > auto previewElementInfo = adoptNS([[WKPreviewElementInfo alloc] _initWithLinkURL:url]); > previewViewController = [uiDelegate webView:_webView previewingViewControllerForElement:previewElementInfo.get() defaultActions:defaultActions]; > } else if ([uiDelegate respondsToSelector:@selector(_webView:previewViewControllerForURL:defaultActions:elementInfo:)]) >@@ -7653,7 +7659,7 @@ static NSString *titleForMenu(bool isLink, bool showLinkPreviews, const URL& url > if (_showLinkPreviews && dataDetectorsResult && dataDetectorsResult.get().previewProvider) > _contextMenuLegacyPreviewController = dataDetectorsResult.get().previewProvider(); > if (dataDetectorsResult && dataDetectorsResult.get().actionProvider) { >- auto menuElements = menuElementsFromPreviewOrDefaults(nil, defaultActionsFromAssistant, elementInfo); >+ auto menuElements = menuElementsFromDefaultActions(defaultActionsFromAssistant, elementInfo); > _contextMenuLegacyMenu = dataDetectorsResult.get().actionProvider(menuElements); > } > END_BLOCK_OBJC_EXCEPTIONS; >@@ -7663,7 +7669,7 @@ static NSString *titleForMenu(bool isLink, bool showLinkPreviews, const URL& url > #endif > > auto menuTitle = titleForMenu(true, _showLinkPreviews, url, _positionInformation.title); >- _contextMenuLegacyMenu = menuFromPreviewOrDefaults(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle); >+ _contextMenuLegacyMenu = menuFromLegacyPreviewOrDefaultActions(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle); > > } else if (_positionInformation.isImage) { > NSURL *nsURL = (NSURL *)url; >@@ -7691,7 +7697,7 @@ static NSString *titleForMenu(bool isLink, bool showLinkPreviews, const URL& url > ALLOW_DEPRECATED_DECLARATIONS_END > > auto menuTitle = titleForMenu(false, _showLinkPreviews, url, _positionInformation.title); >- _contextMenuLegacyMenu = menuFromPreviewOrDefaults(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle); >+ _contextMenuLegacyMenu = menuFromLegacyPreviewOrDefaultActions(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle); > } > > _contextMenuLegacyPreviewController = _showLinkPreviews ? previewViewController : nullptr; >@@ -7837,7 +7843,7 @@ static NSString *titleForMenu(bool isLink, bool showLinkPreviews, const URL& url > auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithInteractionInformationAtPosition:strongSelf->_positionInformation]); > RetainPtr<NSArray<_WKElementAction *>> defaultActionsFromAssistant = strongSelf->_positionInformation.isLink ? [strongSelf->_actionSheetAssistant defaultActionsForLinkSheet:elementInfo.get()] : [strongSelf->_actionSheetAssistant defaultActionsForImageSheet:elementInfo.get()]; > >- auto menuElements = menuElementsFromPreviewOrDefaults(nil, defaultActionsFromAssistant, elementInfo); >+ auto menuElements = menuElementsFromDefaultActions(defaultActionsFromAssistant, elementInfo); > > if (actionProviderFromUIDelegate) > return actionProviderFromUIDelegate(menuElements);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 199246
:
372971
| 372976