[macOS] Dragged images are only available as .tiff when dropping onto macCatalyst...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Nov 2019 06:08:58 +0000 (06:08 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Nov 2019 06:08:58 +0000 (06:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=204598
<rdar://problem/57093920>

Reviewed by Tim Horton.

Source/WebKit:

On macOS, writing dragged images to the pasteboard only as file promises is mostly sufficient for the purposes
of dropping into Finder, Photos, and other apps. However, when dropping into a macCatalyst app, the contents of
NSPasteboard will only contain a file URL, which most Catalyst apps aren't able to handle. The only other valid
image representation that is written to the pasteboard in this case is "public.tiff", which loses fidelity in
the case of animated GIFs.

Instead, if the dragged image has a corresponding UTI and corresponding decoded image data, declare the UTI when
writing promised data to the pasteboard, and later provide data for the UTI, if the drop destination asks, by
using the promised image's data.

Test: DragAndDropTests.ProvideImageDataAsTypeIdentifiers

* UIProcess/Cocoa/WebViewImpl.mm:
(WebKit::WebViewImpl::setPromisedDataForImage):
(WebKit::WebViewImpl::provideDataForPasteboard):

Tools:

Verify that WKWebView is able to provide data in non-TIFF formats when dragging several types of images using a
new API test.

* TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm:

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm

index cd9c946..81e2511 100644 (file)
@@ -1,3 +1,27 @@
+2019-11-25  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [macOS] Dragged images are only available as .tiff when dropping onto macCatalyst apps
+        https://bugs.webkit.org/show_bug.cgi?id=204598
+        <rdar://problem/57093920>
+
+        Reviewed by Tim Horton.
+
+        On macOS, writing dragged images to the pasteboard only as file promises is mostly sufficient for the purposes
+        of dropping into Finder, Photos, and other apps. However, when dropping into a macCatalyst app, the contents of
+        NSPasteboard will only contain a file URL, which most Catalyst apps aren't able to handle. The only other valid
+        image representation that is written to the pasteboard in this case is "public.tiff", which loses fidelity in
+        the case of animated GIFs.
+
+        Instead, if the dragged image has a corresponding UTI and corresponding decoded image data, declare the UTI when
+        writing promised data to the pasteboard, and later provide data for the UTI, if the drop destination asks, by
+        using the promised image's data.
+
+        Test: DragAndDropTests.ProvideImageDataAsTypeIdentifiers
+
+        * UIProcess/Cocoa/WebViewImpl.mm:
+        (WebKit::WebViewImpl::setPromisedDataForImage):
+        (WebKit::WebViewImpl::provideDataForPasteboard):
+
 2019-11-25  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [Win] Update KeyboardEvent as per the latest specification
index d21167a..7138efc 100644 (file)
@@ -4237,6 +4237,9 @@ void WebViewImpl::setPromisedDataForImage(WebCore::Image* image, NSString *filen
     NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:pasteboardName];
     RetainPtr<NSMutableArray> types = adoptNS([[NSMutableArray alloc] initWithObjects:WebCore::legacyFilesPromisePasteboardType(), nil]);
 
+    if (image && !image->uti().isEmpty() && image->data() && !image->data()->isEmpty())
+        [types addObject:image->uti()];
+
     [types addObjectsFromArray:archiveBuffer ? PasteboardTypes::forImagesWithArchive() : PasteboardTypes::forImages()];
     [pasteboard declareTypes:types.get() owner:m_view.getAutoreleased()];
     setFileAndURLTypes(filename, extension, title, url, visibleURL, pasteboard);
@@ -4264,8 +4267,16 @@ void WebViewImpl::pasteboardChangedOwner(NSPasteboard *pasteboard)
 
 void WebViewImpl::provideDataForPasteboard(NSPasteboard *pasteboard, NSString *type)
 {
+    if (!m_promisedImage)
+        return;
+
+    if ([type isEqual:m_promisedImage->uti()] && m_promisedImage->data()) {
+        if (auto platformData = m_promisedImage->data()->createNSData())
+            [pasteboard setData:(__bridge NSData *)platformData.get() forType:type];
+    }
+
     // FIXME: Need to support NSRTFDPboardType.
-    if ([type isEqual:WebCore::legacyTIFFPasteboardType()] && m_promisedImage)
+    if ([type isEqual:WebCore::legacyTIFFPasteboardType()])
         [pasteboard setData:(__bridge NSData *)m_promisedImage->tiffRepresentation() forType:WebCore::legacyTIFFPasteboardType()];
 }
 
index a568d79..a9e72fc 100644 (file)
@@ -1,3 +1,16 @@
+2019-11-25  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [macOS] Dragged images are only available as .tiff when dropping onto macCatalyst apps
+        https://bugs.webkit.org/show_bug.cgi?id=204598
+        <rdar://problem/57093920>
+
+        Reviewed by Tim Horton.
+
+        Verify that WKWebView is able to provide data in non-TIFF formats when dragging several types of images using a
+        new API test.
+
+        * TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm:
+
 2019-11-25  Ross Kirsling  <ross.kirsling@sony.com>
 
         [Win] Ensure MiniBrowser can be built with !ENABLE(WEBKIT_LEGACY)
index 0984104..c482e4b 100644 (file)
@@ -27,6 +27,7 @@
 
 #import "DragAndDropSimulator.h"
 #import "PlatformUtilities.h"
+#import <WebKit/WKPreferencesPrivate.h>
 
 #if ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)
 
@@ -158,4 +159,30 @@ ALLOW_DEPRECATED_DECLARATIONS_END
     EXPECT_FALSE(NSEqualSizes(NSZeroSize, imageFromUniquePasteboard.size));
 }
 
+TEST(DragAndDropTests, ProvideImageDataAsTypeIdentifiers)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [[configuration preferences] _setLargeImageAsyncDecodingEnabled:NO];
+
+    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
+    TestWKWebView *webView = [simulator webView];
+
+    auto uniquePasteboard = retainPtr(NSPasteboard.pasteboardWithUniqueName);
+
+    [webView synchronouslyLoadHTMLString:@"<img src='sunset-in-cupertino-600px.jpg'></img>"];
+    [simulator runFrom:NSMakePoint(25, 25) to:NSMakePoint(300, 300)];
+    [webView pasteboard:uniquePasteboard.get() provideDataForType:(__bridge NSString *)kUTTypeJPEG];
+    EXPECT_GT([uniquePasteboard dataForType:(__bridge NSString *)kUTTypeJPEG].length, 0u);
+
+    [webView synchronouslyLoadHTMLString:@"<img src='icon.png'></img>"];
+    [simulator runFrom:NSMakePoint(25, 25) to:NSMakePoint(300, 300)];
+    [webView pasteboard:uniquePasteboard.get() provideDataForType:(__bridge NSString *)kUTTypePNG];
+    EXPECT_GT([uniquePasteboard dataForType:(__bridge NSString *)kUTTypePNG].length, 0u);
+
+    [webView synchronouslyLoadHTMLString:@"<img src='apple.gif'></img>"];
+    [simulator runFrom:NSMakePoint(25, 25) to:NSMakePoint(300, 300)];
+    [webView pasteboard:uniquePasteboard.get() provideDataForType:(__bridge NSString *)kUTTypeGIF];
+    EXPECT_GT([uniquePasteboard dataForType:(__bridge NSString *)kUTTypeGIF].length, 0u);
+}
+
 #endif // ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)