LibWeb: Store a list of DataTransferItem on the DataTransfer object

When scripts receive a DataTransferItem from any IDL method, the spec
requires we return the same DataTransferItem for a particular item in
the drag data store. Meaning, we cannot just create these on the fly as
needed.

To do this, we store a list of DataTransferItem on the DataTransfer
object. We will return one of these objects any time one is requested by
a script.

It feels a bit weird to have the DataTransfer object store: the drag
data store, a DataTransferItemList, and a list of DataTransferItem. But
this is how other engines implement this as well. It basically has to be
this way as DataTransferItemList is just a proxy to the DataTransfer -
meaning, DataTransfer is the source of truth for all IDL access.
This commit is contained in:
Timothy Flynn 2024-08-21 08:57:16 -04:00 committed by Andreas Kling
commit b3bfd02e64
Notes: github-actions[bot] 2024-08-22 12:22:44 +00:00
2 changed files with 9 additions and 0 deletions

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Enumerate.h>
#include <AK/Find.h>
#include <LibJS/Runtime/Realm.h>
#include <LibWeb/Bindings/DataTransferPrototype.h>
@ -12,6 +13,7 @@
#include <LibWeb/FileAPI/File.h>
#include <LibWeb/FileAPI/FileList.h>
#include <LibWeb/HTML/DataTransfer.h>
#include <LibWeb/HTML/DataTransferItem.h>
#include <LibWeb/HTML/DataTransferItemList.h>
#include <LibWeb/Infra/Strings.h>
@ -51,6 +53,11 @@ DataTransfer::DataTransfer(JS::Realm& realm, NonnullRefPtr<DragDataStore> drag_d
: PlatformObject(realm)
, m_associated_drag_data_store(move(drag_data_store))
{
for (auto const& [i, item] : enumerate(m_associated_drag_data_store->item_list())) {
auto data_transfer_item = DataTransferItem::create(realm, *this, i);
m_item_list.append(data_transfer_item);
}
update_data_transfer_types_list();
}
@ -66,6 +73,7 @@ void DataTransfer::visit_edges(JS::Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_items);
visitor.visit(m_item_list);
}
void DataTransfer::set_drop_effect(String const& drop_effect)