Title: [247652] trunk/Source
Revision
247652
Author
[email protected]
Date
2019-07-19 14:17:50 -0700 (Fri, 19 Jul 2019)

Log Message

Add a menu item to toggle between showing and hiding link previews
https://bugs.webkit.org/show_bug.cgi?id=199940
<rdar://problem/53032288>

Reviewed by Beth Dakin.

Source/WebCore:

New strings for Show/Hide Link Previews.

* en.lproj/Localizable.strings:

Source/WebKit:

Add a new _WKElementAction that toggles the display of link previews
in context menus, and add it to the default set of actions we provide
for links.

When a UIAction is created from this new _WKElementAction type,
it can be identified by WKElementActionTypeToggleShowLinkPreviewsIdentifier.
This allows us to check a UIMenu provided by a delegate to make sure
that they have provided the toggle menu item. If they haven't, we add it
back.

The preference for showing links is moved from kCFPreferencesAnyApplication
to standard user defaults, so that it can be set no matter what the
hosting application is.

* UIProcess/API/Cocoa/_WKElementAction.h: New action type.
* UIProcess/API/Cocoa/_WKElementAction.mm:
(+[_WKElementAction _elementActionWithType:customTitle:assistant:]):
(+[_WKElementAction imageForElementActionType:]): Use eye.fill for now.
I'll need to check with HI to see if there is a more appropriate glyph.
(elementActionTypeToUIActionIdentifier):
(uiActionIdentifierToElementActionType):

* UIProcess/ios/WKActionSheetAssistant.mm: Add the toggle action to
the default set.
(-[WKActionSheetAssistant defaultActionsForLinkSheet:]):

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _registerPreview]): No need to listen for CFPreferences
notifications any more.
(-[WKContentView _unregisterPreview]):
(menuWithShowLinkPreviewAction): New method that adds the UIAction
for toggling previews to a UIMenu if necessary.
(-[WKContentView assignLegacyDataForContextMenuInteraction]):
(-[WKContentView _contextMenuInteraction:configurationForMenuAtLocation:completion:]):
(-[WKContentView _showLinkPreviewsPreferenceChanged:]): Deleted.
(titleForMenu): Deleted. URL text previews will be provided separately.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (247651 => 247652)


--- trunk/Source/WebCore/ChangeLog	2019-07-19 19:55:20 UTC (rev 247651)
+++ trunk/Source/WebCore/ChangeLog	2019-07-19 21:17:50 UTC (rev 247652)
@@ -1,3 +1,15 @@
+2019-07-19  Dean Jackson  <[email protected]>
+
+        Add a menu item to toggle between showing and hiding link previews
+        https://bugs.webkit.org/show_bug.cgi?id=199940
+        <rdar://problem/53032288>
+
+        Reviewed by Beth Dakin.
+
+        New strings for Show/Hide Link Previews.
+
+        * en.lproj/Localizable.strings:
+
 2019-07-19  Antoine Quint  <[email protected]>
 
         Links stop working after long-pressing a link (WK1)

Modified: trunk/Source/WebCore/en.lproj/Localizable.strings (247651 => 247652)


--- trunk/Source/WebCore/en.lproj/Localizable.strings	2019-07-19 19:55:20 UTC (rev 247651)
+++ trunk/Source/WebCore/en.lproj/Localizable.strings	2019-07-19 21:17:50 UTC (rev 247652)
@@ -373,6 +373,9 @@
 /* Hide Media Controls context menu item */
 "Hide Controls" = "Hide Controls";
 
+/* Title for Hide Link Previews action button */
+"Hide Link Previews" = "Hide Link Previews";
+
 /* menu item title */
 "Hide Spelling and Grammar" = "Hide Spelling and Grammar";
 
@@ -697,6 +700,9 @@
 /* Show fonts context menu item */
 "Show Fonts" = "Show Fonts";
 
+/* Title for Show Link Previews action button */
+"Show Link Previews" = "Show Link Previews";
+
 /* menu item title */
 "Show Spelling and Grammar" = "Show Spelling and Grammar";
 

Modified: trunk/Source/WebKit/ChangeLog (247651 => 247652)


