Update service picker API usage.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 May 2014 03:31:43 +0000 (03:31 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 May 2014 03:31:43 +0000 (03:31 +0000)
<rdar://problem/16772674> and https://bugs.webkit.org/show_bug.cgi?id=132452

Reviewed by Tim Horton.

* Misc/WebSharingServicePickerController.h:
* Misc/WebSharingServicePickerController.mm:
(-[WebSharingServicePickerController didShareImageData:confirmDataIsValidTIFFData:]):
  Factor out a common "didShare" handler that optionally validates whether the data represents an image.
(-[WebSharingServicePickerController sharingService:didShareItems:]): Update API usage, including marshalling
  on off-main thread call back to the main thread.

* WebCoreSupport/WebContextMenuClient.mm:
(WebContextMenuClient::contextMenuForEvent): Update API usage.

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

Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Misc/WebSharingServicePickerController.h
Source/WebKit/mac/Misc/WebSharingServicePickerController.mm
Source/WebKit/mac/WebCoreSupport/WebContextMenuClient.mm

index 3e8aaa7..4890de9 100644 (file)
@@ -1,3 +1,20 @@
+2014-05-01  Brady Eidson  <beidson@apple.com>
+
+        Update service picker API usage.
+        <rdar://problem/16772674> and https://bugs.webkit.org/show_bug.cgi?id=132452
+
+        Reviewed by Tim Horton.
+
+        * Misc/WebSharingServicePickerController.h:
+        * Misc/WebSharingServicePickerController.mm:
+        (-[WebSharingServicePickerController didShareImageData:confirmDataIsValidTIFFData:]):
+          Factor out a common "didShare" handler that optionally validates whether the data represents an image.
+        (-[WebSharingServicePickerController sharingService:didShareItems:]): Update API usage, including marshalling
+          on off-main thread call back to the main thread.
+
+        * WebCoreSupport/WebContextMenuClient.mm:
+        (WebContextMenuClient::contextMenuForEvent): Update API usage.
+
 2014-05-01  Anders Carlsson  <andersca@apple.com>
 
         Support OS-version-specific install paths for WebKit.framework
index b6fe628..dcb197d 100644 (file)
@@ -39,8 +39,9 @@ class WebContextMenuClient;
     BOOL _includeEditorServices;
 }
 
-- (instancetype)initWithImage:(NSImage *)image includeEditorServices:(BOOL)includeEditorServices menuClient:(WebContextMenuClient*)menuClient;
+- (instancetype)initWithData:(NSData *)data includeEditorServices:(BOOL)includeEditorServices menuClient:(WebContextMenuClient*)menuClient;
 - (NSMenu *)menu;
+- (void)didShareImageData:(NSData *)data confirmDataIsValidTIFFData:(BOOL)confirmData;
 
 @end
 
