Title: [239086] trunk/Source/WebCore
Revision
239086
Author
wenson_hs...@apple.com
Date
2018-12-11 13:13:32 -0800 (Tue, 11 Dec 2018)

Log 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.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (239085 => 239086)


--- trunk/Source/WebCore/ChangeLog	2018-12-11 21:12:11 UTC (rev 239085)
+++ trunk/Source/WebCore/ChangeLog	2018-12-11 21:13:32 UTC (rev 239086)
@@ -1,3 +1,54 @@
+2018-12-11  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [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.
+
 2018-12-11  Don Olmstead  <don.olmst...@sony.com>
 
         Resource Load Statistics: Use common implementation within NetworkStorageSession

Modified: trunk/Source/WebCore/platform/PasteboardItemInfo.h (239085 => 239086)


--- trunk/Source/WebCore/platform/PasteboardItemInfo.h	2018-12-11 21:12:11 UTC (rev 239085)
+++ trunk/Source/WebCore/platform/PasteboardItemInfo.h	2018-12-11 21:13:32 UTC (rev 239086)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include <wtf/Optional.h>
+#include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -37,13 +38,23 @@
 };
 
 struct PasteboardItemInfo {
-    String pathForFileUpload;
-    String contentTypeForFileUpload;
+    Vector<String> pathsForFileUpload;
+    Vector<String> contentTypesForFileUpload;
     String suggestedFileName;
     bool isNonTextType { false };
     bool containsFileURLAndFileUploadContent { false };
     PasteboardItemPresentationStyle preferredPresentationStyle { PasteboardItemPresentationStyle::Unspecified };
 
+    String pathForContentType(const String& type) const
+    {
+        ASSERT(pathsForFileUpload.size() == contentTypesForFileUpload.size());
+        auto index = contentTypesForFileUpload.find(type);
+        if (index == notFound)
+            return { };
+
+        return pathsForFileUpload[index];
+    }
+
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static std::optional<PasteboardItemInfo> decode(Decoder&);
 };
@@ -51,7 +62,7 @@
 template<class Encoder>
 void PasteboardItemInfo::encode(Encoder& encoder) const
 {
-    encoder << pathForFileUpload << contentTypeForFileUpload << suggestedFileName << isNonTextType << containsFileURLAndFileUploadContent;
+    encoder << pathsForFileUpload << contentTypesForFileUpload << suggestedFileName << isNonTextType << containsFileURLAndFileUploadContent;
     encoder.encodeEnum(preferredPresentationStyle);
 }
 