--- trunk/Source/WebKit/ChangeLog	2019-07-19 19:55:20 UTC (rev 247651)
+++ trunk/Source/WebKit/ChangeLog	2019-07-19 21:17:50 UTC (rev 247652)
@@ -1,3 +1,48 @@
+2019-07-19  Dean Jackson  <[email protected]>
+
+        Add a menu item to toggle between showing and hiding link previews
+        https://bugs.webkit.org/show_bug.cgi?id=199940
+        <rdar://problem/53032288>
+
+        Reviewed by Beth Dakin.
+
+        Add a new _WKElementAction that toggles the display of link previews
+        in context menus, and add it to the default set of actions we provide
+        for links.
+
+        When a UIAction is created from this new _WKElementAction type,
+        it can be identified by WKElementActionTypeToggleShowLinkPreviewsIdentifier.
+        This allows us to check a UIMenu provided by a delegate to make sure
+        that they have provided the toggle menu item. If they haven't, we add it
+        back.
+
+        The preference for showing links is moved from kCFPreferencesAnyApplication
+        to standard user defaults, so that it can be set no matter what the
+        hosting application is.
+
+        * UIProcess/API/Cocoa/_WKElementAction.h: New action type.
+        * UIProcess/API/Cocoa/_WKElementAction.mm: 
+        (+[_WKElementAction _elementActionWithType:customTitle:assistant:]):
+        (+[_WKElementAction imageForElementActionType:]): Use eye.fill for now.
+        I'll need to check with HI to see if there is a more appropriate glyph.
+        (elementActionTypeToUIActionIdentifier):
+        (uiActionIdentifierToElementActionType):
+
+        * UIProcess/ios/WKActionSheetAssistant.mm: Add the toggle action to
+        the default set.
+        (-[WKActionSheetAssistant defaultActionsForLinkSheet:]):
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _registerPreview]): No need to listen for CFPreferences
+        notifications any more.
+        (-[WKContentView _unregisterPreview]):
+        (menuWithShowLinkPreviewAction): New method that adds the UIAction
+        for toggling previews to a UIMenu if necessary.
+        (-[WKContentView assignLegacyDataForContextMenuInteraction]):
+        (-[WKContentView _contextMenuInteraction:configurationForMenuAtLocation:completion:]):
+        (-[WKContentView _showLinkPreviewsPreferenceChanged:]): Deleted.
+        (titleForMenu): Deleted. URL text previews will be provided separately.
+
 2019-07-19  Wenson Hsieh  <[email protected]>
 
         [iOS] Entering 2FA code on idmsa.apple.com causes unexpected scrolling

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.h (247651 => 247652)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.h	2019-07-19 19:55:20 UTC (rev 247651)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.h	2019-07-19 21:17:50 UTC (rev 247652)
@@ -34,6 +34,7 @@
 @class UIImage;
 
 typedef NSString *UIActionIdentifier;
+WK_EXPORT extern UIActionIdentifier const WKElementActionTypeToggleShowLinkPreviewsIdentifier;
 
 typedef void (^WKElementActionHandler)(_WKActivatedElementInfo *);
 typedef BOOL (^WKElementActionDismissalHandler)(void);
@@ -52,6 +53,7 @@
     _WKElementActionTypeOpenInNewTab WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)),
     _WKElementActionTypeOpenInNewWindow WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)),
     _WKElementActionTypeDownload WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)),
+    _WKElementActionToggleShowLinkPreviews WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)),
 } WK_API_AVAILABLE(macos(10.10), ios(8.0));
 
 WK_CLASS_AVAILABLE(macos(10.10), ios(8.0))
@@ -64,6 +66,7 @@
 
 + (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));
+- (UIAction *)uiActionForElementInfo:(_WKActivatedElementInfo *)elementInfo;
 
 - (void)runActionWithElementInfo:(_WKActivatedElementInfo *)info WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(9.0));
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm (247651 => 247652)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm	2019-07-19 19:55:20 UTC (rev 247651)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm	2019-07-19 21:17:50 UTC (rev 247652)
@@ -60,7 +60,11 @@
 static UIActionIdentifier const WKElementActionTypeOpenInNewTabIdentifier = @"WKElementActionTypeOpenInNewTab";
 static UIActionIdentifier const WKElementActionTypeOpenInNewWindowIdentifier = @"WKElementActionTypeOpenInNewWindow";
 static UIActionIdentifier const WKElementActionTypeDownloadIdentifier = @"WKElementActionTypeDownload";
