Changeset 239086 in webkit


Ignore:
Timestamp:
Dec 11, 2018 1:13:32 PM (5 years ago)
Author:
Wenson Hsieh
Message:

[iOS] Send the full list of file upload URLs and types in PasteboardItemInfo
https://bugs.webkit.org/show_bug.cgi?id=192598
Work towards <rdar://problem/35626913>

Reviewed by Tim Horton.

Refactors PasteboardItemInfo to contain lists of file URLs and corresponding pasteboard types, instead of just
a "preferred" file upload URL and type. See below for more details.

  • platform/PasteboardItemInfo.h:

(WebCore::PasteboardItemInfo::pathForContentType const):

Add a helper method to find a file upload URL corresponding to a given type.

(WebCore::PasteboardItemInfo::encode const):
(WebCore::PasteboardItemInfo::decode):

Change pathForFileUpload to pathsForFileUpload, and contentTypeForFileUpload to contentTypesForFileUpload.

  • platform/ios/AbstractPasteboard.h:
  • platform/ios/PasteboardIOS.mm:

(WebCore::Pasteboard::readRespectingUTIFidelities):

Adjust this to take the file path for the highest fidelity representation in pathsForContentType.

(WebCore::Pasteboard::readFilePaths):

  • platform/ios/PlatformPasteboardIOS.mm:

(WebCore::PlatformPasteboard::informationForItemAtIndex):

  • platform/ios/WebItemProviderPasteboard.h:
  • platform/ios/WebItemProviderPasteboard.mm:

(-[NSItemProvider web_containsFileURLAndFileUploadContent]):
(-[NSItemProvider web_fileUploadContentTypes]):

Replace web_containsFileUploadContent with web_fileUploadContentTypes, which returns the full list of file
upload content types (rather than just a BOOL indicating whether one or more of these types exist).

(-[WebItemProviderPasteboard fileUploadURLsAtIndex:fileTypes:]):
(-[WebItemProviderPasteboard numberOfFiles]):
(-[NSItemProvider web_containsFileUploadContent]): Deleted.
(-[WebItemProviderPasteboard preferredFileUploadURLAtIndex:fileType:]): Deleted.

Replaced with -fileUploadURLsAtIndex:fileTypes:. This implementation currently just returns the highest
fidelity loaded type identifier, but this is wrong because it doesn't take into account inline data types that
shouldn't be represented as data for file uploads (for instance, it never makes sense to upload the internal
data serialization for an NSURL as a file on the web).

