diff --git a/Userland/Libraries/LibWeb/Bindings/EventWrapperFactory.cpp b/Userland/Libraries/LibWeb/Bindings/EventWrapperFactory.cpp index 71176cf4f60..ccdb1204f3b 100644 --- a/Userland/Libraries/LibWeb/Bindings/EventWrapperFactory.cpp +++ b/Userland/Libraries/LibWeb/Bindings/EventWrapperFactory.cpp @@ -1,10 +1,12 @@ /* * Copyright (c) 2020, Andreas Kling + * Copyright (c) 2021, Luke Wilde * * SPDX-License-Identifier: BSD-2-Clause */ #include +#include #include #include #include @@ -17,6 +19,8 @@ namespace Web::Bindings { EventWrapper* wrap(JS::GlobalObject& global_object, DOM::Event& event) { + if (is(event)) + return static_cast(wrap_impl(global_object, static_cast(event))); if (is(event)) return static_cast(wrap_impl(global_object, static_cast(event))); if (is(event)) diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h index 303ebb0f92a..fd79b55a683 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h +++ b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -265,6 +267,7 @@ ADD_WINDOW_OBJECT_INTERFACE(CharacterData) \ ADD_WINDOW_OBJECT_INTERFACE(CloseEvent) \ ADD_WINDOW_OBJECT_INTERFACE(Comment) \ + ADD_WINDOW_OBJECT_INTERFACE(CustomEvent) \ ADD_WINDOW_OBJECT_INTERFACE(CSSStyleSheet) \ ADD_WINDOW_OBJECT_INTERFACE(DocumentFragment) \ ADD_WINDOW_OBJECT_INTERFACE(Document) \ diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 7df24978b99..e7c89a9f2e9 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -45,6 +45,7 @@ set(SOURCES DOM/CharacterData.cpp DOM/CharacterData.idl DOM/Comment.cpp + DOM/CustomEvent.cpp DOM/DOMImplementation.cpp DOM/Document.cpp DOM/DocumentFragment.cpp @@ -328,6 +329,7 @@ libweb_js_wrapper(DOM/AbortController) libweb_js_wrapper(DOM/AbortSignal) libweb_js_wrapper(DOM/CharacterData) libweb_js_wrapper(DOM/Comment) +libweb_js_wrapper(DOM/CustomEvent) libweb_js_wrapper(DOM/Document) libweb_js_wrapper(DOM/DocumentFragment) libweb_js_wrapper(DOM/DocumentType) diff --git a/Userland/Libraries/LibWeb/DOM/CustomEvent.cpp b/Userland/Libraries/LibWeb/DOM/CustomEvent.cpp new file mode 100644 index 00000000000..17c414f910b --- /dev/null +++ b/Userland/Libraries/LibWeb/DOM/CustomEvent.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021, Luke Wilde + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Web::DOM { + +CustomEvent::CustomEvent(FlyString const& event_name) + : Event(event_name) +{ +} + +CustomEvent::~CustomEvent() +{ +} + +void CustomEvent::visit_edges(JS::Cell::Visitor& visitor) +{ + visitor.visit(m_detail); +} + +// https://dom.spec.whatwg.org/#dom-customevent-initcustomevent +void CustomEvent::init_custom_event(String const& type, bool bubbles, bool cancelable, JS::Value detail) +{ + // 1. If this’s dispatch flag is set, then return. + if (dispatched()) + return; + + // 2. Initialize this with type, bubbles, and cancelable. + initialize(type, bubbles, cancelable); + + // 3. Set this’s detail attribute to detail. + m_detail = detail; +} + +} diff --git a/Userland/Libraries/LibWeb/DOM/CustomEvent.h b/Userland/Libraries/LibWeb/DOM/CustomEvent.h new file mode 100644 index 00000000000..ad4efe04993 --- /dev/null +++ b/Userland/Libraries/LibWeb/DOM/CustomEvent.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021, Luke Wilde + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::DOM { + +// https://dom.spec.whatwg.org/#customevent +class CustomEvent : public Event { +public: + using WrapperType = Bindings::CustomEventWrapper; + + static NonnullRefPtr create(FlyString const& event_name) + { + return adopt_ref(*new CustomEvent(event_name)); + } + + virtual ~CustomEvent() override; + + // https://dom.spec.whatwg.org/#dom-customevent-detail + JS::Value detail() const { return m_detail; } + + void visit_edges(JS::Cell::Visitor&); + + void init_custom_event(String const& type, bool bubbles, bool cancelable, JS::Value detail); + +private: + CustomEvent(FlyString const&); + + // https://dom.spec.whatwg.org/#dom-customevent-initcustomevent-type-bubbles-cancelable-detail-detail + JS::Value m_detail { JS::js_null() }; +}; + +} diff --git a/Userland/Libraries/LibWeb/DOM/CustomEvent.idl b/Userland/Libraries/LibWeb/DOM/CustomEvent.idl new file mode 100644 index 00000000000..53abba31ac1 --- /dev/null +++ b/Userland/Libraries/LibWeb/DOM/CustomEvent.idl @@ -0,0 +1,8 @@ +[Exposed=(Window,Worker), CustomVisit] +interface CustomEvent : Event { + // FIXME: constructor(DOMString type, optional CustomEventInit eventInitDict = {}); + + readonly attribute any detail; + + undefined initCustomEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional any detail = null); +}; diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 875a36e0a4b..f16a5bd203f 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -739,7 +740,7 @@ NonnullRefPtr Document::create_event(const String& interface) } else if (interface_lowercase == "compositionevent") { event = Event::create(""); // FIXME: Create CompositionEvent } else if (interface_lowercase == "customevent") { - event = Event::create(""); // FIXME: Create CustomEvent + event = CustomEvent::create(""); } else if (interface_lowercase == "devicemotionevent") { event = Event::create(""); // FIXME: Create DeviceMotionEvent } else if (interface_lowercase == "deviceorientationevent") { diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 241a09e83dc..70d9eb29fcc 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -62,6 +62,7 @@ class AbortController; class AbortSignal; class CharacterData; class Comment; +class CustomEvent; class Document; class DocumentFragment; class DocumentLoadEventDelayer; @@ -261,6 +262,7 @@ class CanvasRenderingContext2DWrapper; class CharacterDataWrapper; class CloseEventWrapper; class CommentWrapper; +class CustomEventWrapper; class DocumentFragmentWrapper; class DocumentTypeWrapper; class DocumentWrapper;