+UIActionIdentifier const WKElementActionTypeToggleShowLinkPreviewsIdentifier = @"WKElementActionTypeToggleShowLinkPreviews";
 
+static NSString * const webkitShowLinkPreviewsPreferenceKey = @"WebKitShowLinkPreviews";
+static NSString * const webkitShowLinkPreviewsPreferenceChangedNotification = @"WebKitShowLinkPreviewsPreferenceChanged";
+
 @implementation _WKElementAction  {
     RetainPtr<NSString> _title;
     WKElementActionHandlerInternal _actionHandler;
@@ -160,6 +164,17 @@
             [assistant.delegate actionSheetAssistant:assistant shareElementWithURL:actionInfo.URL ?: actionInfo.imageURL rect:actionInfo.boundingRect];
         };
         break;
+    case _WKElementActionToggleShowLinkPreviews: {
+        bool showingLinkPreviews = true;
+        if (NSNumber *value = [[NSUserDefaults standardUserDefaults] objectForKey:webkitShowLinkPreviewsPreferenceKey])
+            showingLinkPreviews = value.boolValue;
+
+        title = showingLinkPreviews ? WEB_UI_STRING("Hide Link Previews", "Title for Hide Link Previews action button") : WEB_UI_STRING("Show Link Previews", "Title for Show Link Previews action button");
+        handler = ^(WKActionSheetAssistant *, _WKActivatedElementInfo *) {
+            [[NSUserDefaults standardUserDefaults] setBool:!showingLinkPreviews forKey:webkitShowLinkPreviewsPreferenceKey];
+        };
+        break;
+    }
     default:
         [NSException raise:NSInvalidArgumentException format:@"There is no standard web element action of type %ld.", (long)type];
         return nil;
@@ -224,6 +239,8 @@
         return [UIImage systemImageNamed:@"square.grid.2x2"];
     case _WKElementActionTypeDownload:
         return [UIImage systemImageNamed:@"arrow.down.circle"];
+    case _WKElementActionToggleShowLinkPreviews:
+        return [UIImage systemImageNamed:@"eye.fill"];
     }
 }
 
@@ -252,6 +269,8 @@
         return WKElementActionTypeOpenInNewWindowIdentifier;
     case _WKElementActionTypeDownload:
         return WKElementActionTypeDownloadIdentifier;
+    case _WKElementActionToggleShowLinkPreviews:
+        return WKElementActionTypeToggleShowLinkPreviewsIdentifier;
     }
 }
 
@@ -279,6 +298,8 @@
         return _WKElementActionTypeOpenInNewWindow;
     if ([identifier isEqualToString:WKElementActionTypeDownloadIdentifier])
         return _WKElementActionTypeDownload;
+    if ([identifier isEqualToString:WKElementActionTypeToggleShowLinkPreviewsIdentifier])
+        return _WKElementActionToggleShowLinkPreviews;
 
     return _WKElementActionTypeCustom;
 }

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementActionInternal.h (247651 => 247652)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementActionInternal.h	2019-07-19 19:55:20 UTC (rev 247651)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKElementActionInternal.h	2019-07-19 21:17:50 UTC (rev 247652)
@@ -36,8 +36,6 @@
 + (instancetype)_elementActionWithType:(_WKElementActionType)type title:(NSString *)title actionHandler:(WKElementActionHandler)actionHandler;
 - (void)_runActionWithElementInfo:(_WKActivatedElementInfo *)info forActionSheetAssistant:(WKActionSheetAssistant *)assistant;
 
-- (UIAction *)uiActionForElementInfo:(_WKActivatedElementInfo *)elementInfo;
-
 @end
 
 #endif // PLATFORM(IOS_FAMILY)

Modified: trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm (247651 => 247652)


--- trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm	2019-07-19 19:55:20 UTC (rev 247651)
+++ trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm	2019-07-19 21:17:50 UTC (rev 247652)
@@ -558,6 +558,8 @@
         [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeShare assistant:self]];
     }
 
