Title: [278459] trunk
Revision
278459
Author
[email protected]
Date
2021-06-04 08:32:21 -0700 (Fri, 04 Jun 2021)

Log Message

[iOS] Long pressing images on 9gag.com fails to present context menus
https://bugs.webkit.org/show_bug.cgi?id=226625
rdar://78136095

Reviewed by Megan Gardner.

Source/WebKit:

Make some small adjustments to context menu logic to allow the context menu to appear when long pressing images
that are inside links (anchor elements) with _javascript_ URLs. See below for more details.

Test: fast/events/touch/ios/long-press-on-image-in-_javascript_-link.html

* UIProcess/ios/WKActionSheetAssistant.mm:
(isJavaScriptURL):

Pull logic that checks for "_javascript_" URL schemes into a separate helper function, and use it below.

(-[WKActionSheetAssistant _createSheetWithElementActions:defaultTitle:showLinkTitle:]):
(-[WKActionSheetAssistant defaultActionsForLinkSheet:]):
(-[WKActionSheetAssistant defaultActionsForImageSheet:]):

Add `_WKElementActionTypeCopy` for image sheets, even when the target URL is a _javascript_ URL; even if the image
is inside a _javascript_ URL, we should be capable of triggering the "Copy" action by copying the image data and
the image URL, rather than the _javascript_ URL. The change in `WebPage::performActionOnElement` below ensures
that we don't end up copying the _javascript_ URL.

(-[WKActionSheetAssistant handleElementActionWithType:element:needsInteraction:]):

Make another minor adjustment to share the imageURL instead of the target URL in the case where the target is a
_javascript_ URL.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView continueContextMenuInteraction:]):

Avoid bailing early with `continueWithContextMenuConfiguration(nil);` in the case where we're long pressing an
image inside a _javascript_ link.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::performActionOnElement):

Push the _javascript_ URL check in `defaultActionsForImageSheet` down into `WebPage::performActionOnElement`, when
copying an image. This tweak allows us to still show the Copy action for images in _javascript_ URLs, but just
copy the image and image URL instead of the _javascript_ URL.

LayoutTests:

Add a layout test to verify that a context menu is presented when long pressing an image inside a link with a
_javascript_ URL as an `href`.

* fast/events/touch/ios/long-press-on-image-in-_javascript_-link-expected.txt: Added.
* fast/events/touch/ios/long-press-on-image-in-_javascript_-link.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (278458 => 278459)


--- trunk/LayoutTests/ChangeLog	2021-06-04 15:03:00 UTC (rev 278458)
+++ trunk/LayoutTests/ChangeLog	2021-06-04 15:32:21 UTC (rev 278459)
@@ -1,3 +1,17 @@
+2021-06-04  Wenson Hsieh  <[email protected]>
+
+        [iOS] Long pressing images on 9gag.com fails to present context menus
+        https://bugs.webkit.org/show_bug.cgi?id=226625
+        rdar://78136095
+
+        Reviewed by Megan Gardner.
+
+        Add a layout test to verify that a context menu is presented when long pressing an image inside a link with a
+        _javascript_ URL as an `href`.
+
+        * fast/events/touch/ios/long-press-on-image-in-_javascript_-link-expected.txt: Added.
+        * fast/events/touch/ios/long-press-on-image-in-_javascript_-link.html: Added.
+
 2021-06-04  Martin Robinson  <[email protected]>
 
         [Win] Implement scroll-snap-points on Windows

Added: trunk/LayoutTests/fast/events/touch/ios/long-press-on-image-in-_javascript_-link-expected.txt (0 => 278459)


--- trunk/LayoutTests/fast/events/touch/ios/long-press-on-image-in-_javascript_-link-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/long-press-on-image-in-_javascript_-link-expected.txt	2021-06-04 15:32:21 UTC (rev 278459)
@@ -0,0 +1,11 @@
+Verifies that long pressing an image inside a _javascript_ link presents a context menu. To manually test, long press on the image.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Presented context menu
+PASS Dismissed context menu
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/events/touch/ios/long-press-on-image-in-_javascript_-link.html (0 => 278459)


--- trunk/LayoutTests/fast/events/touch/ios/long-press-on-image-in-_javascript_-link.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/long-press-on-image-in-_javascript_-link.html	2021-06-04 15:32:21 UTC (rev 278459)
@@ -0,0 +1,44 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<meta charset="utf-8">
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1, width=device-width, user-scalable=no">
+<script src=""
+<script src=""
+<script src=""
+<style>
+#target {
+    width: 320px;
+    height: 240px;
+    background-color: silver;
+    display: block;
+}
+</style>
+<script>
+jsTestIsAsync = true;
+
+addEventListener("load", async () => {
+    description("Verifies that long pressing an image inside a _javascript_ link presents a context menu. To manually test, long press on the image.");
+
+    if (!window.testRunner || !testRunner.runUIScript)
+        return;
+
+    const rect = document.getElementById("target").getBoundingClientRect();
+    await UIHelper.longPressAtPoint(rect.x + rect.width / 2, rect.y + rect.height / 2);
+    await UIHelper.waitForContextMenuToShow();
+    testPassed("Presented context menu");
+
+    await UIHelper.activateAt(0, 0);
+    await UIHelper.waitForContextMenuToHide();
+    testPassed("Dismissed context menu");
+
+    finishJSTest();
+});
+</script>
+</head>
+<body>
+<a id="target" href=""
+    <img src="" width="320" height="240">
+</a>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebKit/ChangeLog (278458 => 278459)


