diff --git a/Libraries/LibWeb/HTML/DataTransfer.cpp b/Libraries/LibWeb/HTML/DataTransfer.cpp index 377aae87f01..eaa36c56e8a 100644 --- a/Libraries/LibWeb/HTML/DataTransfer.cpp +++ b/Libraries/LibWeb/HTML/DataTransfer.cpp @@ -248,6 +248,22 @@ GC::Ref DataTransfer::add_item(DragDataStoreItem item) return data_transfer_item; } +void DataTransfer::remove_item(size_t index) +{ + VERIFY(m_associated_drag_data_store); + VERIFY(index < m_item_list.size()); + + m_associated_drag_data_store->remove_item_at(index); + auto& item = m_item_list.at(index); + item->set_item_index({}, OptionalNone {}); + m_item_list.remove(index); + for (size_t i = index; i < m_item_list.size(); ++i) { + m_item_list.at(i)->set_item_index({}, i); + } + + update_data_transfer_types_list(); +} + bool DataTransfer::contains_item_with_type(DragDataStoreItem::Kind kind, String const& type) const { VERIFY(m_associated_drag_data_store); diff --git a/Libraries/LibWeb/HTML/DataTransfer.h b/Libraries/LibWeb/HTML/DataTransfer.h index 6972f6a520b..2a963f979ce 100644 --- a/Libraries/LibWeb/HTML/DataTransfer.h +++ b/Libraries/LibWeb/HTML/DataTransfer.h @@ -60,6 +60,7 @@ public: void disassociate_with_drag_data_store(); GC::Ref add_item(DragDataStoreItem item); + void remove_item(size_t index); bool contains_item_with_type(DragDataStoreItem::Kind, String const& type) const; GC::Ref item(size_t index) const; DragDataStoreItem const& drag_data(size_t index) const; diff --git a/Libraries/LibWeb/HTML/DataTransferItem.h b/Libraries/LibWeb/HTML/DataTransferItem.h index 149b234eb0f..86e8045de3f 100644 --- a/Libraries/LibWeb/HTML/DataTransferItem.h +++ b/Libraries/LibWeb/HTML/DataTransferItem.h @@ -25,6 +25,7 @@ public: String kind() const; String type() const; + void set_item_index(Badge, Optional index) { m_item_index = move(index); } void get_as_string(GC::Ptr) const; GC::Ptr get_as_file() const; diff --git a/Libraries/LibWeb/HTML/DataTransferItemList.cpp b/Libraries/LibWeb/HTML/DataTransferItemList.cpp index d3d03f5d19b..f375e05345a 100644 --- a/Libraries/LibWeb/HTML/DataTransferItemList.cpp +++ b/Libraries/LibWeb/HTML/DataTransferItemList.cpp @@ -108,6 +108,23 @@ GC::Ptr DataTransferItemList::add(GC::Ref file) return item; } +// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitemlist-remove +WebIDL::ExceptionOr DataTransferItemList::remove(WebIDL::UnsignedLong index) +{ + // 1. If the DataTransferItemList object is not in the read/write mode, throw an "InvalidStateError" DOMException. + if (m_data_transfer->mode() != DragDataStore::Mode::ReadWrite) + return WebIDL::InvalidStateError::create(realm(), "DataTransferItemList is not in read/write mode"_utf16); + + // 2. If the drag data store does not contain an indexth item, then return. + if (index >= m_data_transfer->length()) + return {}; + + // 3. Remove the indexth item from the drag data store + m_data_transfer->remove_item(index); + + return {}; +} + // https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitemlist-item Optional DataTransferItemList::item_value(size_t index) const { diff --git a/Libraries/LibWeb/HTML/DataTransferItemList.h b/Libraries/LibWeb/HTML/DataTransferItemList.h index a6e9872e212..74918859102 100644 --- a/Libraries/LibWeb/HTML/DataTransferItemList.h +++ b/Libraries/LibWeb/HTML/DataTransferItemList.h @@ -26,6 +26,7 @@ public: WebIDL::ExceptionOr> add(String const& data, String const& type); GC::Ptr add(GC::Ref); + WebIDL::ExceptionOr remove(WebIDL::UnsignedLong index); private: DataTransferItemList(JS::Realm&, GC::Ref); diff --git a/Libraries/LibWeb/HTML/DataTransferItemList.idl b/Libraries/LibWeb/HTML/DataTransferItemList.idl index 07aff3a6206..e59f6010844 100644 --- a/Libraries/LibWeb/HTML/DataTransferItemList.idl +++ b/Libraries/LibWeb/HTML/DataTransferItemList.idl @@ -8,6 +8,6 @@ interface DataTransferItemList { getter DataTransferItem (unsigned long index); DataTransferItem? add(DOMString data, DOMString type); DataTransferItem? add(File data); - [FIXME] undefined remove(unsigned long index); + undefined remove(unsigned long index); [FIXME] undefined clear(); }; diff --git a/Libraries/LibWeb/HTML/DragDataStore.h b/Libraries/LibWeb/HTML/DragDataStore.h index 2d6907ddb6a..bab06002d33 100644 --- a/Libraries/LibWeb/HTML/DragDataStore.h +++ b/Libraries/LibWeb/HTML/DragDataStore.h @@ -47,6 +47,7 @@ public: ~DragDataStore(); void add_item(DragDataStoreItem item) { m_item_list.append(move(item)); } + void remove_item_at(size_t const& index) { m_item_list.remove(index); } ReadonlySpan item_list() const { return m_item_list; } size_t size() const { return m_item_list.size(); } bool has_text_item() const; diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/editing/dnd/datastore/datatransferitemlist-remove.txt b/Tests/LibWeb/Text/expected/wpt-import/html/editing/dnd/datastore/datatransferitemlist-remove.txt new file mode 100644 index 00000000000..f9da1514794 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/editing/dnd/datastore/datatransferitemlist-remove.txt @@ -0,0 +1,7 @@ +Harness status: OK + +Found 2 tests + +2 Pass +Pass remove()ing an out-of-bounds index does nothing +Pass remove()ing an item will put the associated DataTransferItem object in the disabled mode \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html/editing/dnd/datastore/datatransferitemlist-remove.html b/Tests/LibWeb/Text/input/wpt-import/html/editing/dnd/datastore/datatransferitemlist-remove.html new file mode 100644 index 00000000000..a8bb4581fbe --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/editing/dnd/datastore/datatransferitemlist-remove.html @@ -0,0 +1,39 @@ + + +DataTransferItemList remove() method + + + +