+    [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionToggleShowLinkPreviews assistant:self]];
+
     return defaultActions;
 }
 

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (247651 => 247652)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-07-19 19:55:20 UTC (rev 247651)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-07-19 21:17:50 UTC (rev 247652)
@@ -158,7 +158,6 @@
 
 #if HAVE(LINK_PREVIEW) && USE(UICONTEXTMENU)
 static NSString * const webkitShowLinkPreviewsPreferenceKey = @"WebKitShowLinkPreviews";
-static NSString * const webkitShowLinkPreviewsPreferenceChangedNotification = @"WebKitShowLinkPreviewsPreferenceChanged";
 #endif
 
 #if PLATFORM(WATCHOS)
@@ -7581,11 +7580,6 @@
             [previewClickInteraction setDriver:driver];
             [driver setDelegate:(id<_UIClickInteractionDriverDelegate>)previewClickInteraction];
         }
-
-        [self _showLinkPreviewsPreferenceChanged:nil];
-
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_showLinkPreviewsPreferenceChanged:) name:webkitShowLinkPreviewsPreferenceChangedNotification object:nil];
-
         return;
     }
 #endif
@@ -7606,8 +7600,6 @@
 
         [self removeInteraction:_contextMenuInteraction.get()];
         _contextMenuInteraction = nil;
-
-        [[NSNotificationCenter defaultCenter] removeObserver:self name:webkitShowLinkPreviewsPreferenceChangedNotification object:nil];
         return;
     }
 #endif
@@ -7620,16 +7612,6 @@
 
 #if USE(UICONTEXTMENU)
 
-- (void)_showLinkPreviewsPreferenceChanged:(NSNotification *)notification
-{
-    Boolean keyExistsAndHasValidFormat = false;
-    Boolean prefValue = CFPreferencesGetAppBooleanValue((__bridge CFStringRef)webkitShowLinkPreviewsPreferenceKey, kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat);
-    if (keyExistsAndHasValidFormat)
-        _showLinkPreviews = prefValue;
-    else
-        _showLinkPreviews = YES;
-}
-
 static bool needsDeprecatedPreviewAPI(id<WKUIDelegate> delegate)
 {
     // FIXME: Replace these with booleans in UIDelegate.h.
@@ -7708,7 +7690,7 @@
     return actions;
 }
 
-static UIMenu *menuFromLegacyPreviewOrDefaultActions(UIViewController *previewViewController, const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo, NSString *title)
+static UIMenu *menuFromLegacyPreviewOrDefaultActions(UIViewController *previewViewController, const RetainPtr<NSArray>& defaultElementActions, RetainPtr<_WKActivatedElementInfo> elementInfo, NSString *title = nil)
 {
     auto actions = menuElementsFromLegacyPreview(previewViewController);
     if (!actions)
@@ -7717,18 +7699,30 @@
     return [UIMenu menuWithTitle:title children:actions];
 }
 
