Diff
Modified: trunk/Source/WebCore/ChangeLog (215713 => 215714)
--- trunk/Source/WebCore/ChangeLog 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/ChangeLog 2017-04-25 02:35:02 UTC (rev 215714)
@@ -1,3 +1,110 @@
+2017-04-24 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Respect fidelity order when reading web content from item providers
+ https://bugs.webkit.org/show_bug.cgi?id=171155
+ <rdar://problem/31356937>
+
+ Reviewed by Tim Horton.
+
+ Currently, when reading web content from pasteboards, we assume the old UIPasteboard/NSPasteboard model wherein
+ the destination must determine which of the items is considered to have the highest fidelity for the purposes of
+ inserting into an editable area. This destination-side fidelity ranking is determined solely by the NSArray
+ returned from Pasteboard::supportedPasteboardTypes, which lists compatible types in order from highest fidelity
+ to lowest fidelity. Pasteboard::read effectively iterates over this list of types in order, attempting to read
+ highest fidelity types and bailing when it first successfully reads data.
+
+ However, when our pasteboard is backed by UIItemProviders, we should instead read pasteboard types in order of
+ fidelity as specified by the source rather than the destination. To accomplish this, we introduce an alternate
+ codepath, Pasteboard::readRespectingUTIFidelities, which we take if Pasteboard::respectsUTIFidelities is true
+ (currently, this only applies for the purposes of data interaction). This version follows a different flow:
+ for each item in the pasteboard, we ask for just the UTIs for that item, in order of fidelity. For each item,
+ we then call readPasteboardWebContentDataForType to try and read data for that type, continuing until either
+ all UTIs have been attempted, or reading was successful.
+
+ This patch makes two additional adjustments. First, we introduce Pasteboard::getTypesByFidelityForItemAtIndex,
+ which is used by Pasteboard::readRespectingUTIFidelities when querying the list of supported UTIs for each
+ pasteboard item, sorted by highest to lowest fidelity.
+
+ Secondly, we refactor logic to write to the item provider pasteboard in PlatformPasteboardIOS. Since we are
+ now respecting fidelity rankings on the destination, the source must also register UTI types in the right
+ fidelity order. While this was mostly achieved using our existing method of writing a list of object
+ representations to the pasteboard and then all of the contents of a NSString => NSData dictionary containing
+ private UTI data, this approach has two flaws:
+ 1. We are unable to register high-priority custom types, followed by representing objects, followed by more
+ lower-priority custom types, since we assume that all custom types follow all representing objects.
+ 2. Since we're just iterating over a dictionary of NSString => NSData when registering custom UTI
+ representations to the item provider, there cannot inherently be any fidelity ordering for custom types.
+
+ To address both of these issues, we introduce two new objects that encapsulate how we register data to the item
+ provider pasteboard. WebItemProviderRegistrationInfo represents some data that can be registered to an item
+ provider (either an object conforming to UIItemProviderWriting, or an NSString and NSData).
+ WebItemProviderRegistrationInfoList represents a list of WebItemProviderRegistrationInfos in order of highest to
+ lowest fidelity. In PlatformPasteboardIOS, we transform PasteboardWebContent, PasteboardImage, and PasteboardURL
+ into a WebItemProviderRegistrationInfoList, which we then pass along to the WebItemProviderPasteboard. In
+ WebItemProviderPasteboard, we traverse the list of WebItemProviderRegistrationInfos in the list and register
+ each WebItemProviderRegistrationInfo's representing object or data to the item provider.
+
+ Test: DataInteractionTests.RespectsExternalSourceFidelityRankings.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/Pasteboard.h:
+ * platform/PasteboardStrategy.h:
+ * platform/PlatformPasteboard.h:
+ * platform/ios/AbstractPasteboard.h:
+ * platform/ios/AbstractPasteboard.mm: Removed.
+
+ Moves WebItemProviderData, formerly implemented in AbstractPasteboard.mm, into WebItemProviderPasteboard.mm.
+ We can delete AbstractPasteboard.mm as a result.
+
+ * platform/ios/PasteboardIOS.mm:
+ (WebCore::readPasteboardWebContentDataForType):
+
+ Pull out common logic for reading data given a UTI type from the pasteboard into the PasteboardWebContentReader.
+ This is invoked from both the existing Pasteboard::read codepath, as well as the readRespectingUTIFidelities
+ codepath.
+
+ (WebCore::Pasteboard::read):
+
+ Refactored to call the new readPasteboardWebContentDataForType helper. Behavior should not have changed, unless
+ the pasteboard supports UTI fidelities.
+
+ (WebCore::Pasteboard::respectsUTIFidelities):
+ (WebCore::Pasteboard::readRespectingUTIFidelities):
+
+ An alternative to Pasteboard::read that considers source-side fidelity rankings of UTIs.
+
+ * platform/ios/PlatformPasteboardIOS.mm:
+ (WebCore::PlatformPasteboard::getTypesByFidelityForItemAtIndex):
+ (WebCore::PlatformPasteboard::writeObjectRepresentations):
+
+ Refactored to build a WebItemProviderRegistrationInfoList and pass it to the WebItemProviderPasteboard to
+ register items and data.
+
+ (WebCore::PlatformPasteboard::write):
+ * platform/ios/WebItemProviderPasteboard.h:
+ * platform/ios/WebItemProviderPasteboard.mm:
+ (-[WebItemProviderRegistrationInfo initWithRepresentingObject:typeIdentifier:data:]):
+ (-[WebItemProviderRegistrationInfo representingObject]):
+ (-[WebItemProviderRegistrationInfo typeIdentifier]):
+ (-[WebItemProviderRegistrationInfo data]):
+
+ Represents a single calls to register data onto the item provider pasteboard. See
+ WebItemProviderPasteboard.h header comments for more info.
+
+ (-[WebItemProviderRegistrationInfoList init]):
+ (-[WebItemProviderRegistrationInfoList addData:forType:]):
+ (-[WebItemProviderRegistrationInfoList addRepresentingObject:]):
+ (-[WebItemProviderRegistrationInfoList numberOfItems]):
+ (-[WebItemProviderRegistrationInfoList itemAtIndex:]):
+ (-[WebItemProviderRegistrationInfoList enumerateItems:]):
+
+ Represents a series of calls to register representations onto the item provider pasteboard. See
+ WebItemProviderPasteboard.h header comments for more info.
+
+ (-[WebItemProviderPasteboard pasteboardTypesByFidelityForItemAtIndex:]):
+ (-[WebItemProviderPasteboard setItemsUsingRegistrationInfoLists:]):
+ (-[WebItemProviderPasteboard setItemsFromObjectRepresentations:]): Deleted.
+
2017-04-24 Chris Dumez <cdu...@apple.com>
Regression(r204605): support for "cp874" charset alias was inadvertently dropped which may cause issues on certain Thai sites
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (215713 => 215714)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-04-25 02:35:02 UTC (rev 215714)
@@ -6870,7 +6870,6 @@
F48223131E386E240066FC79 /* AbstractPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = F48223121E386E240066FC79 /* AbstractPasteboard.h */; settings = {ATTRIBUTES = (Private, ); }; };
F4BFB9851E1DDF9B00862C24 /* DumpEditingHistory.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389831E1DDF2B0076B7EA /* DumpEditingHistory.js */; };
F4BFB9861E1DDF9B00862C24 /* EditingHistoryUtil.js in Copy Scripts */ = {isa = PBXBuildFile; fileRef = F48389841E1DDF2B0076B7EA /* EditingHistoryUtil.js */; };
- F4D831621E908C0700941174 /* AbstractPasteboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D831611E908C0700941174 /* AbstractPasteboard.mm */; };
F50664F7157F52DC00AC226F /* FormController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F50664F5157F52DC00AC226F /* FormController.cpp */; };
F50664F8157F52DC00AC226F /* FormController.h in Headers */ = {isa = PBXBuildFile; fileRef = F50664F6157F52DC00AC226F /* FormController.h */; };
F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F513A3E915FF4841001526DB /* ValidationMessageClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -15430,7 +15429,6 @@
F48223121E386E240066FC79 /* AbstractPasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractPasteboard.h; sourceTree = "<group>"; };
F48389831E1DDF2B0076B7EA /* DumpEditingHistory.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = DumpEditingHistory.js; path = Scripts/DumpEditingHistory.js; sourceTree = "<group>"; };
F48389841E1DDF2B0076B7EA /* EditingHistoryUtil.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = EditingHistoryUtil.js; path = Scripts/EditingHistoryUtil.js; sourceTree = "<group>"; };
- F4D831611E908C0700941174 /* AbstractPasteboard.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AbstractPasteboard.mm; sourceTree = "<group>"; };
F50664F5157F52DC00AC226F /* FormController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormController.cpp; sourceTree = "<group>"; };
F50664F6157F52DC00AC226F /* FormController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormController.h; sourceTree = "<group>"; };
F513A3E915FF4841001526DB /* ValidationMessageClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidationMessageClient.h; sourceTree = "<group>"; };
@@ -20976,7 +20974,6 @@
children = (
A148328B187F506800DA63A6 /* wak */,
F48223121E386E240066FC79 /* AbstractPasteboard.h */,
- F4D831611E908C0700941174 /* AbstractPasteboard.mm */,
2655414B1489AA2B000DFC5D /* CursorIOS.cpp */,
A1ED778A1BE3293F00DC1791 /* Device.cpp */,
A1ED778B1BE3294000DC1791 /* Device.h */,
@@ -31804,7 +31801,6 @@
A6148A7812E41E3B0044A784 /* JSHTMLKeygenElement.cpp in Sources */,
1AE2AB210A1CE63B00B42B25 /* JSHTMLLabelElement.cpp in Sources */,
1AE2AB230A1CE63B00B42B25 /* JSHTMLLegendElement.cpp in Sources */,
- F4D831621E908C0700941174 /* AbstractPasteboard.mm in Sources */,
1AE2AB250A1CE63B00B42B25 /* JSHTMLLIElement.cpp in Sources */,
A80E7B100A19D606007FB8C5 /* JSHTMLLinkElement.cpp in Sources */,
1AE2AB270A1CE63B00B42B25 /* JSHTMLMapElement.cpp in Sources */,
Modified: trunk/Source/WebCore/platform/Pasteboard.h (215713 => 215714)
--- trunk/Source/WebCore/platform/Pasteboard.h 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/platform/Pasteboard.h 2017-04-25 02:35:02 UTC (rev 215714)
@@ -217,6 +217,11 @@
#endif
private:
+#if PLATFORM(IOS)
+ bool respectsUTIFidelities() const;
+ void readRespectingUTIFidelities(PasteboardWebContentReader&);
+#endif
+
#if PLATFORM(WIN)
void finishCreatingPasteboard();
void writeRangeToDataObject(Range&, Frame&); // FIXME: Layering violation.
Modified: trunk/Source/WebCore/platform/PasteboardStrategy.h (215713 => 215714)
--- trunk/Source/WebCore/platform/PasteboardStrategy.h 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/platform/PasteboardStrategy.h 2017-04-25 02:35:02 UTC (rev 215714)
@@ -52,6 +52,7 @@
virtual RefPtr<SharedBuffer> readBufferFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) = 0;
virtual URL readURLFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) = 0;
virtual void getFilenamesForDataInteraction(Vector<String>& filenames, const String& pasteboardName) = 0;
+ virtual void getTypesByFidelityForItemAtIndex(Vector<String>& types, uint64_t index, const String& pasteboardName) = 0;
#endif // PLATFORM(IOS)
#if PLATFORM(COCOA)
virtual void getTypes(Vector<String>& types, const String& pasteboardName) = 0;
Modified: trunk/Source/WebCore/platform/PlatformPasteboard.h (215713 => 215714)
--- trunk/Source/WebCore/platform/PlatformPasteboard.h 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/platform/PlatformPasteboard.h 2017-04-25 02:35:02 UTC (rev 215714)
@@ -56,6 +56,7 @@
#if PLATFORM(IOS)
WEBCORE_EXPORT PlatformPasteboard();
WEBCORE_EXPORT Vector<String> filenamesForDataInteraction();
+ WEBCORE_EXPORT void getTypesByFidelityForItemAtIndex(Vector<String>& types, int index);
#endif
WEBCORE_EXPORT static String uniqueName();
Modified: trunk/Source/WebCore/platform/ios/AbstractPasteboard.h (215713 => 215714)
--- trunk/Source/WebCore/platform/ios/AbstractPasteboard.h 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/platform/ios/AbstractPasteboard.h 2017-04-25 02:35:02 UTC (rev 215714)
@@ -27,15 +27,8 @@
#if TARGET_OS_IPHONE
-WEBCORE_EXPORT @interface WebPasteboardItemData : NSObject
+NS_ASSUME_NONNULL_BEGIN
-+ (instancetype)itemWithRepresentingObjects:(NSArray *)representingObjects additionalData:(NSDictionary *)additionalData;
-
-@property (nonatomic, readonly, strong) NSArray *representingObjects;
-@property (nonatomic, readonly, strong) NSDictionary *additionalData;
-
-@end
-
@protocol AbstractPasteboard <NSObject>
@required
@@ -47,11 +40,14 @@
- (NSInteger)changeCount;
@optional
-- (void)setItemsFromObjectRepresentations:(NSArray<WebPasteboardItemData *> *)itemData;
+- (void)setItemsUsingRegistrationInfoLists:(NSArray *)itemLists;
- (void)setItems:(NSArray<NSDictionary *> *)items;
+- (NSArray<NSString *> *)pasteboardTypesByFidelityForItemAtIndex:(NSUInteger)index;
@property (readonly, nonatomic) NSInteger numberOfFiles;
@property (readonly, nonatomic) NSArray<NSURL *> *filenamesForDataInteraction;
@end
+NS_ASSUME_NONNULL_END
+
#endif // TARGET_OS_IPHONE
Deleted: trunk/Source/WebCore/platform/ios/AbstractPasteboard.mm (215713 => 215714)
--- trunk/Source/WebCore/platform/ios/AbstractPasteboard.mm 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/platform/ios/AbstractPasteboard.mm 2017-04-25 02:35:02 UTC (rev 215714)
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "AbstractPasteboard.h"
-
-#import <wtf/RetainPtr.h>
-
-#if PLATFORM(IOS)
-
-@interface WebPasteboardItemData ()
-{
- RetainPtr<NSArray> _representingObjects;
- RetainPtr<NSDictionary> _additionalData;
-}
-
-@end
-
-@implementation WebPasteboardItemData
-
-+ (instancetype)itemWithRepresentingObjects:(NSArray *)representingObjects additionalData:(NSDictionary *)additionalData
-{
- return [[[self alloc] initWithRepresentingObjects:representingObjects additionalData:additionalData] autorelease];
-}
-
-- (instancetype)initWithRepresentingObjects:(NSArray *)representingObjects additionalData:(NSDictionary *)additionalData
-{
- if (self = [super init]) {
- _representingObjects = representingObjects;
- _additionalData = additionalData;
- }
- return self;
-}
-
-- (NSArray *)representingObjects
-{
- return _representingObjects.get();
-}
-
-- (NSDictionary *)additionalData
-{
- return _additionalData.get();
-}
-
-@end
-
-#endif // PLATFORM(IOS)
Modified: trunk/Source/WebCore/platform/ios/PasteboardIOS.mm (215713 => 215714)
--- trunk/Source/WebCore/platform/ios/PasteboardIOS.mm 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/platform/ios/PasteboardIOS.mm 2017-04-25 02:35:02 UTC (rev 215714)
@@ -165,8 +165,53 @@
return @[(id)kUTTypePNG, (id)kUTTypeTIFF, (id)kUTTypeJPEG, (id)kUTTypeGIF];
}
+static bool readPasteboardWebContentDataForType(PasteboardWebContentReader& reader, PasteboardStrategy& strategy, NSString *type, int itemIndex, const String& pasteboardName)
+{
+ if ([type isEqualToString:WebArchivePboardType]) {
+ RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(itemIndex, WebArchivePboardType, pasteboardName);
+ return reader.readWebArchive(buffer.get());
+ }
+
+ if ([type isEqualToString:(NSString *)kUTTypeHTML]) {
+ String htmlString = strategy.readStringFromPasteboard(itemIndex, kUTTypeHTML, pasteboardName);
+ return !htmlString.isNull() && reader.readHTML(htmlString);
+ }
+
+ if ([type isEqualToString:(NSString *)kUTTypeFlatRTFD]) {
+ RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(itemIndex, kUTTypeFlatRTFD, pasteboardName);
+ return buffer && reader.readRTFD(*buffer);
+ }
+
+ if ([type isEqualToString:(NSString *)kUTTypeRTF]) {
+ RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(itemIndex, kUTTypeRTF, pasteboardName);
+ return buffer && reader.readRTF(*buffer);
+ }
+
+ if ([supportedImageTypes() containsObject:type]) {
+ RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(itemIndex, type, pasteboardName);
+ return buffer && reader.readImage(buffer.releaseNonNull(), type);
+ }
+
+ if ([type isEqualToString:(NSString *)kUTTypeURL]) {
+ URL url = "" kUTTypeURL, pasteboardName);
+ return !url.isNull() && reader.readURL(url, String());
+ }
+
+ if (UTTypeConformsTo((CFStringRef)type, kUTTypeText)) {
+ String string = strategy.readStringFromPasteboard(itemIndex, kUTTypeText, pasteboardName);
+ return !string.isNull() && reader.readPlainText(string);
+ }
+
+ return false;
+}
+
void Pasteboard::read(PasteboardWebContentReader& reader)
{
+ if (respectsUTIFidelities()) {
+ readRespectingUTIFidelities(reader);
+ return;
+ }
+
PasteboardStrategy& strategy = *platformStrategies()->pasteboardStrategy();
int numberOfItems = strategy.getPasteboardItemsCount(m_pasteboardName);
@@ -179,54 +224,32 @@
for (int i = 0; i < numberOfItems; i++) {
for (int typeIndex = 0; typeIndex < numberOfTypes; typeIndex++) {
- NSString *type = [types objectAtIndex:typeIndex];
-
- if ([type isEqualToString:WebArchivePboardType]) {
- if (RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(i, WebArchivePboardType, m_pasteboardName)) {
- if (reader.readWebArchive(buffer.get()))
- break;
- }
- }
-
- if ([type isEqualToString:(NSString *)kUTTypeHTML]) {
- String htmlString = strategy.readStringFromPasteboard(i, kUTTypeHTML, m_pasteboardName);
- if (!htmlString.isNull() && reader.readHTML(htmlString))
- break;
- }
-
- if ([type isEqualToString:(NSString *)kUTTypeFlatRTFD]) {
- if (RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(i, kUTTypeFlatRTFD, m_pasteboardName)) {
- if (reader.readRTFD(*buffer))
- break;
- }
- }
-
- if ([type isEqualToString:(NSString *)kUTTypeRTF]) {
- if (RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(i, kUTTypeRTF, m_pasteboardName)) {
- if (reader.readRTF(*buffer))
- break;
- }
- }
-
- if ([supportedImageTypes() containsObject:type]) {
- if (RefPtr<SharedBuffer> buffer = strategy.readBufferFromPasteboard(i, type, m_pasteboardName)) {
- if (reader.readImage(buffer.releaseNonNull(), type))
- break;
- }
+ if (readPasteboardWebContentDataForType(reader, strategy, [types objectAtIndex:typeIndex], i, m_pasteboardName))
+ break;
}
+ }
+}
- if ([type isEqualToString:(NSString *)kUTTypeURL]) {
- URL url = "" kUTTypeURL, m_pasteboardName);
- if (!url.isNull() && reader.readURL(url, String()))
- break;
- }
-
- if ([type isEqualToString:(NSString *)kUTTypeText]) {
- String string = strategy.readStringFromPasteboard(i, kUTTypeText, m_pasteboardName);
- if (!string.isNull() && reader.readPlainText(string))
- break;
- }
+bool Pasteboard::respectsUTIFidelities() const
+{
+ // For now, data interaction is the only feature that uses item-provider-based pasteboard representations.
+ // In the future, we may need to consult the client layer to determine whether or not the pasteboard supports
+ // item types ranked by fidelity.
+ return m_pasteboardName == "data interaction pasteboard";
+}
+void Pasteboard::readRespectingUTIFidelities(PasteboardWebContentReader& reader)
+{
+ ASSERT(respectsUTIFidelities());
+ auto& strategy = *platformStrategies()->pasteboardStrategy();
+ for (NSUInteger index = 0, numberOfItems = strategy.getPasteboardItemsCount(m_pasteboardName); index < numberOfItems; ++index) {
+ // Try to read data from each type identifier that this pasteboard item supports, and WebKit also recognizes. Type identifiers are
+ // read in order of fidelity, as specified by each pasteboard item.
+ Vector<String> typesForItemInOrderOfFidelity;
+ strategy.getTypesByFidelityForItemAtIndex(typesForItemInOrderOfFidelity, index, m_pasteboardName);
+ for (auto& type : typesForItemInOrderOfFidelity) {
+ if (readPasteboardWebContentDataForType(reader, strategy, type, index, m_pasteboardName))
+ break;
}
}
}
Modified: trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm (215713 => 215714)
--- trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm 2017-04-25 02:35:02 UTC (rev 215714)
@@ -38,7 +38,10 @@
#import <UIKit/UIPasteboard.h>
#if ENABLE(DATA_INTERACTION)
+#import <UIKit/NSAttributedString+UIItemProvider.h>
+#import <UIKit/NSString+UIItemProvider.h>
#import <UIKit/NSURL+UIItemProvider.h>
+#import <UIKit/UIImage+UIItemProvider.h>
#endif
SOFT_LINK_FRAMEWORK(UIKit)
@@ -73,6 +76,16 @@
types.append(pasteboardType);
}
+void PlatformPasteboard::getTypesByFidelityForItemAtIndex(Vector<String>& types, int index)
+{
+ if (index >= [m_pasteboard numberOfItems] || ![m_pasteboard respondsToSelector:@selector(pasteboardTypesByFidelityForItemAtIndex:)])
+ return;
+
+ NSArray *pasteboardTypesByFidelity = [m_pasteboard pasteboardTypesByFidelityForItemAtIndex:index];
+ for (NSString *typeIdentifier in pasteboardTypesByFidelity)
+ types.append(typeIdentifier);
+}
+
RefPtr<SharedBuffer> PlatformPasteboard::bufferForType(const String&)
{
return nullptr;
@@ -187,24 +200,37 @@
void PlatformPasteboard::writeObjectRepresentations(const PasteboardWebContent& content)
{
- RetainPtr<NSMutableArray> objectRepresentations = adoptNS([[NSMutableArray alloc] init]);
- RetainPtr<NSDictionary> additionalData = richTextRepresentationsForPasteboardWebContent(content);
+#if ENABLE(DATA_INTERACTION)
+ RetainPtr<WebItemProviderRegistrationInfoList> itemsToRegister = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]);
+ ASSERT(content.clientTypes.size() == content.clientData.size());
+ for (size_t i = 0, size = content.clientTypes.size(); i < size; ++i)
+ [itemsToRegister addData:content.clientData[i]->createNSData().get() forType:content.clientTypes[i]];
+
+ if (content.dataInWebArchiveFormat)
+ [itemsToRegister addData:content.dataInWebArchiveFormat->createNSData().get() forType:WebArchivePboardType];
+
if (content.dataInAttributedStringFormat) {
NSAttributedString *attributedString = [NSKeyedUnarchiver unarchiveObjectWithData:content.dataInAttributedStringFormat->createNSData().get()];
if (attributedString)
- [objectRepresentations addObject:attributedString];
+ [itemsToRegister addRepresentingObject:attributedString];
}
+ if (content.dataInRTFFormat)
+ [itemsToRegister addData:content.dataInRTFFormat->createNSData().get() forType:(NSString *)kUTTypeRTF];
+
if (!content.dataInStringFormat.isEmpty())
- [objectRepresentations addObject:(NSString *)content.dataInStringFormat];
+ [itemsToRegister addRepresentingObject:(NSString *)content.dataInStringFormat];
- [m_pasteboard setItemsFromObjectRepresentations:@[[WebPasteboardItemData itemWithRepresentingObjects:objectRepresentations.get() additionalData:additionalData.get()]]];
+ [m_pasteboard setItemsUsingRegistrationInfoLists:@[ itemsToRegister.get() ]];
+#else
+ UNUSED_PARAM(content);
+#endif
}
void PlatformPasteboard::write(const PasteboardWebContent& content)
{
- if ([m_pasteboard respondsToSelector:@selector(setItemsFromObjectRepresentations:)]) {
+ if ([m_pasteboard respondsToSelector:@selector(setItemsUsingRegistrationInfoLists:)]) {
writeObjectRepresentations(content);
return;
}
@@ -218,30 +244,33 @@
void PlatformPasteboard::writeObjectRepresentations(const PasteboardImage& pasteboardImage)
{
- RetainPtr<NSMutableArray> objectRepresentations = adoptNS([[NSMutableArray alloc] init]);
- RetainPtr<NSMutableDictionary> additionalData = adoptNS([[NSMutableDictionary alloc] init]);
+#if ENABLE(DATA_INTERACTION)
+ RetainPtr<WebItemProviderRegistrationInfoList> itemsToRegister = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]);
+ if (!pasteboardImage.resourceMIMEType.isNull())
+ [itemsToRegister addData:pasteboardImage.resourceData->createNSData().get() forType:pasteboardImage.resourceMIMEType];
+
if (auto nativeImage = pasteboardImage.image->nativeImage()) {
UIImage *uiImage = (UIImage *)[getUIImageClass() imageWithCGImage:nativeImage.get()];
if (uiImage)
- [objectRepresentations addObject:uiImage];
+ [itemsToRegister addRepresentingObject:uiImage];
}
if (!pasteboardImage.url.url.isEmpty()) {
NSURL *nsURL = pasteboardImage.url.url;
if (nsURL)
- [objectRepresentations addObject:nsURL];
+ [itemsToRegister addRepresentingObject:nsURL];
}
- if (!pasteboardImage.resourceMIMEType.isNull())
- [additionalData setObject:pasteboardImage.resourceData->createNSData().get() forKey:pasteboardImage.resourceMIMEType];
-
- [m_pasteboard setItemsFromObjectRepresentations:@[[WebPasteboardItemData itemWithRepresentingObjects:objectRepresentations.get() additionalData:additionalData.get()]]];
+ [m_pasteboard setItemsUsingRegistrationInfoLists:@[ itemsToRegister.get() ]];
+#else
+ UNUSED_PARAM(pasteboardImage);
+#endif
}
void PlatformPasteboard::write(const PasteboardImage& pasteboardImage)
{
- if ([m_pasteboard respondsToSelector:@selector(setItemsFromObjectRepresentations:)]) {
+ if ([m_pasteboard respondsToSelector:@selector(setItemsUsingRegistrationInfoLists:)]) {
writeObjectRepresentations(pasteboardImage);
return;
}
@@ -256,27 +285,29 @@
void PlatformPasteboard::writeObjectRepresentations(const String& pasteboardType, const String& text)
{
- RetainPtr<NSMutableArray> objectRepresentations = adoptNS([[NSMutableArray alloc] init]);
- RetainPtr<NSMutableDictionary> additionalData = adoptNS([[NSMutableDictionary alloc] init]);
+#if ENABLE(DATA_INTERACTION)
+ RetainPtr<WebItemProviderRegistrationInfoList> itemsToRegister = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]);
NSString *pasteboardTypeAsNSString = pasteboardType;
NSString *textAsNSString = text;
if (textAsNSString && pasteboardTypeAsNSString.length) {
if (UTTypeConformsTo((__bridge CFStringRef)pasteboardTypeAsNSString, kUTTypeURL))
- [objectRepresentations addObject:[[[NSURL alloc] initWithString:textAsNSString] autorelease]];
+ [itemsToRegister addRepresentingObject:[[[NSURL alloc] initWithString:textAsNSString] autorelease]];
if (UTTypeConformsTo((__bridge CFStringRef)pasteboardTypeAsNSString, kUTTypeText))
- [objectRepresentations addObject:textAsNSString];
- else
- [additionalData setObject:textAsNSString forKey:pasteboardTypeAsNSString];
+ [itemsToRegister addRepresentingObject:textAsNSString];
}
- [m_pasteboard setItemsFromObjectRepresentations:@[[WebPasteboardItemData itemWithRepresentingObjects:objectRepresentations.get() additionalData:additionalData.get()]]];
+ [m_pasteboard setItemsUsingRegistrationInfoLists:@[ itemsToRegister.get() ]];
+#else
+ UNUSED_PARAM(pasteboardType);
+ UNUSED_PARAM(text);
+#endif
}
void PlatformPasteboard::write(const String& pasteboardType, const String& text)
{
- if ([m_pasteboard respondsToSelector:@selector(setItemsFromObjectRepresentations:)]) {
+ if ([m_pasteboard respondsToSelector:@selector(setItemsUsingRegistrationInfoLists:)]) {
writeObjectRepresentations(pasteboardType, text);
return;
}
@@ -293,22 +324,24 @@
void PlatformPasteboard::writeObjectRepresentations(const PasteboardURL& url)
{
- auto objectRepresentations = adoptNS([[NSMutableArray alloc] init]);
+#if ENABLE(DATA_INTERACTION)
+ RetainPtr<WebItemProviderRegistrationInfoList> itemsToRegister = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]);
if (NSURL *nsURL = url.url) {
- [objectRepresentations addObject:nsURL];
-#if ENABLE(DATA_INTERACTION)
+ [itemsToRegister addRepresentingObject:nsURL];
if (!url.title.isEmpty())
nsURL._title = url.title;
-#endif
}
- [m_pasteboard setItemsFromObjectRepresentations:@[[WebPasteboardItemData itemWithRepresentingObjects:objectRepresentations.get() additionalData:nil]]];
+ [m_pasteboard setItemsUsingRegistrationInfoLists:@[ itemsToRegister.get() ]];
+#else
+ UNUSED_PARAM(url);
+#endif
}
void PlatformPasteboard::write(const PasteboardURL& url)
{
- if ([m_pasteboard respondsToSelector:@selector(setItemsFromObjectRepresentations:)]) {
+ if ([m_pasteboard respondsToSelector:@selector(setItemsUsingRegistrationInfoLists:)]) {
writeObjectRepresentations(url);
return;
}
Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h (215713 => 215714)
--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.h 2017-04-25 02:35:02 UTC (rev 215714)
@@ -28,9 +28,41 @@
#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
@class UIItemProvider;
+@protocol UIItemProviderWriting;
NS_ASSUME_NONNULL_BEGIN
+/*! A WebItemProviderRegistrationInfo represents a single call to register something to an item provider.
+ @discussion Either the representing object exists and the type identifier and data are nil, or the
+ representing object is nil and the type identifier and data exist. The former represents a call to
+ register an entire UIItemProviderWriting-conformant object to the item provider, while the latter
+ represents a call to register only a data representation for the given type identifier.
+ */
+WEBCORE_EXPORT @interface WebItemProviderRegistrationInfo : NSObject
+
+@property (nonatomic, readonly, nullable, strong) id <UIItemProviderWriting> representingObject;
+@property (nonatomic, readonly, nullable, strong) NSString *typeIdentifier;
+@property (nonatomic, readonly, nullable, strong) NSData *data;
+
+@end
+
+/*! A WebItemProviderRegistrationInfoList represents a series of registration calls used to set up a
+ @discussion single item provider. The order of items specified in the list (lowest indices first) is
+ the order in which objects or data are registered to the item provider, and therefore indicates the
+ relative fidelity of each item. Private UTI types, such as those vended through the injected editing
+ bundle SPI, are considered to be higher fidelity than the other default types.
+ */
+WEBCORE_EXPORT @interface WebItemProviderRegistrationInfoList : NSObject
+
+- (void)addRepresentingObject:(id <UIItemProviderWriting>)object;
+- (void)addData:(NSData *)data forType:(NSString *)typeIdentifier;
+
+- (NSUInteger)numberOfItems;
+- (nullable WebItemProviderRegistrationInfo *)itemAtIndex:(NSUInteger)index;
+- (void)enumerateItems:(void(^)(WebItemProviderRegistrationInfo *item, NSUInteger index))block;
+
+@end
+
typedef void (^WebItemProviderFileLoadBlock)(NSArray<NSURL *> *);
WEBCORE_EXPORT @interface WebItemProviderPasteboard : NSObject<AbstractPasteboard>
Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm (215713 => 215714)
--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm 2017-04-25 02:35:02 UTC (rev 215714)
@@ -76,6 +76,96 @@
return MATCHES_UTI_TYPE(type, PNG) || MATCHES_UTI_TYPE(type, JPEG) || MATCHES_UTI_TYPE(type, GIF) || MATCHES_UIKIT_TYPE(type, image);
}
+@interface WebItemProviderRegistrationInfo ()
+{
+ RetainPtr<id <UIItemProviderWriting>> _representingObject;
+ RetainPtr<NSString> _typeIdentifier;
+ RetainPtr<NSData> _data;
+}
+@end
+
+@implementation WebItemProviderRegistrationInfo
+
+- (instancetype)initWithRepresentingObject:(id <UIItemProviderWriting>)representingObject typeIdentifier:(NSString *)typeIdentifier data:(NSData *)data
+{
+ if (representingObject)
+ ASSERT(!typeIdentifier && !data);
+ else
+ ASSERT(typeIdentifier && data);
+
+ if (self = [super init]) {
+ _representingObject = representingObject;
+ _typeIdentifier = typeIdentifier;
+ _data = data;
+ }
+ return self;
+}
+
+- (id <UIItemProviderWriting>)representingObject
+{
+ return _representingObject.get();
+}
+
+- (NSString *)typeIdentifier
+{
+ return _typeIdentifier.get();
+}
+
+- (NSData *)data
+{
+ return _data.get();
+}
+
+@end
+
+@interface WebItemProviderRegistrationInfoList ()
+{
+ RetainPtr<NSMutableArray> _items;
+}
+@end
+
+@implementation WebItemProviderRegistrationInfoList
+
+- (instancetype)init
+{
+ if (self = [super init])
+ _items = adoptNS([[NSMutableArray alloc] init]);
+
+ return self;
+}
+
+- (void)addData:(NSData *)data forType:(NSString *)typeIdentifier
+{
+ [_items addObject:[[[WebItemProviderRegistrationInfo alloc] initWithRepresentingObject:nil typeIdentifier:typeIdentifier data:data] autorelease]];
+}
+
+- (void)addRepresentingObject:(id <UIItemProviderWriting>)object
+{
+ ASSERT([object conformsToProtocol:@protocol(UIItemProviderWriting)]);
+ [_items addObject:[[[WebItemProviderRegistrationInfo alloc] initWithRepresentingObject:object typeIdentifier:nil data:nil] autorelease]];
+}
+
+- (NSUInteger)numberOfItems
+{
+ return [_items count];
+}
+
+- (WebItemProviderRegistrationInfo *)itemAtIndex:(NSUInteger)index
+{
+ if (index >= self.numberOfItems)
+ return nil;
+
+ return [_items objectAtIndex:index];
+}
+
+- (void)enumerateItems:(void (^)(WebItemProviderRegistrationInfo *, NSUInteger))block
+{
+ for (NSUInteger index = 0; index < self.numberOfItems; ++index)
+ block([self itemAtIndex:index], index);
+}
+
+@end
+
@interface WebItemProviderPasteboard ()
@property (nonatomic) NSInteger numberOfItems;
@@ -111,6 +201,11 @@
return self;
}
+- (NSArray<NSString *> *)pasteboardTypesByFidelityForItemAtIndex:(NSUInteger)index
+{
+ return [self itemProviderAtIndex:index].registeredTypeIdentifiers ?: @[ ];
+}
+
- (NSArray<NSString *> *)pasteboardTypes
{
if (_cachedTypeIdentifiers)
@@ -153,34 +248,29 @@
return [_itemProviders count];
}
-- (void)setItemsFromObjectRepresentations:(NSArray<WebPasteboardItemData *> *)itemData
+- (void)setItemsUsingRegistrationInfoLists:(NSArray<WebItemProviderRegistrationInfoList *> *)itemLists
{
NSMutableArray *providers = [NSMutableArray array];
- for (WebPasteboardItemData *data in itemData) {
- if (!data.representingObjects.count && !data.additionalData.count)
+ for (WebItemProviderRegistrationInfoList *itemList in itemLists) {
+ if (!itemList.numberOfItems)
continue;
- RetainPtr<UIItemProvider> itemProvider = adoptNS([[getUIItemProviderClass() alloc] init]);
- // First, register all platform objects, prioritizing objects at the beginning of the array.
- for (id representingObject in data.representingObjects) {
- if (![representingObject conformsToProtocol:@protocol(UIItemProviderWriting)])
- continue;
+ auto itemProvider = adoptNS([[getUIItemProviderClass() alloc] init]);
+ [itemList enumerateItems:[itemProvider] (WebItemProviderRegistrationInfo *item, NSUInteger) {
+ if (item.representingObject) {
+ [itemProvider registerObject:item.representingObject visibility:UIItemProviderRepresentationOptionsVisibilityAll];
+ return;
+ }
- [itemProvider registerObject:(id <UIItemProviderWriting>)representingObject visibility:UIItemProviderRepresentationOptionsVisibilityAll];
- }
+ if (!item.typeIdentifier.length || !item.data.length)
+ return;
- // Next, register other custom data representations for type identifiers.
- NSDictionary <NSString *, NSData *> *additionalData = data.additionalData;
- for (NSString *typeIdentifier in additionalData) {
- if (![additionalData[typeIdentifier] isKindOfClass:[NSData class]])
- continue;
-
- [itemProvider registerDataRepresentationForTypeIdentifier:typeIdentifier visibility:UIItemProviderRepresentationOptionsVisibilityAll loadHandler:^NSProgress *(ItemProviderDataLoadCompletionHandler completionHandler)
- {
- completionHandler(additionalData[typeIdentifier], nil);
- return [NSProgress discreteProgressWithTotalUnitCount:100];
+ RetainPtr<NSData> itemData = item.data;
+ [itemProvider registerDataRepresentationForTypeIdentifier:item.typeIdentifier visibility:UIItemProviderRepresentationOptionsVisibilityAll loadHandler:[itemData] (ItemProviderDataLoadCompletionHandler completionHandler) -> NSProgress * {
+ completionHandler(itemData.get(), nil);
+ return nil;
}];
- }
+ }];
[providers addObject:itemProvider.get()];
}
Modified: trunk/Source/WebKit/mac/ChangeLog (215713 => 215714)
--- trunk/Source/WebKit/mac/ChangeLog 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebKit/mac/ChangeLog 2017-04-25 02:35:02 UTC (rev 215714)
@@ -1,3 +1,17 @@
+2017-04-24 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Respect fidelity order when reading web content from item providers
+ https://bugs.webkit.org/show_bug.cgi?id=171155
+ <rdar://problem/31356937>
+
+ Reviewed by Tim Horton.
+
+ Adjusts for changes in WebCore (see WebCore/ChangeLog for more details).
+
+ * WebCoreSupport/WebPlatformStrategies.h:
+ * WebCoreSupport/WebPlatformStrategies.mm:
+ (WebPlatformStrategies::getTypesByFidelityForItemAtIndex):
+
2017-04-24 Alex Christensen <achristen...@webkit.org>
Reduce copies and allocations in SharedBuffer::append
Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.h (215713 => 215714)
--- trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.h 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.h 2017-04-25 02:35:02 UTC (rev 215714)
@@ -67,6 +67,7 @@
RefPtr<WebCore::SharedBuffer> readBufferFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) override;
WebCore::URL readURLFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) override;
void getFilenamesForDataInteraction(Vector<String>& filenames, const String& pasteboardName) override;
+ void getTypesByFidelityForItemAtIndex(Vector<String>& types, uint64_t index, const String& pasteboardName) override;
#endif
int getNumberOfFiles(const String& pasteboardName) override;
void getTypes(Vector<String>& types, const String& pasteboardName) override;
Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm (215713 => 215714)
--- trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebPlatformStrategies.mm 2017-04-25 02:35:02 UTC (rev 215714)
@@ -186,6 +186,11 @@
}
#if PLATFORM(IOS)
+void WebPlatformStrategies::getTypesByFidelityForItemAtIndex(Vector<String>& types, uint64_t index, const String& pasteboardName)
+{
+ PlatformPasteboard(pasteboardName).getTypesByFidelityForItemAtIndex(types, index);
+}
+
void WebPlatformStrategies::writeToPasteboard(const PasteboardURL& url, const String& pasteboardName)
{
PlatformPasteboard(pasteboardName).write(url);
Modified: trunk/Source/WebKit2/ChangeLog (215713 => 215714)
--- trunk/Source/WebKit2/ChangeLog 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebKit2/ChangeLog 2017-04-25 02:35:02 UTC (rev 215714)
@@ -1,3 +1,22 @@
+2017-04-24 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Respect fidelity order when reading web content from item providers
+ https://bugs.webkit.org/show_bug.cgi?id=171155
+ <rdar://problem/31356937>
+
+ Reviewed by Tim Horton.
+
+ Adjusts for changes in WebCore by adding plumbing to support Pasteboard::getTypesByFidelityForItemAtIndex. See
+ WebCore/ChangeLog for more details.
+
+ * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
+ (WebKit::WebPasteboardProxy::getPasteboardTypesByFidelityForItemAtIndex):
+ * UIProcess/WebPasteboardProxy.h:
+ * UIProcess/WebPasteboardProxy.messages.in:
+ * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
+ (WebKit::WebPlatformStrategies::getTypesByFidelityForItemAtIndex):
+ * WebProcess/WebCoreSupport/WebPlatformStrategies.h:
+
2017-04-24 Brady Eidson <beid...@apple.com>
WebProcessPools should always have a WebsiteDataStore
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm (215713 => 215714)
--- trunk/Source/WebKit2/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm 2017-04-25 02:35:02 UTC (rev 215714)
@@ -140,6 +140,11 @@
}
#if PLATFORM(IOS)
+void WebPasteboardProxy::getPasteboardTypesByFidelityForItemAtIndex(uint64_t index, const String& pasteboardName, Vector<String>& types)
+{
+ PlatformPasteboard(pasteboardName).getTypesByFidelityForItemAtIndex(types, index);
+}
+
void WebPasteboardProxy::writeURLToPasteboard(const PasteboardURL& url, const String& pasteboardName)
{
PlatformPasteboard(pasteboardName).write(url);
Modified: trunk/Source/WebKit2/UIProcess/WebPasteboardProxy.h (215713 => 215714)
--- trunk/Source/WebKit2/UIProcess/WebPasteboardProxy.h 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebKit2/UIProcess/WebPasteboardProxy.h 2017-04-25 02:35:02 UTC (rev 215714)
@@ -69,6 +69,7 @@
void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
#if PLATFORM(IOS)
+ void getPasteboardTypesByFidelityForItemAtIndex(uint64_t index, const String& pasteboardName, Vector<String>& types);
void writeURLToPasteboard(const WebCore::PasteboardURL&, const String& pasteboardName);
void writeWebContentToPasteboard(const WebCore::PasteboardWebContent&, const String& pasteboardName);
void writeImageToPasteboard(const WebCore::PasteboardImage&, const String& pasteboardName);
Modified: trunk/Source/WebKit2/UIProcess/WebPasteboardProxy.messages.in (215713 => 215714)
--- trunk/Source/WebKit2/UIProcess/WebPasteboardProxy.messages.in 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebKit2/UIProcess/WebPasteboardProxy.messages.in 2017-04-25 02:35:02 UTC (rev 215714)
@@ -31,6 +31,7 @@
ReadBufferFromPasteboard(uint64_t index, String pasteboardType, String pasteboardName) -> (WebKit::SharedMemory::Handle handle, uint64_t size)
GetPasteboardItemsCount(String pasteboardName) -> (uint64_t itemsCount)
GetFilenamesForDataInteraction(String pasteboardName) -> (Vector<String> filenames)
+ GetPasteboardTypesByFidelityForItemAtIndex(uint64_t index, String pasteboardName) -> (Vector<String> types)
#endif
#if PLATFORM(COCOA)
Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp (215713 => 215714)
--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp 2017-04-25 02:35:02 UTC (rev 215714)
@@ -287,6 +287,11 @@
}
#if PLATFORM(IOS)
+void WebPlatformStrategies::getTypesByFidelityForItemAtIndex(Vector<String>& types, uint64_t index, const String& pasteboardName)
+{
+ WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardTypesByFidelityForItemAtIndex(index, pasteboardName), Messages::WebPasteboardProxy::GetPasteboardTypesByFidelityForItemAtIndex::Reply(types), 0);
+}
+
void WebPlatformStrategies::writeToPasteboard(const PasteboardURL& url, const String& pasteboardName)
{
WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteURLToPasteboard(url, pasteboardName), 0);
Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h (215713 => 215714)
--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h 2017-04-25 02:35:02 UTC (rev 215714)
@@ -68,6 +68,7 @@
RefPtr<WebCore::SharedBuffer> readBufferFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) override;
WebCore::URL readURLFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) override;
void getFilenamesForDataInteraction(Vector<String>& filenames, const String& pasteboardName) override;
+ void getTypesByFidelityForItemAtIndex(Vector<String>& types, uint64_t index, const String& pasteboardName) override;
#endif
#if PLATFORM(COCOA)
int getNumberOfFiles(const String& pasteboardName) override;
Modified: trunk/Tools/ChangeLog (215713 => 215714)
--- trunk/Tools/ChangeLog 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Tools/ChangeLog 2017-04-25 02:35:02 UTC (rev 215714)
@@ -1,3 +1,17 @@
+2017-04-24 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Respect fidelity order when reading web content from item providers
+ https://bugs.webkit.org/show_bug.cgi?id=171155
+ <rdar://problem/31356937>
+
+ Reviewed by Tim Horton.
+
+ Adds a new unit test (DataInteractionTests.RespectsExternalSourceFidelityRankings). See WebCore ChangeLog for
+ more details.
+
+ * TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
+ (TestWebKitAPI::TEST):
+
2017-04-24 Carlos Alberto Lopez Perez <clo...@igalia.com>
SyntaxError fix after r215702.
Modified: trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm (215713 => 215714)
--- trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm 2017-04-25 02:15:48 UTC (rev 215713)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm 2017-04-25 02:35:02 UTC (rev 215714)
@@ -32,7 +32,9 @@
#import "TestWKWebView.h"
#import "WKWebViewConfigurationExtras.h"
#import <MobileCoreServices/MobileCoreServices.h>
+#import <UIKit/NSString+UIItemProvider.h>
#import <UIKit/NSURL+UIItemProvider.h>
+#import <UIKit/UIImage+UIItemProvider.h>
#import <UIKit/UIItemProvider_Private.h>
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
@@ -462,6 +464,39 @@
cleanUpDataInteractionTemporaryPath();
}
+TEST(DataInteractionTests, RespectsExternalSourceFidelityRankings)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"];
+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
+
+ auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+
+ // Here, our source item provider vends two representations: plain text, and then an image. If we don't respect the
+ // fidelity order requested by the source, we'll end up assuming that the image is a higher fidelity representation
+ // than the plain text, and erroneously insert the image. If we respect source fidelities, we'll insert text rather
+ // than an image.
+ auto simulatedItemProviderWithTextFirst = adoptNS([[UIItemProvider alloc] init]);
+ [simulatedItemProviderWithTextFirst registerObject:@"Hello world" visibility:NSItemProviderRepresentationVisibilityAll];
+ [simulatedItemProviderWithTextFirst registerObject:testIconImage() visibility:NSItemProviderRepresentationVisibilityAll];
+ [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithTextFirst.get() ]];
+
+ [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
+ EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
+ EXPECT_FALSE([webView editorContainsImageElement]);
+ [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''"];
+
+ // Now we register the item providers in reverse, and expect the image to be inserted instead of text.
+ auto simulatedItemProviderWithImageFirst = adoptNS([[UIItemProvider alloc] init]);
+ [simulatedItemProviderWithImageFirst registerObject:testIconImage() visibility:NSItemProviderRepresentationVisibilityAll];
+ [simulatedItemProviderWithImageFirst registerObject:@"Hello world" visibility:NSItemProviderRepresentationVisibilityAll];
+ [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithImageFirst.get() ]];
+
+ [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
+ EXPECT_TRUE([webView editorContainsImageElement]);
+}
+
TEST(DataInteractionTests, ExternalSourceUTF8PlainTextOnly)
{
RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);