Allow sharing from imageSheet on an image document
authormegan_gardner@apple.com <megan_gardner@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Apr 2019 01:41:00 +0000 (01:41 +0000)
committermegan_gardner@apple.com <megan_gardner@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Apr 2019 01:41:00 +0000 (01:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196891
<rdar://problem/25377386>

Reviewed by Tim Horton.

Source/WebKit:

Allow sharing from an image sheet generated from an image document
by storing the image URL and using it as a fallback for the URL.
Store it as an image on WKElementAction to not accidentally trigger
any actions that should actually be associated with pure URLs.

* UIProcess/API/Cocoa/_WKActivatedElementInfo.h:
* UIProcess/API/Cocoa/_WKActivatedElementInfo.mm:
(-[_WKActivatedElementInfo _initWithInteractionInformationAtPosition:]):
(-[_WKActivatedElementInfo _initWithType:URL:imageURL:location:title:ID:rect:image:]):
(-[_WKActivatedElementInfo _initWithType:URL:imageURL:location:title:ID:rect:image:userInfo:]):
(-[_WKActivatedElementInfo imageURL]):
(-[_WKActivatedElementInfo _initWithType:URL:location:title:ID:rect:image:]): Deleted.
(-[_WKActivatedElementInfo _initWithType:URL:location:title:ID:rect:image:userInfo:]): Deleted.
* UIProcess/API/Cocoa/_WKActivatedElementInfoInternal.h:
* UIProcess/API/Cocoa/_WKElementAction.mm:
(+[_WKElementAction _elementActionWithType:customTitle:assistant:]):
* UIProcess/ios/WKActionSheetAssistant.mm:
(-[WKActionSheetAssistant showImageSheet]):
(-[WKActionSheetAssistant defaultActionsForImageSheet:]):
(-[WKActionSheetAssistant showLinkSheet]):
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _showAttachmentSheet]):
(-[WKContentView _dataForPreviewItemController:atPosition:type:]):
(-[WKContentView _presentedViewControllerForPreviewItemController:]):

Tools:

Test to make sure that the correct imageURL is extracted from an image element.

* TestWebKitAPI/Tests/WebKitCocoa/WKRequestActivatedElementInfo.mm:
(TestWebKitAPI::TEST):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244368 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfo.h
Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfo.mm
Source/WebKit/UIProcess/API/Cocoa/_WKActivatedElementInfoInternal.h
Source/WebKit/UIProcess/API/Cocoa/_WKElementAction.mm
Source/WebKit/UIProcess/ios/WKActionSheetAssistant.mm
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKRequestActivatedElementInfo.mm

index a485fa7..e9f902f 100644 (file)
@@ -1,3 +1,36 @@
+2019-04-16  Megan Gardner  <megan_gardner@apple.com>
+
+        Allow sharing from imageSheet on an image document
+        https://bugs.webkit.org/show_bug.cgi?id=196891
+        <rdar://problem/25377386>
+
+        Reviewed by Tim Horton.
+
+        Allow sharing from an image sheet generated from an image document
+        by storing the image URL and using it as a fallback for the URL.
+        Store it as an image on WKElementAction to not accidentally trigger
+        any actions that should actually be associated with pure URLs.
+
+        * UIProcess/API/Cocoa/_WKActivatedElementInfo.h:
+        * UIProcess/API/Cocoa/_WKActivatedElementInfo.mm:
+        (-[_WKActivatedElementInfo _initWithInteractionInformationAtPosition:]):
+        (-[_WKActivatedElementInfo _initWithType:URL:imageURL:location:title:ID:rect:image:]):
+        (-[_WKActivatedElementInfo _initWithType:URL:imageURL:location:title:ID:rect:image:userInfo:]):
+        (-[_WKActivatedElementInfo imageURL]):
+        (-[_WKActivatedElementInfo _initWithType:URL:location:title:ID:rect:image:]): Deleted.
+        (-[_WKActivatedElementInfo _initWithType:URL:location:title:ID:rect:image:userInfo:]): Deleted.
+        * UIProcess/API/Cocoa/_WKActivatedElementInfoInternal.h:
+        * UIProcess/API/Cocoa/_WKElementAction.mm:
+        (+[_WKElementAction _elementActionWithType:customTitle:assistant:]):
+        * UIProcess/ios/WKActionSheetAssistant.mm:
+        (-[WKActionSheetAssistant showImageSheet]):
+        (-[WKActionSheetAssistant defaultActionsForImageSheet:]):
+        (-[WKActionSheetAssistant showLinkSheet]):
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _showAttachmentSheet]):
+        (-[WKContentView _dataForPreviewItemController:atPosition:type:]):
+        (-[WKContentView _presentedViewControllerForPreviewItemController:]):
+
 2019-04-16  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [Cocoa] Add a way for Apple-internal clients to opt into recommended compatibility mode
