diff options
author | Linus Groh <mail@linusgroh.de> | 2021-04-10 18:51:29 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-10 21:00:04 +0200 |
commit | 9d2635d94bbb8ef6233c3d7292d107df72d17bec (patch) | |
tree | 76e128744f60836ca3599bcf6402950c45eceadf | |
parent | 2172e51246283311b8e699212baa9a5283b98737 (diff) | |
download | serenity-9d2635d94bbb8ef6233c3d7292d107df72d17bec.zip |
LibWeb: Support nullable EventListener parameters in WrapperGenerator
The internal C++ function will now receive a RefPtr<EventListener> for
'EventListener?' and a NonnullRefPtr<EventListener> for 'EventListener'.
Examples of this are addEventListener() and removeEventListener(), which
both have nullable callback parameters.
-rw-r--r-- | Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp | 20 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/EventTarget.cpp | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/EventTarget.h | 4 |
3 files changed, 29 insertions, 7 deletions
diff --git a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp index 291b5ebc64..5f13b97ed8 100644 --- a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp +++ b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp @@ -522,7 +522,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter else scoped_generator.set("return_statement", "return {};"); - // FIXME: Add support for optional to all types + // FIXME: Add support for optional and nullable to all types if (parameter.type.is_string()) { if (!optional) { scoped_generator.append(R"~~~( @@ -541,13 +541,26 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter )~~~"); } } else if (parameter.type.name == "EventListener") { - scoped_generator.append(R"~~~( + if (parameter.type.nullable) { + scoped_generator.append(R"~~~( + RefPtr<EventListener> @cpp_name@; + if (!@js_name@@js_suffix@.is_null()) { + if (!@js_name@@js_suffix@.is_function()) { + vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "Function"); + @return_statement@ + } + @cpp_name@ = adopt(*new EventListener(JS::make_handle(&@js_name@@js_suffix@.as_function()))); + } +)~~~"); + } else { + scoped_generator.append(R"~~~( if (!@js_name@@js_suffix@.is_function()) { vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "Function"); @return_statement@ } auto @cpp_name@ = adopt(*new EventListener(JS::make_handle(&@js_name@@js_suffix@.as_function()))); )~~~"); + } } else if (is_wrappable_type(parameter.type)) { scoped_generator.append(R"~~~( auto @cpp_name@_object = @js_name@@js_suffix@.to_object(global_object); @@ -774,6 +787,7 @@ void generate_implementation(const IDL::Interface& interface) #include <LibWeb/Bindings/DocumentTypeWrapper.h> #include <LibWeb/Bindings/DocumentWrapper.h> #include <LibWeb/Bindings/EventTargetWrapperFactory.h> +#include <LibWeb/Bindings/EventWrapperFactory.h> #include <LibWeb/Bindings/HTMLCanvasElementWrapper.h> #include <LibWeb/Bindings/HTMLHeadElementWrapper.h> #include <LibWeb/Bindings/HTMLImageElementWrapper.h> @@ -1111,6 +1125,8 @@ void generate_prototype_implementation(const IDL::Interface& interface) #include <LibWeb/Bindings/DocumentTypeWrapper.h> #include <LibWeb/Bindings/DocumentWrapper.h> #include <LibWeb/Bindings/EventTargetWrapperFactory.h> +#include <LibWeb/Bindings/EventWrapper.h> +#include <LibWeb/Bindings/EventWrapperFactory.h> #include <LibWeb/Bindings/ExceptionOrUtils.h> #include <LibWeb/Bindings/HTMLCanvasElementWrapper.h> #include <LibWeb/Bindings/HTMLHeadElementWrapper.h> diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp index 5f8ca71c8a..a42a2cd02d 100644 --- a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp +++ b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp @@ -39,19 +39,25 @@ EventTarget::~EventTarget() { } -void EventTarget::add_event_listener(const FlyString& event_name, NonnullRefPtr<EventListener> listener) +// https://dom.spec.whatwg.org/#add-an-event-listener +void EventTarget::add_event_listener(const FlyString& event_name, RefPtr<EventListener> listener) { + if (listener.is_null()) + return; auto existing_listener = m_listeners.first_matching([&](auto& entry) { return entry.listener->type() == event_name && &entry.listener->function() == &listener->function() && entry.listener->capture() == listener->capture(); }); if (existing_listener.has_value()) return; listener->set_type(event_name); - m_listeners.append({ event_name, move(listener) }); + m_listeners.append({ event_name, listener.release_nonnull() }); } -void EventTarget::remove_event_listener(const FlyString& event_name, NonnullRefPtr<EventListener> listener) +// https://dom.spec.whatwg.org/#remove-an-event-listener +void EventTarget::remove_event_listener(const FlyString& event_name, RefPtr<EventListener> listener) { + if (listener.is_null()) + return; m_listeners.remove_first_matching([&](auto& entry) { auto matches = entry.event_name == event_name && &entry.listener->function() == &listener->function() && entry.listener->capture() == listener->capture(); if (matches) diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.h b/Userland/Libraries/LibWeb/DOM/EventTarget.h index af1a1d7b0c..d74d633fec 100644 --- a/Userland/Libraries/LibWeb/DOM/EventTarget.h +++ b/Userland/Libraries/LibWeb/DOM/EventTarget.h @@ -45,8 +45,8 @@ public: void ref() { ref_event_target(); } void unref() { unref_event_target(); } - void add_event_listener(const FlyString& event_name, NonnullRefPtr<EventListener>); - void remove_event_listener(const FlyString& event_name, NonnullRefPtr<EventListener>); + void add_event_listener(const FlyString& event_name, RefPtr<EventListener>); + void remove_event_listener(const FlyString& event_name, RefPtr<EventListener>); void remove_from_event_listener_list(NonnullRefPtr<EventListener>); |