index b85d656..748c371 100644 (file)
@@ -49,7 +49,16 @@ typedef enum {
 @property NSSharingServicePickerStyle style;
 - (NSMenu *)menu;
 @end
+#endif
 
+#if __has_include(<AppKit/NSItemProvider.h>)
+#import <AppKit/NSItemProvider.h>
+#else
+@interface NSItemProvider : NSObject
+@property (copy, readonly) NSArray *registeredTypeIdentifiers;
+- (instancetype)initWithItem:(id <NSSecureCoding>)item typeIdentifier:(NSString *)typeIdentifier;
+- (void)loadItemForTypeIdentifier:(NSString *)typeIdentifier options:(NSDictionary *)options completionHandler:(void (^)(id <NSSecureCoding> item, NSError *error))completionHandler;
+@end
 #endif
 
 static NSString *serviceControlsPasteboardName = @"WebKitServiceControlsPasteboard";
@@ -58,12 +67,14 @@ using namespace WebCore;
 
 @implementation WebSharingServicePickerController
 
-- (instancetype)initWithImage:(NSImage *)image includeEditorServices:(BOOL)includeEditorServices menuClient:(WebContextMenuClient*)menuClient
+- (instancetype)initWithData:(NSData *)data includeEditorServices:(BOOL)includeEditorServices menuClient:(WebContextMenuClient*)menuClient
 {
     if (!(self = [super init]))
         return nil;
 
-    _picker = adoptNS([[NSSharingServicePicker alloc] initWithItems:@[ image ]]);
+    RetainPtr<NSItemProvider> itemProvider = adoptNS([[NSItemProvider alloc] initWithItem:data typeIdentifier:@"public.data"]);
+
+    _picker = adoptNS([[NSSharingServicePicker alloc] initWithItems:@[ itemProvider.get() ]]);
     [_picker setStyle:NSSharingServicePickerStyleRollover];
     [_picker setDelegate:self];
 
@@ -86,8 +97,34 @@ using namespace WebCore;
     return [_picker menu];
 }
 
-#pragma mark NSSharingServicePickerDelegate methods
+- (void)didShareImageData:(NSData *)data confirmDataIsValidTIFFData:(BOOL)confirmData
+{
+    Page* page = [_menuClient->webView() page];
+    if (!page)
+        return;
+
+    if (confirmData) {
+        RetainPtr<NSImage> nsImage = adoptNS([[NSImage alloc] initWithData:data]);
+        if (!nsImage) {
+            LOG_ERROR("Shared image data cannot create a valid NSImage");
+            return;
+        }
+
+        data = [nsImage TIFFRepresentation];
+    }
+
+    NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:serviceControlsPasteboardName];
+    [pasteboard declareTypes:@[ NSPasteboardTypeTIFF ] owner:nil];
+    [pasteboard setData:data forType:NSPasteboardTypeTIFF];
+
+    Frame& frame = page->focusController().focusedOrMainFrame();
+    if (!frame.selection().isNone())
+        frame.editor().readSelectionFromPasteboard(serviceControlsPasteboardName);
 
+    [self clear];
+}
+
+#pragma mark NSSharingServicePickerDelegate methods
 
 - (NSArray *)sharingServicePicker:(NSSharingServicePicker *)sharingServicePicker sharingServicesForItems:(NSArray *)items mask:(NSSharingServiceMask)mask proposedSharingServices:(NSArray *)proposedServices
 {
@@ -123,25 +160,32 @@ using namespace WebCore;
     if ([items count] != 1)
         return;
 
-    RetainPtr<CGImageSourceRef> source = adoptCF(CGImageSourceCreateWithData((CFDataRef)[items objectAtIndex:0], NULL));
-    RetainPtr<CGImageRef> cgImage = adoptCF(CGImageSourceCreateImageAtIndex(source.get(), 0, NULL));
-
-    if (!cgImage)
-        return;
-
-    Page* page = [_menuClient->webView() page];
-    if (!page)
-        return;
+    id item = [items objectAtIndex:0];
 
-    NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:serviceControlsPasteboardName];
-    [pasteboard declareTypes:@[ NSPasteboardTypeTIFF ] owner:nil];
-    [pasteboard setData:[items objectAtIndex:0] forType:NSPasteboardTypeTIFF];
-
-    Frame& frame = page->focusController().focusedOrMainFrame();
-    if (!frame.selection().isNone())
-        frame.editor().readSelectionFromPasteboard(serviceControlsPasteboardName);
-
-    [self clear];
+    if ([item isKindOfClass:[NSImage class]])
+        [self didShareImageData:[item TIFFRepresentation] confirmDataIsValidTIFFData:NO];
+    else if ([item isKindOfClass:[NSItemProvider class]]) {
+        NSItemProvider *itemProvider = (NSItemProvider *)item;
+        NSString *itemUTI = itemProvider.registeredTypeIdentifiers.firstObject;
+        
+        [itemProvider loadItemForTypeIdentifier:itemUTI options:nil completionHandler:^(id receivedData, NSError *dataError) {
+            if (!receivedData) {
+                LOG_ERROR("Did not receive data from NSItemProvider");
+                return;
+            }
+
+            if (![receivedData isKindOfClass:[NSData class]]) {
+                LOG_ERROR("Data received from NSItemProvider is not of type NSData");
+                return;
+            }
+
+            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+                [self didShareImageData:receivedData confirmDataIsValidTIFFData:YES];
+            }];
+
+        }];
+    } else
+        LOG_ERROR("sharingService:didShareItems: - Unknown item type returned");
 }
 
 - (void)sharingService:(NSSharingService *)sharingService didFailToShareItems:(NSArray *)items error:(NSError *)error
index 4cd930c..6191f4d 100644 (file)
@@ -50,6 +50,7 @@
 #import <WebCore/URL.h>
 #import <WebCore/LocalizedStrings.h>
 #import <WebCore/Page.h>
+#import <WebCore/SharedBuffer.h>
 #import <WebCore/Frame.h>
 #import <WebCore/FrameView.h>
 #import <WebCore/RuntimeApplicationChecks.h>
@@ -363,8 +364,13 @@ NSMenu *WebContextMenuClient::contextMenuForEvent(NSEvent *event, NSView *view)
 #if ENABLE(SERVICE_CONTROLS)
     if (Image* image = page->contextMenuController().context().controlledImage()) {
         ASSERT(page->contextMenuController().context().hitTestResult().innerNode());
+
+        RefPtr<SharedBuffer> data = image->data();
+        ASSERT(data);
+        RetainPtr<CFDataRef> cfData = data->createCFData();
+
         bool isContentEditable = page->contextMenuController().context().hitTestResult().innerNode()->isContentEditable();
-        m_sharingServicePickerController = adoptNS([[WebSharingServicePickerController alloc] initWithImage:image->getNSImage() includeEditorServices:isContentEditable menuClient:this]);
+        m_sharingServicePickerController = adoptNS([[WebSharingServicePickerController alloc] initWithData:(NSData *)cfData.get() includeEditorServices:isContentEditable menuClient:this]);
         
         return [m_sharingServicePickerController menu];
     }