index 4898812..6a566db 100644 (file)
@@ -42,6 +42,7 @@ WK_CLASS_AVAILABLE(macos(10.10), ios(8.0))
 @interface _WKActivatedElementInfo : NSObject
 
 @property (nonatomic, readonly) NSURL *URL;
+@property (nonatomic, readonly) NSURL *imageURL;
 @property (nonatomic, readonly) NSString *title;
 @property (nonatomic, readonly) _WKActivatedElementType type;
 @property (nonatomic, readonly) CGRect boundingRect;
index d7d41e4..5430403 100644 (file)
@@ -39,6 +39,7 @@
 
 @implementation _WKActivatedElementInfo  {
     RetainPtr<NSURL> _URL;
+    RetainPtr<NSURL> _imageURL;
     RetainPtr<NSString> _title;
     CGPoint _interactionLocation;
     RetainPtr<NSString> _ID;
@@ -64,6 +65,7 @@
         return nil;
     
     _URL = information.url;
+    _imageURL = information.imageURL;
     _interactionLocation = information.request.point;
     _title = information.title;
     _boundingRect = information.bounds;
 }
 #endif
 
-- (instancetype)_initWithType:(_WKActivatedElementType)type URL:(NSURL *)url location:(CGPoint)location title:(NSString *)title ID:(NSString *)ID rect:(CGRect)rect image:(WebKit::ShareableBitmap*)image
+- (instancetype)_initWithType:(_WKActivatedElementType)type URL:(NSURL *)url imageURL:(NSURL *)imageURL location:(CGPoint)location title:(NSString *)title ID:(NSString *)ID rect:(CGRect)rect image:(WebKit::ShareableBitmap*)image
 {
-    return [self _initWithType:type URL:url location:location title:title ID:ID rect:rect image:image userInfo:nil];
+    return [self _initWithType:type URL:url imageURL:imageURL location:location title:title ID:ID rect:rect image:image userInfo:nil];
 }
 
-- (instancetype)_initWithType:(_WKActivatedElementType)type URL:(NSURL *)url location:(CGPoint)location title:(NSString *)title ID:(NSString *)ID rect:(CGRect)rect image:(WebKit::ShareableBitmap*)image userInfo:(NSDictionary *)userInfo
+- (instancetype)_initWithType:(_WKActivatedElementType)type URL:(NSURL *)url imageURL:(NSURL *)imageURL location:(CGPoint)location title:(NSString *)title ID:(NSString *)ID rect:(CGRect)rect image:(WebKit::ShareableBitmap*)image userInfo:(NSDictionary *)userInfo
 {
     if (!(self = [super init]))
         return nil;
 
     _URL = adoptNS([url copy]);
+    _imageURL = adoptNS([imageURL copy]);
     _interactionLocation = location;
     _title = adoptNS([title copy]);
     _boundingRect = rect;
     return _URL.get();
 }
 
