diff --git a/Tests/LibWeb/Text/expected/HTML/data-transfer.txt b/Tests/LibWeb/Text/expected/HTML/data-transfer.txt index e3dd3e966d7..96592024645 100644 --- a/Tests/LibWeb/Text/expected/HTML/data-transfer.txt +++ b/Tests/LibWeb/Text/expected/HTML/data-transfer.txt @@ -1,7 +1,7 @@ dropEffect: none effectAllowed: none length=0, types= -stringItem: [object DataTransferItem] +stringItem: kind=string, type=custom-type length=1, types=custom-type -fileItem: [object DataTransferItem] +fileItem: kind=file, type=text/plain length=2, types=custom-type,Files diff --git a/Tests/LibWeb/Text/input/HTML/data-transfer.html b/Tests/LibWeb/Text/input/HTML/data-transfer.html index 2fec8c148fa..0d092360fa6 100644 --- a/Tests/LibWeb/Text/input/HTML/data-transfer.html +++ b/Tests/LibWeb/Text/input/HTML/data-transfer.html @@ -9,7 +9,7 @@ println(`length=${dataTransferItemList.length}, types=${dataTransfer.types}`); let stringItem = dataTransferItemList.add("well hello friends", "custom-type"); - println(`stringItem: ${stringItem}`); + println(`stringItem: kind=${stringItem.kind}, type=${stringItem.type}`); println(`length=${dataTransferItemList.length}, types=${dataTransfer.types}`); if (dataTransferItemList[0] !== stringItem) { @@ -26,7 +26,7 @@ }); let fileItem = dataTransferItemList.add(file); - println(`fileItem: ${fileItem}`); + println(`fileItem: kind=${fileItem.kind}, type=${fileItem.type}`); println(`length=${dataTransferItemList.length}, types=${dataTransfer.types}`); if (dataTransferItemList[1] !== fileItem) { diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp b/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp index fdd44e77b40..69be65202dc 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp @@ -266,6 +266,14 @@ JS::NonnullGCPtr DataTransfer::item(size_t index) const return m_item_list[index]; } +DragDataStoreItem const& DataTransfer::drag_data(size_t index) const +{ + VERIFY(m_associated_drag_data_store); + VERIFY(index < m_item_list.size()); + + return m_associated_drag_data_store->item_list()[index]; +} + size_t DataTransfer::length() const { if (m_associated_drag_data_store) diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.h b/Userland/Libraries/LibWeb/HTML/DataTransfer.h index f613fdedd14..950b695cadb 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.h +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.h @@ -62,6 +62,7 @@ public: JS::NonnullGCPtr add_item(DragDataStoreItem item); bool contains_item_with_type(DragDataStoreItem::Kind, String const& type) const; JS::NonnullGCPtr item(size_t index) const; + DragDataStoreItem const& drag_data(size_t index) const; size_t length() const; private: diff --git a/Userland/Libraries/LibWeb/HTML/DataTransferItem.cpp b/Userland/Libraries/LibWeb/HTML/DataTransferItem.cpp index 471fe7a547a..fdf2ea8b004 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransferItem.cpp +++ b/Userland/Libraries/LibWeb/HTML/DataTransferItem.cpp @@ -40,4 +40,49 @@ void DataTransferItem::visit_edges(JS::Cell::Visitor& visitor) visitor.visit(m_data_transfer); } +// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitem-kind +String DataTransferItem::kind() const +{ + // The kind attribute must return the empty string if the DataTransferItem object is in the disabled mode; otherwise + // it must return the string given in the cell from the second column of the following table from the row whose cell + // in the first column contains the drag data item kind of the item represented by the DataTransferItem object: + // + // Kind | String + // --------------- + // Text | "string" + // File | "file" + if (!mode().has_value()) + return {}; + + auto const& item = m_data_transfer->drag_data(*m_item_index); + + switch (item.kind) { + case DragDataStoreItem::Kind::Text: + return "string"_string; + case DragDataStoreItem::Kind::File: + return "file"_string; + } + + VERIFY_NOT_REACHED(); +} + +// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitem-type +String DataTransferItem::type() const +{ + // The type attribute must return the empty string if the DataTransferItem object is in the disabled mode; otherwise + // it must return the drag data item type string of the item represented by the DataTransferItem object. + if (!mode().has_value()) + return {}; + + auto const& item = m_data_transfer->drag_data(*m_item_index); + return item.type_string; +} + +Optional DataTransferItem::mode() const +{ + if (!m_item_index.has_value()) + return {}; + return m_data_transfer->mode(); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/DataTransferItem.h b/Userland/Libraries/LibWeb/HTML/DataTransferItem.h index ea27da64095..5659286497f 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransferItem.h +++ b/Userland/Libraries/LibWeb/HTML/DataTransferItem.h @@ -22,12 +22,17 @@ public: static JS::NonnullGCPtr create(JS::Realm&, JS::NonnullGCPtr, size_t item_index); virtual ~DataTransferItem() override; + String kind() const; + String type() const; + private: DataTransferItem(JS::Realm&, JS::NonnullGCPtr, size_t item_index); virtual void initialize(JS::Realm&) override; virtual void visit_edges(JS::Cell::Visitor&) override; + Optional mode() const; + JS::NonnullGCPtr m_data_transfer; Optional m_item_index; }; diff --git a/Userland/Libraries/LibWeb/HTML/DataTransferItem.idl b/Userland/Libraries/LibWeb/HTML/DataTransferItem.idl index 785667f4d43..157e87b2894 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransferItem.idl +++ b/Userland/Libraries/LibWeb/HTML/DataTransferItem.idl @@ -5,8 +5,8 @@ callback FunctionStringCallback = undefined (DOMString data); // https://html.spec.whatwg.org/multipage/dnd.html#datatransferitem [Exposed=Window] interface DataTransferItem { - [FIXME] readonly attribute DOMString kind; - [FIXME] readonly attribute DOMString type; + readonly attribute DOMString kind; + readonly attribute DOMString type; [FIXME] undefined getAsString(FunctionStringCallback? _callback); [FIXME] File? getAsFile(); };