--- trunk/Source/WebKit/ChangeLog	2021-06-04 15:03:00 UTC (rev 278458)
+++ trunk/Source/WebKit/ChangeLog	2021-06-04 15:32:21 UTC (rev 278459)
@@ -1,3 +1,48 @@
+2021-06-04  Wenson Hsieh  <[email protected]>
+
+        [iOS] Long pressing images on 9gag.com fails to present context menus
+        https://bugs.webkit.org/show_bug.cgi?id=226625
+        rdar://78136095
+
+        Reviewed by Megan Gardner.
+
+        Make some small adjustments to context menu logic to allow the context menu to appear when long pressing images
+        that are inside links (anchor elements) with _javascript_ URLs. See below for more details.
+
+        Test: fast/events/touch/ios/long-press-on-image-in-_javascript_-link.html
+
+        * UIProcess/ios/WKActionSheetAssistant.mm:
+        (isJavaScriptURL):
+
+        Pull logic that checks for "_javascript_" URL schemes into a separate helper function, and use it below.
+
+        (-[WKActionSheetAssistant _createSheetWithElementActions:defaultTitle:showLinkTitle:]):
+        (-[WKActionSheetAssistant defaultActionsForLinkSheet:]):
+        (-[WKActionSheetAssistant defaultActionsForImageSheet:]):
+
+        Add `_WKElementActionTypeCopy` for image sheets, even when the target URL is a _javascript_ URL; even if the image
+        is inside a _javascript_ URL, we should be capable of triggering the "Copy" action by copying the image data and
+        the image URL, rather than the _javascript_ URL. The change in `WebPage::performActionOnElement` below ensures
+        that we don't end up copying the _javascript_ URL.
+
+        (-[WKActionSheetAssistant handleElementActionWithType:element:needsInteraction:]):
+
+        Make another minor adjustment to share the imageURL instead of the target URL in the case where the target is a
+        _javascript_ URL.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView continueContextMenuInteraction:]):
+
+        Avoid bailing early with `continueWithContextMenuConfiguration(nil);` in the case where we're long pressing an
+        image inside a _javascript_ link.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::performActionOnElement):
+
+        Push the _javascript_ URL check in `defaultActionsForImageSheet` down into `WebPage::performActionOnElement`, when
+        copying an image. This tweak allows us to still show the Copy action for images in _javascript_ URLs, but just
+        copy the image and image URL instead of the _javascript_ URL.
+
 2021-06-04  Michael Catanzaro  <[email protected]>
 
         Fix more GCC warnings

Modified: trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm (278458 => 278459)


--- trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm	2021-06-04 15:03:00 UTC (rev 278458)
+++ trunk/Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm	2021-06-04 15:32:21 UTC (rev 278459)
@@ -338,6 +338,12 @@
     return _positionInformation;
 }
 
+static bool isJavaScriptURL(NSURL *url)
+{
+    auto scheme = url.scheme;
+    return scheme && [scheme caseInsensitiveCompare:@"_javascript_"] == NSOrderedSame;
+}
+
 - (void)_createSheetWithElementActions:(NSArray *)actions defaultTitle:(NSString *)defaultTitle showLinkTitle:(BOOL)showLinkTitle
 {
     auto delegate = _delegate.get();
@@ -348,8 +354,6 @@
         return;
 
     NSURL *targetURL = _positionInformation->url;
-    NSString *urlScheme = [targetURL scheme];
-    BOOL isJavaScriptURL = [urlScheme length] && [urlScheme caseInsensitiveCompare:@"_javascript_"] == NSOrderedSame;
     // FIXME: We should check if _javascript_ is enabled in the preferences.
 
     _interactionSheet = adoptNS([[WKActionSheet alloc] init]);
@@ -359,7 +363,7 @@
     NSString *titleString = nil;
     BOOL titleIsURL = NO;
     if (showLinkTitle && [[targetURL absoluteString] length]) {
-        if (isJavaScriptURL)
+        if (isJavaScriptURL(targetURL))
             titleString = WEB_UI_STRING_KEY("_javascript_", "_javascript_ Action Sheet Title", "Title for action sheet for _javascript_ link");
         else {
             titleString = WTF::userVisibleString(targetURL);
@@ -563,7 +567,7 @@
             [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeSaveImage assistant:self]];
     }
 
-    if (![[targetURL scheme] length] || [[targetURL scheme] caseInsensitiveCompare:@"_javascript_"] != NSOrderedSame) {
+    if (!isJavaScriptURL(targetURL)) {
         [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeCopy assistant:self]];
         [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeShare assistant:self]];
     }
@@ -597,9 +601,9 @@
 #endif
     if (TCCAccessPreflight(getkTCCServicePhotos(), NULL) != kTCCAccessPreflightDenied)
         [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeSaveImage assistant:self]];
