- Revision
- 233339
- Author
- [email protected]
- Date
- 2018-06-28 16:52:57 -0700 (Thu, 28 Jun 2018)
Log Message
[iOS] DataTransfer.getData always returns the empty string when dropping text
https://bugs.webkit.org/show_bug.cgi?id=187130
<rdar://problem/41014117>
Reviewed by Ryosuke Niwa.
Source/WebCore:
Currently, DataTransfer.getData() always returns the empty string on drop. This is because all data on drop is
backed by local files in the temporary directory, so the number of files is never 0; this, combined with the
fact that WebKit will suppress access to the DataTransfer object if there is one or more file in the pasteboard,
means that getData() never works for drag and drop on iOS at the moment. To fix this, we need to know whether a
dropped item provider is a file.
Ideally, we'd have a flag to tell us whether or not an NSItemProvider being dropped is a file, or instead just
inline data - in fact, this flag already exists in the form of UIPreferredPresentationStyle. Unfortunately, not
all apps that vend draggable files specify this, so we can't simply ask the item provider whether it's intended
to be a file. As a workaround, we can use several heuristics to determine the "file content state" of the drag
pasteboard on iOS (see below for more details).
This patch adds some plumbing through the client layers to grab a list of item information describing each
dropped item provider on iOS. Using this information, we tweak the logic in Pasteboard::fileContentState to make
an educated guess at whether or not the pasteboard really contains files; if we determine that the pasteboard
probably contains no files, we'll allow DataTransfer.getData() to retrieve information from the pasteboard.
Otherwise, if the pasteboard may contain files, we'll fall back to our current behavior of including the "Files"
type in DataTransfer.types and allowing the page to grab file data using DataTransfer.files or
DataTransfer.items.
Tests: DataInteractionTests.DataTransferGetDataReadPlainAndRichText
DataInteractionTests.DataTransferSuppressGetDataDueToPresenceOfTextFile
* dom/DataTransfer.cpp:
(WebCore::DataTransfer::filesFromPasteboardAndItemList const):
Check Pasteboard::fileContentState() to ensure that we don't expose files when DataTransfer.types does not
contain the "Files" type, and vice versa, and DataTranser.files is also empty in this case.
* dom/DataTransferItemList.cpp:
* platform/PasteboardItemInfo.h:
Add a couple of additional members to PasteboardItemInfo: suggestedFileName and hasDeclaredNonTextType, a flag
that indicates whether or not the pasteboard item has a type representation that is a declared type, but is not
a text type (i.e. does not conform to "public.text", "public.url", or rich text format with attachment types).
(WebCore::PasteboardItemInfo::encode const):
(WebCore::PasteboardItemInfo::decode):
* platform/PasteboardStrategy.h:
* platform/PlatformPasteboard.h:
* platform/cocoa/PasteboardCocoa.mm:
(WebCore::Pasteboard::fileContentState):
Instead of always considering a dropped item provider on iOS to represent a file, only do so if at least one of
the following conditions are met:
- The drop session contains multiple item providers (flocking text selections is a very rare use case).
- The item provider was explicitly marked as an attachment.
- The item provider has a suggested file name.
- The item provider has any other content that is not text.
In the case where none of the above conditions are met, the item provider (if it ends up being a file) is
essentially indistinguishable from inline data. An example of this is dropping a plain text file that is
unnamed, with no presentation style, and alongside no other items nor other known type representations. These
are cases in which whether the item is treated as a file or as inline data is (hopefully) irrelevant.
* platform/ios/PlatformPasteboardIOS.mm:
(WebCore::PlatformPasteboard::allPasteboardItemInfo):
(WebCore::PlatformPasteboard::informationForItemAtIndex):
Source/WebKit:
Add plumbing to grab information for each item in the pasteboard. See WebCore ChangeLog for more detail.
* UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
(WebKit::WebPasteboardProxy::allPasteboardItemInfo):
* UIProcess/WebPasteboardProxy.h:
* UIProcess/WebPasteboardProxy.messages.in:
* WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
(WebKit::WebPlatformStrategies::allPasteboardItemInfo):
* WebProcess/WebCoreSupport/WebPlatformStrategies.h:
Source/WebKitLegacy/mac:
Add plumbing to grab information for each item in the pasteboard. See WebCore ChangeLog for more detail.
* WebCoreSupport/WebPlatformStrategies.h:
* WebCoreSupport/WebPlatformStrategies.mm:
(WebPlatformStrategies::allPasteboardItemInfo):
Tools:
Add 2 new API tests to verify that:
- When dropping an item with text, markup, and URL representations, the page is allowed to get "text/html",
"text/plain" and "text/uri-list" data.
- Adding a suggested name to a plain text item causes WebKit to treat it as a file, and suppress access to
DataTransfer.getData().
Additionally tweaks a couple of existing API tests. Namely, in two API tests
(ExternalSourceOverrideDropFileUpload and ExternalSourceHTMLToUploadArea) only a markup string is dropped, and
we previously expected to handle the drop as a file. To allow this test to continue serving its purpose, tweak
them such that the registered items appear to be file-backed (i.e. by adding a suggested filename in one of the
tests, and specifying UIPreferredPresentationStyleAttachment in the other).
* TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
(TestWebKitAPI::TEST):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (233338 => 233339)
--- trunk/Source/WebCore/ChangeLog 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebCore/ChangeLog 2018-06-28 23:52:57 UTC (rev 233339)
@@ -1,3 +1,70 @@
+2018-06-28 Wenson Hsieh <[email protected]>
+
+ [iOS] DataTransfer.getData always returns the empty string when dropping text
+ https://bugs.webkit.org/show_bug.cgi?id=187130
+ <rdar://problem/41014117>
+
+ Reviewed by Ryosuke Niwa.
+
+ Currently, DataTransfer.getData() always returns the empty string on drop. This is because all data on drop is
+ backed by local files in the temporary directory, so the number of files is never 0; this, combined with the
+ fact that WebKit will suppress access to the DataTransfer object if there is one or more file in the pasteboard,
+ means that getData() never works for drag and drop on iOS at the moment. To fix this, we need to know whether a
+ dropped item provider is a file.
+
+ Ideally, we'd have a flag to tell us whether or not an NSItemProvider being dropped is a file, or instead just
+ inline data - in fact, this flag already exists in the form of UIPreferredPresentationStyle. Unfortunately, not
+ all apps that vend draggable files specify this, so we can't simply ask the item provider whether it's intended
+ to be a file. As a workaround, we can use several heuristics to determine the "file content state" of the drag
+ pasteboard on iOS (see below for more details).
+
+ This patch adds some plumbing through the client layers to grab a list of item information describing each
+ dropped item provider on iOS. Using this information, we tweak the logic in Pasteboard::fileContentState to make
+ an educated guess at whether or not the pasteboard really contains files; if we determine that the pasteboard
+ probably contains no files, we'll allow DataTransfer.getData() to retrieve information from the pasteboard.
+ Otherwise, if the pasteboard may contain files, we'll fall back to our current behavior of including the "Files"
+ type in DataTransfer.types and allowing the page to grab file data using DataTransfer.files or
+ DataTransfer.items.
+
+ Tests: DataInteractionTests.DataTransferGetDataReadPlainAndRichText
+ DataInteractionTests.DataTransferSuppressGetDataDueToPresenceOfTextFile
+
+ * dom/DataTransfer.cpp:
+ (WebCore::DataTransfer::filesFromPasteboardAndItemList const):
+
+ Check Pasteboard::fileContentState() to ensure that we don't expose files when DataTransfer.types does not
+ contain the "Files" type, and vice versa, and DataTranser.files is also empty in this case.
+
+ * dom/DataTransferItemList.cpp:
+ * platform/PasteboardItemInfo.h:
+
+ Add a couple of additional members to PasteboardItemInfo: suggestedFileName and hasDeclaredNonTextType, a flag
+ that indicates whether or not the pasteboard item has a type representation that is a declared type, but is not
+ a text type (i.e. does not conform to "public.text", "public.url", or rich text format with attachment types).
+
+ (WebCore::PasteboardItemInfo::encode const):
+ (WebCore::PasteboardItemInfo::decode):
+ * platform/PasteboardStrategy.h:
+ * platform/PlatformPasteboard.h:
+ * platform/cocoa/PasteboardCocoa.mm:
+ (WebCore::Pasteboard::fileContentState):
+
+ Instead of always considering a dropped item provider on iOS to represent a file, only do so if at least one of
+ the following conditions are met:
+ - The drop session contains multiple item providers (flocking text selections is a very rare use case).
+ - The item provider was explicitly marked as an attachment.
+ - The item provider has a suggested file name.
+ - The item provider has any other content that is not text.
+
+ In the case where none of the above conditions are met, the item provider (if it ends up being a file) is
+ essentially indistinguishable from inline data. An example of this is dropping a plain text file that is
+ unnamed, with no presentation style, and alongside no other items nor other known type representations. These
+ are cases in which whether the item is treated as a file or as inline data is (hopefully) irrelevant.
+
+ * platform/ios/PlatformPasteboardIOS.mm:
+ (WebCore::PlatformPasteboard::allPasteboardItemInfo):
+ (WebCore::PlatformPasteboard::informationForItemAtIndex):
+
2018-06-28 Timothy Hatcher <[email protected]>
Don't force black text when TextIndicator draws backgrounds or all content.
Modified: trunk/Source/WebCore/dom/DataTransfer.cpp (233338 => 233339)
--- trunk/Source/WebCore/dom/DataTransfer.cpp 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebCore/dom/DataTransfer.cpp 2018-06-28 23:52:57 UTC (rev 233339)
@@ -327,7 +327,7 @@
{
bool addedFilesFromPasteboard = false;
Vector<Ref<File>> files;
- if (!forDrag() || forFileDrag()) {
+ if ((!forDrag() || forFileDrag()) && m_pasteboard->fileContentState() != Pasteboard::FileContentState::NoFileOrImageData) {
WebCorePasteboardFileReader reader;
m_pasteboard->read(reader);
files = WTFMove(reader.files);
Modified: trunk/Source/WebCore/platform/PasteboardItemInfo.h (233338 => 233339)
--- trunk/Source/WebCore/platform/PasteboardItemInfo.h 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebCore/platform/PasteboardItemInfo.h 2018-06-28 23:52:57 UTC (rev 233339)
@@ -39,6 +39,8 @@
struct PasteboardItemInfo {
String pathForFileUpload;
String contentTypeForFileUpload;
+ String suggestedFileName;
+ bool isNonTextType { false };
PasteboardItemPresentationStyle preferredPresentationStyle { PasteboardItemPresentationStyle::Unspecified };
template<class Encoder> void encode(Encoder&) const;
@@ -48,7 +50,7 @@
template<class Encoder>
void PasteboardItemInfo::encode(Encoder& encoder) const
{
- encoder << pathForFileUpload << contentTypeForFileUpload;
+ encoder << pathForFileUpload << contentTypeForFileUpload << suggestedFileName << isNonTextType;
encoder.encodeEnum(preferredPresentationStyle);
}
@@ -62,6 +64,12 @@
if (!decoder.decode(result.contentTypeForFileUpload))
return std::nullopt;
+ if (!decoder.decode(result.suggestedFileName))
+ return std::nullopt;
+
+ if (!decoder.decode(result.isNonTextType))
+ return std::nullopt;
+
if (!decoder.decodeEnum(result.preferredPresentationStyle))
return std::nullopt;
Modified: trunk/Source/WebCore/platform/PasteboardStrategy.h (233338 => 233339)
--- trunk/Source/WebCore/platform/PasteboardStrategy.h 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebCore/platform/PasteboardStrategy.h 2018-06-28 23:52:57 UTC (rev 233339)
@@ -51,6 +51,7 @@
virtual String readStringFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) = 0;
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 Vector<PasteboardItemInfo> allPasteboardItemInfo(const String& pasteboardName) = 0;
virtual PasteboardItemInfo informationForItemAtIndex(int index, 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;
Modified: trunk/Source/WebCore/platform/PlatformPasteboard.h (233338 => 233339)
--- trunk/Source/WebCore/platform/PlatformPasteboard.h 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebCore/platform/PlatformPasteboard.h 2018-06-28 23:52:57 UTC (rev 233339)
@@ -60,6 +60,7 @@
WEBCORE_EXPORT explicit PlatformPasteboard(const String& pasteboardName);
#if PLATFORM(IOS) || PLATFORM(WPE)
WEBCORE_EXPORT PlatformPasteboard();
+ WEBCORE_EXPORT Vector<PasteboardItemInfo> allPasteboardItemInfo();
WEBCORE_EXPORT PasteboardItemInfo informationForItemAtIndex(int index);
WEBCORE_EXPORT void getTypesByFidelityForItemAtIndex(Vector<String>& types, int index);
WEBCORE_EXPORT void updateSupportedTypeIdentifiers(const Vector<String>& types);
Modified: trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm (233338 => 233339)
--- trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm 2018-06-28 23:52:57 UTC (rev 233339)
@@ -137,6 +137,36 @@
Pasteboard::FileContentState Pasteboard::fileContentState()
{
bool mayContainFilePaths = platformStrategies()->pasteboardStrategy()->getNumberOfFiles(m_pasteboardName);
+
+#if PLATFORM(IOS)
+ if (mayContainFilePaths) {
+ // On iOS, files are not written to the pasteboard using file URLs, so we need a heuristic to determine
+ // whether or not the pasteboard contains items that represent files. An example of when this gets tricky
+ // is differentiating between cases where the user is dragging a plain text file, versus selected text.
+ // Some common signs that indicate a file drop as opposed to dropping inline data are:
+ //
+ // 1. Multiple items - the system generally does not give opportunities to flock multiple pieces of
+ // selected text.
+ // 2. Preferred attachment presentation style - this means the source has explicitly marked the item
+ // as a file-like entity, as opposed to inline data.
+ // 3. A suggested name - this means that the source has explicitly specified a potential file name for
+ // the item when dropped.
+ // 4. The presence of any other declared non-text data in the same item indicates that the content being
+ // dropped can take on another non-text format, which could be a file.
+ //
+ // If none of these four conditions are satisfied, it's very likely that the content being dropped is just
+ // an inline piece of text, with no files in the pasteboard (and therefore, no risk of leaking file paths
+ // to web content). In cases such as these, we should not suppress DataTransfer access.
+ auto items = platformStrategies()->pasteboardStrategy()->allPasteboardItemInfo(m_pasteboardName);
+ mayContainFilePaths = items.size() != 1 || notFound != items.findMatching([] (auto& item) {
+ if (item.preferredPresentationStyle != PasteboardItemPresentationStyle::Unspecified)
+ return item.preferredPresentationStyle == PasteboardItemPresentationStyle::Attachment;
+
+ return !item.suggestedFileName.isEmpty() || item.isNonTextType;
+ });
+ }
+#endif
+
if (!mayContainFilePaths) {
Vector<String> cocoaTypes;
platformStrategies()->pasteboardStrategy()->getTypes(cocoaTypes, m_pasteboardName);
Modified: trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm (233338 => 233339)
--- trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm 2018-06-28 23:52:57 UTC (rev 233339)
@@ -122,6 +122,14 @@
}
}
+Vector<PasteboardItemInfo> PlatformPasteboard::allPasteboardItemInfo()
+{
+ Vector<PasteboardItemInfo> itemInfo;
+ for (NSInteger itemIndex = 0; itemIndex < [m_pasteboard numberOfItems]; ++itemIndex)
+ itemInfo.append(informationForItemAtIndex(itemIndex));
+ return itemInfo;
+}
+
PasteboardItemInfo PlatformPasteboard::informationForItemAtIndex(int index)
{
if (index >= [m_pasteboard numberOfItems])
@@ -136,6 +144,28 @@
NSItemProvider *itemProvider = [[m_pasteboard itemProviders] objectAtIndex:index];
info.preferredPresentationStyle = pasteboardItemPresentationStyle(itemProvider.preferredPresentationStyle);
+ info.suggestedFileName = itemProvider.suggestedName;
+ for (NSString *typeIdentifier in itemProvider.registeredTypeIdentifiers) {
+ CFStringRef cfTypeIdentifier = (CFStringRef)typeIdentifier;
+ if (!UTTypeIsDeclared(cfTypeIdentifier))
+ continue;
+
+ if (UTTypeConformsTo(cfTypeIdentifier, kUTTypeText))
+ continue;
+
+ if (UTTypeConformsTo(cfTypeIdentifier, kUTTypeURL))
+ continue;
+
+ if (UTTypeConformsTo(cfTypeIdentifier, kUTTypeRTFD))
+ continue;
+
+ if (UTTypeConformsTo(cfTypeIdentifier, kUTTypeFlatRTFD))
+ continue;
+
+ info.isNonTextType = true;
+ break;
+ }
+
return info;
}
@@ -146,6 +176,11 @@
return { };
}
+Vector<PasteboardItemInfo> PlatformPasteboard::allPasteboardItemInfo()
+{
+ return { };
+}
+
#endif
static bool pasteboardMayContainFilePaths(id<AbstractPasteboard> pasteboard)
Modified: trunk/Source/WebKit/ChangeLog (233338 => 233339)
--- trunk/Source/WebKit/ChangeLog 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebKit/ChangeLog 2018-06-28 23:52:57 UTC (rev 233339)
@@ -1,3 +1,21 @@
+2018-06-28 Wenson Hsieh <[email protected]>
+
+ [iOS] DataTransfer.getData always returns the empty string when dropping text
+ https://bugs.webkit.org/show_bug.cgi?id=187130
+ <rdar://problem/41014117>
+
+ Reviewed by Ryosuke Niwa.
+
+ Add plumbing to grab information for each item in the pasteboard. See WebCore ChangeLog for more detail.
+
+ * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
+ (WebKit::WebPasteboardProxy::allPasteboardItemInfo):
+ * UIProcess/WebPasteboardProxy.h:
+ * UIProcess/WebPasteboardProxy.messages.in:
+ * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
+ (WebKit::WebPlatformStrategies::allPasteboardItemInfo):
+ * WebProcess/WebCoreSupport/WebPlatformStrategies.h:
+
2018-06-28 Youenn Fablet <[email protected]>
Early return when handling fetch event in case service worker origin does not match origin of a subresource load
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm (233338 => 233339)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm 2018-06-28 23:52:57 UTC (rev 233339)
@@ -226,6 +226,11 @@
itemsCount = PlatformPasteboard(pasteboardName).count();
}
+void WebPasteboardProxy::allPasteboardItemInfo(const String& pasteboardName, Vector<PasteboardItemInfo>& allInfo)
+{
+ allInfo = PlatformPasteboard(pasteboardName).allPasteboardItemInfo();
+}
+
void WebPasteboardProxy::informationForItemAtIndex(int index, const String& pasteboardName, PasteboardItemInfo& info)
{
info = PlatformPasteboard(pasteboardName).informationForItemAtIndex(index);
Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h (233338 => 233339)
--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h 2018-06-28 23:52:57 UTC (rev 233339)
@@ -78,6 +78,7 @@
void readURLFromPasteboard(uint64_t index, const String& pasteboardType, const String& pasteboardName, String& url, String& title);
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 allPasteboardItemInfo(const String& pasteboardName, Vector<WebCore::PasteboardItemInfo>&);
void informationForItemAtIndex(int index, const String& pasteboardName, WebCore::PasteboardItemInfo& filename);
void updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName);
#endif
Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in (233338 => 233339)
--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in 2018-06-28 23:52:57 UTC (rev 233339)
@@ -30,6 +30,7 @@
ReadURLFromPasteboard(uint64_t index, String pasteboardType, String pasteboardName) -> (String url, String title)
ReadBufferFromPasteboard(uint64_t index, String pasteboardType, String pasteboardName) -> (WebKit::SharedMemory::Handle handle, uint64_t size)
GetPasteboardItemsCount(String pasteboardName) -> (uint64_t itemsCount)
+ AllPasteboardItemInfo(String pasteboardName) -> (Vector<WebCore::PasteboardItemInfo> allInfo)
InformationForItemAtIndex(uint64_t index, String pasteboardName) -> (struct WebCore::PasteboardItemInfo info)
UpdateSupportedTypeIdentifiers(Vector<String> identifiers, String pasteboardName)
GetPasteboardTypesByFidelityForItemAtIndex(uint64_t index, String pasteboardName) -> (Vector<String> types)
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp (233338 => 233339)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp 2018-06-28 23:52:57 UTC (rev 233339)
@@ -322,6 +322,13 @@
return itemsCount;
}
+Vector<PasteboardItemInfo> WebPlatformStrategies::allPasteboardItemInfo(const String& pasteboardName)
+{
+ Vector<PasteboardItemInfo> allInfo;
+ WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::AllPasteboardItemInfo(pasteboardName), Messages::WebPasteboardProxy::AllPasteboardItemInfo::Reply(allInfo), 0);
+ return allInfo;
+}
+
PasteboardItemInfo WebPlatformStrategies::informationForItemAtIndex(int index, const String& pasteboardName)
{
PasteboardItemInfo info;
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h (233338 => 233339)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.h 2018-06-28 23:52:57 UTC (rev 233339)
@@ -65,6 +65,7 @@
String readStringFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) override;
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;
+ Vector<WebCore::PasteboardItemInfo> allPasteboardItemInfo(const String& pasteboardName) override;
WebCore::PasteboardItemInfo informationForItemAtIndex(int index, 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;
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (233338 => 233339)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2018-06-28 23:52:57 UTC (rev 233339)
@@ -1,3 +1,17 @@
+2018-06-28 Wenson Hsieh <[email protected]>
+
+ [iOS] DataTransfer.getData always returns the empty string when dropping text
+ https://bugs.webkit.org/show_bug.cgi?id=187130
+ <rdar://problem/41014117>
+
+ Reviewed by Ryosuke Niwa.
+
+ Add plumbing to grab information for each item in the pasteboard. See WebCore ChangeLog for more detail.
+
+ * WebCoreSupport/WebPlatformStrategies.h:
+ * WebCoreSupport/WebPlatformStrategies.mm:
+ (WebPlatformStrategies::allPasteboardItemInfo):
+
2018-06-26 Eric Carlson <[email protected]>
[Mac] AirPlay picker uses incorrect theme in Dark mode
Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h (233338 => 233339)
--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h 2018-06-28 23:52:57 UTC (rev 233339)
@@ -66,6 +66,7 @@
String readStringFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName) override;
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;
+ Vector<WebCore::PasteboardItemInfo> allPasteboardItemInfo(const String& pasteboardName) override;
WebCore::PasteboardItemInfo informationForItemAtIndex(int index, 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;
Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm (233338 => 233339)
--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.mm 2018-06-28 23:52:57 UTC (rev 233339)
@@ -240,6 +240,11 @@
return PlatformPasteboard(pasteboardName).readString(index, type);
}
+Vector<WebCore::PasteboardItemInfo> WebPlatformStrategies::allPasteboardItemInfo(const String& pasteboardName)
+{
+ return PlatformPasteboard(pasteboardName).allPasteboardItemInfo();
+}
+
WebCore::PasteboardItemInfo WebPlatformStrategies::informationForItemAtIndex(int index, const String& pasteboardName)
{
return PlatformPasteboard(pasteboardName).informationForItemAtIndex(index);
Modified: trunk/Tools/ChangeLog (233338 => 233339)
--- trunk/Tools/ChangeLog 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Tools/ChangeLog 2018-06-28 23:52:57 UTC (rev 233339)
@@ -1,3 +1,26 @@
+2018-06-28 Wenson Hsieh <[email protected]>
+
+ [iOS] DataTransfer.getData always returns the empty string when dropping text
+ https://bugs.webkit.org/show_bug.cgi?id=187130
+ <rdar://problem/41014117>
+
+ Reviewed by Ryosuke Niwa.
+
+ Add 2 new API tests to verify that:
+ - When dropping an item with text, markup, and URL representations, the page is allowed to get "text/html",
+ "text/plain" and "text/uri-list" data.
+ - Adding a suggested name to a plain text item causes WebKit to treat it as a file, and suppress access to
+ DataTransfer.getData().
+
+ Additionally tweaks a couple of existing API tests. Namely, in two API tests
+ (ExternalSourceOverrideDropFileUpload and ExternalSourceHTMLToUploadArea) only a markup string is dropped, and
+ we previously expected to handle the drop as a file. To allow this test to continue serving its purpose, tweak
+ them such that the registered items appear to be file-backed (i.e. by adding a suggested filename in one of the
+ tests, and specifying UIPreferredPresentationStyleAttachment in the other).
+
+ * TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
+ (TestWebKitAPI::TEST):
+
2018-06-28 Basuke Suzuki <[email protected]>
Unreviewed, rolling out r226652.
Modified: trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm (233338 => 233339)
--- trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm 2018-06-28 23:23:32 UTC (rev 233338)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm 2018-06-28 23:52:57 UTC (rev 233339)
@@ -650,6 +650,7 @@
auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
[simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData];
+ [simulatedHTMLItemProvider setSuggestedName:@"index.html"];
auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
[dataInteractionSimulator setShouldAllowMoveOperation:NO];
@@ -980,6 +981,7 @@
auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]);
NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding];
[simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData];
+ [simulatedHTMLItemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment];
auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
[dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session)
@@ -1691,6 +1693,51 @@
});
}
+TEST(DataInteractionTests, DataTransferGetDataReadPlainAndRichText)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView synchronouslyLoadTestPageNamed:@"DataTransfer"];
+ auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+
+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]);
+ NSDictionary *textAttributes = @{ NSFontAttributeName: [UIFont boldSystemFontOfSize:20] };
+ NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"WebKit" attributes:textAttributes];
+ [itemProvider registerObject:richText visibility:NSItemProviderRepresentationVisibilityAll];
+ [itemProvider registerObject:[NSURL URLWithString:@"https://www.webkit.org/"] visibility:NSItemProviderRepresentationVisibilityAll];
+ [itemProvider registerObject:@"WebKit" visibility:NSItemProviderRepresentationVisibilityAll];
+
+ [simulator setExternalItemProviders:@[ itemProvider.get() ]];
+ [simulator runFrom:CGPointZero to:CGPointMake(50, 100)];
+
+ EXPECT_WK_STREQ("text/html, text/plain, text/uri-list", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
+ EXPECT_WK_STREQ("WebKit", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
+ EXPECT_WK_STREQ("https://www.webkit.org/", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
+ EXPECT_WK_STREQ("WebKit", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
+ EXPECT_WK_STREQ("(STRING, text/html), (STRING, text/plain), (STRING, text/uri-list)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
+}
+
+TEST(DataInteractionTests, DataTransferSuppressGetDataDueToPresenceOfTextFile)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+ [webView synchronouslyLoadTestPageNamed:@"DataTransfer"];
+ auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
+
+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]);
+ [itemProvider registerObject:@"Hello world" visibility:NSItemProviderRepresentationVisibilityAll];
+ [itemProvider setSuggestedName:@"hello.txt"];
+
+ [simulator setExternalItemProviders:@[ itemProvider.get() ]];
+ [simulator runFrom:CGPointZero to:CGPointMake(50, 100)];
+
+ EXPECT_WK_STREQ("Files", [webView stringByEvaluatingJavaScript:@"types.textContent"]);
+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]);
+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]);
+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]);
+ EXPECT_WK_STREQ("(FILE, text/plain)", [webView stringByEvaluatingJavaScript:@"items.textContent"]);
+ EXPECT_WK_STREQ("('hello.txt', text/plain)", [webView stringByEvaluatingJavaScript:@"files.textContent"]);
+}
+
TEST(DataInteractionTests, DataTransferGetDataCannotReadPrivateArbitraryTypes)
{
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);