Make DataTransferItemList work with plain text entries
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Aug 2017 02:23:41 +0000 (02:23 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Aug 2017 02:23:41 +0000 (02:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175596

Reviewed by Wenson Hsieh.

Source/JavaScriptCore:

Added DataTransferItem as a common identifier since it's a runtime enabled feature.

* runtime/CommonIdentifiers.h:

Source/WebCore:

Added the basic machinery to get the list of plain text items to DataTransferItemList and DataTransferItem.

Each DataTransferItem now depends on DataTransfer so it does ref-forwarding like DataTransferItemList to make
DataTransfer alive as long as any DataTransferItem is alive.

Specifications: https://html.spec.whatwg.org/multipage/dnd.html#the-datatransferitem-interface
                https://html.spec.whatwg.org/multipage/dnd.html#the-datatransferitemlist-interface

Tests: editing/pasteboard/datatransfer-items-drop-plaintext-file.html
       editing/pasteboard/datatransfer-items-paste-plaintext.html

* dom/DataTransferItem.cpp:
(WebCore::DataTransferItem::DataTransferItem): Added two variants one for plain text and another one for a file.
(WebCore::DataTransferItem::kind const): Rewritten.
(WebCore::DataTransferItem::getAsString const): Implemented.
(WebCore::DataTransferItem::getAsFile const): Implemented.
* dom/DataTransferItem.h:
(WebCore::DataTransferItem::ref): Added.
(WebCore::DataTransferItem::deref): Added.
(WebCore::DataTransferItem::type const): Returns String instead of AtomicString.
(WebCore::DataTransferItem::kind const): Moved to cpp.
* dom/DataTransferItem.idl: Removed NoInterfaceObject since the interface object should exist on DOMWindow.
* dom/DataTransferItemList.cpp:
(WebCore::DataTransferItemList::length): Implemented.
(WebCore::DataTransferItemList::item): Ditto.
(WebCore::isSupportedType): Added. For now, we only support text/plain.
(WebCore::DataTransferItemList::ensureItems): Added. Constructs the list of DataTransferItems.
* dom/DataTransferItemList.h:
(DataTransferItemList): Added m_items. The list is filled lazily by ensureItems.
* dom/DataTransferItemList.idl: Removed NoInterfaceObject since the interface object should exist on DOMWindow.

LayoutTests:

Rebaselined the tests and added two regression tests for pasting plain text and dropping a plain text file.

Unfortunately, dropping a file is only supported by DumpRenderTree on Mac :( so it's disabled elsewhere.

* editing/pasteboard/datatransfer-idl-expected.txt: Rebaselined now that NoInterfaceObject has been dropped from
DataTransferItem.idl and DataTransferItemList.idl as expected.
* editing/pasteboard/datatransfer-idl.html: Fixed the bug that it wasn't testing IDL for DataTransferItem.
* editing/pasteboard/datatransfer-items-drop-plaintext-file-expected.txt: Added.
* editing/pasteboard/datatransfer-items-drop-plaintext-file.html: Added.
* editing/pasteboard/datatransfer-items-paste-plaintext-expected.txt: Added.
* editing/pasteboard/datatransfer-items-paste-plaintext.html: Added.
* editing/resources/text-pasteboard-data.txt: Added.
* platform/gtk/js/dom/global-constructors-attributes-expected.txt:
* platform/ios/TestExpectations:
* platform/mac-elcapitan-wk2/js/dom/global-constructors-attributes-expected.txt:
* platform/mac-elcapitan/js/dom/global-constructors-attributes-expected.txt:
* platform/mac-highsierra-wk1/js/dom/global-constructors-attributes-expected.txt:
* platform/mac-highsierra/js/dom/global-constructors-attributes-expected.txt:
* platform/mac/js/dom/global-constructors-attributes-expected.txt:
* platform/win/TestExpectations:
* platform/wk2/TestExpectations:
* platform/wpe/js/dom/global-constructors-attributes-expected.txt:

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

27 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/datatransfer-idl-expected.txt
LayoutTests/editing/pasteboard/datatransfer-idl.html
LayoutTests/editing/pasteboard/datatransfer-items-drop-plaintext-file-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/datatransfer-items-drop-plaintext-file.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/datatransfer-items-paste-plaintext-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/datatransfer-items-paste-plaintext.html [new file with mode: 0644]
LayoutTests/editing/resources/text-pasteboard-data.txt [new file with mode: 0644]
LayoutTests/platform/gtk/js/dom/global-constructors-attributes-expected.txt
LayoutTests/platform/ios/TestExpectations
LayoutTests/platform/mac-elcapitan-wk2/js/dom/global-constructors-attributes-expected.txt
LayoutTests/platform/mac-elcapitan/js/dom/global-constructors-attributes-expected.txt
LayoutTests/platform/mac-highsierra-wk1/js/dom/global-constructors-attributes-expected.txt
LayoutTests/platform/mac-highsierra/js/dom/global-constructors-attributes-expected.txt
LayoutTests/platform/mac/js/dom/global-constructors-attributes-expected.txt
LayoutTests/platform/win/TestExpectations
LayoutTests/platform/wk2/TestExpectations
LayoutTests/platform/wpe/js/dom/global-constructors-attributes-expected.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/CommonIdentifiers.h
Source/WebCore/ChangeLog
Source/WebCore/dom/DataTransferItem.cpp
Source/WebCore/dom/DataTransferItem.h
Source/WebCore/dom/DataTransferItem.idl
Source/WebCore/dom/DataTransferItemList.cpp
Source/WebCore/dom/DataTransferItemList.h
Source/WebCore/dom/DataTransferItemList.idl

index cf63fd4957bfc0fdbf3d30b41b2bd0f0594a7454..a9d944d163c9374d82a0f530dad4762eb035e5c8 100644 (file)
@@ -1,3 +1,33 @@
+2017-08-15  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Make DataTransferItemList work with plain text entries
+        https://bugs.webkit.org/show_bug.cgi?id=175596
+
+        Reviewed by Wenson Hsieh.
+
+        Rebaselined the tests and added two regression tests for pasting plain text and dropping a plain text file.
+
+        Unfortunately, dropping a file is only supported by DumpRenderTree on Mac :( so it's disabled elsewhere.
+
+        * editing/pasteboard/datatransfer-idl-expected.txt: Rebaselined now that NoInterfaceObject has been dropped from
+        DataTransferItem.idl and DataTransferItemList.idl as expected.
+        * editing/pasteboard/datatransfer-idl.html: Fixed the bug that it wasn't testing IDL for DataTransferItem.
+        * editing/pasteboard/datatransfer-items-drop-plaintext-file-expected.txt: Added.
+        * editing/pasteboard/datatransfer-items-drop-plaintext-file.html: Added.
+        * editing/pasteboard/datatransfer-items-paste-plaintext-expected.txt: Added.
+        * editing/pasteboard/datatransfer-items-paste-plaintext.html: Added.
+        * editing/resources/text-pasteboard-data.txt: Added.
+        * platform/gtk/js/dom/global-constructors-attributes-expected.txt:
+        * platform/ios/TestExpectations:
+        * platform/mac-elcapitan-wk2/js/dom/global-constructors-attributes-expected.txt:
+        * platform/mac-elcapitan/js/dom/global-constructors-attributes-expected.txt:
+        * platform/mac-highsierra-wk1/js/dom/global-constructors-attributes-expected.txt:
+        * platform/mac-highsierra/js/dom/global-constructors-attributes-expected.txt:
+        * platform/mac/js/dom/global-constructors-attributes-expected.txt:
+        * platform/win/TestExpectations:
+        * platform/wk2/TestExpectations:
+        * platform/wpe/js/dom/global-constructors-attributes-expected.txt:
+
 2017-08-15  Chris Dumez  <cdumez@apple.com>
 
         Fetch / Beacon: Use "application/octet-stream" Content-Type for payloads of type ArrayBuffer / ArrayBufferView
index 7f589f64870b5018f1c317d137e3ed1d01b175c1..93ee6df45827a3aaacd00cc339da1da34834beb7 100644 (file)
@@ -1,3 +1,4 @@
+CONSOLE MESSAGE: line 251: callback not yet supported
 
 PASS DataTransfer interface: existence and properties of interface object 
 PASS DataTransfer interface object length 
@@ -13,14 +14,23 @@ PASS DataTransfer interface: operation getData(DOMString)
 PASS DataTransfer interface: operation setData(DOMString,DOMString) 
 PASS DataTransfer interface: operation clearData(DOMString) 
 PASS DataTransfer interface: attribute files 
-FAIL DataTransferItemList interface: existence and properties of interface object assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
-FAIL DataTransferItemList interface object length assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
-FAIL DataTransferItemList interface object name assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
-FAIL DataTransferItemList interface: existence and properties of interface prototype object assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
-FAIL DataTransferItemList interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
-FAIL DataTransferItemList interface: attribute length assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
-FAIL DataTransferItemList interface: operation add(DOMString,DOMString) assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
-FAIL DataTransferItemList interface: operation add(File) assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
-FAIL DataTransferItemList interface: operation remove(unsigned long) assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
-FAIL DataTransferItemList interface: operation clear() assert_own_property: self does not have own property "DataTransferItemList" expected property "DataTransferItemList" missing
+PASS DataTransferItemList interface: existence and properties of interface object 
+PASS DataTransferItemList interface object length 
+PASS DataTransferItemList interface object name 
+PASS DataTransferItemList interface: existence and properties of interface prototype object 
+PASS DataTransferItemList interface: existence and properties of interface prototype object's "constructor" property 
+PASS DataTransferItemList interface: attribute length 
+FAIL DataTransferItemList interface: operation add(DOMString,DOMString) assert_equals: property has wrong .length expected 1 but got 0
+FAIL DataTransferItemList interface: operation add(File) assert_equals: property has wrong .length expected 1 but got 0
+PASS DataTransferItemList interface: operation remove(unsigned long) 
+PASS DataTransferItemList interface: operation clear() 
+PASS DataTransferItem interface: existence and properties of interface object 
+PASS DataTransferItem interface object length 
+PASS DataTransferItem interface object name 
+PASS DataTransferItem interface: existence and properties of interface prototype object 
+PASS DataTransferItem interface: existence and properties of interface prototype object's "constructor" property 
+PASS DataTransferItem interface: attribute kind 
+PASS DataTransferItem interface: attribute type 
+PASS DataTransferItem interface: operation getAsString(FunctionStringCallback) 
+PASS DataTransferItem interface: operation getAsFile() 
 
index b6dd64e08543d40ec1e57fedcee470a364f5b07e..5438e2bd6208574ff2917abcbe9192d471d18b10 100644 (file)
@@ -39,7 +39,7 @@ interface DataTransferItemList {
 interface DataTransferItem {
     readonly attribute DOMString kind;
     readonly attribute DOMString type;
-    void getAsString(FunctionStringCallback? _callback);
+    void getAsString(FunctionStringCallback? callback);
     File? getAsFile();
 };
 
@@ -48,13 +48,11 @@ callback FunctionStringCallback = void (DOMString data);
 <script>
 var idlsArray = new IdlArray();
 var idl = document.getElementById("datatransfer-idl").textContent
-    + document.getElementById("datatransferitemlist-idl").textContent;
+    + document.getElementById("datatransferitemlist-idl").textContent
     + document.getElementById("datatransferitem-idl").textContent;
 
 idlsArray.add_idls(idl);
 idlsArray.add_untested_idls("interface Element {};");
-//idlsArray.add_untested_idls("interface ReadableStream {};");
-//idlsArray.add_objects({ Response: ['new Response()'] });
 idlsArray.test();
 </script>
 </body>
diff --git a/LayoutTests/editing/pasteboard/datatransfer-items-drop-plaintext-file-expected.txt b/LayoutTests/editing/pasteboard/datatransfer-items-drop-plaintext-file-expected.txt
new file mode 100644 (file)
index 0000000..bec5abd
--- /dev/null
@@ -0,0 +1,17 @@
+This tests accessing DataTransferItemList when dropping a file. To manually test, drag and drop LayoutTests/editing/resources/text-pasteboard-data.txt from another app (e.g. Finder) to the box below.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS dataTransfer.items.length is 1
+PASS dataTransfer.items[0].kind is "file"
+PASS dataTransfer.items[0].type is "text/plain"
+PASS file = dataTransfer.items[0].getAsFile(); file is not null
+PASS file.name is "text-pasteboard-data.txt"
+PASS reader = new FileReader(); reader.onload = () => checkFileContent(reader.result); reader.readAsText(file); did not throw exception.
+PASS "hello, world." is "hello, world."
+PASS dataTransfer.items[0].getAsFile() is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/pasteboard/datatransfer-items-drop-plaintext-file.html b/LayoutTests/editing/pasteboard/datatransfer-items-drop-plaintext-file.html
new file mode 100644 (file)
index 0000000..21e9ca9
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<body onload="runTest()">
+<script src="../../resources/js-test-pre.js"></script>
+<script>
+
+description('This tests accessing DataTransferItemList when dropping a file.'
+    + ' To manually test, drag and drop <a href="../resources/text-pasteboard-data.txt">LayoutTests/editing/resources/text-pasteboard-data.txt</a> from another app (e.g. Finder) to the box below.');
+
+function runTest()
+{
+    if (!window.testRunner)
+        return;
+    if (!window.eventSender || !eventSender.beginDragWithFiles) {
+        testFailed('This test requires eventSender.beginDragWithFiles');
+        finishJSTest();
+        return;
+    }
+
+    eventSender.beginDragWithFiles(["../resources/text-pasteboard-data.txt"]);
+    const target = document.getElementById('target');
+    eventSender.mouseMoveTo(target.offsetLeft + 5, target.offsetTop + 5);
+    eventSender.mouseUp();
+}
+
+function drop(event)
+{
+    event.preventDefault();
+    dataTransfer = event.dataTransfer;
+    shouldBe('dataTransfer.items.length', '1');
+    shouldBeEqualToString('dataTransfer.items[0].kind', 'file');
+    shouldBeEqualToString('dataTransfer.items[0].type', 'text/plain');
+    shouldNotBe('file = dataTransfer.items[0].getAsFile(); file', 'null');
+    shouldBeEqualToString('file.name', 'text-pasteboard-data.txt');
+    shouldNotThrow('reader = new FileReader(); reader.onload = () => checkFileContent(reader.result); reader.readAsText(file);');
+}
+
+function checkFileContent(content)
+{
+    shouldBeEqualToString('"' + content + '"', 'hello, world.');
+    shouldBe('dataTransfer.items[0].getAsFile()', 'null');
+    finishJSTest();
+}
+
+jsTestIsAsync = true;
+successfullyParsed = true;
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+<div id="target" contenteditable="true" ondrop="drop(event)" style="width: 100px; height: 100px; border: solid 1px black;"></div>
+</body>
+</html>
diff --git a/LayoutTests/editing/pasteboard/datatransfer-items-paste-plaintext-expected.txt b/LayoutTests/editing/pasteboard/datatransfer-items-paste-plaintext-expected.txt
new file mode 100644 (file)
index 0000000..dbd758a
--- /dev/null
@@ -0,0 +1,15 @@
+This tests dataTransfer.items. To manually test, click on "Copy text" and paste (Command+V on Mac Control+V elsewhere).
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS clipboardData.items.length is 1
+PASS clipboardData.items[0].kind is "string"
+PASS clipboardData.items[0].type is "text/plain"
+PASS clipboardData.items[0].getAsFile() is null
+PASS clipboardData.items[0].getAsString(checkContent) is undefined
+PASS "hello, world" is "hello, world"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/editing/pasteboard/datatransfer-items-paste-plaintext.html b/LayoutTests/editing/pasteboard/datatransfer-items-paste-plaintext.html
new file mode 100644 (file)
index 0000000..f359505
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test-pre.js"></script>
+<script>
+
+description('This tests dataTransfer.items. To manually test, click on "Copy text" and paste (Command+V on Mac Control+V elsewhere).');
+
+function copyText()
+{
+    document.getElementById('source').style.display = null;
+    document.getElementById('source').focus();
+    document.execCommand('SelectAll', false, null);
+    document.execCommand('Copy', false, null);
+    document.getElementById('source').style.display = 'none';
+    document.getElementById('target').focus();
+    if (window.testRunner)
+        testRunner.execCommand('Paste', null);
+}
+
+function paste(event)
+{
+    clipboardData = event.clipboardData;
+    shouldBe('clipboardData.items.length', '1');
+    shouldBeEqualToString('clipboardData.items[0].kind', 'string');
+    shouldBeEqualToString('clipboardData.items[0].type', 'text/plain');
+    shouldBe('clipboardData.items[0].getAsFile()', 'null');
+    shouldBe('clipboardData.items[0].getAsString(checkContent)', 'undefined');
+}
+
+function checkContent(content)
+{
+    shouldBeEqualToString('"' + content + '"', 'hello, world');
+    document.getElementById('container').style.display = 'none';
+    finishJSTest();
+}
+
+if (window.testRunner)
+    window.onload = copyText;
+jsTestIsAsync = true;
+successfullyParsed = true;
+
+</script>
+<div id="container">
+    <button onclick="copyText();">Copy text</button>
+    <div id="source" contenteditable="true" style="display: none">hello, world</div>
+    <div id="target" contenteditable="true" onpaste="paste(event)"></div>
+</div>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/editing/resources/text-pasteboard-data.txt b/LayoutTests/editing/resources/text-pasteboard-data.txt
new file mode 100644 (file)
index 0000000..1214afd
--- /dev/null
@@ -0,0 +1 @@
+hello, world.
\ No newline at end of file
index 007e8218dbb0d60ce9916ec26e256cbebaf33b64..2c2be617b9ad6609eeed4b8829b341e5ffdd4e25 100644 (file)
@@ -398,6 +398,16 @@ PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('get
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('set') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').enumerable is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').value is DataTransferItem
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').value is DataTransferItemList
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').configurable is true
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').value is DataView
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('get') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('set') is false
index 1c92ec3654c012d5b26469c671335a121c2b9203..166216c6df22092478a66ff95393b0ecd061b010 100644 (file)
@@ -235,6 +235,8 @@ fast/dom/DeviceOrientation
 fast/canvas/canvas-toDataURL-webp.html
 
 # Drag-and-drop is not supported:
+editing/pasteboard/datatransfer-items-drop-plaintext-file.html
+editing/pasteboard/datatransfer-items-paste-plaintext.html
 editing/pasteboard/drag-link-with-data-transfer-adds-trusted-link-to-pasteboard.html
 fast/events/bogus-dropEffect-effectAllowed.html
 fast/events/clear-drag-state.html
index c758464b359cdec8061fc6f078156fd2c2d52589..718e1764f43c5f84217b1a5c422f1dfe6adaca24 100644 (file)
@@ -398,6 +398,16 @@ PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('get
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('set') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').enumerable is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').value is DataTransferItem
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').value is DataTransferItemList
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').configurable is true
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').value is DataView
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('get') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('set') is false
index a268d139147568141ed2ab7bf40b51db9ce0ede7..b44ef298d9e26f03e161c023ab4640d8c211037d 100644 (file)
@@ -388,6 +388,16 @@ PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('get
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('set') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').enumerable is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').value is DataTransferItem
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').value is DataTransferItemList
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').configurable is true
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').value is DataView
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('get') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('set') is false
index 1ce1a2762ee72691ee7bbe170d2253242154f343..e801c7fc308ad7028c57a7a171c8f29f24389e88 100644 (file)
@@ -393,6 +393,16 @@ PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('get
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('set') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').enumerable is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').value is DataTransferItem
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').value is DataTransferItemList
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').configurable is true
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').value is DataView
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('get') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('set') is false
index 1335e98706cf53fce7846bc483e643f3c048198a..6ce191bd24300546db5fb82b57526f8b1f5329b1 100644 (file)
@@ -408,6 +408,16 @@ PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('get
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('set') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').enumerable is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').value is DataTransferItem
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').value is DataTransferItemList
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').configurable is true
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').value is DataView
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('get') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('set') is false
index 96f381d9078a19241ab95bd55fbc817cfdf7b9b1..61edc00b7862bc9d3626420f2195889f1dcdbe4a 100644 (file)
@@ -403,6 +403,16 @@ PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('get
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('set') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').enumerable is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').value is DataTransferItem
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').value is DataTransferItemList
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').configurable is true
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').value is DataView
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('get') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('set') is false
index 541ec6801d41b55182142785834bf310e64ba49d..e012d20010cdf6a47765843276de910f273f2fb8 100644 (file)
@@ -121,6 +121,7 @@ svg/custom/svg-allowed-in-dashboard-object.html [ Skip ]
 fast/repaint/overflow-scroll-touch-repaint.html [ Skip ]
 
 # TODO Drag & Drop doesn't work correctly in DRT <rdar://5621244>
+editing/pasteboard/datatransfer-items-drop-plaintext-file.html
 fast/events/drop-handler-should-not-stop-navigate.html [ Skip ]
 fast/events/drag-in-frames.html [ Skip ]
 fast/events/drag-to-navigate.html [ Skip ]
index 47a938019632954da6852949fd156e8398e6dbb1..56997652792dbc162f10146ccea45391f567c555 100644 (file)
@@ -563,6 +563,7 @@ platform/mac/fast/events/objc-event-api.html
 
 # WebKitTestRunner needs an implementation of eventSender.beginDragWithFiles
 # https://bugs.webkit.org/show_bug.cgi?id=64285
+editing/pasteboard/datatransfer-items-drop-plaintext-file.html
 editing/pasteboard/file-drag-to-editable.html [ Skip ]
 editing/pasteboard/file-input-files-access.html
 fast/dom/FileList-iterator.html
index f108a3f1ab7bd85552a67aa4b592a5e48ed7160d..a69cacd6a38fd7bbd99d628354f91fcdfe2fe34e 100644 (file)
@@ -393,6 +393,16 @@ PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('get
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').hasOwnProperty('set') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').enumerable is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataTransfer').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').value is DataTransferItem
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItem').configurable is true
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').value is DataTransferItemList
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('get') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').hasOwnProperty('set') is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').enumerable is false
+PASS Object.getOwnPropertyDescriptor(global, 'DataTransferItemList').configurable is true
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').value is DataView
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('get') is false
 PASS Object.getOwnPropertyDescriptor(global, 'DataView').hasOwnProperty('set') is false
index d12b1fea104b8a2d9ab90099274714476c2373d3..da5a42564ecff1b1f39010653032f334cb90e056 100644 (file)
@@ -1,3 +1,14 @@
+2017-08-15  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Make DataTransferItemList work with plain text entries
+        https://bugs.webkit.org/show_bug.cgi?id=175596
+
+        Reviewed by Wenson Hsieh.
+
+        Added DataTransferItem as a common identifier since it's a runtime enabled feature.
+
+        * runtime/CommonIdentifiers.h:
+
 2017-08-15  Robin Morisset  <rmorisset@apple.com>
 
         Support the 'with' keyword in FTL
index b94b60c974944f11b8ab3929cd8517e5f8fd474e..e88d3d5a06dc37beb489d323ecb50eeb3da649ba 100644 (file)
@@ -43,6 +43,7 @@
     macro(CustomElementRegistry) \
     macro(Date) \
     macro(DateTimeFormat) \
+    macro(DataTransferItem) \
     macro(DataTransferItemList) \
     macro(DocumentTimeline) \
     macro(Error) \
index 25cbc567e3793cf880775e5b399928d02f386c97..26a2ec5f902ccae11a743d790919121e5e3d2fa8 100644 (file)
@@ -1,3 +1,41 @@
+2017-08-15  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Make DataTransferItemList work with plain text entries
+        https://bugs.webkit.org/show_bug.cgi?id=175596
+
+        Reviewed by Wenson Hsieh.
+
+        Added the basic machinery to get the list of plain text items to DataTransferItemList and DataTransferItem.
+
+        Each DataTransferItem now depends on DataTransfer so it does ref-forwarding like DataTransferItemList to make
+        DataTransfer alive as long as any DataTransferItem is alive.
+
+        Specifications: https://html.spec.whatwg.org/multipage/dnd.html#the-datatransferitem-interface
+                        https://html.spec.whatwg.org/multipage/dnd.html#the-datatransferitemlist-interface
+
+        Tests: editing/pasteboard/datatransfer-items-drop-plaintext-file.html
+               editing/pasteboard/datatransfer-items-paste-plaintext.html
+
+        * dom/DataTransferItem.cpp:
+        (WebCore::DataTransferItem::DataTransferItem): Added two variants one for plain text and another one for a file.
+        (WebCore::DataTransferItem::kind const): Rewritten.
+        (WebCore::DataTransferItem::getAsString const): Implemented.
+        (WebCore::DataTransferItem::getAsFile const): Implemented.
+        * dom/DataTransferItem.h:
+        (WebCore::DataTransferItem::ref): Added.
+        (WebCore::DataTransferItem::deref): Added.
+        (WebCore::DataTransferItem::type const): Returns String instead of AtomicString.
+        (WebCore::DataTransferItem::kind const): Moved to cpp.
+        * dom/DataTransferItem.idl: Removed NoInterfaceObject since the interface object should exist on DOMWindow.
+        * dom/DataTransferItemList.cpp:
+        (WebCore::DataTransferItemList::length): Implemented.
+        (WebCore::DataTransferItemList::item): Ditto.
+        (WebCore::isSupportedType): Added. For now, we only support text/plain.
+        (WebCore::DataTransferItemList::ensureItems): Added. Constructs the list of DataTransferItems.
+        * dom/DataTransferItemList.h:
+        (DataTransferItemList): Added m_items. The list is filled lazily by ensureItems.
+        * dom/DataTransferItemList.idl: Removed NoInterfaceObject since the interface object should exist on DOMWindow.
+
 2017-08-15  Simon Fraser  <simon.fraser@apple.com>
 
         Remove ScrollView::clipsRepaints() which was only used by Chromium
index dd8a489bf49bd03365d840ebe7d2502148435eff..a0cf5355ab03ca1ddd088c459cea8542aa00c503 100644 (file)
 #include "config.h"
 #include "DataTransferItem.h"
 
-#include "Blob.h"
+#include "File.h"
+#include "ScriptExecutionContext.h"
 #include "StringCallback.h"
 
 namespace WebCore {
 
-DataTransferItem::DataTransferItem()
+DataTransferItem::DataTransferItem(DataTransfer& dataTransfer, const String& type)
+    : m_dataTransfer(dataTransfer)
+    , m_type(type)
+{
+}
+
+DataTransferItem::DataTransferItem(DataTransfer& dataTransfer, const String& type, Ref<File>&& file)
+    : m_dataTransfer(dataTransfer)
+    , m_type(type)
+    , m_file(WTFMove(file))
 {
 }
 
@@ -45,13 +55,25 @@ DataTransferItem::~DataTransferItem()
 {
 }
 
-void DataTransferItem::getAsString(RefPtr<StringCallback>&&) const
+String DataTransferItem::kind() const
 {
+    return m_file ? ASCIILiteral("file") : ASCIILiteral("string");
+}
+
+void DataTransferItem::getAsString(ScriptExecutionContext& context, RefPtr<StringCallback>&& callback) const
+{
+    if (!callback || !m_dataTransfer.canReadData() || m_file)
+        return;
+
+    // FIXME: Make this async.
+    callback->scheduleCallback(context, m_dataTransfer.getData(m_type));
 }
 
-RefPtr<Blob> DataTransferItem::getAsFile() const
+RefPtr<File> DataTransferItem::getAsFile() const
 {
-    return nullptr;
+    if (!m_dataTransfer.canReadData())
+        return nullptr;
+    return m_file.copyRef();
 }
 
 } // namespace WebCore
index bf6002cb90a5d180252b83f64d7e64c335cf70a2..2a54b5a198a403f9472dc509d97d14eb702febab 100644 (file)
 
 #pragma once
 
+#include "DataTransfer.h"
+#include "ScriptWrappable.h"
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 #include <wtf/text/AtomicString.h>
 
 namespace WebCore {
 
-class Blob;
+class File;
+class ScriptExecutionContext;
 class StringCallback;
 
-class DataTransferItem : public RefCounted<DataTransferItem> {
+class DataTransferItem : public ScriptWrappable {
+    WTF_MAKE_NONCOPYABLE(DataTransferItem); WTF_MAKE_FAST_ALLOCATED;
 public:
-    DataTransferItem();
+    DataTransferItem(DataTransfer&, const String&);
+    DataTransferItem(DataTransfer&, const String&, Ref<File>&&);
     ~DataTransferItem();
 
-    const AtomicString& kind() const { return m_kind; }
-    const AtomicString& type() const { return m_type; }
-    void getAsString(RefPtr<StringCallback>&&) const;
-    RefPtr<Blob> getAsFile() const;
+    // DataTransfer owns DataTransferItem, and DataTransfer is kept alive as long as DataTransferItem is alive.
+    void ref() { m_dataTransfer.ref(); }
+    void deref() { m_dataTransfer.deref(); }
+
+    String kind() const;
+    const String& type() const { return m_type; }
+    void getAsString(ScriptExecutionContext&, RefPtr<StringCallback>&&) const;
+    RefPtr<File> getAsFile() const;
 
 private:
-    AtomicString m_kind;
-    AtomicString m_type;
+    DataTransfer& m_dataTransfer;
+    const String m_type;
+    RefPtr<File> m_file;
 };
 
 }
index 229fbbfb683ea7daf7070749f93d97cbf88e1b3a..7397a7ff0b08303333700d98d7ab8419903aa048 100644 (file)
  */
 
 [
-    NoInterfaceObject,
     EnabledAtRuntime=DataTransferItems,
     ImplementationLacksVTable,
 ] interface DataTransferItem {
     readonly attribute DOMString kind;
     readonly attribute DOMString type;
 
-    void getAsString(optional StringCallback? callback);
-    Blob getAsFile();
+    [CallWith=ScriptExecutionContext] void getAsString(StringCallback? callback);
+    File getAsFile();
 };
 
index 9b982b93eba09eac12d598742d81f5cfa6ae5e0b..3345259e64d1787a0175447e0d2313d620628cef 100644 (file)
 #include "DataTransferItemList.h"
 
 #include "DataTransferItem.h"
+#include "FileList.h"
 
 namespace WebCore {
 
 unsigned DataTransferItemList::length() const
 {
-    return 0;
+    return ensureItems().size();
 }
 
-RefPtr<DataTransferItem> DataTransferItemList::item(unsigned)
+RefPtr<DataTransferItem> DataTransferItemList::item(unsigned index)
 {
-    return nullptr;
+    auto& items = ensureItems();
+    if (items.size() <= index)
+        return nullptr;
+    return items[index].get();
 }
 
 ExceptionOr<void> DataTransferItemList::add(const String&, const String&)
@@ -57,5 +61,36 @@ void DataTransferItemList::clear()
 {
 }
 
+// FIXME: DataTransfer should filter types itself.
+static bool isSupportedType(const String& type)
+{
+    return equalIgnoringASCIICase(type, "text/plain");
+}
+
+Vector<std::unique_ptr<DataTransferItem>>& DataTransferItemList::ensureItems() const
+{
+    if (m_items)
+        return *m_items;
+
+    Vector<std::unique_ptr<DataTransferItem>> items;
+    for (String& type : m_dataTransfer.types()) {
+        if (isSupportedType(type))
+            items.append(std::make_unique<DataTransferItem>(m_dataTransfer, type));
+    }
+
+    FileList& files = m_dataTransfer.files();
+    for (unsigned i = 0, length = files.length(); i < length; ++i) {
+        File& file = *files.item(i);
+        String type = File::contentTypeForFile(file.path());
+        if (isSupportedType(type))
+            items.append(std::make_unique<DataTransferItem>(m_dataTransfer, type, file));
+    }
+
+
+    m_items = WTFMove(items);
+
+    return *m_items;
+}
+
 }
 
index 5548d4884912bc72659ce205245cc568e08dcdd8..7bab3b55f95ea38242447687bf2748aaed1a1619 100644 (file)
 #pragma once
 
 #include "DataTransfer.h"
+#include "DataTransferItem.h"
 #include "ExceptionOr.h"
+#include "ScriptWrappable.h"
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 
 namespace WebCore {
 
-class DataTransferItem;
 class File;
 
-class DataTransferItemList {
+class DataTransferItemList : public ScriptWrappable {
     WTF_MAKE_NONCOPYABLE(DataTransferItemList); WTF_MAKE_FAST_ALLOCATED;
 public:
     DataTransferItemList(DataTransfer& dataTransfer)
@@ -61,7 +62,10 @@ public:
     void clear();
 
 private:
+    Vector<std::unique_ptr<DataTransferItem>>& ensureItems() const;
+
     DataTransfer& m_dataTransfer;
+    mutable std::optional<Vector<std::unique_ptr<DataTransferItem>>> m_items;
 };
 
 } // namespace WebCore
index 24c022747d6f27e7e16767f874813596344c892a..8f2369f32713e967e4bddd413b40c1cb5b4219da 100644 (file)
@@ -30,7 +30,6 @@
  */
 
 [
-    NoInterfaceObject,
     EnabledAtRuntime=DataTransferItems,
     JSGenerateToNativeObject,
     JSGenerateToJSObject,