LibWeb: Implement DataTransferItemList.remove()

This commit is contained in:
Tim Ledbetter 2025-09-05 07:23:46 +01:00 committed by Jelle Raaijmakers
commit d9341adb1e
Notes: github-actions[bot] 2025-09-12 10:31:50 +00:00
9 changed files with 84 additions and 1 deletions

View file

@ -248,6 +248,22 @@ GC::Ref<DataTransferItem> 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);

View file

@ -60,6 +60,7 @@ public:
void disassociate_with_drag_data_store();
GC::Ref<DataTransferItem> add_item(DragDataStoreItem item);
void remove_item(size_t index);
bool contains_item_with_type(DragDataStoreItem::Kind, String const& type) const;
GC::Ref<DataTransferItem> item(size_t index) const;
DragDataStoreItem const& drag_data(size_t index) const;

View file

@ -25,6 +25,7 @@ public:
String kind() const;
String type() const;
void set_item_index(Badge<DataTransfer>, Optional<size_t> index) { m_item_index = move(index); }
void get_as_string(GC::Ptr<WebIDL::CallbackType>) const;
GC::Ptr<FileAPI::File> get_as_file() const;

View file

@ -108,6 +108,23 @@ GC::Ptr<DataTransferItem> DataTransferItemList::add(GC::Ref<FileAPI::File> file)
return item;
}
// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitemlist-remove
WebIDL::ExceptionOr<void> 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<JS::Value> DataTransferItemList::item_value(size_t index) const
{

View file

@ -26,6 +26,7 @@ public:
WebIDL::ExceptionOr<GC::Ptr<DataTransferItem>> add(String const& data, String const& type);
GC::Ptr<DataTransferItem> add(GC::Ref<FileAPI::File>);
WebIDL::ExceptionOr<void> remove(WebIDL::UnsignedLong index);
private:
DataTransferItemList(JS::Realm&, GC::Ref<DataTransfer>);

View file

@ -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();
};

View file

@ -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<DragDataStoreItem> item_list() const { return m_item_list; }
size_t size() const { return m_item_list.size(); }
bool has_text_item() const;

View file

@ -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

View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>DataTransferItemList remove() method</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<script>
"use strict";
// https://github.com/whatwg/html/issues/2925
test(() => {
const dt = new DataTransfer();
// Must not throw
dt.items.remove(0);
dt.items.remove(1);
dt.items.add("data", "text/plain");
// Must not throw
dt.items.remove(1);
}, "remove()ing an out-of-bounds index does nothing");
test(() => {
const file = new File(["🕺💃"], "test.png", {
type: "image/png"
});
const dt = new DataTransfer();
dt.items.add(file);
let item = dt.items[0];
dt.items.remove(0);
assert_equals(item.kind, "");
assert_equals(item.type, "");
assert_equals(item.getAsFile(), null);
}, "remove()ing an item will put the associated DataTransferItem object in the disabled mode");
</script>