Diff
Modified: trunk/LayoutTests/ChangeLog (220828 => 220829)
--- trunk/LayoutTests/ChangeLog 2017-08-17 06:11:21 UTC (rev 220828)
+++ trunk/LayoutTests/ChangeLog 2017-08-17 06:17:09 UTC (rev 220829)
@@ -1,3 +1,17 @@
+2017-08-16 Ryosuke Niwa <[email protected]>
+
+ Add the support for mutating clipboard data via DataTransferItemList
+ https://bugs.webkit.org/show_bug.cgi?id=175639
+
+ Reviewed by Wenson Hsieh.
+
+ Rebaselined the IDL test which now passes all test cases, and added a regression test for mutating clipboard data
+ via dataTransfer.items and methods on dataTransfer for plaintext.
+
+ * editing/pasteboard/datatransfer-idl-expected.txt:
+ * editing/pasteboard/datatransfer-items-copy-plaintext-expected.txt: Added.
+ * editing/pasteboard/datatransfer-items-copy-plaintext.html: Added.
+
2017-08-16 Ryan Haddad <[email protected]>
Mark fullscreen/full-screen-iframe-legacy.html as flaky on Sierra WK1.
Modified: trunk/LayoutTests/editing/pasteboard/datatransfer-idl-expected.txt (220828 => 220829)
--- trunk/LayoutTests/editing/pasteboard/datatransfer-idl-expected.txt 2017-08-17 06:11:21 UTC (rev 220828)
+++ trunk/LayoutTests/editing/pasteboard/datatransfer-idl-expected.txt 2017-08-17 06:17:09 UTC (rev 220829)
@@ -20,8 +20,8 @@
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 add(DOMString,DOMString)
+PASS DataTransferItemList interface: operation add(File)
PASS DataTransferItemList interface: operation remove(unsigned long)
PASS DataTransferItemList interface: operation clear()
PASS DataTransferItem interface: existence and properties of interface object
Added: trunk/LayoutTests/editing/pasteboard/datatransfer-items-copy-plaintext-expected.txt (0 => 220829)
--- trunk/LayoutTests/editing/pasteboard/datatransfer-items-copy-plaintext-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/datatransfer-items-copy-plaintext-expected.txt 2017-08-17 06:17:09 UTC (rev 220829)
@@ -0,0 +1,43 @@
+This tests copying plain text using 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 0
+PASS clipboardData.setData("text/plain", "rock"); clipboardData.items.length is 1
+PASS initialItem = clipboardData.items[0]; initialItem.kind is "string"
+PASS initialItem.type is "text/plain"
+PASS initialItem.getAsFile() is null
+PASS initialItem.getAsString(checkContent(1, "rock")) is undefined
+PASS clipboardData.items.add("paper", "text/plain") threw exception NotSupportedError: The operation is not supported..
+PASS clipboardData.items[0] is initialItem
+PASS clipboardData.clearData(); clipboardData.items.length is 0
+PASS clipboardData.items.add("scissors", "text/plain"); clipboardData.items.length is 1
+PASS clipboardData.items[0] is not initialItem
+PASS initialItem.kind is "string"
+PASS initialItem.type is ""
+PASS initialItem.getAsFile() is null
+PASS initialItem.getAsString(() => testFailed("getAsString should exit immeidately if item is disabled")) is undefined
+PASS clipboardData.getData("text/plain") is "scissors"
+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(2, "scissors")) is undefined
+PASS clipboardData.items.clear(); clipboardData.items.length is 0
+PASS clipboardData.getData("text/plain") is ""
+PASS clipboardData.items.add("WebKit", "text/plain"); 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(3, "WebKit")) is undefined
+PASS clipboardData.items.remove(1) threw exception IndexSizeError: The index is not in the allowed range..
+PASS clipboardData.items.length is 1
+PASS clipboardData.items.remove(0); clipboardData.items.length is 0
+PASS clipboardData.getData("text/plain") is ""
+PASS actualContent1 is "rock"
+PASS actualContent2 is "scissors"
+PASS actualContent3 is "WebKit"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/editing/pasteboard/datatransfer-items-copy-plaintext.html (0 => 220829)
--- trunk/LayoutTests/editing/pasteboard/datatransfer-items-copy-plaintext.html (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/datatransfer-items-copy-plaintext.html 2017-08-17 06:17:09 UTC (rev 220829)
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+
+description('This tests copying plain text using dataTransfer.items. To manually test, click on "Copy text" and paste (Command+V on Mac Control+V elsewhere).');
+
+function copyText()
+{
+ document.getElementById('source').focus();
+ document.execCommand('SelectAll', false, null);
+ document.execCommand('Copy', false, null);
+}
+
+function copy(event)
+{
+ clipboardData = event.clipboardData;
+ shouldBe('clipboardData.items.length', '0');
+ shouldBe('clipboardData.setData("text/plain", "rock"); clipboardData.items.length', '1');
+ shouldBeEqualToString('initialItem = clipboardData.items[0]; initialItem.kind', 'string');
+ shouldBeEqualToString('initialItem.type', 'text/plain');
+ shouldBe('initialItem.getAsFile()', 'null');
+ shouldBe('initialItem.getAsString(checkContent(1, "rock"))', 'undefined');
+
+ shouldThrowErrorName('clipboardData.items.add("paper", "text/plain")', 'NotSupportedError');
+ shouldBe('clipboardData.items[0]', 'initialItem');
+ shouldBe('clipboardData.clearData(); clipboardData.items.length', '0');
+
+ shouldBe('clipboardData.items.add("scissors", "text/plain"); clipboardData.items.length', '1');
+ shouldNotBe('clipboardData.items[0]', 'initialItem');
+ shouldBeEqualToString('initialItem.kind', 'string');
+ shouldBeEqualToString('initialItem.type', '');
+ shouldBe('initialItem.getAsFile()', 'null');
+ shouldBe('initialItem.getAsString(() => testFailed("getAsString should exit immeidately if item is disabled"))', 'undefined');
+
+ shouldBeEqualToString('clipboardData.getData("text/plain")', 'scissors');
+ 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(2, "scissors"))', 'undefined');
+
+ shouldBe('clipboardData.items.clear(); clipboardData.items.length', '0');
+ shouldBeEqualToString('clipboardData.getData("text/plain")', '');
+
+ shouldBe('clipboardData.items.add("WebKit", "text/plain"); 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(3, "WebKit"))', 'undefined');
+
+ shouldThrowErrorName('clipboardData.items.remove(1)', 'IndexSizeError');
+ shouldBe('clipboardData.items.length', '1');
+ shouldBe('clipboardData.items.remove(0); clipboardData.items.length', '0');
+ shouldBeEqualToString('clipboardData.getData("text/plain")', '');
+}
+
+let count = 0;
+function checkContent(number, expectedContent)
+{
+ count++;
+ return (content) => {
+ const variableName = 'actualContent' + number;
+ window[variableName] = content;
+ shouldBeEqualToString(variableName, expectedContent);
+ count--;
+ if (!count) {
+ 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" _oncopy_="copy(event)" contenteditable="true">hello, world</div>
+</div>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (220828 => 220829)
--- trunk/Source/WebCore/ChangeLog 2017-08-17 06:11:21 UTC (rev 220828)
+++ trunk/Source/WebCore/ChangeLog 2017-08-17 06:17:09 UTC (rev 220829)
@@ -1,3 +1,62 @@
+2017-08-16 Ryosuke Niwa <[email protected]>
+
+ Add the support for mutating clipboard data via DataTransferItemList
+ https://bugs.webkit.org/show_bug.cgi?id=175639
+
+ Reviewed by Wenson Hsieh.
+
+ Added the support for adding plaintext data via dataTransfer.items.add, clearing data via clear,
+ and removing an entry via remove. When DataTransferItem is removed from DataTransferItemList,
+ we must put into the disabled mode.
+
+ To support the removal of DataTransferItem, this patch replaces a reference to DataTransfer by
+ a WeakPtr to DataTransferItemList, and stops forwarding ref from DataTransferItem to DataTransfer.
+ This means that DataTransfer can now be GC'ed before DataTransferItem is GC'ed.
+
+ Because the identify and the order of DataTransferItems need to be preserved, we can't simply
+ re-popluate m_itemList in DataTransferItemList. Instead, whenever the clipboard content is mutated,
+ we make the parallel modifications to m_itemList. This includes changes made via DataTransfer
+ methods such as setData and clearData.
+
+ Test: editing/pasteboard/datatransfer-items-copy-plaintext.html
+
+ * dom/DataTransfer.cpp:
+ (WebCore::DataTransfer::clearData): Invoke didClearStringData when m_itemList exists.
+ (WebCore::DataTransfer::setData): Ditto.
+ (WebCore::DataTransfer::createForInputEvent):
+ (WebCore::DataTransfer::createForDrag):
+ (WebCore::DataTransfer::createForDrop):
+ * dom/DataTransferItem.cpp:
+ (WebCore::DataTransferItem::create):
+ (WebCore::DataTransferItem::DataTransferItem):
+ (WebCore::DataTransferItem::clearListAndPutIntoDisabledMode): Added.
+ (WebCore::DataTransferItem::type const): Moved from the header.
+ (WebCore::DataTransferItem::getAsString const):
+ (WebCore::DataTransferItem::getAsFile const):
+ * dom/DataTransferItem.h:
+ (WebCore::DataTransferItem::ref): Deleted.
+ (WebCore::DataTransferItem::deref): Deleted.
+ (WebCore::DataTransferItem::isFile const): Added.
+ (WebCore::DataTransferItem::type const): Move to the cpp file.
+ * dom/DataTransferItemList.cpp:
+ (WebCore::isSupportedType): Moved.
+ (WebCore::DataTransferItemList::DataTransferItemList): Moved from the header.
+ (WebCore::DataTransferItemList::~DataTransferItemList): Added.
+ (WebCore::DataTransferItemList::item):
+ (WebCore::DataTransferItemList::add): Implemented the variant to add string data.
+ (WebCore::DataTransferItemList::remove): Implemented. For now, we don't have to deal with removing
+ a file since a writable dataTransfer never contains a File object.
+ (WebCore::DataTransferItemList::clear): Implemented.
+ (WebCore::DataTransferItemList::ensureItems const):
+ (WebCore::removeStringItemOfLowercasedType): Added.
+ (WebCore::DataTransferItemList::didClearStringData): Called when dataTransfer.clear is called.
+ (WebCore::DataTransferItemList::didSetStringData): Ditto for
+ * dom/DataTransferItemList.h:
+ (WebCore::DataTransferItemList): Added a WeakPtrFactory. Also use a vector of Ref<DataTransferItem>
+ instead of unique_ptr<DataTransferItem> since DataTransferItem can outlive DataTransferItemList.
+ (WebCore::DataTransferItemList::dataTransfer): Added.
+ * dom/DataTransferItemList.idl:
+
2017-08-16 Andy Estes <[email protected]>
[Apple Pay] Rename PaymentRequest to ApplePaySessionPaymentRequest
Modified: trunk/Source/WebCore/dom/DataTransfer.cpp (220828 => 220829)
--- trunk/Source/WebCore/dom/DataTransfer.cpp 2017-08-17 06:11:21 UTC (rev 220828)
+++ trunk/Source/WebCore/dom/DataTransfer.cpp 2017-08-17 06:17:09 UTC (rev 220829)
@@ -118,6 +118,8 @@
m_pasteboard->clear();
else
m_pasteboard->clear(type);
+ if (m_itemList)
+ m_itemList->didClearStringData(type);
}
String DataTransfer::getData(const String& type) const
@@ -144,6 +146,8 @@
#endif
m_pasteboard->writeString(type, data);
+ if (m_itemList)
+ m_itemList->didSetStringData(type);
}
DataTransferItemList& DataTransfer::items()
Modified: trunk/Source/WebCore/dom/DataTransferItem.cpp (220828 => 220829)
--- trunk/Source/WebCore/dom/DataTransferItem.cpp 2017-08-17 06:11:21 UTC (rev 220828)
+++ trunk/Source/WebCore/dom/DataTransferItem.cpp 2017-08-17 06:17:09 UTC (rev 220829)
@@ -32,6 +32,7 @@
#include "config.h"
#include "DataTransferItem.h"
+#include "DataTransferItemList.h"
#include "File.h"
#include "ScriptExecutionContext.h"
#include "StringCallback.h"
@@ -38,14 +39,24 @@
namespace WebCore {
-DataTransferItem::DataTransferItem(DataTransfer& dataTransfer, const String& type)
- : m_dataTransfer(dataTransfer)
+Ref<DataTransferItem> DataTransferItem::create(WeakPtr<DataTransferItemList>&& list, const String& type)
+{
+ return adoptRef(*new DataTransferItem(WTFMove(list), type));
+}
+
+Ref<DataTransferItem> DataTransferItem::create(WeakPtr<DataTransferItemList>&& list, const String& type, Ref<File>&& file)
+{
+ return adoptRef(*new DataTransferItem(WTFMove(list), type, WTFMove(file)));
+}
+
+DataTransferItem::DataTransferItem(WeakPtr<DataTransferItemList>&& list, const String& type)
+ : m_list(WTFMove(list))
, m_type(type)
{
}
-DataTransferItem::DataTransferItem(DataTransfer& dataTransfer, const String& type, Ref<File>&& file)
- : m_dataTransfer(dataTransfer)
+DataTransferItem::DataTransferItem(WeakPtr<DataTransferItemList>&& list, const String& type, Ref<File>&& file)
+ : m_list(WTFMove(list))
, m_type(type)
, m_file(WTFMove(file))
{
@@ -55,23 +66,37 @@
{
}
+void DataTransferItem::clearListAndPutIntoDisabledMode()
+{
+ m_list.clear();
+}
+
String DataTransferItem::kind() const
{
return m_file ? ASCIILiteral("file") : ASCIILiteral("string");
}
+String DataTransferItem::type() const
+{
+ return isInDisabledMode() ? String() : m_type;
+}
+
void DataTransferItem::getAsString(ScriptExecutionContext& context, RefPtr<StringCallback>&& callback) const
{
- if (!callback || !m_dataTransfer.canReadData() || m_file)
+ if (!callback || !m_list || m_file)
return;
+ auto& dataTransfer = m_list->dataTransfer();
+ if (!dataTransfer.canReadData())
+ return;
+
// FIXME: Make this async.
- callback->scheduleCallback(context, m_dataTransfer.getData(m_type));
+ callback->scheduleCallback(context, dataTransfer.getData(m_type));
}
RefPtr<File> DataTransferItem::getAsFile() const
{
- if (!m_dataTransfer.canReadData())
+ if (!m_list || !m_list->dataTransfer().canReadData())
return nullptr;
return m_file.copyRef();
}
Modified: trunk/Source/WebCore/dom/DataTransferItem.h (220828 => 220829)
--- trunk/Source/WebCore/dom/DataTransferItem.h 2017-08-17 06:11:21 UTC (rev 220828)
+++ trunk/Source/WebCore/dom/DataTransferItem.h 2017-08-17 06:17:09 UTC (rev 220829)
@@ -35,32 +35,38 @@
#include "ScriptWrappable.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
+#include <wtf/WeakPtr.h>
#include <wtf/text/AtomicString.h>
namespace WebCore {
+class DataTransferListItem;
class File;
class ScriptExecutionContext;
class StringCallback;
-class DataTransferItem : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(DataTransferItem); WTF_MAKE_FAST_ALLOCATED;
+class DataTransferItem : public RefCounted<DataTransferItem> {
public:
- DataTransferItem(DataTransfer&, const String&);
- DataTransferItem(DataTransfer&, const String&, Ref<File>&&);
+ static Ref<DataTransferItem> create(WeakPtr<DataTransferItemList>&&, const String&);
+ static Ref<DataTransferItem> create(WeakPtr<DataTransferItemList>&&, const String&, Ref<File>&&);
+
~DataTransferItem();
- // DataTransfer owns DataTransferItem, and DataTransfer is kept alive as long as DataTransferItem is alive.
- void ref() { m_dataTransfer.ref(); }
- void deref() { m_dataTransfer.deref(); }
+ void clearListAndPutIntoDisabledMode();
+ bool isFile() const { return m_file; }
String kind() const;
- const String& type() const { return m_type; }
+ String type() const;
void getAsString(ScriptExecutionContext&, RefPtr<StringCallback>&&) const;
RefPtr<File> getAsFile() const;
private:
- DataTransfer& m_dataTransfer;
+ DataTransferItem(WeakPtr<DataTransferItemList>&&, const String&);
+ DataTransferItem(WeakPtr<DataTransferItemList>&&, const String&, Ref<File>&&);
+
+ bool isInDisabledMode() const { return !m_list; }
+
+ WeakPtr<DataTransferItemList> m_list;
const String m_type;
RefPtr<File> m_file;
};
Modified: trunk/Source/WebCore/dom/DataTransferItemList.cpp (220828 => 220829)
--- trunk/Source/WebCore/dom/DataTransferItemList.cpp 2017-08-17 06:11:21 UTC (rev 220828)
+++ trunk/Source/WebCore/dom/DataTransferItemList.cpp 2017-08-17 06:17:09 UTC (rev 220829)
@@ -28,9 +28,26 @@
#include "DataTransferItem.h"
#include "FileList.h"
+#include "Pasteboard.h"
namespace WebCore {
+// FIXME: DataTransfer should filter types itself.
+static bool isSupportedType(const String& type)
+{
+ return type == "text/plain";
+}
+
+DataTransferItemList::DataTransferItemList(DataTransfer& dataTransfer)
+ : m_weakPtrFactory(this)
+ , m_dataTransfer(dataTransfer)
+{
+}
+
+DataTransferItemList::~DataTransferItemList()
+{
+}
+
unsigned DataTransferItemList::length() const
{
return ensureItems().size();
@@ -41,56 +58,131 @@
auto& items = ensureItems();
if (items.size() <= index)
return nullptr;
- return items[index].get();
+ return items[index].copyRef();
}
-ExceptionOr<void> DataTransferItemList::add(const String&, const String&)
+ExceptionOr<RefPtr<DataTransferItem>> DataTransferItemList::add(const String& data, const String& type)
{
- return { };
+ if (!m_dataTransfer.canWriteData())
+ return nullptr;
+
+ for (auto& item : ensureItems()) {
+ if (!item->isFile() && equalIgnoringASCIICase(item->type(), type))
+ return Exception { NotSupportedError };
+ }
+
+ String lowercasedType = type.convertToASCIILowercase();
+
+ // FIXME: Allow writing & reading of any types to clipboard / drag data store.
+ if (!isSupportedType(lowercasedType))
+ return nullptr;
+
+ m_dataTransfer.pasteboard().writeString(lowercasedType, data);
+ ASSERT(m_items);
+ m_items->append(DataTransferItem::create(m_weakPtrFactory.createWeakPtr(), type));
+ return RefPtr<DataTransferItem> { m_items->last().copyRef() };
}
-void DataTransferItemList::add(RefPtr<File>&&)
+RefPtr<DataTransferItem> DataTransferItemList::add(Ref<File>&&)
{
+ return nullptr;
}
-void DataTransferItemList::remove(unsigned)
+ExceptionOr<void> DataTransferItemList::remove(unsigned index)
{
+ if (!m_dataTransfer.canWriteData())
+ return Exception { InvalidStateError };
+
+ auto& items = ensureItems();
+ if (items.size() <= index)
+ return Exception { IndexSizeError }; // Matches Gecko. See https://github.com/whatwg/html/issues/2925
+
+ // FIXME: Handle the removal of files once we added the support for writing a File.
+ ASSERT(!items[index]->isFile());
+
+ auto& removedItem = items[index].get();
+ m_dataTransfer.pasteboard().clear(removedItem.type());
+ removedItem.clearListAndPutIntoDisabledMode();
+ items.remove(index);
+
+ return { };
}
void DataTransferItemList::clear()
{
+ m_dataTransfer.pasteboard().clear();
+ if (m_items) {
+ for (auto& item : *m_items)
+ item->clearListAndPutIntoDisabledMode();
+ m_items->clear();
+ }
}
-// FIXME: DataTransfer should filter types itself.
-static bool isSupportedType(const String& type)
+Vector<Ref<DataTransferItem>>& DataTransferItemList::ensureItems() const
{
- 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;
+ Vector<Ref<DataTransferItem>> items;
for (String& type : m_dataTransfer.types()) {
- if (isSupportedType(type))
- items.append(std::make_unique<DataTransferItem>(m_dataTransfer, type));
+ String lowercasedType = type.convertToASCIILowercase();
+ if (isSupportedType(lowercasedType))
+ items.append(DataTransferItem::create(m_weakPtrFactory.createWeakPtr(), lowercasedType));
}
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());
+ String type = File::contentTypeForFile(file.path()).convertToASCIILowercase();
if (isSupportedType(type))
- items.append(std::make_unique<DataTransferItem>(m_dataTransfer, type, file));
+ items.append(DataTransferItem::create(m_weakPtrFactory.createWeakPtr(), type, file));
}
-
m_items = WTFMove(items);
return *m_items;
}
+static void removeStringItemOfLowercasedType(Vector<Ref<DataTransferItem>>& items, const String& lowercasedType)
+{
+ auto index = items.findMatching([lowercasedType](auto& item) {
+ return !item->isFile() && item->type() == lowercasedType;
+ });
+ if (index == notFound)
+ return;
+ items[index]->clearListAndPutIntoDisabledMode();
+ items.remove(index);
}
+void DataTransferItemList::didClearStringData(const String& type)
+{
+ if (!m_items)
+ return;
+
+ auto& items = *m_items;
+ if (!type.isNull())
+ return removeStringItemOfLowercasedType(items, type.convertToASCIILowercase());
+
+ for (auto& item : items) {
+ if (!item->isFile())
+ item->clearListAndPutIntoDisabledMode();
+ }
+ items.removeAllMatching([](auto& item) {
+ return !item->isFile();
+ });
+}
+
+// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-setdata
+void DataTransferItemList::didSetStringData(const String& type)
+{
+ if (!m_items)
+ return;
+
+ String lowercasedType = type.convertToASCIILowercase();
+ removeStringItemOfLowercasedType(*m_items, type.convertToASCIILowercase());
+
+ m_items->append(DataTransferItem::create(m_weakPtrFactory.createWeakPtr(), lowercasedType));
+}
+
+}
+
Modified: trunk/Source/WebCore/dom/DataTransferItemList.h (220828 => 220829)
--- trunk/Source/WebCore/dom/DataTransferItemList.h 2017-08-17 06:11:21 UTC (rev 220828)
+++ trunk/Source/WebCore/dom/DataTransferItemList.h 2017-08-17 06:17:09 UTC (rev 220829)
@@ -32,40 +32,46 @@
#pragma once
#include "DataTransfer.h"
-#include "DataTransferItem.h"
#include "ExceptionOr.h"
#include "ScriptWrappable.h"
#include <wtf/Forward.h>
+#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
+#include <wtf/WeakPtr.h>
namespace WebCore {
+class DataTransferItem;
class File;
class DataTransferItemList : public ScriptWrappable {
WTF_MAKE_NONCOPYABLE(DataTransferItemList); WTF_MAKE_FAST_ALLOCATED;
public:
- DataTransferItemList(DataTransfer& dataTransfer)
- : m_dataTransfer(dataTransfer)
- {
- }
+ DataTransferItemList(DataTransfer&);
+ ~DataTransferItemList();
// DataTransfer owns DataTransferItemList, and DataTransfer is kept alive as long as DataTransferItemList is alive.
void ref() { m_dataTransfer.ref(); }
void deref() { m_dataTransfer.deref(); }
+ DataTransfer& dataTransfer() { return m_dataTransfer; }
+ // DOM API
unsigned length() const;
RefPtr<DataTransferItem> item(unsigned index);
- ExceptionOr<void> add(const String& data, const String& type);
- void add(RefPtr<File>&&);
- void remove(unsigned index);
+ ExceptionOr<RefPtr<DataTransferItem>> add(const String& data, const String& type);
+ RefPtr<DataTransferItem> add(Ref<File>&&);
+ ExceptionOr<void> remove(unsigned index);
void clear();
+ void didClearStringData(const String& type);
+ void didSetStringData(const String& type);
+
private:
- Vector<std::unique_ptr<DataTransferItem>>& ensureItems() const;
+ Vector<Ref<DataTransferItem>>& ensureItems() const;
+ WeakPtrFactory<DataTransferItemList> m_weakPtrFactory;
DataTransfer& m_dataTransfer;
- mutable std::optional<Vector<std::unique_ptr<DataTransferItem>>> m_items;
+ mutable std::optional<Vector<Ref<DataTransferItem>>> m_items;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/DataTransferItemList.idl (220828 => 220829)
--- trunk/Source/WebCore/dom/DataTransferItemList.idl 2017-08-17 06:11:21 UTC (rev 220828)
+++ trunk/Source/WebCore/dom/DataTransferItemList.idl 2017-08-17 06:17:09 UTC (rev 220829)
@@ -38,10 +38,10 @@
readonly attribute long length;
getter DataTransferItem item(unsigned long index);
- [MayThrowException] void add(optional DOMString data = "" optional DOMString type = "undefined");
- void add(File? file);
+ [MayThrowException] DataTransferItem? add(DOMString data, DOMString type);
+ DataTransferItem? add(File file);
- void remove(unsigned long index);
+ [MayThrowException] void remove(unsigned long index);
void clear();
};