@@ -59,10 +70,10 @@
 std::optional<PasteboardItemInfo> PasteboardItemInfo::decode(Decoder& decoder)
 {
     PasteboardItemInfo result;
-    if (!decoder.decode(result.pathForFileUpload))
+    if (!decoder.decode(result.pathsForFileUpload))
         return std::nullopt;
 
-    if (!decoder.decode(result.contentTypeForFileUpload))
+    if (!decoder.decode(result.contentTypesForFileUpload))
         return std::nullopt;
 
     if (!decoder.decode(result.suggestedFileName))

Modified: trunk/Source/WebCore/platform/ios/AbstractPasteboard.h (239085 => 239086)


--- trunk/Source/WebCore/platform/ios/AbstractPasteboard.h	2018-12-11 21:12:11 UTC (rev 239085)
+++ trunk/Source/WebCore/platform/ios/AbstractPasteboard.h	2018-12-11 21:13:32 UTC (rev 239086)
@@ -57,7 +57,10 @@
 - (NSArray<NSString *> *)pasteboardTypesByFidelityForItemAtIndex:(NSUInteger)index;
 @property (readonly, nonatomic) NSInteger numberOfFiles;
 @property (readonly, nonatomic) NSArray<NSURL *> *allDroppedFileURLs;
-- (nullable NSURL *)preferredFileUploadURLAtIndex:(NSUInteger)index fileType:(NSString *_Nullable *_Nullable)outFileType;
+
+// Computes lists of file URLs and types. Each file URL and type corresponds to a representation of the item provider at the given index.
+// In order from highest fidelity to lowest fidelity.
+- (NSArray<NSURL *> *)fileUploadURLsAtIndex:(NSUInteger)index fileTypes:(NSArray<NSString *> *_Nullable *_Nonnull)outFileTypes;
 - (void)updateSupportedTypeIdentifiers:(NSArray<NSString *> *)types;
 
 @end

Modified: trunk/Source/WebCore/platform/ios/PasteboardIOS.mm (239085 => 239086)


--- trunk/Source/WebCore/platform/ios/PasteboardIOS.mm	2018-12-11 21:12:11 UTC (rev 239085)
+++ trunk/Source/WebCore/platform/ios/PasteboardIOS.mm	2018-12-11 21:13:32 UTC (rev 239086)
@@ -294,9 +294,9 @@
     for (NSUInteger index = 0, numberOfItems = strategy.getPasteboardItemsCount(m_pasteboardName); index < numberOfItems; ++index) {
 #if ENABLE(ATTACHMENT_ELEMENT)
         auto info = strategy.informationForItemAtIndex(index, m_pasteboardName);
-        bool canReadAttachment = policy == WebContentReadingPolicy::AnyType && RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() && !info.pathForFileUpload.isEmpty();
+        bool canReadAttachment = policy == WebContentReadingPolicy::AnyType && RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() && !info.pathsForFileUpload.isEmpty();
         if (canReadAttachment && info.preferredPresentationStyle == PasteboardItemPresentationStyle::Attachment) {
-            reader.readFilePaths({ info.pathForFileUpload });
+            reader.readFilePaths({ info.pathsForFileUpload.first() });
             continue;
         }
 #endif
@@ -317,7 +317,7 @@
         }
 #if ENABLE(ATTACHMENT_ELEMENT)
         if (canReadAttachment && result == ReaderResult::DidNotReadType)
-            reader.readFilePaths({ info.pathForFileUpload });
+            reader.readFilePaths({ info.pathsForFileUpload.first() });
 #endif
     }
 }
@@ -459,7 +459,7 @@
     auto& strategy = *platformStrategies()->pasteboardStrategy();
     for (NSUInteger index = 0, numberOfItems = strategy.getPasteboardItemsCount(m_pasteboardName); index < numberOfItems; ++index) {
         // Currently, drag and drop is the only case on iOS where the "pasteboard" may contain file paths.
-        auto filePath = strategy.informationForItemAtIndex(index, m_pasteboardName).pathForFileUpload;
+        auto filePath = strategy.informationForItemAtIndex(index, m_pasteboardName).pathsForFileUpload.first();
         if (!filePath.isEmpty())
             filePaths.append(WTFMove(filePath));
     }

Modified: trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm (239085 => 239086)


--- trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm	2018-12-11 21:12:11 UTC (rev 239085)
+++ trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm	2018-12-11 21:13:32 UTC (rev 239086)
@@ -144,10 +144,18 @@
         return { };
 
     PasteboardItemInfo info;
