ladybird/Userland/Libraries/LibWeb/HTML/DataTransfer.h
Timothy Flynn b3bfd02e64 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.
2024-08-22 14:21:13 +02:00

86 lines
2.9 KiB
C++

/*
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibJS/Forward.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/HTML/DragDataStore.h>
namespace Web::HTML {
#define ENUMERATE_DATA_TRANSFER_EFFECTS \
__ENUMERATE_DATA_TRANSFER_EFFECT(none) \
__ENUMERATE_DATA_TRANSFER_EFFECT(copy) \
__ENUMERATE_DATA_TRANSFER_EFFECT(copyLink) \
__ENUMERATE_DATA_TRANSFER_EFFECT(copyMove) \
__ENUMERATE_DATA_TRANSFER_EFFECT(link) \
__ENUMERATE_DATA_TRANSFER_EFFECT(linkMove) \
__ENUMERATE_DATA_TRANSFER_EFFECT(move) \
__ENUMERATE_DATA_TRANSFER_EFFECT(all) \
__ENUMERATE_DATA_TRANSFER_EFFECT(uninitialized)
namespace DataTransferEffect {
#define __ENUMERATE_DATA_TRANSFER_EFFECT(name) extern FlyString name;
ENUMERATE_DATA_TRANSFER_EFFECTS
#undef __ENUMERATE_DATA_TRANSFER_EFFECT
}
// https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface
class DataTransfer : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(DataTransfer, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(DataTransfer);
public:
static JS::NonnullGCPtr<DataTransfer> create(JS::Realm&, NonnullRefPtr<DragDataStore>);
static JS::NonnullGCPtr<DataTransfer> construct_impl(JS::Realm&);
virtual ~DataTransfer() override;
FlyString const& drop_effect() const { return m_drop_effect; }
void set_drop_effect(String const&);
void set_drop_effect(FlyString);
FlyString const& effect_allowed() const { return m_effect_allowed; }
void set_effect_allowed(String const&);
void set_effect_allowed(FlyString);
void set_effect_allowed_internal(FlyString);
JS::NonnullGCPtr<DataTransferItemList> items();
ReadonlySpan<String> types() const;
String get_data(String const& format) const;
JS::NonnullGCPtr<FileAPI::FileList> files() const;
void disassociate_with_drag_data_store();
private:
DataTransfer(JS::Realm&, NonnullRefPtr<DragDataStore>);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(JS::Cell::Visitor&) 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#dom-datatransfer-items
JS::GCPtr<DataTransferItemList> m_items;
Vector<JS::NonnullGCPtr<DataTransferItem>> m_item_list;
// https://html.spec.whatwg.org/multipage/dnd.html#concept-datatransfer-types
Vector<String> m_types;
// https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface:drag-data-store-3
RefPtr<DragDataStore> m_associated_drag_data_store;
};
}