DataTransfer.items does not contain items for custom types supplied via add or setData
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 8 Oct 2017 21:58:28 +0000 (21:58 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 8 Oct 2017 21:58:28 +0000 (21:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178016

Reviewed by Darin Adler.

Source/WebCore:

Minor tweaks to expose pasteboard types and data through DataTransfer's item list. This patch fixes two primary
issues: (1) custom pasteboard data is not exposed through the item list in any way, and (2) the "Files"
compatibility type is exposed as a separate data transfer item of kind 'string' when dropping or pasting files.

Tests: editing/pasteboard/data-transfer-items-add-custom-data.html
       editing/pasteboard/data-transfer-items-drop-file.html

* dom/DataTransfer.cpp:
(WebCore::normalizeType):

Use stripLeadingAndTrailingHTMLSpaces instead of stripWhitespace.

(WebCore::shouldReadOrWriteTypeAsCustomData):
(WebCore::DataTransfer::getDataForItem const):
(WebCore::DataTransfer::getData const):

Add getDataForItem, a version of getData that does not normalize types before reading from the pasteboard. This
normalization step is only needed for backwards compatibility with legacy types (such as "text" and "url")
written to and read from using getData and setData; when using DataTransferItemList.add to set data, adding data
for these types should instead write as custom pasteboard data.

(WebCore::DataTransfer::setDataFromItemList):
(WebCore::DataTransfer::types const):
(WebCore::DataTransfer::typesForItemList const):

Add typesForItemList, which fetches the list of types to expose as items on the DataTransfer. Importantly, this
does not include the "Files" type added for compatibility when accessing DataTransfer.types, instead returning
an empty array. The actual files are added separately, by iterating over DataTransfer's files in ensureItems.

Note that when starting a drag or copying, we will still expose the full list of file and string types to
bindings and not just file-backed items. Since all of this information is supplied by the page in the first
place, we don't have to worry about exposing information, such as file paths, that may exist on the pasteboard.

* dom/DataTransfer.h:
* dom/DataTransferItem.cpp:
(WebCore::DataTransferItem::getAsString const):
* dom/DataTransferItemList.cpp:
(WebCore::shouldExposeTypeInItemList):
(WebCore::DataTransferItemList::add):
(WebCore::DataTransferItemList::ensureItems const):
(WebCore::isSupportedType): Deleted.

LayoutTests:

Adds new layout tests to check DataTransfer.items when dropping a file, and when copying and pasting with custom
pasteboard data types. Tweaks an existing test to adjust for normalizeType stripping HTML whitespace rather than
ASCII whitespace.

* TestExpectations:
* editing/pasteboard/data-transfer-get-data-non-normalized-types-expected.txt:
* editing/pasteboard/data-transfer-get-data-non-normalized-types.html:
* editing/pasteboard/data-transfer-items-add-custom-data-expected.txt: Added.
* editing/pasteboard/data-transfer-items-add-custom-data.html: Added.
* editing/pasteboard/data-transfer-items-drop-file-expected.txt: Added.
* editing/pasteboard/data-transfer-items-drop-file.html: Added.
* platform/ios-simulator-wk1/TestExpectations:
* platform/mac-wk1/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223034 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/editing/pasteboard/data-transfer-get-data-non-normalized-types-expected.txt
LayoutTests/editing/pasteboard/data-transfer-get-data-non-normalized-types.html
LayoutTests/editing/pasteboard/data-transfer-items-add-custom-data-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/data-transfer-items-add-custom-data.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/data-transfer-items-drop-file-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/data-transfer-items-drop-file.html [new file with mode: 0644]
LayoutTests/platform/ios-simulator-wk1/TestExpectations
LayoutTests/platform/mac-wk1/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/dom/DataTransfer.cpp
Source/WebCore/dom/DataTransfer.h
Source/WebCore/dom/DataTransferItem.cpp
Source/WebCore/dom/DataTransferItemList.cpp

index d35a586..4fab450 100644 (file)
@@ -1,3 +1,24 @@
+2017-10-08  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        DataTransfer.items does not contain items for custom types supplied via add or setData
+        https://bugs.webkit.org/show_bug.cgi?id=178016
+
+        Reviewed by Darin Adler.
+
+        Adds new layout tests to check DataTransfer.items when dropping a file, and when copying and pasting with custom
+        pasteboard data types. Tweaks an existing test to adjust for normalizeType stripping HTML whitespace rather than
+        ASCII whitespace.
+
+        * TestExpectations:
+        * editing/pasteboard/data-transfer-get-data-non-normalized-types-expected.txt:
+        * editing/pasteboard/data-transfer-get-data-non-normalized-types.html:
+        * editing/pasteboard/data-transfer-items-add-custom-data-expected.txt: Added.
+        * editing/pasteboard/data-transfer-items-add-custom-data.html: Added.
+        * editing/pasteboard/data-transfer-items-drop-file-expected.txt: Added.
+        * editing/pasteboard/data-transfer-items-drop-file.html: Added.
+        * platform/ios-simulator-wk1/TestExpectations:
+        * platform/mac-wk1/TestExpectations:
+
 2017-10-08  Ryosuke Niwa  <rniwa@webkit.org>
 
         dragenter and dragleave shouldn't use the same data transfer object
index 38b97c5..7295066 100644 (file)
@@ -76,6 +76,7 @@ editing/pasteboard/data-transfer-get-data-on-drop-url.html [ Skip ]
 editing/pasteboard/data-transfer-is-unique-for-dragenter-and-dragleave.html [ Skip ]
 editing/pasteboard/drag-end-crash-accessing-item-list.html [ Skip ]
 editing/pasteboard/data-transfer-item-list-add-file-on-drag.html [ Skip ]
+editing/pasteboard/data-transfer-items-drop-file.html [ Skip ]
 
 # Only iOS supports QuickLook
 quicklook [ Skip ]
index 5dcf360..3229a00 100644 (file)
@@ -3,7 +3,7 @@ Rich text
     " text/plain; ": "",
     "text/uri-list; ": "http://www.apple.com/",
     "text/html; ": "<b style='color: green'></b>",
-    "\fcustom type\u000b": "custom data"
+    "\fcustom type\r": "custom data"
 }
 {
     "\tText": "",
index eaeda72..2950757 100644 (file)
@@ -53,7 +53,7 @@ function getDataWithTypesFromEvent(event, types) {
 }
 
 function handlePaste1(event) {
-    output.textContent += JSON.stringify(getDataWithTypesFromEvent(event, [" text/plain; ", "text/uri-list; ", "text/html; ", "\fcustom type\v"]), null, "    ") + "\n";
+    output.textContent += JSON.stringify(getDataWithTypesFromEvent(event, [" text/plain; ", "text/uri-list; ", "text/html; ", "\fcustom type\r"]), null, "    ") + "\n";
     event.preventDefault();
 }
 
diff --git a/LayoutTests/editing/pasteboard/data-transfer-items-add-custom-data-expected.txt b/LayoutTests/editing/pasteboard/data-transfer-items-add-custom-data-expected.txt
new file mode 100644 (file)
index 0000000..9034c20
--- /dev/null
@@ -0,0 +1,41 @@
+Copy me
+
+*** Handling copy ***
+
+Types => data
+text/html => "HTML data written using setData"
+text/plain => "plain text data written using items.add"
+text/uri-list => "https://www.webkit.org/"
+using setdata => "data written using DataTransfer.setData"
+using add => "data written using DataTransferItemList.add"
+text => "plain text data written using items.add"
+url => "https://www.webkit.org/"
+Item list
+[0] => (type = "text/html", string = "<i>HTML data written using setData</i>")
+[1] => (type = "text/plain", string = "plain text data written using items.add")
+[2] => (type = "text/uri-list", string = "https://www.webkit.org/")
+[3] => (type = "using setdata", string = "data written using DataTransfer.setData")
+[4] => (type = "using add", string = "data written using DataTransferItemList.add")
+[5] => (type = "text", string = "this should be custom data")
+[6] => (type = "url", string = "this should also be custom data")
+File list
+
+*** Handling paste ***
+
+Types => data
+text/html => "HTML data written using setData"
+text/plain => "plain text data written using items.add"
+text/uri-list => "https://www.webkit.org/"
+using setdata => "data written using DataTransfer.setData"
+using add => "data written using DataTransferItemList.add"
+text => "plain text data written using items.add"
+url => "https://www.webkit.org/"
+Item list
+[0] => (type = "text/html", string = "<i>HTML data written using setData</i>")
+[1] => (type = "text/plain", string = "plain text data written using items.add")
+[2] => (type = "text/uri-list", string = "https://www.webkit.org/")
+[3] => (type = "using setdata", string = "data written using DataTransfer.setData")
+[4] => (type = "using add", string = "data written using DataTransferItemList.add")
+[5] => (type = "text", string = "this should be custom data")
+[6] => (type = "url", string = "this should also be custom data")
+File list
diff --git a/LayoutTests/editing/pasteboard/data-transfer-items-add-custom-data.html b/LayoutTests/editing/pasteboard/data-transfer-items-add-custom-data.html
new file mode 100644 (file)
index 0000000..345879e
--- /dev/null
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<style>
+html, body {
+    width: 100%;
+    height: 100%;
+}
+</style>
+<body contenteditable>
+    <div id="source">Copy me</div>
+    <pre id="output">
+        To manually test, copy the above text and paste anywhere in the body.
+        This will dump the contents of the DataTransfer on copy and paste events as output text.
+        You should see the custom types "text" and "url" written to the DataTransfer as custom
+        data exposed on the DataTransfer's item list, on both copy and paste.
+    </pre>
+</body>
+<script>
+
+function write(markup) {
+    output.insertAdjacentHTML("beforeend", markup);
+}
+
+function outputForFile(file) {
+    return file ? `(name = '${file.name}', size = ${file.size} bytes, type = '${file.type}')` : "(null)";
+}
+
+globalStringLoadCount = 0;
+currentStringLoadCount = 0;
+
+function loadString(item) {
+    currentStringLoadCount++;
+    const outputElementId = `string-${++globalStringLoadCount}`;
+    item.getAsString(string => {
+        document.getElementById(outputElementId).textContent = string;
+        currentStringLoadCount--;
+        if (!currentStringLoadCount && window.didFinishLoadingAllStrings)
+            didFinishLoadingAllStrings();
+    });
+    return `<span id=${outputElementId}></span>`;
+}
+
+function writeOutputForEvent(event) {
+    write(`<br><h3>*** Handling ${event.type} ***</h3>`);
+    write(`<div><strong>Types => data</strong></div>`);
+    for (const type of event.clipboardData.types)
+        write(`<div>${type} => "${event.clipboardData.getData(type)}"</div>`);
+    let index = 0;
+    write(`<div><strong>Item list</strong></div>`);
+    for (const item of event.clipboardData.items) {
+        if (item.kind === "file")
+            write(`<div>[${index++}] => ${outputForFile(item.getAsFile())}</div>`);
+        else
+            write(`<div>[${index++}] => (type = "${item.type}", string = "${loadString(item)}")</div>`);
+    }
+    write(`<div><strong>File list</strong></div>`);
+    index = 0;
+    for (const file of event.clipboardData.files)
+        write(`<div>[${index++}] => ${outputForFile(file)}</div>`);
+}
+
+function setCustomData(event) {
+    output.textContent = "";
+
+    event.clipboardData.setData("text/html", "<i>HTML data written using setData</i>");
+    event.clipboardData.items.add("plain text data written using items.add", "text/plain");
+    event.clipboardData.items.add("https://www.webkit.org/", "text/uri-list");
+    event.clipboardData.setData("using setData", "data written using DataTransfer.setData");
+    event.clipboardData.items.add("data written using DataTransferItemList.add", "using add");
+
+    // Per the spec, "text" and "url" will be normalized to "text/plain" and "text/uri-list" when using
+    // DataTransfer.getData. However, this custom data should still be accessible through DataTransferItems.
+    event.clipboardData.items.add("this should be custom data", "text");
+    event.clipboardData.items.add("this should also be custom data", "url");
+
+    writeOutputForEvent(event);
+}
+
+getSelection().setBaseAndExtent(source, 0, source, 1);
+
+document.body.addEventListener("paste", event => {
+    event.preventDefault();
+    writeOutputForEvent(event);
+});
+source.addEventListener("copy", event => {
+    event.preventDefault();
+    setCustomData(event);
+});
+
+if (window.testRunner && window.internals) {
+    internals.settings.setCustomPasteboardDataEnabled(true);
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+
+    document.execCommand("Copy");
+    document.execCommand("Paste");
+
+    didFinishLoadingAllStrings = () => testRunner.notifyDone();
+}
+</script>
diff --git a/LayoutTests/editing/pasteboard/data-transfer-items-drop-file-expected.txt b/LayoutTests/editing/pasteboard/data-transfer-items-drop-file-expected.txt
new file mode 100644 (file)
index 0000000..fde2e47
--- /dev/null
@@ -0,0 +1,9 @@
+
+*** Handling drop ***
+
+Types => data
+Files => ""
+Item list
+[0] => (name = 'apple.gif', size = 1476 bytes, type = 'image/gif')
+File list
+[0] => (name = 'apple.gif', size = 1476 bytes, type = 'image/gif')
diff --git a/LayoutTests/editing/pasteboard/data-transfer-items-drop-file.html b/LayoutTests/editing/pasteboard/data-transfer-items-drop-file.html
new file mode 100644 (file)
index 0000000..ee333b4
--- /dev/null
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<style>
+html, body {
+    width: 100%;
+    height: 100%;
+}
+</style>
+<body contenteditable>
+    <pre id="output">
+        This test is best run under DumpRenderTree. To manually test, drop a file anywhere in the body.
+        This will dump the contents of the DataTransfer on drop as output text.
+        You should see an item of kind "file" in the resulting item list, as well as an entry in the item list.
+        There should <i>not</i> be an item of kind "string" and type "file".
+    </pre>
+</body>
+<script>
+
+function write(markup) {
+    output.insertAdjacentHTML("beforeend", markup);
+}
+
+function outputForFile(file) {
+    return file ? `(name = '${file.name}', size = ${file.size} bytes, type = '${file.type}')` : "(null)";
+}
+
+function writeOutputForEvent(event) {
+    output.textContent = "";
+
+    write(`<br><h3>*** Handling ${event.type} ***</h3>`);
+    const pasteboard = event.dataTransfer || event.clipboardData;
+    write(`<div><strong>Types => data</strong></div>`);
+    for (const type of pasteboard.types)
+        write(`<div>${type} => "${pasteboard.getData(type)}"</div>`);
+    let index = 0;
+    write(`<div><strong>Item list</strong></div>`);
+    for (const item of pasteboard.items) {
+        if (item.kind === "file")
+            write(`<div>[${index++}] => ${outputForFile(item.getAsFile())}</div>`);
+        else
+            write(`<div>[${index++}] => (kind = ${item.kind}, type = ${item.type})</div>`);
+    }
+    write(`<div><strong>File list</strong></div>`);
+    index = 0;
+    for (const file of pasteboard.files)
+        write(`<div>[${index++}] => ${outputForFile(file)}</div>`);
+}
+
+document.body.addEventListener("drop", event => {
+    event.preventDefault();
+    writeOutputForEvent(event);
+});
+
+if (window.testRunner && window.internals && window.eventSender) {
+    internals.settings.setCustomPasteboardDataEnabled(true);
+    testRunner.dumpAsText();
+
+    eventSender.beginDragWithFiles(["resources/apple.gif"]);
+    eventSender.mouseMoveTo(100, 100);
+    eventSender.mouseUp();
+}
+</script>
index 061e74b..968bf26 100644 (file)
@@ -13,3 +13,4 @@ editing/pasteboard/data-transfer-get-data-on-paste-rich-text.html [ Pass ]
 editing/pasteboard/data-transfer-get-data-non-normalized-types.html [ Pass ]
 editing/pasteboard/data-transfer-item-list-add-file-on-copy.html [ Pass ]
 editing/pasteboard/data-transfer-item-list-add-file-multiple-times.html [ Pass ]
+editing/pasteboard/data-transfer-items-add-custom-data.html [ Pass ]
index 3e6f73e..1331cee 100644 (file)
@@ -14,6 +14,7 @@ editing/pasteboard/data-transfer-get-data-on-drop-url.html [ Pass ]
 editing/pasteboard/data-transfer-is-unique-for-dragenter-and-dragleave.html [ Pass ]
 editing/pasteboard/drag-end-crash-accessing-item-list.html [ Pass ]
 editing/pasteboard/data-transfer-item-list-add-file-on-drag.html [ Pass ]
+editing/pasteboard/data-transfer-items-drop-file.html [ Pass ]
 
 #//////////////////////////////////////////////////////////////////////////////////////////
 # End platform-specific directories.
index 3c0f07a..1fb4bc3 100644 (file)
@@ -1,3 +1,52 @@
+2017-10-08  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        DataTransfer.items does not contain items for custom types supplied via add or setData
+        https://bugs.webkit.org/show_bug.cgi?id=178016
+
+        Reviewed by Darin Adler.
+
+        Minor tweaks to expose pasteboard types and data through DataTransfer's item list. This patch fixes two primary
+        issues: (1) custom pasteboard data is not exposed through the item list in any way, and (2) the "Files"
+        compatibility type is exposed as a separate data transfer item of kind 'string' when dropping or pasting files.
+
+        Tests: editing/pasteboard/data-transfer-items-add-custom-data.html
+               editing/pasteboard/data-transfer-items-drop-file.html
+
+        * dom/DataTransfer.cpp:
+        (WebCore::normalizeType):
+
+        Use stripLeadingAndTrailingHTMLSpaces instead of stripWhitespace.
+
+        (WebCore::shouldReadOrWriteTypeAsCustomData):
+        (WebCore::DataTransfer::getDataForItem const):
+        (WebCore::DataTransfer::getData const):
+
+        Add getDataForItem, a version of getData that does not normalize types before reading from the pasteboard. This
+        normalization step is only needed for backwards compatibility with legacy types (such as "text" and "url")
+        written to and read from using getData and setData; when using DataTransferItemList.add to set data, adding data
+        for these types should instead write as custom pasteboard data.
+
+        (WebCore::DataTransfer::setDataFromItemList):
+        (WebCore::DataTransfer::types const):
+        (WebCore::DataTransfer::typesForItemList const):
+
+        Add typesForItemList, which fetches the list of types to expose as items on the DataTransfer. Importantly, this
+        does not include the "Files" type added for compatibility when accessing DataTransfer.types, instead returning
+        an empty array. The actual files are added separately, by iterating over DataTransfer's files in ensureItems.
+
+        Note that when starting a drag or copying, we will still expose the full list of file and string types to
+        bindings and not just file-backed items. Since all of this information is supplied by the page in the first
+        place, we don't have to worry about exposing information, such as file paths, that may exist on the pasteboard.
+
+        * dom/DataTransfer.h:
+        * dom/DataTransferItem.cpp:
+        (WebCore::DataTransferItem::getAsString const):
+        * dom/DataTransferItemList.cpp:
+        (WebCore::shouldExposeTypeInItemList):
+        (WebCore::DataTransferItemList::add):
+        (WebCore::DataTransferItemList::ensureItems const):
+        (WebCore::isSupportedType): Deleted.
+
 2017-10-08  Darin Adler  <darin@apple.com>
 
         CustomElementRegistry.define was throwing a JavaScript syntax error instead of a DOM syntax error
index b0d9df4..5c6b227 100644 (file)
@@ -36,6 +36,7 @@
 #include "Frame.h"
 #include "FrameLoader.h"
 #include "HTMLImageElement.h"
+#include "HTMLParserIdioms.h"
 #include "Image.h"
 #include "Pasteboard.h"
 #include "Settings.h"
@@ -109,7 +110,7 @@ static String normalizeType(const String& type)
     if (type.isNull())
         return type;
 
-    String lowercaseType = type.stripWhiteSpace().convertToASCIILowercase();
+    String lowercaseType = stripLeadingAndTrailingHTMLSpaces(type).convertToASCIILowercase();
     if (lowercaseType == "text" || lowercaseType.startsWithIgnoringASCIICase("text/plain;"))
         return "text/plain";
     if (lowercaseType == "url" || lowercaseType.startsWithIgnoringASCIICase("text/uri-list;"))
@@ -120,6 +121,11 @@ static String normalizeType(const String& type)
     return lowercaseType;
 }
 
+static bool shouldReadOrWriteTypeAsCustomData(const String& type)
+{
+    return Settings::customPasteboardDataEnabled() && !Pasteboard::isSafeTypeForDOMToReadAndWrite(type);
+}
+
 void DataTransfer::clearData(const String& type)
 {
     if (!canWriteData())
@@ -134,7 +140,7 @@ void DataTransfer::clearData(const String& type)
         m_itemList->didClearStringData(normalizedType);
 }
 
-String DataTransfer::getData(const String& type) const
+String DataTransfer::getDataForItem(const String& type) const
 {
     if (!canReadData())
         return String();
@@ -142,10 +148,15 @@ String DataTransfer::getData(const String& type) const
     if ((forFileDrag() || Settings::customPasteboardDataEnabled()) && m_pasteboard->containsFiles())
         return { };
 
-    auto normalizedType = normalizeType(type);
-    if (Settings::customPasteboardDataEnabled() && !Pasteboard::isSafeTypeForDOMToReadAndWrite(normalizedType))
-        return m_pasteboard->readStringInCustomData(normalizedType);
-    return m_pasteboard->readString(normalizedType);
+    auto lowercaseType = stripLeadingAndTrailingHTMLSpaces(type).convertToASCIILowercase();
+    if (shouldReadOrWriteTypeAsCustomData(lowercaseType))
+        return m_pasteboard->readStringInCustomData(lowercaseType);
+    return m_pasteboard->readString(lowercaseType);
+}
+
+String DataTransfer::getData(const String& type) const
+{
+    return getDataForItem(normalizeType(type));
 }
 
 void DataTransfer::setData(const String& type, const String& data)
@@ -167,7 +178,7 @@ void DataTransfer::setDataFromItemList(const String& type, const String& data)
     ASSERT(canWriteData());
     RELEASE_ASSERT(is<StaticPasteboard>(*m_pasteboard));
 
-    if (Settings::customPasteboardDataEnabled() && !Pasteboard::isSafeTypeForDOMToReadAndWrite(type))
+    if (shouldReadOrWriteTypeAsCustomData(type))
         downcast<StaticPasteboard>(*m_pasteboard).writeStringInCustomData(type, data);
     else
         m_pasteboard->writeString(type, data);
@@ -200,23 +211,33 @@ DataTransferItemList& DataTransfer::items()
 
 Vector<String> DataTransfer::types() const
 {
+    return types(AddFilesType::Yes);
+}
+
+Vector<String> DataTransfer::typesForItemList() const
+{
+    return types(AddFilesType::No);
+}
+
+Vector<String> DataTransfer::types(AddFilesType addFilesType) const
+{
     if (!canReadTypes())
         return { };
     
     if (!Settings::customPasteboardDataEnabled()) {
         auto types = m_pasteboard->typesForLegacyUnsafeBindings();
         ASSERT(!types.contains("Files"));
-        if (m_pasteboard->containsFiles())
+        if (m_pasteboard->containsFiles() && addFilesType == AddFilesType::Yes)
             types.append("Files");
         return types;
     }
 
     if (m_itemList && m_itemList->hasItems() && m_itemList->items().findMatching([] (const auto& item) { return item->isFile(); }) != notFound)
-        return { ASCIILiteral("Files") };
+        return addFilesType == AddFilesType::Yes ? Vector<String> { ASCIILiteral("Files") } : Vector<String> { };
 
     if (m_pasteboard->containsFiles()) {
         ASSERT(!m_pasteboard->typesSafeForBindings().contains("Files"));
-        return { ASCIILiteral("Files") };
+        return addFilesType == AddFilesType::Yes ? Vector<String> { ASCIILiteral("Files") } : Vector<String> { };
     }
 
     auto types = m_pasteboard->typesSafeForBindings();
index abbede1..818bbff 100644 (file)
@@ -58,12 +58,14 @@ public:
 
     DataTransferItemList& items();
     Vector<String> types() const;
+    Vector<String> typesForItemList() const;
 
     FileList& files() const;
 
     void clearData(const String& type = String());
 
     String getData(const String& type) const;
+    String getDataForItem(const String& type) const;
 
     void setData(const String& type, const String& data);
     void setDataFromItemList(const String& type, const String& data);
@@ -118,6 +120,8 @@ private:
     bool forFileDrag() const { return false; }
 #endif
 
+    enum class AddFilesType { No, Yes };
+    Vector<String> types(AddFilesType) const;
     Vector<Ref<File>> filesFromPasteboardAndItemList() const;
 
     StoreMode m_storeMode;
index 831904c..7c8cd52 100644 (file)
@@ -95,7 +95,7 @@ void DataTransferItem::getAsString(ScriptExecutionContext& context, RefPtr<Strin
         return;
 
     // FIXME: Make this async.
-    callback->scheduleCallback(context, dataTransfer.getData(m_type));
+    callback->scheduleCallback(context, dataTransfer.getDataForItem(m_type));
 }
 
 RefPtr<File> DataTransferItem::getAsFile() const
index 82ce2de..6de3685 100644 (file)
 #include "DataTransferItem.h"
 #include "FileList.h"
 #include "Pasteboard.h"
+#include "Settings.h"
 
 namespace WebCore {
 
-// FIXME: DataTransfer should filter types itself.
-static bool isSupportedType(const String& type)
-{
-    return type == "text/plain"
-        || type == "text/html"
-        || type == "text/uri-list";
-}
-
 DataTransferItemList::DataTransferItemList(DataTransfer& dataTransfer)
     : m_dataTransfer(dataTransfer)
 {
@@ -62,6 +55,11 @@ RefPtr<DataTransferItem> DataTransferItemList::item(unsigned index)
     return items[index].copyRef();
 }
 
+static bool shouldExposeTypeInItemList(const String& type)
+{
+    return Settings::customPasteboardDataEnabled() || Pasteboard::isSafeTypeForDOMToReadAndWrite(type);
+}
+
 ExceptionOr<RefPtr<DataTransferItem>> DataTransferItemList::add(const String& data, const String& type)
 {
     if (!m_dataTransfer.canWriteData())
@@ -74,14 +72,13 @@ ExceptionOr<RefPtr<DataTransferItem>> DataTransferItemList::add(const String& da
 
     String lowercasedType = type.convertToASCIILowercase();
 
-    // FIXME: Allow writing & reading of any types to clipboard / drag data store.
-    if (!isSupportedType(lowercasedType))
+    if (!shouldExposeTypeInItemList(lowercasedType))
         return nullptr;
 
     m_dataTransfer.setDataFromItemList(lowercasedType, data);
     ASSERT(m_items);
     m_items->append(DataTransferItem::create(m_weakPtrFactory.createWeakPtr(*this), lowercasedType));
-    return RefPtr<DataTransferItem> { m_items->last().copyRef() };
+    return m_items->last().ptr();
 }
 
 RefPtr<DataTransferItem> DataTransferItemList::add(Ref<File>&& file)
@@ -137,9 +134,9 @@ Vector<Ref<DataTransferItem>>& DataTransferItemList::ensureItems() const
         return *m_items;
 
     Vector<Ref<DataTransferItem>> items;
-    for (auto& type : m_dataTransfer.types()) {
+    for (auto& type : m_dataTransfer.typesForItemList()) {
         auto lowercasedType = type.convertToASCIILowercase();
-        if (isSupportedType(lowercasedType))
+        if (shouldExposeTypeInItemList(lowercasedType))
             items.append(DataTransferItem::create(m_weakPtrFactory.createWeakPtr(*const_cast<DataTransferItemList*>(this)), lowercasedType));
     }