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);