-    if (!targetURL.scheme.length || [targetURL.scheme caseInsensitiveCompare:@"_javascript_"] != NSOrderedSame)
-        [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeCopy assistant:self]];
 
+    [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeCopy assistant:self]];
+
 #if ENABLE(IMAGE_EXTRACTION)
     if ([_delegate respondsToSelector:@selector(actionSheetAssistant:shouldIncludeImageExtractionActionForElement:)] && [_delegate actionSheetAssistant:self shouldIncludeImageExtractionActionForElement:elementInfo])
         [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeImageExtraction assistant:self]];
@@ -1017,8 +1021,10 @@
     case _WKElementActionTypeShare:
         if (URL(element.imageURL).protocolIsData() && element.image && [delegate respondsToSelector:@selector(actionSheetAssistant:shareElementWithImage:rect:)])
             [delegate actionSheetAssistant:self shareElementWithImage:element.image rect:element.boundingRect];
-        else
-            [delegate actionSheetAssistant:self shareElementWithURL:element.URL ?: element.imageURL rect:element.boundingRect];
+        else {
+            auto urlToShare = element.URL && !isJavaScriptURL(element.URL) ? element.URL : element.imageURL;
+            [delegate actionSheetAssistant:self shareElementWithURL:urlToShare rect:element.boundingRect];
+        }
         break;
     case _WKElementActionTypeImageExtraction:
 #if ENABLE(IMAGE_EXTRACTION)

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (278458 => 278459)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-06-04 15:03:00 UTC (rev 278458)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-06-04 15:32:21 UTC (rev 278459)
@@ -10372,8 +10372,21 @@
             return;
         }
 
+        bool canShowHTTPLinkOrDataDetectorPreview = ([&] {
+            if (linkURL.protocolIsInHTTPFamily())
+                return true;
+
+            if (WebCore::DataDetection::canBePresentedByDataDetectors(linkURL))
+                return true;
+
+            if ([strongSelf positionInformationHasImageOverlayDataDetector])
+                return true;
+
+            return false;
+        })();
+
         ASSERT_IMPLIES(strongSelf->_positionInformation.isImage, strongSelf->_positionInformation.image);
-        if (strongSelf->_positionInformation.isImage && strongSelf->_positionInformation.image && !strongSelf->_positionInformation.isLink) {
+        if (strongSelf->_positionInformation.isImage && strongSelf->_positionInformation.image && !canShowHTTPLinkOrDataDetectorPreview) {
             auto cgImage = strongSelf->_positionInformation.image->makeCGImageCopy();
 
             strongSelf->_contextMenuActionProviderDelegateNeedsOverride = NO;
@@ -10414,7 +10427,7 @@
 #if ENABLE(DATA_DETECTION)
         // FIXME: Support _javascript_ urls here. But make sure they don't show a preview.
         // <rdar://problem/50572283>
-        if (!linkURL.protocolIsInHTTPFamily() && !WebCore::DataDetection::canBePresentedByDataDetectors(linkURL) && ![strongSelf positionInformationHasImageOverlayDataDetector]) {
+        if (!canShowHTTPLinkOrDataDetectorPreview) {
             continueWithContextMenuConfiguration(nil);
             return;
         }

Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (278458 => 278459)


--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2021-06-04 15:03:00 UTC (rev 278458)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2021-06-04 15:32:21 UTC (rev 278459)
@@ -3157,16 +3157,18 @@
 
     if (static_cast<SheetAction>(action) == SheetAction::Copy) {
         if (is<RenderImage>(*element.renderer())) {
-            URL url;
-            String title;
-            if (auto* linkElement = containingLinkAnchorElement(element)) {
-                url = ""
-                title = linkElement->attributeWithoutSynchronization(HTMLNames::titleAttr);
-                if (!title.length())
-                    title = linkElement->textContent();
-                title = stripLeadingAndTrailingHTMLSpaces(title);
+            URL urlToCopy;
+            String titleToCopy;
+            if (auto linkElement = makeRefPtr(containingLinkAnchorElement(element))) {
+                if (auto url = "" !url.isEmpty() && !url.protocolIsJavaScript()) {
+                    urlToCopy = url;
+                    titleToCopy = linkElement->attributeWithoutSynchronization(HTMLNames::titleAttr);
+                    if (!titleToCopy.length())
+                        titleToCopy = linkElement->textContent();
+                    titleToCopy = stripLeadingAndTrailingHTMLSpaces(titleToCopy);
+                }
             }
-            m_interactionNode->document().editor().writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(PagePasteboardContext::create(element.document().pageID())), element, url, title);
+            m_interactionNode->document().editor().writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(PagePasteboardContext::create(element.document().pageID())), element, urlToCopy, titleToCopy);
         } else if (element.isLink())
             m_interactionNode->document().editor().copyURL(element.document().completeURL(stripLeadingAndTrailingHTMLSpaces(element.attributeWithoutSynchronization(HTMLNames::hrefAttr))), element.textContent());
 #if ENABLE(ATTACHMENT_ELEMENT)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to