-    if ([m_pasteboard respondsToSelector:@selector(preferredFileUploadURLAtIndex:fileType:)]) {
-        NSString *fileType = nil;
-        info.pathForFileUpload = [m_pasteboard preferredFileUploadURLAtIndex:index fileType:&fileType].path;
-        info.contentTypeForFileUpload = fileType;
+    if ([m_pasteboard respondsToSelector:@selector(fileUploadURLsAtIndex:fileTypes:)]) {
+        NSArray<NSString *> *fileTypes = nil;
+        NSArray *urls = [m_pasteboard fileUploadURLsAtIndex:index fileTypes:&fileTypes];
+        ASSERT(fileTypes.count == urls.count);
+
+        info.pathsForFileUpload.reserveInitialCapacity(urls.count);
+        for (NSURL *url in urls)
+            info.pathsForFileUpload.uncheckedAppend(url.path);
+
+        info.contentTypesForFileUpload.reserveInitialCapacity(fileTypes.count);
+        for (NSString *fileType : fileTypes)
+            info.contentTypesForFileUpload.uncheckedAppend(fileType);
     }
 
     NSItemProvider *itemProvider = [[m_pasteboard itemProviders] objectAtIndex:index];

Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h (239085 => 239086)


--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h	2018-12-11 21:12:11 UTC (rev 239085)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h	2018-12-11 21:13:32 UTC (rev 239086)
@@ -97,9 +97,6 @@
 // This will only be non-empty when an operation is being performed.
 @property (readonly, nonatomic) NSArray<NSURL *> *allDroppedFileURLs;
 
-// The preferred file URL corresponds to the highest fidelity non-private UTI that was loaded.
-- (nullable NSURL *)preferredFileUploadURLAtIndex:(NSUInteger)index fileType:(NSString *_Nullable *_Nullable)outFileType;
-
 @property (readonly, nonatomic) BOOL hasPendingOperation;
 - (void)incrementPendingOperationCount;
 - (void)decrementPendingOperationCount;

Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm (239085 => 239086)


--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm	2018-12-11 21:12:11 UTC (rev 239085)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm	2018-12-11 21:13:32 UTC (rev 239086)
@@ -68,21 +68,23 @@
 {
     for (NSString *identifier in self.registeredTypeIdentifiers) {
         if (UTTypeConformsTo((__bridge CFStringRef)identifier, kUTTypeFileURL))
-            return self.web_containsFileUploadContent;
+            return self.web_fileUploadContentTypes.count;
     }
     return NO;
 }
 
-- (BOOL)web_containsFileUploadContent
+- (NSArray<NSString *> *)web_fileUploadContentTypes
 {
+    auto types = adoptNS([NSMutableArray new]);
     for (NSString *identifier in self.registeredTypeIdentifiers) {
         if (UTTypeConformsTo((__bridge CFStringRef)identifier, kUTTypeURL))
             continue;
 
         if (typeConformsToTypes(identifier, Pasteboard::supportedFileUploadPasteboardTypes()))
-            return YES;
+            [types addObject:identifier];
     }
-    return NO;
+
+    return types.autorelease();
 }
 
 @end
@@ -628,35 +630,27 @@
     return _changeCount;
 }
 
-- (NSURL *)preferredFileUploadURLAtIndex:(NSUInteger)index fileType:(NSString **)outFileType
+- (NSArray<NSURL *> *)fileUploadURLsAtIndex:(NSUInteger)index fileTypes:(NSArray<NSString *> **)outFileTypes
 {
-    if (outFileType)
-        *outFileType = nil;
+    auto fileTypes = adoptNS([NSMutableArray new]);
+    auto fileURLs = adoptNS([NSMutableArray new]);
 
     if (index >= _loadResults.size())
-        return nil;
+        return @[ ];
 
     auto result = _loadResults[index];
     if (![result canBeRepresentedAsFileUpload])
-        return nil;
+        return @[ ];
 
-    NSItemProvider *itemProvider = [result itemProvider];
-    for (NSString *registeredTypeIdentifier in itemProvider.registeredTypeIdentifiers) {
-        // Search for the highest fidelity non-private type identifier we loaded from the item provider.
-        if (!UTTypeIsDeclared((__bridge CFStringRef)registeredTypeIdentifier) && !UTTypeIsDynamic((__bridge CFStringRef)registeredTypeIdentifier))
-            continue;
-
-        for (NSString *loadedTypeIdentifier in [result loadedTypeIdentifiers]) {
-            if (!UTTypeConformsTo((__bridge CFStringRef)registeredTypeIdentifier, (__bridge CFStringRef)loadedTypeIdentifier))
-                continue;
-
-            if (outFileType)
-                *outFileType = loadedTypeIdentifier;
-            return [result fileURLForType:loadedTypeIdentifier];
+    for (NSString *contentType in [result itemProvider].web_fileUploadContentTypes) {
+        if (NSURL *url = "" fileURLForType:contentType]) {
+            [fileTypes addObject:contentType];
+            [fileURLs addObject:url];
         }
     }
 
-    return nil;
+    *outFileTypes = fileTypes.autorelease();
+    return fileURLs.autorelease();
 }
 
 - (NSArray<NSURL *> *)allDroppedFileURLs
@@ -684,7 +678,7 @@
         }
 #endif
         // Otherwise, fall back to examining the item's registered type identifiers.
-        if (itemProvider.web_containsFileUploadContent)
+        if (itemProvider.web_fileUploadContentTypes.count)
             ++numberOfFiles;
     }
     return numberOfFiles;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to