+- (NSURL *)imageURL
+{
+    return _imageURL.get();
+}
+
 - (NSString *)title
 {
     return _title.get();
index 2951af7..42ee26d 100644 (file)
@@ -38,8 +38,8 @@ namespace WebKit {
 + (instancetype)activatedElementInfoWithInteractionInformationAtPosition:(const WebKit::InteractionInformationAtPosition&)information;
 - (instancetype)_initWithInteractionInformationAtPosition:(const WebKit::InteractionInformationAtPosition&)information;
 #endif
-- (instancetype)_initWithType:(_WKActivatedElementType)type URL:(NSURL *)url location:(CGPoint)location title:(NSString *)title ID:(NSString *)ID rect:(CGRect)rect image:(WebKit::ShareableBitmap*)image;
-- (instancetype)_initWithType:(_WKActivatedElementType)type URL:(NSURL *)url location:(CGPoint)location title:(NSString *)title ID:(NSString *)ID rect:(CGRect)rect image:(WebKit::ShareableBitmap*)image userInfo:(NSDictionary *)userInfo;
+- (instancetype)_initWithType:(_WKActivatedElementType)type URL:(NSURL *)url imageURL:(NSURL *)imageURL location:(CGPoint)location title:(NSString *)title ID:(NSString *)ID rect:(CGRect)rect image:(WebKit::ShareableBitmap*)image;
+- (instancetype)_initWithType:(_WKActivatedElementType)type URL:(NSURL *)url imageURL:(NSURL *)imageURL location:(CGPoint)location title:(NSString *)title ID:(NSString *)ID rect:(CGRect)rect image:(WebKit::ShareableBitmap*)image userInfo:(NSDictionary *)userInfo;
 
 @property (nonatomic, readonly) CGPoint _interactionLocation;
 
index 23c4f65..1ed754c 100644 (file)
@@ -129,7 +129,7 @@ static void addToReadingList(NSURL *targetURL, NSString *title)
     case _WKElementActionTypeShare:
         title = WEB_UI_STRING("Share…", "Title for Share action button");
         handler = ^(WKActionSheetAssistant *assistant, _WKActivatedElementInfo *actionInfo) {
-            [assistant.delegate actionSheetAssistant:assistant shareElementWithURL:actionInfo.URL rect:actionInfo.boundingRect];
+            [assistant.delegate actionSheetAssistant:assistant shareElementWithURL:actionInfo.URL ?: actionInfo.imageURL rect:actionInfo.boundingRect];
         };
         break;
     default:
index f73b867..9f4ed92 100644 (file)
@@ -392,10 +392,11 @@ static const CGFloat presentationElementRectPadding = 15;
 
     void (^showImageSheetWithAlternateURLBlock)(NSURL*, NSDictionary *userInfo) = ^(NSURL *alternateURL, NSDictionary *userInfo) {
         NSURL *targetURL = _positionInformation->url;
+        NSURL *imageURL = _positionInformation->imageURL;
         if (!targetURL)
             targetURL = alternateURL;
         auto elementBounds = _positionInformation->bounds;
-        auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeImage URL:targetURL location:_positionInformation->request.point title:_positionInformation->title ID:_positionInformation->idAttribute rect:elementBounds image:_positionInformation->image.get() userInfo:userInfo]);
+        auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeImage URL:targetURL imageURL:imageURL location:_positionInformation->request.point title:_positionInformation->title ID:_positionInformation->idAttribute rect:elementBounds image:_positionInformation->image.get() userInfo:userInfo]);
         if ([delegate respondsToSelector:@selector(actionSheetAssistant:showCustomSheetForElement:)] && [delegate actionSheetAssistant:self showCustomSheetForElement:elementInfo.get()])
             return;
         auto defaultActions = [self defaultActionsForImageSheet:elementInfo.get()];
@@ -536,7 +537,8 @@ ALLOW_DEPRECATED_DECLARATIONS_END
     if (targetURL) {
         [self _appendOpenActionsForURL:targetURL actions:defaultActions.get() elementInfo:elementInfo];
         [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeShare assistant:self]];
-    }
+    } else if ([elementInfo imageURL])
+        [defaultActions addObject:[_WKElementAction _elementActionWithType:_WKElementActionTypeShare assistant:self]];
 
 #if HAVE(SAFARI_SERVICES_FRAMEWORK)
     if ([getSSReadingListClass() supportsURL:targetURL])
@@ -571,7 +573,7 @@ ALLOW_DEPRECATED_DECLARATIONS_END
         return;
     }
 
-    auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeLink URL:targetURL location:_positionInformation->request.point title:_positionInformation->title ID:_positionInformation->idAttribute rect:_positionInformation->bounds image:_positionInformation->image.get()]);
+    auto elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeLink URL:targetURL imageURL:(NSURL*)_positionInformation->imageURL location:_positionInformation->request.point title:_positionInformation->title ID:_positionInformation->idAttribute rect:_positionInformation->bounds image:_positionInformation->image.get()]);
     if ([_delegate respondsToSelector:@selector(actionSheetAssistant:showCustomSheetForElement:)] && [_delegate actionSheetAssistant:self showCustomSheetForElement:elementInfo.get()]) {
         _needsLinkIndicator = NO;
         return;
index 3434966..b672979 100644 (file)
@@ -1799,7 +1799,7 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI
     if (![uiDelegate respondsToSelector:@selector(_webView:showCustomSheetForElement:)])
         return;
 
-    auto element = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeAttachment URL:(NSURL *)_positionInformation.url location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:nil]);
+    auto element = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeAttachment URL:(NSURL *)_positionInformation.url imageURL:(NSURL *)_positionInformation.imageURL location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:nil]);
     [uiDelegate _webView:_webView showCustomSheetForElement:element.get()];
 }
 
