Changeset 210287 in webkit


Ignore:
Timestamp:
Jan 4, 2017 2:30:32 PM (7 years ago)
Author:
enrica@apple.com
Message:

Support File Promise during drag for macOS.
https://bugs.webkit.org/show_bug.cgi?id=165204
rdar://problem/19595567

Reviewed by Tim Horton.

Source/WebCore:

Adds the support for handling File Promise type during
drag. DragData now has the knowledge of the NSFilesPromisePboardType and
checks for the data type during drag.

  • page/mac/DragControllerMac.mm:

(WebCore::DragController::dragOperation):

  • platform/DragData.h:

(WebCore::DragData::setFileNames):
(WebCore::DragData::fileNames):

  • platform/mac/DragDataMac.mm:

(WebCore::DragData::containsFiles):
(WebCore::DragData::numberOfFiles):
(WebCore::DragData::asFilenames):
(WebCore::DragData::containsCompatibleContent):
(WebCore::DragData::containsPromise):
(WebCore::DragData::asURL):

Source/WebKit/mac:

Adds support for dropping a File Promise in a WebView.
The implementation uses new File Promise API available in Sierra.

  • Misc/WebNSPasteboardExtras.mm:

(+[NSPasteboard _web_dragTypesForURL]):

  • WebView/WebView.mm:

(-[WebView performDragOperation:]):

Source/WebKit2:

Adds support for dropping a File Promise in a WKWebView.
The implementation uses new File Promise API available in Sierra.

  • Shared/WebCoreArgumentCoders.cpp:

(IPC::ArgumentCoder<DragData>::encode):
(IPC::ArgumentCoder<DragData>::decode):

  • Shared/mac/PasteboardTypes.mm:

(WebKit::PasteboardTypes::forURL):

  • UIProcess/Cocoa/WebViewImpl.h:
  • UIProcess/Cocoa/WebViewImpl.mm:

(WebKit::WebViewImpl::createSandboxExtensionsIfNeeded):
(WebKit::WebViewImpl::performDragOperation):
(WebKit::maybeCreateSandboxExtensionFromPasteboard): Deleted.
(WebKit::createSandboxExtensionsForFileUpload): Deleted.

