diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 50f4846b99c..5c1dee0f699 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -353,6 +353,7 @@ class CloseWatcher; class CloseWatcherManager; class CustomElementDefinition; class CustomElementRegistry; +class DataTransfer; class DataTransferItem; class DataTransferItemList; class DecodedImageData; diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp b/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp index 770d5f1318b..45d377464ab 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.cpp @@ -13,6 +13,14 @@ namespace Web::HTML { JS_DEFINE_ALLOCATOR(DataTransfer); +namespace DataTransferEffect { + +#define __ENUMERATE_DATA_TRANSFER_EFFECT(name) FlyString name = #name##_fly_string; +ENUMERATE_DATA_TRANSFER_EFFECTS +#undef __ENUMERATE_DATA_TRANSFER_EFFECT + +} + JS::NonnullGCPtr DataTransfer::construct_impl(JS::Realm& realm) { return realm.heap().allocate(realm, realm); @@ -31,4 +39,42 @@ void DataTransfer::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(DataTransfer); } +void DataTransfer::set_drop_effect(String const& drop_effect) +{ + set_drop_effect(FlyString { drop_effect }); +} + +void DataTransfer::set_drop_effect(FlyString drop_effect) +{ + using namespace DataTransferEffect; + + // On setting, if the new value is one of "none", "copy", "link", or "move", then the attribute's current value must + // be set to the new value. Other values must be ignored. + if (drop_effect.is_one_of(none, copy, link, move)) + m_drop_effect = AK::move(drop_effect); +} + +void DataTransfer::set_effect_allowed(String const& effect_allowed) +{ + set_effect_allowed(FlyString { effect_allowed }); +} + +void DataTransfer::set_effect_allowed(FlyString effect_allowed) +{ + // On setting, if drag data store's mode is the read/write mode and the new value is one of "none", "copy", "copyLink", + // "copyMove", "link", "linkMove", "move", "all", or "uninitialized", then the attribute's current value must be set + // to the new value. Otherwise, it must be left unchanged. + if (m_associated_drag_data_store.has_value() && m_associated_drag_data_store->mode() == DragDataStore::Mode::ReadWrite) + set_effect_allowed_internal(move(effect_allowed)); +} + +void DataTransfer::set_effect_allowed_internal(FlyString effect_allowed) +{ + // AD-HOC: We need to be able to set the effectAllowed attribute internally regardless of the state of the drag data store. + using namespace DataTransferEffect; + + if (effect_allowed.is_one_of(none, copy, copyLink, copyMove, link, linkMove, move, all, uninitialized)) + m_effect_allowed = AK::move(effect_allowed); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.h b/Userland/Libraries/LibWeb/HTML/DataTransfer.h index 5073a6a8943..0d1d5cf3e18 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.h +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.h @@ -8,9 +8,30 @@ #include #include +#include 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); @@ -19,10 +40,31 @@ public: static JS::NonnullGCPtr 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); + + void associate_with_drag_data_store(DragDataStore& drag_data_store) { m_associated_drag_data_store = drag_data_store; } + void disassociate_with_drag_data_store() { m_associated_drag_data_store.clear(); } + private: DataTransfer(JS::Realm&); virtual void initialize(JS::Realm&) override; + + // 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#the-datatransfer-interface:drag-data-store-3 + Optional m_associated_drag_data_store; }; } diff --git a/Userland/Libraries/LibWeb/HTML/DataTransfer.idl b/Userland/Libraries/LibWeb/HTML/DataTransfer.idl index eb43f4487a1..15afedde7e5 100644 --- a/Userland/Libraries/LibWeb/HTML/DataTransfer.idl +++ b/Userland/Libraries/LibWeb/HTML/DataTransfer.idl @@ -3,8 +3,8 @@ interface DataTransfer { constructor(); - [FIXME] attribute DOMString dropEffect; - [FIXME] attribute DOMString effectAllowed; + attribute DOMString dropEffect; + attribute DOMString effectAllowed; [FIXME, SameObject] readonly attribute DataTransferItemList items;