@@ -7271,7 +7271,7 @@ static BOOL shouldUsePreviewForLongPress()
         dataForPreview[UIPreviewDataLink] = (NSURL *)_positionInformation.imageURL;
     } else if (canShowAttachmentPreview) {
         *type = UIPreviewItemTypeAttachment;
-        auto element = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeAttachment URL:(NSURL *)linkURL location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:nil]);
+        auto element = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeAttachment URL:(NSURL *)linkURL imageURL:(NSURL *)_positionInformation.imageURL location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:nil]);
         NSUInteger index = [uiDelegate _webView:_webView indexIntoAttachmentListForElement:element.get()];
         if (index != NSNotFound) {
             BOOL sourceIsManaged = NO;
@@ -7333,7 +7333,7 @@ static NSString *previewIdentifierForElementAction(_WKElementAction *action)
 
         // Treat animated images like a link preview
         if (isValidURLForImagePreview && _positionInformation.isAnimatedImage) {
-            RetainPtr<_WKActivatedElementInfo> animatedImageElementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeImage URL:targetURL location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:_positionInformation.image.get()]);
+            RetainPtr<_WKActivatedElementInfo> animatedImageElementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeImage URL:targetURL imageURL:nil location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:_positionInformation.image.get()]);
 
             if ([uiDelegate respondsToSelector:@selector(_webView:previewViewControllerForAnimatedImageAtURL:defaultActions:elementInfo:imageSize:)]) {
                 RetainPtr<NSArray> actions = [_actionSheetAssistant defaultActionsForImageSheet:animatedImageElementInfo.get()];
@@ -7341,7 +7341,7 @@ static NSString *previewIdentifierForElementAction(_WKElementAction *action)
             }
         }
 
-        RetainPtr<_WKActivatedElementInfo> elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeLink URL:targetURL location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:_positionInformation.image.get()]);
+        RetainPtr<_WKActivatedElementInfo> elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeLink URL:targetURL imageURL:nil location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:_positionInformation.image.get()]);
 
         auto actions = [_actionSheetAssistant defaultActionsForLinkSheet:elementInfo.get()];
         if ([uiDelegate respondsToSelector:@selector(webView:previewingViewControllerForElement:defaultActions:)]) {
@@ -7379,7 +7379,7 @@ static NSString *previewIdentifierForElementAction(_WKElementAction *action)
             imageInfo = userInfo;
         }
 
-        RetainPtr<_WKActivatedElementInfo> elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeImage URL:alternateURL.get() location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:_positionInformation.image.get() userInfo:imageInfo.get()]);
+        RetainPtr<_WKActivatedElementInfo> elementInfo = adoptNS([[_WKActivatedElementInfo alloc] _initWithType:_WKActivatedElementTypeImage URL:alternateURL.get() imageURL:nil location:_positionInformation.request.point title:_positionInformation.title ID:_positionInformation.idAttribute rect:_positionInformation.bounds image:_positionInformation.image.get() userInfo:imageInfo.get()]);
         _page->startInteractionWithElementAtPosition(_positionInformation.request.point);
 
         if ([uiDelegate respondsToSelector:@selector(_webView:willPreviewImageWithURL:)])
index e7286be..74aa74b 100644 (file)
@@ -1,3 +1,16 @@
+2019-04-16  Megan Gardner  <megan_gardner@apple.com>
+
+        Allow sharing from imageSheet on an image document
+        https://bugs.webkit.org/show_bug.cgi?id=196891
+        <rdar://problem/25377386>
+
+        Reviewed by Tim Horton.
+
+        Test to make sure that the correct imageURL is extracted from an image element.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKRequestActivatedElementInfo.mm:
+        (TestWebKitAPI::TEST):
+
 2019-04-16  Alex Christensen  <achristensen@webkit.org>
 
         REGRESSION(r244162) Clearing website data from ephemeral WKWebsiteDataStore should finish instead of asserting or hanging
index 1aebea8..94061fc 100644 (file)
@@ -72,6 +72,30 @@ TEST(WebKit, RequestActivatedElementInfoForLink)
     TestWebKitAPI::Util::run(&finished);
 }
     
+TEST(WebKit, RequestActivatedElementInfoForImage)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 215, 174)]);
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"icon" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"]];
+    [webView loadRequest:request];
+    [webView _test_waitForDidFinishNavigation];
+    
+    __block bool finished = false;
+    [webView _requestActivatedElementAtPosition:CGPointMake(50, 50) completionBlock: ^(_WKActivatedElementInfo *elementInfo) {
+        
+        EXPECT_TRUE(elementInfo.type == _WKActivatedElementTypeImage);
+        EXPECT_WK_STREQ(elementInfo.imageURL.lastPathComponent, "icon.png");
+        EXPECT_NOT_NULL(elementInfo.image);
+        EXPECT_EQ(elementInfo.boundingRect.size.width, 215);
+        EXPECT_EQ(elementInfo.boundingRect.size.height, 174);
+        EXPECT_EQ(elementInfo.image.size.width, 215);
+        EXPECT_EQ(elementInfo.image.size.height, 174);
+        
+        finished = true;
+    }];
+    
+    TestWebKitAPI::Util::run(&finished);
+}
+    
 TEST(WebKit, RequestActivatedElementInfoForBlank)
 {
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);