Location:
trunk/Source
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r210284 r210287  
     12017-01-04  Enrica Casucci  <enrica@apple.com>
     2
     3        Support File Promise during drag for macOS.
     4        https://bugs.webkit.org/show_bug.cgi?id=165204
     5        rdar://problem/19595567
     6
     7        Reviewed by Tim Horton.
     8
     9        Adds the support for handling File Promise type during
     10        drag. DragData now has the knowledge of the NSFilesPromisePboardType and
     11        checks for the data type during drag.
     12
     13        * page/mac/DragControllerMac.mm:
     14        (WebCore::DragController::dragOperation):
     15        * platform/DragData.h:
     16        (WebCore::DragData::setFileNames):
     17        (WebCore::DragData::fileNames):
     18        * platform/mac/DragDataMac.mm:
     19        (WebCore::DragData::containsFiles):
     20        (WebCore::DragData::numberOfFiles):
     21        (WebCore::DragData::asFilenames):
     22        (WebCore::DragData::containsCompatibleContent):
     23        (WebCore::DragData::containsPromise):
     24        (WebCore::DragData::asURL):
     25
    1262017-01-04  Chris Dumez  <cdumez@apple.com>
    227
  • trunk/Source/WebCore/page/mac/DragControllerMac.mm

    r208904 r210287  
    6262DragOperation DragController::dragOperation(const DragData& dragData)
    6363{
    64     if ((dragData.flags() & DragApplicationIsModal) || !dragData.containsURL())
     64    if ((dragData.flags() & DragApplicationIsModal) || !(dragData.containsURL() || dragData.containsPromise()))
    6565        return DragOperationNone;
    6666
  • trunk/Source/WebCore/platform/DragData.h

    r208904 r210287  
    106106    bool containsFiles() const;
    107107    unsigned numberOfFiles() const;
     108    void setFileNames(Vector<String>& fileNames) { m_fileNames = WTFMove(fileNames); }
     109    const Vector<String>& fileNames() const { return m_fileNames; }
    108110#if PLATFORM(MAC)
    109111    const String& pasteboardName() const { return m_pasteboardName; }
     112    bool containsPromise() const;
    110113#endif
    111114
     
    129132    DragOperation m_draggingSourceOperationMask;
    130133    DragApplicationFlags m_applicationFlags;
     134    Vector<String> m_fileNames;
    131135#if PLATFORM(MAC)
    132136    String m_pasteboardName;
  • trunk/Source/WebCore/platform/mac/DragDataMac.mm

    r173686 r210287  
    7474    Vector<String> types;
    7575    platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName);
    76     return types.contains(String(NSFilenamesPboardType));
     76    return types.contains(String(NSFilenamesPboardType)) || types.contains(String(NSFilesPromisePboardType));
    7777}
    7878
     
    8181    Vector<String> files;
    8282    platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(NSFilenamesPboardType), m_pasteboardName);
     83    if (!files.size())
     84        platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(NSFilesPromisePboardType), m_pasteboardName);
    8385    return files.size();
    8486}
     
    8789{
    8890    platformStrategies()->pasteboardStrategy()->getPathnamesForType(result, String(NSFilenamesPboardType), m_pasteboardName);
     91    if (!result.size())
     92        result = fileNames();
    8993}
    9094
     
    129133        || types.contains(String(NSHTMLPboardType))
    130134        || types.contains(String(NSFilenamesPboardType))
     135        || types.contains(String(NSFilesPromisePboardType))
    131136        || types.contains(String(NSTIFFPboardType))
    132137        || types.contains(String(NSPDFPboardType))
     
    138143        || types.contains(String(kUTTypePNG));
    139144}
    140    
     145
     146bool DragData::containsPromise() const
     147{
     148    Vector<String> files;
     149    platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(NSFilesPromisePboardType), m_pasteboardName);
     150    return files.size() == 1;
     151}
     152
    141153bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const
    142154{
     
    185197        }
    186198    }
    187    
     199
     200    if (types.contains(String(NSFilesPromisePboardType)) && fileNames().size() == 1)
     201        return [URLByCanonicalizingURL([NSURL fileURLWithPath:fileNames()[0]]) absoluteString];
     202
    188203    return String();       
    189204}
  • trunk/Source/WebKit/mac/ChangeLog

    r210273 r210287  
     12017-01-04  Enrica Casucci  <enrica@apple.com>
     2
     3        Support File Promise during drag for macOS.
     4        https://bugs.webkit.org/show_bug.cgi?id=165204
     5        rdar://problem/19595567
     6
     7        Reviewed by Tim Horton.
     8
     9        Adds support for dropping a File Promise in a WebView.
     10        The implementation uses new File Promise API available in Sierra.
     11
     12        * Misc/WebNSPasteboardExtras.mm:
     13        (+[NSPasteboard _web_dragTypesForURL]):
     14        * WebView/WebView.mm:
     15        (-[WebView performDragOperation:]):
     16
    1172017-01-04  Tim Horton  <timothy_horton@apple.com>
    218
  • trunk/Source/WebKit/mac/Misc/WebNSPasteboardExtras.mm

    r201588 r210287  
    114114        NSStringPboardType,
    115115        NSFilenamesPboardType,
     116#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
     117        NSFilesPromisePboardType,
     118#endif
    116119        nil];
    117120}
  • trunk/Source/WebKit/mac/WebView/WebView.mm

    r210273 r210287  
    65186518    IntPoint client([draggingInfo draggingLocation]);
    65196519    IntPoint global(globalPoint([draggingInfo draggingLocation], [self window]));
    6520     DragData dragData(draggingInfo, client, global, static_cast<DragOperation>([draggingInfo draggingSourceOperationMask]), [self applicationFlags:draggingInfo]);
    6521     return core(self)->dragController().performDragOperation(dragData);
     6520    DragData *dragData = new DragData(draggingInfo, client, global, static_cast<DragOperation>([draggingInfo draggingSourceOperationMask]), [self applicationFlags:draggingInfo]);
     6521
     6522#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
     6523    if ([draggingInfo.draggingPasteboard.types containsObject:NSFilesPromisePboardType]) {
     6524        NSArray *files = [draggingInfo.draggingPasteboard propertyListForType:NSFilesPromisePboardType];
     6525        if (![files isKindOfClass:[NSArray class]]) {
     6526            delete dragData;
     6527            return false;
     6528        }
     6529        size_t fileCount = files.count;
     6530        Vector<String> *fileNames = new Vector<String>;
     6531        NSURL *dropLocation = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
     6532        [draggingInfo enumerateDraggingItemsWithOptions:0 forView:self classes:@[[NSFilePromiseReceiver class]] searchOptions:@{ } usingBlock:^(NSDraggingItem * __nonnull draggingItem, NSInteger idx, BOOL * __nonnull stop) {
     6533            NSFilePromiseReceiver *item = draggingItem.item;
     6534            NSDictionary *options = @{ };
     6535
     6536            [item receivePromisedFilesAtDestination:dropLocation options:options operationQueue:[NSOperationQueue new] reader:^(NSURL * _Nonnull fileURL, NSError * _Nullable errorOrNil) {
     6537                if (errorOrNil)
     6538                    return;
     6539
     6540                dispatch_async(dispatch_get_main_queue(), [self, path = RetainPtr<NSString>(fileURL.path), fileNames, fileCount, dragData] {
     6541                    fileNames->append(path.get());
     6542                    if (fileNames->size() == fileCount) {
     6543                        dragData->setFileNames(*fileNames);
     6544                        core(self)->dragController().performDragOperation(*dragData);
     6545                        delete dragData;
     6546                        delete fileNames;
     6547                    }
     6548                });
     6549            }];
     6550        }];
     6551
     6552        return true;
     6553    }
     6554#endif
     6555    bool returnValue = core(self)->dragController().performDragOperation(*dragData);
     6556    delete dragData;
     6557
     6558    return returnValue;
    65226559}
    65236560
  • trunk/Source/WebKit2/ChangeLog

    r210281 r210287  
     12017-01-04  Enrica Casucci  <enrica@apple.com>
     2
     3        Support File Promise during drag for macOS.
     4        https://bugs.webkit.org/show_bug.cgi?id=165204
     5        rdar://problem/19595567
     6
     7        Reviewed by Tim Horton.
     8
     9        Adds support for dropping a File Promise in a WKWebView.
     10        The implementation uses new File Promise API available in Sierra.
     11
     12        * Shared/WebCoreArgumentCoders.cpp:
     13        (IPC::ArgumentCoder<DragData>::encode):
     14        (IPC::ArgumentCoder<DragData>::decode):
     15        * Shared/mac/PasteboardTypes.mm:
     16        (WebKit::PasteboardTypes::forURL):
     17        * UIProcess/Cocoa/WebViewImpl.h:
     18        * UIProcess/Cocoa/WebViewImpl.mm:
     19        (WebKit::WebViewImpl::createSandboxExtensionsIfNeeded):
     20        (WebKit::WebViewImpl::performDragOperation):
     21        (WebKit::maybeCreateSandboxExtensionFromPasteboard): Deleted.
     22        (WebKit::createSandboxExtensionsForFileUpload): Deleted.
     23
    1242017-01-04  Jeremy Jones  <jeremyj@apple.com>
    225
  • trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp

    r208916 r210287  
    12261226#if PLATFORM(MAC)
    12271227    encoder << dragData.pasteboardName();
     1228    encoder << dragData.fileNames();
    12281229#endif
    12291230}
     
    12521253        return false;
    12531254#endif
     1255    Vector<String> fileNames;
     1256    if (!decoder.decode(fileNames))
     1257        return false;
    12541258
    12551259    dragData = DragData(pasteboardName, clientPosition, globalPosition, draggingSourceOperationMask, applicationFlags);
     1260    dragData.setFileNames(fileNames);
    12561261
    12571262    return true;
  • trunk/Source/WebKit2/Shared/mac/PasteboardTypes.mm

    r201189 r210287  
    5454NSArray* PasteboardTypes::forURL()
    5555{
    56     static NSArray *types = retain([NSArray arrayWithObjects:WebURLsWithTitlesPboardType, NSURLPboardType, WebURLPboardType,  WebURLNamePboardType, NSStringPboardType, NSFilenamesPboardType, nil]);
     56    static NSArray *types = retain([NSArray arrayWithObjects:WebURLsWithTitlesPboardType, NSURLPboardType, WebURLPboardType,  WebURLNamePboardType, NSStringPboardType, NSFilenamesPboardType,
     57#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
     58                                    NSFilesPromisePboardType,
     59#endif
     60                                    nil]);
    5761    return types;
    5862}
  • trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.h

    r210075 r210287  
    583583    bool mightBeginDragWhileInactive();
    584584    bool mightBeginScrollWhileInactive();
     585    void createSandboxExtensionsIfNeeded(const Vector<String>& files, SandboxExtension::Handle&, SandboxExtension::HandleArray& handles);
    585586
    586587#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
  • trunk/Source/WebKit2/UIProcess/Cocoa/WebViewImpl.mm

    r210247 r210287  
    36173617}
    36183618
    3619 // FIXME: This code is more or less copied from Pasteboard::getBestURL.
    3620 // It would be nice to be able to share the code somehow.
    3621 static bool maybeCreateSandboxExtensionFromPasteboard(NSPasteboard *pasteboard, SandboxExtension::Handle& sandboxExtensionHandle)
    3622 {
    3623     NSArray *types = pasteboard.types;
    3624     if (![types containsObject:NSFilenamesPboardType])
    3625         return false;
    3626 
    3627     NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
    3628     if (files.count != 1)
    3629         return false;
    3630 
    3631     NSString *file = [files objectAtIndex:0];
    3632     BOOL isDirectory;
    3633     if (![[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory])
    3634         return false;
    3635 
    3636     if (isDirectory)
    3637         return false;
    3638 
    3639     SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
    3640     return true;
    3641 }
    3642 
    3643 static void createSandboxExtensionsForFileUpload(NSPasteboard *pasteboard, SandboxExtension::HandleArray& handles)
    3644 {
    3645     NSArray *types = pasteboard.types;
    3646     if (![types containsObject:NSFilenamesPboardType])
    3647         return;
    3648 
    3649     NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
    3650     handles.allocate(files.count);
    3651     for (unsigned i = 0; i < files.count; i++) {
    3652         NSString *file = [files objectAtIndex:i];
     3619void WebViewImpl::createSandboxExtensionsIfNeeded(const Vector<String>& files, SandboxExtension::Handle& handle, SandboxExtension::HandleArray& handles)
     3620{
     3621    if (!files.size())
     3622        return;
     3623
     3624    if (files.size() == 1) {
     3625        BOOL isDirectory;
     3626        if ([[NSFileManager defaultManager] fileExistsAtPath:files[0] isDirectory:&isDirectory] && !isDirectory) {
     3627            SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, handle);
     3628            m_page->process().willAcquireUniversalFileReadSandboxExtension();
     3629        }
     3630    }
     3631
     3632    handles.allocate(files.size());
     3633    for (size_t i = 0; i< files.size(); i++) {
     3634        NSString *file = files[i];
    36533635        if (![[NSFileManager defaultManager] fileExistsAtPath:file])
    36543636            continue;
    3655         SandboxExtension::Handle handle;
    36563637        SandboxExtension::createHandle(file, SandboxExtension::ReadOnly, handles[i]);
    36573638    }
     
    36623643    WebCore::IntPoint client([m_view convertPoint:draggingInfo.draggingLocation fromView:nil]);
    36633644    WebCore::IntPoint global(WebCore::globalPoint(draggingInfo.draggingLocation, m_view.window));
    3664     WebCore::DragData dragData(draggingInfo, client, global, static_cast<WebCore::DragOperation>(draggingInfo.draggingSourceOperationMask), applicationFlagsForDrag(m_view, draggingInfo));
    3665 
     3645    WebCore::DragData *dragData = new WebCore::DragData(draggingInfo, client, global, static_cast<WebCore::DragOperation>(draggingInfo.draggingSourceOperationMask), applicationFlagsForDrag(m_view, draggingInfo));
     3646
     3647    NSArray *types = draggingInfo.draggingPasteboard.types;
    36663648    SandboxExtension::Handle sandboxExtensionHandle;
    3667     bool createdExtension = maybeCreateSandboxExtensionFromPasteboard(draggingInfo.draggingPasteboard, sandboxExtensionHandle);
    3668     if (createdExtension)
    3669         m_page->process().willAcquireUniversalFileReadSandboxExtension();
    3670 
    36713649    SandboxExtension::HandleArray sandboxExtensionForUpload;
    3672     createSandboxExtensionsForFileUpload(draggingInfo.draggingPasteboard, sandboxExtensionForUpload);
    3673 
    3674     m_page->performDragOperation(dragData, draggingInfo.draggingPasteboard.name, sandboxExtensionHandle, sandboxExtensionForUpload);
     3650
     3651    if ([types containsObject:NSFilenamesPboardType]) {
     3652        NSArray *files = [draggingInfo.draggingPasteboard propertyListForType:NSFilenamesPboardType];
     3653        if (![files isKindOfClass:[NSArray class]]) {
     3654            delete dragData;
     3655            return false;
     3656        }
     3657
     3658        Vector<String> fileNames;
     3659
     3660        for (NSString *file in files)
     3661            fileNames.append(file);
     3662        createSandboxExtensionsIfNeeded(fileNames, sandboxExtensionHandle, sandboxExtensionForUpload);
     3663    }
     3664#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
     3665    else if ([types containsObject:NSFilesPromisePboardType]) {
     3666        NSArray *files = [draggingInfo.draggingPasteboard propertyListForType:NSFilesPromisePboardType];
     3667        if (![files isKindOfClass:[NSArray class]]) {
     3668            delete dragData;
     3669            return false;
     3670        }
     3671        size_t fileCount = files.count;
     3672        Vector<String> *fileNames = new Vector<String>;
     3673        NSURL *dropLocation = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
     3674        String pasteboardName = draggingInfo.draggingPasteboard.name;
     3675        [draggingInfo enumerateDraggingItemsWithOptions:0 forView:m_view classes:@[[NSFilePromiseReceiver class]] searchOptions:@{ } usingBlock:^(NSDraggingItem * __nonnull draggingItem, NSInteger idx, BOOL * __nonnull stop) {
     3676            NSFilePromiseReceiver *item = draggingItem.item;
     3677            NSDictionary *options = @{ };
     3678
     3679            [item receivePromisedFilesAtDestination:dropLocation options:options operationQueue:[NSOperationQueue new] reader:^(NSURL * _Nonnull fileURL, NSError * _Nullable errorOrNil) {
     3680                if (errorOrNil)
     3681                    return;
     3682
     3683                dispatch_async(dispatch_get_main_queue(), [this, path = RetainPtr<NSString>(fileURL.path), fileNames, fileCount, dragData, pasteboardName] {
     3684                    fileNames->append(path.get());
     3685                    if (fileNames->size() == fileCount) {
     3686                        SandboxExtension::Handle sandboxExtensionHandle;
     3687                        SandboxExtension::HandleArray sandboxExtensionForUpload;
     3688
     3689                        createSandboxExtensionsIfNeeded(*fileNames, sandboxExtensionHandle, sandboxExtensionForUpload);
     3690                        dragData->setFileNames(*fileNames);
     3691                        m_page->performDragOperation(*dragData, pasteboardName, sandboxExtensionHandle, sandboxExtensionForUpload);
     3692                        delete dragData;
     3693                        delete fileNames;
     3694                    }
     3695                });
     3696            }];
     3697        }];
     3698
     3699        return true;
     3700    }
     3701#endif
     3702
     3703    m_page->performDragOperation(*dragData, draggingInfo.draggingPasteboard.name, sandboxExtensionHandle, sandboxExtensionForUpload);
     3704    delete dragData;
    36753705
    36763706    return true;
Note: See TracChangeset for help on using the changeset viewer.