diff --git a/Tests/LibWeb/Text/expected/HTML/drag-and-drop.txt b/Tests/LibWeb/Text/expected/HTML/drag-and-drop.txt index 65dcfd8ef17..10392e4d5a0 100644 --- a/Tests/LibWeb/Text/expected/HTML/drag-and-drop.txt +++ b/Tests/LibWeb/Text/expected/HTML/drag-and-drop.txt @@ -1,26 +1,43 @@ Simple drag and drop: dragenter + types: Files dragover + types: Files drop + types: Files Drag enter and leave: dragenter + types: Files dragover + types: Files dragleave + types: Files dragenter + types: Files dragover + types: Files drop + types: Files Drag enter not accepted: dragenter + types: Files Drag over not accepted: dragenter + types: Files dragover + types: Files dragover + types: Files dragleave + types: Files Drop not accepted: dragenter + types: Files dragover + types: Files drop + types: Files diff --git a/Tests/LibWeb/Text/input/HTML/drag-and-drop.html b/Tests/LibWeb/Text/input/HTML/drag-and-drop.html index a2e52f672df..a1d00a19ce4 100644 --- a/Tests/LibWeb/Text/input/HTML/drag-and-drop.html +++ b/Tests/LibWeb/Text/input/HTML/drag-and-drop.html @@ -5,23 +5,28 @@ let target = document.getElementById("target"); let acceptDragEvents = true; + const printEvent = (name, e) => { + println(name); + println(` types: ${e.dataTransfer.types}`); + }; + target.addEventListener("dragenter", e => { - println("dragenter"); + printEvent("dragenter", e); if (acceptDragEvents) { e.preventDefault(); } }); target.addEventListener("dragover", e => { - println("dragover"); + printEvent("dragover", e); if (acceptDragEvents) { e.preventDefault(); } }); - target.addEventListener("dragleave", () => { - println("dragleave"); + target.addEventListener("dragleave", e => { + printEvent("dragleave", e); }); target.addEventListener("drop", e => { - println("drop"); + printEvent("drop", e); if (acceptDragEvents) { e.preventDefault(); } diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp b/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp index 45d377464ab..94cd5c1ddba 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp @@ -77,4 +77,57 @@ void DataTransfer::set_effect_allowed_internal(FlyString effect_allowed) m_effect_allowed = AK::move(effect_allowed); } +// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-types +ReadonlySpan DataTransfer::types() const +{ + // The types attribute must return this DataTransfer object's types array. + return m_types; +} + +void DataTransfer::associate_with_drag_data_store(DragDataStore& drag_data_store) +{ + m_associated_drag_data_store = drag_data_store; + update_data_transfer_types_list(); +} + +void DataTransfer::disassociate_with_drag_data_store() +{ + m_associated_drag_data_store.clear(); + update_data_transfer_types_list(); +} + +// https://html.spec.whatwg.org/multipage/dnd.html#concept-datatransfer-types +void DataTransfer::update_data_transfer_types_list() +{ + // 1. Let L be an empty sequence. + Vector types; + + // 2. If the DataTransfer object is still associated with a drag data store, then: + if (m_associated_drag_data_store.has_value()) { + bool contains_file = false; + + // 1. For each item in the DataTransfer object's drag data store item list whose kind is text, add an entry to L + // consisting of the item's type string. + for (auto const& item : m_associated_drag_data_store->item_list()) { + switch (item.kind) { + case DragDataStoreItem::Kind::Text: + types.append(item.type_string); + break; + case DragDataStoreItem::Kind::File: + contains_file = true; + break; + } + } + + // 2. If there are any items in the DataTransfer object's drag data store item list whose kind is File, then add + // an entry to L consisting of the string "Files". (This value can be distinguished from the other values + // because it is not lowercase.) + if (contains_file) + types.append("Files"_string); + } + + // 3. Set the DataTransfer object's types array to the result of creating a frozen array from L. + m_types = move(types); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.h b/Userland/Libraries/LibWeb/HTML/DataTransfer.h index 0d1d5cf3e18..0a33f5b34f1 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.h +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.h @@ -49,20 +49,27 @@ public: void set_effect_allowed(FlyString); void set_effect_allowed_internal(FlyString); - void associate_with_drag_data_store(DragDataStore& drag_data_store) { m_associated_drag_data_store = drag_data_store; } - void disassociate_with_drag_data_store() { m_associated_drag_data_store.clear(); } + ReadonlySpan types() const; + + void associate_with_drag_data_store(DragDataStore& drag_data_store); + void disassociate_with_drag_data_store(); private: DataTransfer(JS::Realm&); virtual void initialize(JS::Realm&) override; + void update_data_transfer_types_list(); + // https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-dropeffect FlyString m_drop_effect { DataTransferEffect::none }; // https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-effectallowed FlyString m_effect_allowed { DataTransferEffect::none }; + // https://html.spec.whatwg.org/multipage/dnd.html#concept-datatransfer-types + Vector m_types; + // https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface:drag-data-store-3 Optional m_associated_drag_data_store; }; diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.idl b/Userland/Libraries/LibWeb/HTML/DataTransfer.idl index 15afedde7e5..9a61a3a31dd 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.idl +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.idl @@ -11,7 +11,7 @@ interface DataTransfer { [FIXME] undefined setDragImage(Element image, long x, long y); // old interface - [FIXME] readonly attribute FrozenArray types; + readonly attribute sequence types; // FIXME: This should be FrozenArray [FIXME] DOMString getData(DOMString format); [FIXME] undefined setData(DOMString format, DOMString data); [FIXME] undefined clearData(optional DOMString format);