From 5c9287aa99e52886a3d144c26de6a54980a53db6 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 21 Aug 2024 06:50:22 -0400 Subject: [PATCH] LibWeb: Implement separate DataTransfer factories for IDL / internal use The IDL constructor has to take separate steps than a DataTransfer that is internally constructed. Notably, an IDL-created object has its own drag data store, and that store is placed in a read-write mode. --- .../Text/expected/HTML/data-transfer.txt | 2 ++ .../LibWeb/Text/input/HTML/data-transfer.html | 8 +++++ .../Libraries/LibWeb/HTML/DataTransfer.cpp | 31 +++++++++++++------ Userland/Libraries/LibWeb/HTML/DataTransfer.h | 4 +-- .../LibWeb/Page/DragAndDropEventHandler.cpp | 3 +- 5 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/HTML/data-transfer.txt create mode 100644 Tests/LibWeb/Text/input/HTML/data-transfer.html diff --git a/Tests/LibWeb/Text/expected/HTML/data-transfer.txt b/Tests/LibWeb/Text/expected/HTML/data-transfer.txt new file mode 100644 index 00000000000..59aa6d4f348 --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/data-transfer.txt @@ -0,0 +1,2 @@ +dropEffect: none +effectAllowed: none diff --git a/Tests/LibWeb/Text/input/HTML/data-transfer.html b/Tests/LibWeb/Text/input/HTML/data-transfer.html new file mode 100644 index 00000000000..af33a611f6d --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/data-transfer.html @@ -0,0 +1,8 @@ + + diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp b/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp index a569403d543..9686a57674d 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp @@ -27,14 +27,31 @@ ENUMERATE_DATA_TRANSFER_EFFECTS } -JS::NonnullGCPtr DataTransfer::construct_impl(JS::Realm& realm) +JS::NonnullGCPtr DataTransfer::create(JS::Realm& realm, NonnullRefPtr drag_data_store) { - return realm.heap().allocate(realm, realm); + return realm.heap().allocate(realm, realm, move(drag_data_store)); } -DataTransfer::DataTransfer(JS::Realm& realm) - : PlatformObject(realm) +// https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer +JS::NonnullGCPtr DataTransfer::construct_impl(JS::Realm& realm) { + // 1. Set the drag data store's item list to be an empty list. + auto drag_data_store = DragDataStore::create(); + + // 2. Set the drag data store's mode to read/write mode. + drag_data_store->set_mode(DragDataStore::Mode::ReadWrite); + + // 3. Set the dropEffect and effectAllowed to "none". + // NOTE: This is done by the default-initializers. + + return realm.heap().allocate(realm, realm, move(drag_data_store)); +} + +DataTransfer::DataTransfer(JS::Realm& realm, NonnullRefPtr drag_data_store) + : PlatformObject(realm) + , m_associated_drag_data_store(move(drag_data_store)) +{ + update_data_transfer_types_list(); } DataTransfer::~DataTransfer() = default; @@ -195,12 +212,6 @@ JS::NonnullGCPtr DataTransfer::files() const return files; } -void DataTransfer::associate_with_drag_data_store(NonnullRefPtr drag_data_store) -{ - m_associated_drag_data_store = move(drag_data_store); - update_data_transfer_types_list(); -} - void DataTransfer::disassociate_with_drag_data_store() { m_associated_drag_data_store.clear(); diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.h b/Userland/Libraries/LibWeb/HTML/DataTransfer.h index c6d327ab6fd..eb6941df74d 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.h +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.h @@ -37,6 +37,7 @@ class DataTransfer : public Bindings::PlatformObject { JS_DECLARE_ALLOCATOR(DataTransfer); public: + static JS::NonnullGCPtr create(JS::Realm&, NonnullRefPtr); static JS::NonnullGCPtr construct_impl(JS::Realm&); virtual ~DataTransfer() override; @@ -55,11 +56,10 @@ public: String get_data(String const& format) const; JS::NonnullGCPtr files() const; - void associate_with_drag_data_store(NonnullRefPtr drag_data_store); void disassociate_with_drag_data_store(); private: - DataTransfer(JS::Realm&); + DataTransfer(JS::Realm&, NonnullRefPtr); virtual void initialize(JS::Realm&) override; virtual void visit_edges(JS::Cell::Visitor&) override; diff --git a/Userland/Libraries/LibWeb/Page/DragAndDropEventHandler.cpp b/Userland/Libraries/LibWeb/Page/DragAndDropEventHandler.cpp index 8f2fa3db242..d202e6a0508 100644 --- a/Userland/Libraries/LibWeb/Page/DragAndDropEventHandler.cpp +++ b/Userland/Libraries/LibWeb/Page/DragAndDropEventHandler.cpp @@ -506,8 +506,7 @@ JS::NonnullGCPtr DragAndDropEventHandler::fire_a_drag_and_drop_ } // 6. Let dataTransfer be a newly created DataTransfer object associated with the given drag data store. - auto data_transfer = HTML::DataTransfer::construct_impl(realm); - data_transfer->associate_with_drag_data_store(*m_drag_data_store); + auto data_transfer = HTML::DataTransfer::create(realm, *m_drag_data_store); // 7. Set the effectAllowed attribute to the drag data store's drag data store allowed effects state. data_transfer->set_effect_allowed_internal(m_drag_data_store->allowed_effects_state());