Instead, use existing logic in web_fileUploadContentTypes to determine which file types can be treated as file
uploads, and return all of these file types that we've loaded.

Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r239081 r239086  
     12018-12-11  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Send the full list of file upload URLs and types in PasteboardItemInfo
     4        https://bugs.webkit.org/show_bug.cgi?id=192598
     5        Work towards <rdar://problem/35626913>
     6
     7        Reviewed by Tim Horton.
     8
     9        Refactors PasteboardItemInfo to contain lists of file URLs and corresponding pasteboard types, instead of just
     10        a "preferred" file upload URL and type. See below for more details.
     11
     12        * platform/PasteboardItemInfo.h:
     13        (WebCore::PasteboardItemInfo::pathForContentType const):
     14
     15        Add a helper method to find a file upload URL corresponding to a given type.
     16
     17        (WebCore::PasteboardItemInfo::encode const):
     18        (WebCore::PasteboardItemInfo::decode):
     19
     20        Change `pathForFileUpload` to `pathsForFileUpload`, and `contentTypeForFileUpload` to `contentTypesForFileUpload`.
     21
     22        * platform/ios/AbstractPasteboard.h:
     23        * platform/ios/PasteboardIOS.mm:
     24        (WebCore::Pasteboard::readRespectingUTIFidelities):
     25
     26        Adjust this to take the file path for the highest fidelity representation in `pathsForContentType`.
     27
     28        (WebCore::Pasteboard::readFilePaths):
     29        * platform/ios/PlatformPasteboardIOS.mm:
     30        (WebCore::PlatformPasteboard::informationForItemAtIndex):
     31        * platform/ios/WebItemProviderPasteboard.h:
     32        * platform/ios/WebItemProviderPasteboard.mm:
     33        (-[NSItemProvider web_containsFileURLAndFileUploadContent]):
     34        (-[NSItemProvider web_fileUploadContentTypes]):
     35
     36        Replace `web_containsFileUploadContent` with `web_fileUploadContentTypes`, which returns the full list of file
     37        upload content types (rather than just a `BOOL` indicating whether one or more of these types exist).
     38
     39        (-[WebItemProviderPasteboard fileUploadURLsAtIndex:fileTypes:]):
     40        (-[WebItemProviderPasteboard numberOfFiles]):
     41        (-[NSItemProvider web_containsFileUploadContent]): Deleted.
     42        (-[WebItemProviderPasteboard preferredFileUploadURLAtIndex:fileType:]): Deleted.
     43
     44        Replaced with `-fileUploadURLsAtIndex:fileTypes:`. This implementation currently just returns the highest
     45        fidelity loaded type identifier, but this is wrong because it doesn't take into account inline data types that
     46        shouldn't be represented as data for file uploads (for instance, it never makes sense to upload the internal
     47        data serialization for an `NSURL` as a file on the web).
     48
     49        Instead, use existing logic in `web_fileUploadContentTypes` to determine which file types can be treated as file
     50        uploads, and return all of these file types that we've loaded.
     51
    1522018-12-11  Don Olmstead  <don.olmstead@sony.com>
    253
  • trunk/Source/WebCore/platform/PasteboardItemInfo.h

    r238795 r239086  
    2727
    2828#include <wtf/Optional.h>
     29#include <wtf/Vector.h>
    2930#include <wtf/text/WTFString.h>
    3031
     
    3839
    3940struct PasteboardItemInfo {
    40     String pathForFileUpload;
    41     String contentTypeForFileUpload;
     41    Vector<String> pathsForFileUpload;
     42    Vector<String> contentTypesForFileUpload;
    4243    String suggestedFileName;
    4344    bool isNonTextType { false };
    4445    bool containsFileURLAndFileUploadContent { false };
    4546    PasteboardItemPresentationStyle preferredPresentationStyle { PasteboardItemPresentationStyle::Unspecified };
     47
     48    String pathForContentType(const String& type) const
     49    {
     50        ASSERT(pathsForFileUpload.size() == contentTypesForFileUpload.size());
     51        auto index = contentTypesForFileUpload.find(type);
     52        if (index == notFound)
     53            return { };
     54
     55        return pathsForFileUpload[index];
     56    }
    4657
    4758    template<class Encoder> void encode(Encoder&) const;
     
    5263void PasteboardItemInfo::encode(Encoder& encoder) const
    5364{
    54     encoder << pathForFileUpload << contentTypeForFileUpload << suggestedFileName << isNonTextType << containsFileURLAndFileUploadContent;
     65    encoder << pathsForFileUpload << contentTypesForFileUpload << suggestedFileName << isNonTextType << containsFileURLAndFileUploadContent;
    5566    encoder.encodeEnum(preferredPresentationStyle);
    5667}
     
    6071{
    6172    PasteboardItemInfo result;
    62     if (!decoder.decode(result.pathForFileUpload))
     73    if (!decoder.decode(result.pathsForFileUpload))
    6374        return std::nullopt;
    6475
    65     if (!decoder.decode(result.contentTypeForFileUpload))
     76    if (!decoder.decode(result.contentTypesForFileUpload))
    6677        return std::nullopt;
    6778
  • trunk/Source/WebCore/platform/ios/AbstractPasteboard.h

    r226396 r239086  
    5858@property (readonly, nonatomic) NSInteger numberOfFiles;
    5959@property (readonly, nonatomic) NSArray<NSURL *> *allDroppedFileURLs;
    60 - (nullable NSURL *)preferredFileUploadURLAtIndex:(NSUInteger)index fileType:(NSString *_Nullable *_Nullable)outFileType;
     60
     61// Computes lists of file URLs and types. Each file URL and type corresponds to a representation of the item provider at the given index.
     62// In order from highest fidelity to lowest fidelity.
     63- (NSArray<NSURL *> *)fileUploadURLsAtIndex:(NSUInteger)index fileTypes:(NSArray<NSString *> *_Nullable *_Nonnull)outFileTypes;
    6164- (void)updateSupportedTypeIdentifiers:(NSArray<NSString *> *)types;
    6265
  • trunk/Source/WebCore/platform/ios/PasteboardIOS.mm

    r239053 r239086  
    295295#if ENABLE(ATTACHMENT_ELEMENT)
    296296        auto info = strategy.informationForItemAtIndex(index, m_pasteboardName);
    297         bool canReadAttachment = policy == WebContentReadingPolicy::AnyType && RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() && !info.pathForFileUpload.isEmpty();
     297        bool canReadAttachment = policy == WebContentReadingPolicy::AnyType && RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() && !info.pathsForFileUpload.isEmpty();
    298298        if (canReadAttachment && info.preferredPresentationStyle == PasteboardItemPresentationStyle::Attachment) {
    299             reader.readFilePaths({ info.pathForFileUpload });
     299            reader.readFilePaths({ info.pathsForFileUpload.first() });
    300300            continue;
    301301        }
     
    318318#if ENABLE(ATTACHMENT_ELEMENT)
    319319        if (canReadAttachment && result == ReaderResult::DidNotReadType)
    320             reader.readFilePaths({ info.pathForFileUpload });
     320            reader.readFilePaths({ info.pathsForFileUpload.first() });
    321321#endif
    322322    }
     
    460460    for (NSUInteger index = 0, numberOfItems = strategy.getPasteboardItemsCount(m_pasteboardName); index < numberOfItems; ++index) {
    461461        // Currently, drag and drop is the only case on iOS where the "pasteboard" may contain file paths.
    462         auto filePath = strategy.informationForItemAtIndex(index, m_pasteboardName).pathForFileUpload;
     462        auto filePath = strategy.informationForItemAtIndex(index, m_pasteboardName).pathsForFileUpload.first();
    463463        if (!filePath.isEmpty())
    464464            filePaths.append(WTFMove(filePath));
  • trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm

    r238795 r239086  
    145145
    146146    PasteboardItemInfo info;
    147     if ([m_pasteboard respondsToSelector:@selector(preferredFileUploadURLAtIndex:fileType:)]) {
    148         NSString *fileType = nil;
    149         info.pathForFileUpload = [m_pasteboard preferredFileUploadURLAtIndex:index fileType:&fileType].path;
    150         info.contentTypeForFileUpload = fileType;
     147    if ([m_pasteboard respondsToSelector:@selector(fileUploadURLsAtIndex:fileTypes:)]) {
     148        NSArray<NSString *> *fileTypes = nil;
     149        NSArray *urls = [m_pasteboard fileUploadURLsAtIndex:index fileTypes:&fileTypes];
     150        ASSERT(fileTypes.count == urls.count);
     151
     152        info.pathsForFileUpload.reserveInitialCapacity(urls.count);
     153        for (NSURL *url in urls)
     154            info.pathsForFileUpload.uncheckedAppend(url.path);
     155
     156        info.contentTypesForFileUpload.reserveInitialCapacity(fileTypes.count);
     157        for (NSString *fileType : fileTypes)
     158            info.contentTypesForFileUpload.uncheckedAppend(fileType);
    151159    }
    152160
  • trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h

    r238795 r239086  
    9898@property (readonly, nonatomic) NSArray<NSURL *> *allDroppedFileURLs;
    9999
    100 // The preferred file URL corresponds to the highest fidelity non-private UTI that was loaded.
    101 - (nullable NSURL *)preferredFileUploadURLAtIndex:(NSUInteger)index fileType:(NSString *_Nullable *_Nullable)outFileType;
    102 
    103100@property (readonly, nonatomic) BOOL hasPendingOperation;
    104101- (void)incrementPendingOperationCount;
  • trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm

    r239053 r239086  
    6969    for (NSString *identifier in self.registeredTypeIdentifiers) {
    7070        if (UTTypeConformsTo((__bridge CFStringRef)identifier, kUTTypeFileURL))
    71             return self.web_containsFileUploadContent;
     71            return self.web_fileUploadContentTypes.count;
    7272    }
    7373    return NO;
    7474}
    7575
    76 - (BOOL)web_containsFileUploadContent
    77 {
     76- (NSArray<NSString *> *)web_fileUploadContentTypes
     77{
     78    auto types = adoptNS([NSMutableArray new]);
    7879    for (NSString *identifier in self.registeredTypeIdentifiers) {
    7980        if (UTTypeConformsTo((__bridge CFStringRef)identifier, kUTTypeURL))
     
    8182
    8283        if (typeConformsToTypes(identifier, Pasteboard::supportedFileUploadPasteboardTypes()))
    83             return YES;
    84     }
    85     return NO;
     84            [types addObject:identifier];
     85    }
     86
     87    return types.autorelease();
    8688}
    8789
     
    629631}
    630632
    631 - (NSURL *)preferredFileUploadURLAtIndex:(NSUInteger)index fileType:(NSString **)outFileType
    632 {
    633     if (outFileType)
    634         *outFileType = nil;
     633- (NSArray<NSURL *> *)fileUploadURLsAtIndex:(NSUInteger)index fileTypes:(NSArray<NSString *> **)outFileTypes
     634{
     635    auto fileTypes = adoptNS([NSMutableArray new]);
     636    auto fileURLs = adoptNS([NSMutableArray new]);
    635637
    636638    if (index >= _loadResults.size())
    637         return nil;
     639        return @[ ];
    638640
    639641    auto result = _loadResults[index];
    640642    if (![result canBeRepresentedAsFileUpload])
    641         return nil;
    642 
    643     NSItemProvider *itemProvider = [result itemProvider];
    644     for (NSString *registeredTypeIdentifier in itemProvider.registeredTypeIdentifiers) {
    645         // Search for the highest fidelity non-private type identifier we loaded from the item provider.
    646         if (!UTTypeIsDeclared((__bridge CFStringRef)registeredTypeIdentifier) && !UTTypeIsDynamic((__bridge CFStringRef)registeredTypeIdentifier))
    647             continue;
    648 
    649         for (NSString *loadedTypeIdentifier in [result loadedTypeIdentifiers]) {
    650             if (!UTTypeConformsTo((__bridge CFStringRef)registeredTypeIdentifier, (__bridge CFStringRef)loadedTypeIdentifier))
    651                 continue;
    652 
    653             if (outFileType)
    654                 *outFileType = loadedTypeIdentifier;
    655             return [result fileURLForType:loadedTypeIdentifier];
     643        return @[ ];
     644
     645    for (NSString *contentType in [result itemProvider].web_fileUploadContentTypes) {
     646        if (NSURL *url = [result fileURLForType:contentType]) {
     647            [fileTypes addObject:contentType];
     648            [fileURLs addObject:url];
    656649        }
    657650    }
    658651
    659     return nil;
     652    *outFileTypes = fileTypes.autorelease();
     653    return fileURLs.autorelease();
    660654}
    661655
     
    685679#endif
    686680        // Otherwise, fall back to examining the item's registered type identifiers.
    687         if (itemProvider.web_containsFileUploadContent)
     681        if (itemProvider.web_fileUploadContentTypes.count)
    688682            ++numberOfFiles;
    689683    }
Note: See TracChangeset for help on using the changeset viewer.