https://bugs.webkit.org/show_bug.cgi?id=173338
<rdar://problem/
32777720>
Reviewed by Tim Horton.
Source/WebCore:
Currently, replacing the list of UIItemProviders right before a drop is handled results in
WebItemProviderPasteboard failing to load non-"public.content"-conformant items. This is because DragController
computes and sends to the UI process a list of UTIs to load (preferredTypeIdentifiers: one type identifier for
each item provider in WebItemProviderPasteboard). However, if the list of item providers changes immediately
before a drop is performed, WebItemProviderPasteboard will get into an inconsistent state where it has a
different number of preferred type identifiers to load than available item providers. This causes
WebItemProviderPasteboard to fail when choosing what type identifiers to load from each item provider.
To fix this, we instead have the web process propagate a list of supported type identifiers to the UI process,
which is a property of only the drop destination rather than both the destination and item providers. When
performing a drop, we then use the current item providers on WebItemProviderPasteboard to consult this list of
supported type identifiers to resolve our list of preferred type identifiers to load.
Globally renames updatePreferredTypeIdentifiers to updateSupportedTypeIdentifiers.
Tests:
DataInteractionTests.ExternalSourceOverrideDropFileUpload
DataInteractionTests.ExternalSourceOverrideDropInsertURL
* page/DragController.cpp:
(WebCore::DragController::dragEnteredOrUpdated):
(WebCore::DragController::updateSupportedTypeIdentifiersForDragHandlingMethod):
(WebCore::DragController::updatePreferredTypeIdentifiersForDragHandlingMethod): Deleted.
* page/DragController.h:
* page/mac/DragControllerMac.mm:
(WebCore::DragController::updateSupportedTypeIdentifiersForDragHandlingMethod):
(WebCore::DragController::updatePreferredTypeIdentifiersForDragHandlingMethod): Deleted.
* platform/DragData.h:
* platform/PasteboardStrategy.h:
* platform/PlatformPasteboard.h:
* platform/ios/AbstractPasteboard.h:
* platform/ios/PlatformPasteboardIOS.mm:
(WebCore::PlatformPasteboard::updateSupportedTypeIdentifiers):
(WebCore::PlatformPasteboard::updatePreferredTypeIdentifiers): Deleted.
* platform/ios/WebItemProviderPasteboard.mm:
(-[WebItemProviderPasteboard init]):
(-[WebItemProviderPasteboard updateSupportedTypeIdentifiers:]):
(-[WebItemProviderPasteboard setItemProviders:]):
(-[WebItemProviderPasteboard typeIsAppropriateForSupportedTypes:]):
(-[WebItemProviderPasteboard typeIdentifierToLoadForRegisteredTypeIdentfiers:]):
Add logic to resolve preferred type identifiers from an item providers list of registered type identifiers.
This formerly existed on DragData.
(-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:synchronousTimeout:]):
(-[WebItemProviderPasteboard updatePreferredTypeIdentifiers:]): Deleted.
* platform/mac/DragDataMac.mm:
Remove preferred type identifier resolution logic from DragData.
(WebCore::typeIsAppropriateForSupportedTypes): Deleted.
(WebCore::DragData::updatePreferredTypeIdentifiers): Deleted.
Source/WebKit/mac:
Rename updatePreferredTypeIdentifiers to updateSupportedTypeIdentifiers.
* WebCoreSupport/WebPlatformStrategies.h:
* WebCoreSupport/WebPlatformStrategies.mm:
(WebPlatformStrategies::updateSupportedTypeIdentifiers):
(WebPlatformStrategies::updatePreferredTypeIdentifiers): Deleted.
Source/WebKit2:
Rename updatePreferredTypeIdentifiers to updateSupportedTypeIdentifiers. Also, introduce
_webView:willPerformDropWithSession: as SPI on WKUIDelegate.
* UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
* UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
(WebKit::WebPasteboardProxy::updateSupportedTypeIdentifiers):
(WebKit::WebPasteboardProxy::updatePreferredTypeIdentifiers): Deleted.
* UIProcess/WebPasteboardProxy.h:
* UIProcess/WebPasteboardProxy.messages.in:
* WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
(WebKit::WebPlatformStrategies::updateSupportedTypeIdentifiers):
(WebKit::WebPlatformStrategies::updatePreferredTypeIdentifiers): Deleted.
* WebProcess/WebCoreSupport/WebPlatformStrategies.h:
Tools:
Adds new unit tests to ensure that -_webView:willPerformDropWithSession: can be used to filter out drag items
used by WebKit when handling a drop. These tests ensure that WebItemProviderPasteboard is still able to handle
these remaining items on drop.
* TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
(TestWebKitAPI::TEST):
* TestWebKitAPI/ios/DataInteractionSimulator.h:
* TestWebKitAPI/ios/DataInteractionSimulator.mm:
Add -overridePerformDropBlock, which can be set to provide custom handling of dropped items.
(-[DataInteractionSimulator _webView:willPerformDropWithSession:]):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@218343
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2017-06-15 Wenson Hsieh <wenson_hsieh@apple.com>
+
+ Using -[WebItemProviderPasteboard setItemProviders:] to swap out item providers before a drop breaks item provider loading
+ https://bugs.webkit.org/show_bug.cgi?id=173338
+ <rdar://problem/32777720>
+
+ Reviewed by Tim Horton.
+
+ Currently, replacing the list of UIItemProviders right before a drop is handled results in
+ WebItemProviderPasteboard failing to load non-"public.content"-conformant items. This is because DragController
+ computes and sends to the UI process a list of UTIs to load (preferredTypeIdentifiers: one type identifier for
+ each item provider in WebItemProviderPasteboard). However, if the list of item providers changes immediately
+ before a drop is performed, WebItemProviderPasteboard will get into an inconsistent state where it has a
+ different number of preferred type identifiers to load than available item providers. This causes
+ WebItemProviderPasteboard to fail when choosing what type identifiers to load from each item provider.
+
+ To fix this, we instead have the web process propagate a list of supported type identifiers to the UI process,
+ which is a property of only the drop destination rather than both the destination and item providers. When
+ performing a drop, we then use the current item providers on WebItemProviderPasteboard to consult this list of
+ supported type identifiers to resolve our list of preferred type identifiers to load.
+
+ Globally renames updatePreferredTypeIdentifiers to updateSupportedTypeIdentifiers.
+
+ Tests:
+ DataInteractionTests.ExternalSourceOverrideDropFileUpload
+ DataInteractionTests.ExternalSourceOverrideDropInsertURL
+
+ * page/DragController.cpp:
+ (WebCore::DragController::dragEnteredOrUpdated):
+ (WebCore::DragController::updateSupportedTypeIdentifiersForDragHandlingMethod):
+ (WebCore::DragController::updatePreferredTypeIdentifiersForDragHandlingMethod): Deleted.
+ * page/DragController.h:
+ * page/mac/DragControllerMac.mm:
+ (WebCore::DragController::updateSupportedTypeIdentifiersForDragHandlingMethod):
+ (WebCore::DragController::updatePreferredTypeIdentifiersForDragHandlingMethod): Deleted.
+ * platform/DragData.h:
+ * platform/PasteboardStrategy.h:
+ * platform/PlatformPasteboard.h:
+ * platform/ios/AbstractPasteboard.h:
+ * platform/ios/PlatformPasteboardIOS.mm:
+ (WebCore::PlatformPasteboard::updateSupportedTypeIdentifiers):
+ (WebCore::PlatformPasteboard::updatePreferredTypeIdentifiers): Deleted.
+ * platform/ios/WebItemProviderPasteboard.mm:
+ (-[WebItemProviderPasteboard init]):
+ (-[WebItemProviderPasteboard updateSupportedTypeIdentifiers:]):
+ (-[WebItemProviderPasteboard setItemProviders:]):
+ (-[WebItemProviderPasteboard typeIsAppropriateForSupportedTypes:]):
+ (-[WebItemProviderPasteboard typeIdentifierToLoadForRegisteredTypeIdentfiers:]):
+
+ Add logic to resolve preferred type identifiers from an item providers list of registered type identifiers.
+ This formerly existed on DragData.
+
+ (-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:synchronousTimeout:]):
+ (-[WebItemProviderPasteboard updatePreferredTypeIdentifiers:]): Deleted.
+ * platform/mac/DragDataMac.mm:
+
+ Remove preferred type identifier resolution logic from DragData.
+
+ (WebCore::typeIsAppropriateForSupportedTypes): Deleted.
+ (WebCore::DragData::updatePreferredTypeIdentifiers): Deleted.
+
2017-06-15 Sam Weinig <sam@webkit.org>
[WebIDL] Replace general inclusion of JSDOMConvert.h with inclusion of individual converter files to reduce unnecessary inclusion
{
mouseMovedIntoDocument(m_page.mainFrame().documentAtPoint(dragData.clientPosition()));
- m_preferredTypeIdentifiersToLoad = { };
m_dragDestinationAction = dragData.dragDestinationAction();
if (m_dragDestinationAction == DragDestinationActionNone) {
clearDragCaret(); // FIXME: Why not call mouseMovedIntoDocument(nullptr)?
m_dragHandlingMethod = DragHandlingMethod::PageLoad;
}
- updatePreferredTypeIdentifiersForDragHandlingMethod(m_dragHandlingMethod, dragData);
+ updateSupportedTypeIdentifiersForDragHandlingMethod(m_dragHandlingMethod, dragData);
return dragOperation;
}
#if !ENABLE(DATA_INTERACTION)
-void DragController::updatePreferredTypeIdentifiersForDragHandlingMethod(DragHandlingMethod, const DragData&) const
+void DragController::updateSupportedTypeIdentifiersForDragHandlingMethod(DragHandlingMethod, const DragData&) const
{
}
static const float DragImageAlpha;
private:
- void updatePreferredTypeIdentifiersForDragHandlingMethod(DragHandlingMethod, const DragData&) const;
+ void updateSupportedTypeIdentifiersForDragHandlingMethod(DragHandlingMethod, const DragData&) const;
bool dispatchTextInputEventFor(Frame*, const DragData&);
bool canProcessDrag(const DragData&);
bool concludeEditDrag(const DragData&);
DragDestinationAction m_dragDestinationAction;
DragSourceAction m_dragSourceAction;
- Vector<String> m_preferredTypeIdentifiersToLoad;
bool m_didInitiateDrag;
DragOperation m_sourceDragOperation; // Set in startDrag when a drag starts from a mouse down within WebKit
IntPoint m_dragOffset;
#import "MainFrame.h"
#import "Page.h"
#import "Pasteboard.h"
+#import "PasteboardStrategy.h"
+#import "PlatformStrategies.h"
#import "Range.h"
#if ENABLE(DATA_INTERACTION)
#if ENABLE(DATA_INTERACTION)
-void DragController::updatePreferredTypeIdentifiersForDragHandlingMethod(DragHandlingMethod dragHandlingMethod, const DragData& dragData) const
+void DragController::updateSupportedTypeIdentifiersForDragHandlingMethod(DragHandlingMethod dragHandlingMethod, const DragData& dragData) const
{
Vector<String> supportedTypes;
switch (dragHandlingMethod) {
supportedTypes.append(kUTTypeContent);
break;
}
- dragData.updatePreferredTypeIdentifiers(supportedTypes);
+ platformStrategies()->pasteboardStrategy()->updateSupportedTypeIdentifiers(supportedTypes, dragData.pasteboardName());
}
#endif
bool containsURLTypeIdentifier() const;
bool containsPromise() const;
#endif
-#if ENABLE(DATA_INTERACTION)
- void updatePreferredTypeIdentifiers(const Vector<String>& supportedTypes) const;
-#endif
#if PLATFORM(GTK)
virtual RefPtr<SharedBuffer> readBufferFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) = 0;
virtual URL readURLFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName, String& title) = 0;
virtual void getFilenamesForDataInteraction(Vector<String>& filenames, const String& pasteboardName) = 0;
- virtual void updatePreferredTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName) = 0;
+ virtual void updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName) = 0;
virtual void getTypesByFidelityForItemAtIndex(Vector<String>& types, uint64_t index, const String& pasteboardName) = 0;
#endif // PLATFORM(IOS)
#if PLATFORM(COCOA)
WEBCORE_EXPORT PlatformPasteboard();
WEBCORE_EXPORT Vector<String> filenamesForDataInteraction();
WEBCORE_EXPORT void getTypesByFidelityForItemAtIndex(Vector<String>& types, int index);
- WEBCORE_EXPORT void updatePreferredTypeIdentifiers(const Vector<String>& types);
+ WEBCORE_EXPORT void updateSupportedTypeIdentifiers(const Vector<String>& types);
#endif
WEBCORE_EXPORT static String uniqueName();
- (NSArray<NSString *> *)pasteboardTypesByFidelityForItemAtIndex:(NSUInteger)index;
@property (readonly, nonatomic) NSInteger numberOfFiles;
@property (readonly, nonatomic) NSArray<NSURL *> *fileURLsForDataInteraction;
-- (void)updatePreferredTypeIdentifiers:(NSArray<NSString *> *)types;
+- (void)updateSupportedTypeIdentifiers:(NSArray<NSString *> *)types;
@end
return (NSURL *)value;
}
-void PlatformPasteboard::updatePreferredTypeIdentifiers(const Vector<String>& types)
+void PlatformPasteboard::updateSupportedTypeIdentifiers(const Vector<String>& types)
{
- if (![m_pasteboard respondsToSelector:@selector(updatePreferredTypeIdentifiers:)])
+ if (![m_pasteboard respondsToSelector:@selector(updateSupportedTypeIdentifiers:)])
return;
NSMutableArray *typesArray = [NSMutableArray arrayWithCapacity:types.size()];
for (auto type : types)
[typesArray addObject:(NSString *)type];
- [m_pasteboard updatePreferredTypeIdentifiers:typesArray];
+ [m_pasteboard updateSupportedTypeIdentifiers:typesArray];
}
}
RetainPtr<NSArray> _itemProviders;
RetainPtr<NSArray> _cachedTypeIdentifiers;
RetainPtr<NSArray> _typeToFileURLMaps;
- RetainPtr<NSArray> _preferredTypeIdentifiers;
+ RetainPtr<NSArray> _supportedTypeIdentifiers;
RetainPtr<NSArray> _registrationInfoLists;
}
_changeCount = 0;
_pendingOperationCount = 0;
_typeToFileURLMaps = adoptNS([[NSArray alloc] init]);
- _preferredTypeIdentifiers = nil;
+ _supportedTypeIdentifiers = nil;
_registrationInfoLists = nil;
}
return self;
}
-- (void)updatePreferredTypeIdentifiers:(NSArray<NSString *> *)types
+- (void)updateSupportedTypeIdentifiers:(NSArray<NSString *> *)types
{
- if ([_itemProviders count] == types.count)
- _preferredTypeIdentifiers = types;
+ _supportedTypeIdentifiers = types;
}
- (NSArray<NSString *> *)pasteboardTypesByFidelityForItemAtIndex:(NSUInteger)index
if (_itemProviders == itemProviders || [_itemProviders isEqualToArray:itemProviders])
return;
- if (itemProviders.count != [_itemProviders count])
- _preferredTypeIdentifiers = nil;
-
_itemProviders = itemProviders;
_changeCount++;
_cachedTypeIdentifiers = nil;
return [NSURL fileURLWithPath:[temporaryDataInteractionDirectory stringByAppendingPathComponent:suggestedName ?: url.lastPathComponent]];
}
+- (BOOL)typeIsAppropriateForSupportedTypes:(NSString *)type
+{
+ // A type is considered appropriate to load if it conforms to one or more supported types.
+ for (NSString *supportedTypeIdentifier in _supportedTypeIdentifiers.get()) {
+ if (UTTypeConformsTo((CFStringRef)type, (CFStringRef)supportedTypeIdentifier))
+ return YES;
+ }
+ return NO;
+}
+
+- (NSString *)typeIdentifierToLoadForRegisteredTypeIdentfiers:(NSArray<NSString *> *)registeredTypeIdentifiers
+{
+ NSString *highestFidelityContentType = nil;
+ for (NSString *registeredTypeIdentifier in registeredTypeIdentifiers) {
+ if ([self typeIsAppropriateForSupportedTypes:registeredTypeIdentifier])
+ return registeredTypeIdentifier;
+
+ if (!highestFidelityContentType && UTTypeConformsTo((CFStringRef)registeredTypeIdentifier, kUTTypeContent))
+ highestFidelityContentType = registeredTypeIdentifier;
+ }
+ return highestFidelityContentType;
+}
+
- (void)doAfterLoadingProvidedContentIntoFileURLs:(WebItemProviderFileLoadBlock)action
{
[self doAfterLoadingProvidedContentIntoFileURLs:action synchronousTimeout:0];
auto changeCountBeforeLoading = _changeCount;
auto typeToFileURLMaps = adoptNS([[NSMutableArray alloc] initWithCapacity:[_itemProviders count]]);
- RetainPtr<NSArray> preferredTypeIdentifiers;
- if ([_preferredTypeIdentifiers count] == [_itemProviders count])
- preferredTypeIdentifiers = _preferredTypeIdentifiers;
-
// First, figure out which item providers we want to try and load files from.
- auto itemProvidersWithFiles = adoptNS([[NSMutableArray alloc] init]);
- auto contentTypeIdentifiersToLoad = adoptNS([[NSMutableArray alloc] init]);
- auto indicesOfItemProvidersWithFiles = adoptNS([[NSMutableArray alloc] init]);
- [_itemProviders enumerateObjectsUsingBlock:[preferredTypeIdentifiers, itemProvidersWithFiles, contentTypeIdentifiersToLoad, indicesOfItemProvidersWithFiles, typeToFileURLMaps] (UIItemProvider *itemProvider, NSUInteger index, BOOL *) {
- NSString *typeIdentifierOfContentToSave = nil;
-
- if (preferredTypeIdentifiers && [itemProvider.registeredTypeIdentifiers containsObject:[preferredTypeIdentifiers objectAtIndex:index]])
- typeIdentifierOfContentToSave = [preferredTypeIdentifiers objectAtIndex:index];
-
- if (!typeIdentifierOfContentToSave) {
- // Fall back to the first "public.content"-conformant type identifier.
- for (NSString *identifier in itemProvider.registeredTypeIdentifiers) {
- if (!UTTypeConformsTo((CFStringRef)identifier, kUTTypeContent))
- continue;
-
- typeIdentifierOfContentToSave = identifier;
- break;
- }
+ auto itemProvidersToLoad = adoptNS([[NSMutableArray alloc] init]);
+ auto typeIdentifiersToLoad = adoptNS([[NSMutableArray alloc] init]);
+ auto indicesOfitemProvidersToLoad = adoptNS([[NSMutableArray alloc] init]);
+ RetainPtr<WebItemProviderPasteboard> protectedSelf = self;
+ [_itemProviders enumerateObjectsUsingBlock:[protectedSelf, itemProvidersToLoad, typeIdentifiersToLoad, indicesOfitemProvidersToLoad, typeToFileURLMaps] (UIItemProvider *itemProvider, NSUInteger index, BOOL *) {
+ NSString *typeIdentifierToLoad = [protectedSelf typeIdentifierToLoadForRegisteredTypeIdentfiers:itemProvider.registeredTypeIdentifiers];
+ if (typeIdentifierToLoad) {
+ [itemProvidersToLoad addObject:itemProvider];
+ [typeIdentifiersToLoad addObject:typeIdentifierToLoad];
+ [indicesOfitemProvidersToLoad addObject:@(index)];
}
-
- if (typeIdentifierOfContentToSave) {
- [itemProvidersWithFiles addObject:itemProvider];
- [contentTypeIdentifiersToLoad addObject:typeIdentifierOfContentToSave];
- [indicesOfItemProvidersWithFiles addObject:@(index)];
- }
-
[typeToFileURLMaps addObject:@{ }];
}];
- if (![itemProvidersWithFiles count]) {
+ if (![itemProvidersToLoad count]) {
action(@[ ]);
return;
}
auto setFileURLsLock = adoptNS([[NSLock alloc] init]);
auto synchronousFileLoadingGroup = adoptOSObject(dispatch_group_create());
auto fileLoadingGroup = adoptOSObject(dispatch_group_create());
- for (NSUInteger index = 0; index < [itemProvidersWithFiles count]; ++index) {
- RetainPtr<UIItemProvider> itemProvider = [itemProvidersWithFiles objectAtIndex:index];
- RetainPtr<NSString> typeIdentifier = [contentTypeIdentifiersToLoad objectAtIndex:index];
- NSUInteger indexInItemProviderArray = [[indicesOfItemProvidersWithFiles objectAtIndex:index] unsignedIntegerValue];
+ for (NSUInteger index = 0; index < [itemProvidersToLoad count]; ++index) {
+ RetainPtr<UIItemProvider> itemProvider = [itemProvidersToLoad objectAtIndex:index];
+ RetainPtr<NSString> typeIdentifier = [typeIdentifiersToLoad objectAtIndex:index];
+ NSUInteger indexInItemProviderArray = [[indicesOfitemProvidersToLoad objectAtIndex:index] unsignedIntegerValue];
RetainPtr<NSString> suggestedName = [itemProvider suggestedName];
dispatch_group_enter(fileLoadingGroup.get());
dispatch_group_enter(synchronousFileLoadingGroup.get());
return String();
}
-#if ENABLE(DATA_INTERACTION)
-
-static bool typeIsAppropriateForSupportedTypes(const String& type, const Vector<String>& supportedTypes)
-{
- CFStringRef cfType = type.createCFString().autorelease();
- for (auto supportedType : supportedTypes) {
- if (UTTypeConformsTo(cfType, supportedType.createCFString().get()))
- return true;
- }
- return false;
-}
-
-void DragData::updatePreferredTypeIdentifiers(const Vector<String>& supportedTypes) const
-{
- Vector<String> bestTypeIdentifiers;
- auto& strategy = *platformStrategies()->pasteboardStrategy();
- uint64_t itemCount = strategy.getPasteboardItemsCount(m_pasteboardName);
- for (uint64_t itemIndex = 0; itemIndex < itemCount; ++itemIndex) {
- Vector<String> typeIdentifiers;
- strategy.getTypesByFidelityForItemAtIndex(typeIdentifiers, itemIndex, m_pasteboardName);
-
- String bestTypeIdentifier = emptyString();
- for (auto& type : typeIdentifiers) {
- if (!typeIsAppropriateForSupportedTypes(type, supportedTypes))
- continue;
-
- bestTypeIdentifier = type;
- break;
- }
- bestTypeIdentifiers.append(bestTypeIdentifier);
- }
-
- strategy.updatePreferredTypeIdentifiers(bestTypeIdentifiers, m_pasteboardName);
-}
-
-#endif
-
} // namespace WebCore
#endif // ENABLE(DRAG_SUPPORT)
+2017-06-15 Wenson Hsieh <wenson_hsieh@apple.com>
+
+ Using -[WebItemProviderPasteboard setItemProviders:] to swap out item providers before a drop breaks item provider loading
+ https://bugs.webkit.org/show_bug.cgi?id=173338
+ <rdar://problem/32777720>
+
+ Reviewed by Tim Horton.
+
+ Rename updatePreferredTypeIdentifiers to updateSupportedTypeIdentifiers.
+
+ * WebCoreSupport/WebPlatformStrategies.h:
+ * WebCoreSupport/WebPlatformStrategies.mm:
+ (WebPlatformStrategies::updateSupportedTypeIdentifiers):
+ (WebPlatformStrategies::updatePreferredTypeIdentifiers): Deleted.
+
2017-06-13 Daniel Bates <dabates@apple.com>
Implement W3C Secure Contexts Draft Specification
RefPtr<WebCore::SharedBuffer> readBufferFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) override;
WebCore::URL readURLFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName, String& title) override;
void getFilenamesForDataInteraction(Vector<String>& filenames, const String& pasteboardName) override;
- void updatePreferredTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName) override;
+ void updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName) override;
void getTypesByFidelityForItemAtIndex(Vector<String>& types, uint64_t index, const String& pasteboardName) override;
#endif
int getNumberOfFiles(const String& pasteboardName) override;
return PlatformPasteboard(pasteboardName).count();
}
-void WebPlatformStrategies::updatePreferredTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName)
+void WebPlatformStrategies::updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName)
{
- PlatformPasteboard(pasteboardName).updatePreferredTypeIdentifiers(identifiers);
+ PlatformPasteboard(pasteboardName).updateSupportedTypeIdentifiers(identifiers);
}
RefPtr<WebCore::SharedBuffer> WebPlatformStrategies::readBufferFromPasteboard(int index, const String& type, const String& pasteboardName)
+2017-06-15 Wenson Hsieh <wenson_hsieh@apple.com>
+
+ Using -[WebItemProviderPasteboard setItemProviders:] to swap out item providers before a drop breaks item provider loading
+ https://bugs.webkit.org/show_bug.cgi?id=173338
+ <rdar://problem/32777720>
+
+ Reviewed by Tim Horton.
+
+ Rename updatePreferredTypeIdentifiers to updateSupportedTypeIdentifiers. Also, introduce
+ _webView:willPerformDropWithSession: as SPI on WKUIDelegate.
+
+ * UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
+ * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
+ (WebKit::WebPasteboardProxy::updateSupportedTypeIdentifiers):
+ (WebKit::WebPasteboardProxy::updatePreferredTypeIdentifiers): Deleted.
+ * UIProcess/WebPasteboardProxy.h:
+ * UIProcess/WebPasteboardProxy.messages.in:
+ * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
+ (WebKit::WebPlatformStrategies::updateSupportedTypeIdentifiers):
+ (WebKit::WebPlatformStrategies::updatePreferredTypeIdentifiers): Deleted.
+ * WebProcess/WebCoreSupport/WebPlatformStrategies.h:
+
2017-06-15 Carlos Garcia Campos <cgarcia@igalia.com>
[GTK] Cleanup headers includes in GTK+ API files
@class UIDragItem;
@class UITargetedDragPreview;
@protocol UIDragSession;
+@protocol UIDropSession;
#endif
@protocol WKUIDelegatePrivate <WKUIDelegate>
#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
- (UITargetedDragPreview *)_webView:(WKWebView *)webView previewForLiftingItem:(UIDragItem *)item session:(id <UIDragSession>)session WK_API_AVAILABLE(ios(WK_IOS_TBA));
- (UITargetedDragPreview *)_webView:(WKWebView *)webView previewForCancellingItem:(UIDragItem *)item withDefault:(UITargetedDragPreview *)defaultPreview WK_API_AVAILABLE(ios(WK_IOS_TBA));
+- (NSArray<UIDragItem *> *)_webView:(WKWebView *)webView willPerformDropWithSession:(id <UIDropSession>)session WK_API_AVAILABLE(ios(WK_IOS_TBA));
#endif
- (void)_webView:(WKWebView *)webView didChangeSafeAreaShouldAffectObscuredInsets:(BOOL)safeAreaShouldAffectObscuredInsets WK_API_AVAILABLE(ios(WK_IOS_TBA));
#else
filenames = PlatformPasteboard(pasteboardName).filenamesForDataInteraction();
}
-void WebPasteboardProxy::updatePreferredTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName)
+void WebPasteboardProxy::updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName)
{
- PlatformPasteboard(pasteboardName).updatePreferredTypeIdentifiers(identifiers);
+ PlatformPasteboard(pasteboardName).updateSupportedTypeIdentifiers(identifiers);
}
#endif
void readBufferFromPasteboard(uint64_t index, const String& pasteboardType, const String& pasteboardName, SharedMemory::Handle&, uint64_t& size);
void getPasteboardItemsCount(const String& pasteboardName, uint64_t& itemsCount);
void getFilenamesForDataInteraction(const String& pasteboardName, Vector<String>& filenames);
- void updatePreferredTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName);
+ void updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName);
#endif
#if PLATFORM(COCOA)
void getNumberOfFiles(const String& pasteboardName, uint64_t& numberOfFiles);
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)
- UpdatePreferredTypeIdentifiers(Vector<String> identifiers, String pasteboardName)
+ UpdateSupportedTypeIdentifiers(Vector<String> identifiers, String pasteboardName)
GetPasteboardTypesByFidelityForItemAtIndex(uint64_t index, String pasteboardName) -> (Vector<String> types)
#endif
WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetFilenamesForDataInteraction(pasteboardName), Messages::WebPasteboardProxy::GetFilenamesForDataInteraction::Reply(filenames), 0);
}
-void WebPlatformStrategies::updatePreferredTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName)
+void WebPlatformStrategies::updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName)
{
- WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::UpdatePreferredTypeIdentifiers(identifiers, pasteboardName), 0);
+ WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::UpdateSupportedTypeIdentifiers(identifiers, pasteboardName), 0);
}
RefPtr<WebCore::SharedBuffer> WebPlatformStrategies::readBufferFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName)
RefPtr<WebCore::SharedBuffer> readBufferFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) override;
WebCore::URL readURLFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName, String& title) override;
void getFilenamesForDataInteraction(Vector<String>& filenames, const String& pasteboardName) override;
- void updatePreferredTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName) override;
+ void updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName) override;
void getTypesByFidelityForItemAtIndex(Vector<String>& types, uint64_t index, const String& pasteboardName) override;
#endif
#if PLATFORM(COCOA)
+2017-06-15 Wenson Hsieh <wenson_hsieh@apple.com>
+
+ Using -[WebItemProviderPasteboard setItemProviders:] to swap out item providers before a drop breaks item provider loading
+ https://bugs.webkit.org/show_bug.cgi?id=173338
+ <rdar://problem/32777720>
+
+ Reviewed by Tim Horton.
+
+ Adds new unit tests to ensure that -_webView:willPerformDropWithSession: can be used to filter out drag items
+ used by WebKit when handling a drop. These tests ensure that WebItemProviderPasteboard is still able to handle
+ these remaining items on drop.
+
+ * TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
+ (TestWebKitAPI::TEST):
+ * TestWebKitAPI/ios/DataInteractionSimulator.h:
+ * TestWebKitAPI/ios/DataInteractionSimulator.mm:
+
+ Add -overridePerformDropBlock, which can be set to provide custom handling of dropped items.
+
+ (-[DataInteractionSimulator _webView:willPerformDropWithSession:]):
+
2017-06-15 Per Arne Vollan <pvollan@apple.com>
[Win] Crash in accessibility layout test.
EXPECT_WK_STREQ("Hello world\nfile:///some/file/that/is/not/real", [webView stringByEvaluatingJavaScript:@"document.body.innerText"]);
}
+TEST(DataInteractionTests, ExternalSourceOverrideDropFileUpload)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"];
+
+ auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]);
+ NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5);
+ [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData];
+
+ auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
+ NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
+ [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData];
+
+ auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+ [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
+ {
+ EXPECT_EQ(2UL, session.items.count);
+ UIDragItem *firstItem = session.items[0];
+ UIDragItem *secondItem = session.items[1];
+ EXPECT_TRUE([firstItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeJPEG ]]);
+ EXPECT_TRUE([secondItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeHTML ]]);
+ return @[ secondItem ];
+ }];
+ [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), simulatedHTMLItemProvider.get() ]];
+ [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)];
+
+ NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"];
+ EXPECT_WK_STREQ("text/html", outputValue.UTF8String);
+}
+
+TEST(DataInteractionTests, ExternalSourceOverrideDropInsertURL)
+{
+ 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()]);
+ [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
+ {
+ NSMutableArray<UIDragItem *> *allowedItems = [NSMutableArray array];
+ for (UIDragItem *item in session.items) {
+ if ([item.itemProvider.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL])
+ [allowedItems addObject:item];
+ }
+ EXPECT_EQ(1UL, allowedItems.count);
+ return allowedItems;
+ }];
+
+ auto firstItemProvider = adoptNS([[UIItemProvider alloc] init]);
+ [firstItemProvider registerObject:@"This is a string." visibility:UIItemProviderRepresentationOptionsVisibilityAll];
+ auto secondItemProvider = adoptNS([[UIItemProvider alloc] init]);
+ [secondItemProvider registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll];
+ [dataInteractionSimulator setExternalItemProviders:@[ firstItemProvider.get(), secondItemProvider.get() ]];
+ [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)];
+
+ EXPECT_WK_STREQ("https://webkit.org/", [webView stringByEvaluatingJavaScript:@"editor.textContent"]);
+}
+
TEST(DataInteractionTests, OverrideDataInteractionOperation)
{
RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
@property (nonatomic) BOOL shouldEnsureUIApplication;
@property (nonatomic) BlockPtr<BOOL(_WKActivatedElementInfo *)> showCustomActionSheetBlock;
@property (nonatomic) BlockPtr<NSArray *(UIItemProvider *, NSArray *, NSDictionary *)> convertItemProvidersBlock;
+@property (nonatomic) BlockPtr<NSArray *(id <UIDropSession>)> overridePerformDropBlock;
@property (nonatomic, strong) NSArray *externalItemProviders;
@property (nonatomic) BlockPtr<NSUInteger(NSUInteger, id)> overrideDataInteractionOperationBlock;
@property (nonatomic) BlockPtr<void(BOOL, NSArray *)> dataInteractionOperationCompletionBlock;
return self.showCustomActionSheetBlock(element);
}
+- (NSArray<UIDragItem *> *)_webView:(WKWebView *)webView willPerformDropWithSession:(id <UIDropSession>)session
+{
+ return self.overridePerformDropBlock ? self.overridePerformDropBlock(session) : session.items;
+}
+
#pragma mark - _WKInputDelegate
- (BOOL)_webView:(WKWebView *)webView focusShouldStartInputSession:(id <_WKFocusedElementInfo>)info