-static NSString *titleForMenu(bool isLink, bool showLinkPreviews, const URL& url, const String& title)
+static UIMenu *menuWithShowLinkPreviewAction(UIMenu *originalMenu)
 {
-    if (isLink && !showLinkPreviews) {
-        if (!url.isEmpty()) {
-            if (WTF::protocolIsJavaScript(url))
-                return WEB_UI_STRING_KEY("_javascript_", "_javascript_ Action Sheet Title", "Title for action sheet for _javascript_ link");
-            return WTF::userVisibleString(url);
+    if (!originalMenu)
+        return nil;
+
+    // Look for a UIAction that has the WKElementActionTypeToggleShowLinkPreviewsIdentifier.
+    NSUInteger result = [originalMenu.children indexOfObjectPassingTest:^BOOL(UIMenuElement *element, NSUInteger index, BOOL *stop) {
+        if (![element isKindOfClass:[UIAction class]])
+            return NO;
+        if ([(UIAction *)element identifier] == WKElementActionTypeToggleShowLinkPreviewsIdentifier) {
+            *stop = YES;
+            return YES;
         }
-    } else if (!isLink && !title.isEmpty())
-        return title;
+        return NO;
+    }];
+    if (result != NSNotFound)
+        return originalMenu;
 
-    return nil;
+    // We didn't find one, so make a new UIMenu with the toggle action.
+    NSMutableArray<UIMenuElement *> *menuElements = [NSMutableArray arrayWithCapacity:(originalMenu.children.count + 1)];
+    [menuElements addObjectsFromArray:originalMenu.children];
+    _WKElementAction *toggleAction = [_WKElementAction elementActionWithType:_WKElementActionToggleShowLinkPreviews];
+    [menuElements addObject:[toggleAction uiActionForElementInfo:nil]];
+    return [originalMenu menuByReplacingChildren:menuElements];
 }
 
 - (void)assignLegacyDataForContextMenuInteraction
@@ -7763,6 +7757,7 @@
         if ([uiDelegate respondsToSelector:@selector(webView:previewingViewControllerForElement:defaultActions:)]) {
             auto defaultActions = wkLegacyPreviewActionsFromElementActions(defaultActionsFromAssistant.get(), elementInfo.get());
             auto previewElementInfo = adoptNS([[WKPreviewElementInfo alloc] _initWithLinkURL:url]);
+            // FIXME: Clients using this legacy API will always show their previewViewController and ignore _showLinkPreviews.
             previewViewController = [uiDelegate webView:_webView previewingViewControllerForElement:previewElementInfo.get() defaultActions:defaultActions];
         } else if ([uiDelegate respondsToSelector:@selector(_webView:previewViewControllerForURL:defaultActions:elementInfo:)])
             previewViewController = [uiDelegate _webView:_webView previewViewControllerForURL:url defaultActions:defaultActionsFromAssistant.get() elementInfo:elementInfo.get()];
@@ -7782,7 +7777,7 @@
                     _contextMenuLegacyPreviewController = dataDetectorsResult.get().previewProvider();
                 if (dataDetectorsResult && dataDetectorsResult.get().actionProvider) {
                     auto menuElements = menuElementsFromDefaultActions(defaultActionsFromAssistant, elementInfo);
-                    _contextMenuLegacyMenu = dataDetectorsResult.get().actionProvider(menuElements);
+                    _contextMenuLegacyMenu = menuWithShowLinkPreviewAction(dataDetectorsResult.get().actionProvider(menuElements));
                 }
                 END_BLOCK_OBJC_EXCEPTIONS;
             }
@@ -7789,8 +7784,7 @@
             return;
         }
 
-        auto menuTitle = titleForMenu(true, _showLinkPreviews, url, _positionInformation.title);
-        _contextMenuLegacyMenu = menuFromLegacyPreviewOrDefaultActions(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle);
+        _contextMenuLegacyMenu = menuFromLegacyPreviewOrDefaultActions(previewViewController, defaultActionsFromAssistant, elementInfo);
 
     } else if (_positionInformation.isImage) {
         NSURL *nsURL = (NSURL *)url;
@@ -7817,11 +7811,10 @@
             previewViewController = [[WKImagePreviewViewController alloc] initWithCGImage:cgImage defaultActions:defaultActionsFromAssistant.get() elementInfo:elementInfo.get()];
         ALLOW_DEPRECATED_DECLARATIONS_END
 
-        auto menuTitle = titleForMenu(false, _showLinkPreviews, url, _positionInformation.title);
-        _contextMenuLegacyMenu = menuFromLegacyPreviewOrDefaultActions(previewViewController, defaultActionsFromAssistant, elementInfo, menuTitle);
+        _contextMenuLegacyMenu = menuFromLegacyPreviewOrDefaultActions(previewViewController, defaultActionsFromAssistant, elementInfo, _positionInformation.title);
     }
 
-    _contextMenuLegacyPreviewController = _showLinkPreviews ? previewViewController : nullptr;
+    _contextMenuLegacyPreviewController = previewViewController;
 }
 
 - (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location
@@ -7839,6 +7832,10 @@
     if (!_webView.configuration._longPressActionsEnabled)
         return completion(nil);
 
+    _showLinkPreviews = true;
+    if (NSNumber *value = [[NSUserDefaults standardUserDefaults] objectForKey:webkitShowLinkPreviewsPreferenceKey])
+        _showLinkPreviews = value.boolValue;
+
     const auto position = [interaction locationInView:self];
     WebKit::InteractionInformationRequest request { WebCore::roundedIntPoint(position) };
     request.includeSnapshot = true;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to