summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/Bindings/CallbackType.cpp25
-rw-r--r--Userland/Libraries/LibWeb/Bindings/CallbackType.h18
-rw-r--r--Userland/Libraries/LibWeb/Bindings/EventListenerWrapper.cpp22
-rw-r--r--Userland/Libraries/LibWeb/Bindings/EventListenerWrapper.h29
-rw-r--r--Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp11
-rw-r--r--Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h5
-rw-r--r--Userland/Libraries/LibWeb/Bindings/WindowObject.cpp53
-rw-r--r--Userland/Libraries/LibWeb/Bindings/WindowObject.h2
-rw-r--r--Userland/Libraries/LibWeb/CMakeLists.txt7
-rw-r--r--Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp10
-rw-r--r--Userland/Libraries/LibWeb/CSS/MediaQueryList.h6
-rw-r--r--Userland/Libraries/LibWeb/DOM/AbortSignal.cpp4
-rw-r--r--Userland/Libraries/LibWeb/DOM/AbortSignal.h2
-rw-r--r--Userland/Libraries/LibWeb/DOM/DOMEventListener.cpp8
-rw-r--r--Userland/Libraries/LibWeb/DOM/DOMEventListener.h10
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.cpp8
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.h4
-rw-r--r--Userland/Libraries/LibWeb/DOM/EventDispatcher.cpp6
-rw-r--r--Userland/Libraries/LibWeb/DOM/EventDispatcher.h2
-rw-r--r--Userland/Libraries/LibWeb/DOM/EventTarget.cpp111
-rw-r--r--Userland/Libraries/LibWeb/DOM/EventTarget.h16
-rw-r--r--Userland/Libraries/LibWeb/DOM/IDLEventListener.cpp29
-rw-r--r--Userland/Libraries/LibWeb/DOM/IDLEventListener.h27
-rw-r--r--Userland/Libraries/LibWeb/DOM/MutationObserver.cpp2
-rw-r--r--Userland/Libraries/LibWeb/DOM/MutationObserver.h10
-rw-r--r--Userland/Libraries/LibWeb/DOM/NodeFilter.cpp29
-rw-r--r--Userland/Libraries/LibWeb/DOM/NodeFilter.h26
-rw-r--r--Userland/Libraries/LibWeb/DOM/NodeIterator.cpp6
-rw-r--r--Userland/Libraries/LibWeb/DOM/NodeIterator.h6
-rw-r--r--Userland/Libraries/LibWeb/DOM/TreeWalker.cpp6
-rw-r--r--Userland/Libraries/LibWeb/DOM/TreeWalker.h6
-rw-r--r--Userland/Libraries/LibWeb/Forward.h4
-rw-r--r--Userland/Libraries/LibWeb/HTML/EventHandler.cpp32
-rw-r--r--Userland/Libraries/LibWeb/HTML/EventHandler.h28
-rw-r--r--Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.cpp16
-rw-r--r--Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.h4
-rw-r--r--Userland/Libraries/LibWeb/HTML/MessagePort.cpp16
-rw-r--r--Userland/Libraries/LibWeb/HTML/MessagePort.h4
-rw-r--r--Userland/Libraries/LibWeb/HTML/Window.cpp18
-rw-r--r--Userland/Libraries/LibWeb/HTML/Window.h6
-rw-r--r--Userland/Libraries/LibWeb/HTML/WindowEventHandlers.cpp16
-rw-r--r--Userland/Libraries/LibWeb/HTML/WindowEventHandlers.h4
-rw-r--r--Userland/Libraries/LibWeb/HTML/Worker.cpp16
-rw-r--r--Userland/Libraries/LibWeb/HTML/Worker.h4
-rw-r--r--Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp16
-rw-r--r--Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h4
-rw-r--r--Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.cpp2
-rw-r--r--Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.h2
-rw-r--r--Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.cpp2
-rw-r--r--Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.h2
-rw-r--r--Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp16
-rw-r--r--Userland/Libraries/LibWeb/WebSockets/WebSocket.h4
-rw-r--r--Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp4
-rw-r--r--Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h2
-rw-r--r--Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.cpp16
-rw-r--r--Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.h4
56 files changed, 415 insertions, 333 deletions
diff --git a/Userland/Libraries/LibWeb/Bindings/CallbackType.cpp b/Userland/Libraries/LibWeb/Bindings/CallbackType.cpp
new file mode 100644
index 0000000000..a575548be5
--- /dev/null
+++ b/Userland/Libraries/LibWeb/Bindings/CallbackType.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibJS/Runtime/Object.h>
+#include <LibWeb/Bindings/CallbackType.h>
+
+namespace Web::Bindings {
+
+CallbackType::CallbackType(JS::Object& callback, HTML::EnvironmentSettingsObject& callback_context)
+ : callback(callback)
+ , callback_context(callback_context)
+{
+}
+
+StringView CallbackType::class_name() const { return "CallbackType"sv; }
+void CallbackType::visit_edges(Cell::Visitor& visitor)
+{
+ Cell::visit_edges(visitor);
+ visitor.visit(&callback);
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/Bindings/CallbackType.h b/Userland/Libraries/LibWeb/Bindings/CallbackType.h
index 8b4d0cd538..b1f2cebbb3 100644
--- a/Userland/Libraries/LibWeb/Bindings/CallbackType.h
+++ b/Userland/Libraries/LibWeb/Bindings/CallbackType.h
@@ -1,28 +1,30 @@
/*
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
+ * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
-#include <LibJS/Heap/Handle.h>
+#include <LibJS/Heap/Cell.h>
#include <LibWeb/Forward.h>
namespace Web::Bindings {
// https://heycam.github.io/webidl/#idl-callback-interface
-struct CallbackType {
- CallbackType(JS::Handle<JS::Object> callback, HTML::EnvironmentSettingsObject& callback_context)
- : callback(move(callback))
- , callback_context(callback_context)
- {
- }
+class CallbackType final : public JS::Cell {
+public:
+ CallbackType(JS::Object& callback, HTML::EnvironmentSettingsObject& callback_context);
- JS::Handle<JS::Object> callback;
+ JS::Object& callback;
// https://heycam.github.io/webidl/#dfn-callback-context
HTML::EnvironmentSettingsObject& callback_context;
+
+private:
+ virtual StringView class_name() const override;
+ virtual void visit_edges(Cell::Visitor&) override;
};
}
diff --git a/Userland/Libraries/LibWeb/Bindings/EventListenerWrapper.cpp b/Userland/Libraries/LibWeb/Bindings/EventListenerWrapper.cpp
deleted file mode 100644
index ebcc9a890f..0000000000
--- a/Userland/Libraries/LibWeb/Bindings/EventListenerWrapper.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <LibJS/Runtime/FunctionObject.h>
-#include <LibJS/Runtime/GlobalObject.h>
-#include <LibWeb/Bindings/EventListenerWrapper.h>
-#include <LibWeb/DOM/IDLEventListener.h>
-
-namespace Web {
-namespace Bindings {
-
-EventListenerWrapper::EventListenerWrapper(JS::Realm& realm, DOM::IDLEventListener& impl)
- : Wrapper(*realm.intrinsics().object_prototype())
- , m_impl(impl)
-{
-}
-
-}
-}
diff --git a/Userland/Libraries/LibWeb/Bindings/EventListenerWrapper.h b/Userland/Libraries/LibWeb/Bindings/EventListenerWrapper.h
deleted file mode 100644
index 8c1dbcd216..0000000000
--- a/Userland/Libraries/LibWeb/Bindings/EventListenerWrapper.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <LibWeb/Bindings/Wrapper.h>
-
-namespace Web {
-namespace Bindings {
-
-class EventListenerWrapper final : public Wrapper {
- JS_OBJECT(EventListenerWrapper, Wrapper);
-
-public:
- EventListenerWrapper(JS::Realm& realm, DOM::IDLEventListener&);
- virtual ~EventListenerWrapper() override = default;
-
- DOM::IDLEventListener& impl() { return *m_impl; }
- DOM::IDLEventListener const& impl() const { return *m_impl; }
-
-private:
- NonnullRefPtr<DOM::IDLEventListener> m_impl;
-};
-
-}
-}
diff --git a/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp b/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp
index 74c7ece8ab..66ea40e872 100644
--- a/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp
+++ b/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp
@@ -92,11 +92,10 @@ JS::Completion invoke_callback(Bindings::CallbackType& callback, Optional<JS::Va
this_argument = JS::js_undefined();
// 3. Let F be the ECMAScript object corresponding to callable.
- auto* function_object = callback.callback.cell();
- VERIFY(function_object);
+ auto& function_object = callback.callback;
// 4. If ! IsCallable(F) is false:
- if (!function_object->is_function()) {
+ if (!function_object.is_function()) {
// 1. Note: This is only possible when the callback function came from an attribute marked with [LegacyTreatNonObjectAsNull].
// 2. Return the result of converting undefined to the callback function’s return type.
@@ -106,7 +105,7 @@ JS::Completion invoke_callback(Bindings::CallbackType& callback, Optional<JS::Va
// 5. Let realm be F’s associated Realm.
// See the comment about associated realm on step 4 of call_user_object_operation.
- auto& realm = function_object->shape().realm();
+ auto& realm = function_object.shape().realm();
// 6. Let relevant settings be realm’s settings object.
auto& relevant_settings = verify_cast<HTML::EnvironmentSettingsObject>(*realm.host_defined());
@@ -124,8 +123,8 @@ JS::Completion invoke_callback(Bindings::CallbackType& callback, Optional<JS::Va
// For simplicity, we currently make the caller do this. However, this means we can't throw exceptions at this point like the spec wants us to.
// 11. Let callResult be Call(F, thisArg, esArgs).
- auto& vm = function_object->vm();
- auto call_result = JS::call(vm, verify_cast<JS::FunctionObject>(*function_object), this_argument.value(), move(args));
+ auto& vm = function_object.vm();
+ auto call_result = JS::call(vm, verify_cast<JS::FunctionObject>(function_object), this_argument.value(), move(args));
// 12. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
if (call_result.is_throw_completion()) {
diff --git a/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h b/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h
index 0f7ea9226a..7ad5afadf1 100644
--- a/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h
+++ b/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h
@@ -54,7 +54,7 @@ JS::Completion call_user_object_operation(Bindings::CallbackType& callback, Stri
this_argument = JS::js_undefined();
// 3. Let O be the ECMAScript object corresponding to value.
- auto& object = *callback.callback.cell();
+ auto& object = callback.callback;
// 4. Let realm be O’s associated Realm.
auto& realm = object.shape().realm();
@@ -126,8 +126,7 @@ JS::Completion invoke_callback(Bindings::CallbackType& callback, Optional<JS::Va
template<typename... Args>
JS::Completion invoke_callback(Bindings::CallbackType& callback, Optional<JS::Value> this_argument, Args&&... args)
{
- auto* function_object = callback.callback.cell();
- VERIFY(function_object);
+ auto& function_object = callback.callback;
JS::MarkedVector<JS::Value> arguments_list { function_object->vm().heap() };
(arguments_list.append(forward<Args>(args)), ...);
diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp
index 32624314d2..b331cef7ec 100644
--- a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp
+++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp
@@ -229,7 +229,7 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::prompt)
static JS::ThrowCompletionOr<TimerHandler> make_timer_handler(JS::VM& vm, JS::Value handler)
{
if (handler.is_function())
- return Bindings::CallbackType(JS::make_handle<JS::Object>(handler.as_function()), HTML::incumbent_settings_object());
+ return JS::make_handle(vm.heap().allocate_without_realm<Bindings::CallbackType>(handler.as_function(), HTML::incumbent_settings_object()));
return TRY(handler.to_string(vm));
}
@@ -311,8 +311,8 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::request_animation_frame)
auto* callback_object = TRY(vm.argument(0).to_object(vm));
if (!callback_object->is_function())
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAFunctionNoParam);
- NonnullOwnPtr<Bindings::CallbackType> callback = adopt_own(*new Bindings::CallbackType(JS::make_handle(callback_object), HTML::incumbent_settings_object()));
- return JS::Value(impl->request_animation_frame(move(callback)));
+ auto* callback = vm.heap().allocate_without_realm<Bindings::CallbackType>(*callback_object, HTML::incumbent_settings_object());
+ return JS::Value(impl->request_animation_frame(*callback));
}
JS_DEFINE_NATIVE_FUNCTION(WindowObject::cancel_animation_frame)
@@ -334,9 +334,9 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::queue_microtask)
if (!callback_object->is_function())
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAFunctionNoParam);
- auto callback = adopt_own(*new Bindings::CallbackType(JS::make_handle(callback_object), HTML::incumbent_settings_object()));
+ auto* callback = vm.heap().allocate_without_realm<Bindings::CallbackType>(*callback_object, HTML::incumbent_settings_object());
- impl->queue_microtask(move(callback));
+ impl->queue_microtask(*callback);
return JS::js_undefined();
}
@@ -350,9 +350,9 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::request_idle_callback)
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAFunctionNoParam);
// FIXME: accept options object
- auto callback = adopt_own(*new Bindings::CallbackType(JS::make_handle(callback_object), HTML::incumbent_settings_object()));
+ auto* callback = vm.heap().allocate_without_realm<Bindings::CallbackType>(*callback_object, HTML::incumbent_settings_object());
- return JS::Value(impl->request_idle_callback(move(callback)));
+ return JS::Value(impl->request_idle_callback(*callback));
}
JS_DEFINE_NATIVE_FUNCTION(WindowObject::cancel_idle_callback)
@@ -748,25 +748,26 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::name_setter)
return JS::js_undefined();
}
-#define __ENUMERATE(attribute, event_name) \
- JS_DEFINE_NATIVE_FUNCTION(WindowObject::attribute##_getter) \
- { \
- auto* impl = TRY(impl_from(vm)); \
- auto retval = impl->attribute(); \
- if (!retval) \
- return JS::js_null(); \
- return retval->callback.cell(); \
- } \
- JS_DEFINE_NATIVE_FUNCTION(WindowObject::attribute##_setter) \
- { \
- auto* impl = TRY(impl_from(vm)); \
- auto value = vm.argument(0); \
- Optional<Bindings::CallbackType> cpp_value; \
- if (value.is_object()) { \
- cpp_value = Bindings::CallbackType { JS::make_handle(&value.as_object()), HTML::incumbent_settings_object() }; \
- } \
- impl->set_##attribute(cpp_value); \
- return JS::js_undefined(); \
+#define __ENUMERATE(attribute, event_name) \
+ JS_DEFINE_NATIVE_FUNCTION(WindowObject::attribute##_getter) \
+ { \
+ auto* impl = TRY(impl_from(vm)); \
+ auto retval = impl->attribute(); \
+ if (!retval) \
+ return JS::js_null(); \
+ return &retval->callback; \
+ } \
+ JS_DEFINE_NATIVE_FUNCTION(WindowObject::attribute##_setter) \
+ { \
+ auto* impl = TRY(impl_from(vm)); \
+ auto value = vm.argument(0); \
+ Bindings::CallbackType* cpp_value; \
+ if (value.is_object()) { \
+ cpp_value = vm.heap().allocate_without_realm<Bindings::CallbackType>( \
+ value.as_object(), HTML::incumbent_settings_object()); \
+ } \
+ impl->set_##attribute(cpp_value); \
+ return JS::js_undefined(); \
}
ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE)
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.h b/Userland/Libraries/LibWeb/Bindings/WindowObject.h
index b3bd2e61f5..86cc00a6d4 100644
--- a/Userland/Libraries/LibWeb/Bindings/WindowObject.h
+++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.h
@@ -24,7 +24,7 @@ namespace Web {
namespace Bindings {
// https://html.spec.whatwg.org/#timerhandler
-using TimerHandler = Variant<CallbackType, String>;
+using TimerHandler = Variant<JS::Handle<CallbackType>, String>;
class WindowObject
: public JS::GlobalObject
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt
index cb794c1f3d..da2e149af8 100644
--- a/Userland/Libraries/LibWeb/CMakeLists.txt
+++ b/Userland/Libraries/LibWeb/CMakeLists.txt
@@ -2,9 +2,9 @@ include(libweb_generators)
set(SOURCES
Bindings/AudioConstructor.cpp
- Bindings/CrossOriginAbstractOperations.cpp
Bindings/CSSNamespace.cpp
- Bindings/EventListenerWrapper.cpp
+ Bindings/CallbackType.cpp
+ Bindings/CrossOriginAbstractOperations.cpp
Bindings/EventTargetWrapperFactory.cpp
Bindings/EventWrapperFactory.cpp
Bindings/IDLAbstractOperations.cpp
@@ -97,12 +97,14 @@ set(SOURCES
DOM/EventDispatcher.cpp
DOM/EventTarget.cpp
DOM/HTMLCollection.cpp
+ DOM/IDLEventListener.cpp
DOM/LiveNodeList.cpp
DOM/MutationObserver.cpp
DOM/MutationRecord.cpp
DOM/MutationType.cpp
DOM/NamedNodeMap.cpp
DOM/Node.cpp
+ DOM/NodeFilter.cpp
DOM/NodeIterator.cpp
DOM/NodeOperations.cpp
DOM/ParentNode.cpp
@@ -146,6 +148,7 @@ set(SOURCES
HTML/CrossOrigin/Reporting.cpp
HTML/DOMParser.cpp
HTML/DOMStringMap.cpp
+ HTML/EventHandler.cpp
HTML/EventLoop/EventLoop.cpp
HTML/EventLoop/Task.cpp
HTML/EventLoop/TaskQueue.cpp
diff --git a/Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp b/Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp
index 23bda33f00..74caf27013 100644
--- a/Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp
+++ b/Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp
@@ -57,7 +57,7 @@ JS::Object* MediaQueryList::create_wrapper(JS::Realm& realm)
}
// https://www.w3.org/TR/cssom-view/#dom-mediaquerylist-addlistener
-void MediaQueryList::add_listener(RefPtr<DOM::IDLEventListener> listener)
+void MediaQueryList::add_listener(DOM::IDLEventListener* listener)
{
// 1. If listener is null, terminate these steps.
if (!listener)
@@ -67,19 +67,19 @@ void MediaQueryList::add_listener(RefPtr<DOM::IDLEventListener> listener)
// callback set to listener, and capture set to false, unless there already is an event listener
// in that list with the same type, callback, and capture.
// (NOTE: capture is set to false by default)
- add_event_listener_without_options(HTML::EventNames::change, listener);
+ add_event_listener_without_options(HTML::EventNames::change, *listener);
}
// https://www.w3.org/TR/cssom-view/#dom-mediaquerylist-removelistener
-void MediaQueryList::remove_listener(RefPtr<DOM::IDLEventListener> listener)
+void MediaQueryList::remove_listener(DOM::IDLEventListener* listener)
{
// 1. Remove an event listener from the associated list of event listeners, whose type is change, callback is listener, and capture is false.
// NOTE: While the spec doesn't technically use remove_event_listener and instead manipulates the list directly, every major engine uses remove_event_listener.
// This means if an event listener removes another event listener that comes after it, the removed event listener will not be invoked.
- remove_event_listener_without_options(HTML::EventNames::change, listener);
+ remove_event_listener_without_options(HTML::EventNames::change, *listener);
}
-void MediaQueryList::set_onchange(Optional<Bindings::CallbackType> event_handler)
+void MediaQueryList::set_onchange(Bindings::CallbackType* event_handler)
{
set_event_handler_attribute(HTML::EventNames::change, event_handler);
}
diff --git a/Userland/Libraries/LibWeb/CSS/MediaQueryList.h b/Userland/Libraries/LibWeb/CSS/MediaQueryList.h
index 0c6c5df248..71f88439bb 100644
--- a/Userland/Libraries/LibWeb/CSS/MediaQueryList.h
+++ b/Userland/Libraries/LibWeb/CSS/MediaQueryList.h
@@ -45,10 +45,10 @@ public:
virtual void unref_event_target() override { unref(); }
virtual JS::Object* create_wrapper(JS::Realm&) override;
- void add_listener(RefPtr<DOM::IDLEventListener> listener);
- void remove_listener(RefPtr<DOM::IDLEventListener> listener);
+ void add_listener(DOM::IDLEventListener*);
+ void remove_listener(DOM::IDLEventListener*);
- void set_onchange(Optional<Bindings::CallbackType>);
+ void set_onchange(Bindings::CallbackType*);
Bindings::CallbackType* onchange();
private:
diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp
index df48463fe3..86f1404a70 100644
--- a/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp
+++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.cpp
@@ -63,9 +63,9 @@ void AbortSignal::signal_abort(JS::Value reason)
dispatch_event(Event::create(HTML::EventNames::abort));
}
-void AbortSignal::set_onabort(Optional<Bindings::CallbackType> event_handler)
+void AbortSignal::set_onabort(Bindings::CallbackType* event_handler)
{
- set_event_handler_attribute(HTML::EventNames::abort, move(event_handler));
+ set_event_handler_attribute(HTML::EventNames::abort, event_handler);
}
Bindings::CallbackType* AbortSignal::onabort()
diff --git a/Userland/Libraries/LibWeb/DOM/AbortSignal.h b/Userland/Libraries/LibWeb/DOM/AbortSignal.h
index b05e1e9d06..3166e87a67 100644
--- a/Userland/Libraries/LibWeb/DOM/AbortSignal.h
+++ b/Userland/Libraries/LibWeb/DOM/AbortSignal.h
@@ -47,7 +47,7 @@ public:
void signal_abort(JS::Value reason);
- void set_onabort(Optional<Bindings::CallbackType>);
+ void set_onabort(Bindings::CallbackType*);
Bindings::CallbackType* onabort();
// https://dom.spec.whatwg.org/#dom-abortsignal-reason
diff --git a/Userland/Libraries/LibWeb/DOM/DOMEventListener.cpp b/Userland/Libraries/LibWeb/DOM/DOMEventListener.cpp
index 39ceba325e..29c53a1b59 100644
--- a/Userland/Libraries/LibWeb/DOM/DOMEventListener.cpp
+++ b/Userland/Libraries/LibWeb/DOM/DOMEventListener.cpp
@@ -9,6 +9,14 @@
#include <LibWeb/DOM/IDLEventListener.h>
namespace Web::DOM {
+
DOMEventListener::DOMEventListener() = default;
DOMEventListener::~DOMEventListener() = default;
+
+void DOMEventListener::visit_edges(Cell::Visitor& visitor)
+{
+ Cell::visit_edges(visitor);
+ visitor.visit(callback.ptr());
+}
+
}
diff --git a/Userland/Libraries/LibWeb/DOM/DOMEventListener.h b/Userland/Libraries/LibWeb/DOM/DOMEventListener.h
index 41de2ef1a1..a5a9b5d5d5 100644
--- a/Userland/Libraries/LibWeb/DOM/DOMEventListener.h
+++ b/Userland/Libraries/LibWeb/DOM/DOMEventListener.h
@@ -7,13 +7,15 @@
#pragma once
#include <AK/FlyString.h>
+#include <LibJS/Heap/GCPtr.h>
+#include <LibJS/Runtime/Object.h>
#include <LibWeb/Forward.h>
namespace Web::DOM {
// https://dom.spec.whatwg.org/#concept-event-listener
// NOTE: The spec calls this "event listener", and it's *importantly* not the same as "EventListener"
-class DOMEventListener : public RefCounted<DOMEventListener> {
+class DOMEventListener : public JS::Cell {
public:
DOMEventListener();
~DOMEventListener();
@@ -22,7 +24,7 @@ public:
FlyString type;
// callback (null or an EventListener object)
- RefPtr<IDLEventListener> callback;
+ JS::GCPtr<IDLEventListener> callback;
// signal (null or an AbortSignal object)
RefPtr<DOM::AbortSignal> signal;
@@ -38,6 +40,10 @@ public:
// removed (a boolean for bookkeeping purposes, initially false)
bool removed { false };
+
+private:
+ virtual void visit_edges(Cell::Visitor&) override;
+ virtual StringView class_name() const override { return "DOMEventListener"sv; }
};
}
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp
index b15b17d3b4..796ee21a18 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Document.cpp
@@ -1744,15 +1744,15 @@ ExceptionOr<Document::PrefixAndTagName> Document::validate_qualified_name(String
}
// https://dom.spec.whatwg.org/#dom-document-createnodeiterator
-NonnullRefPtr<NodeIterator> Document::create_node_iterator(Node& root, unsigned what_to_show, RefPtr<NodeFilter> filter)
+NonnullRefPtr<NodeIterator> Document::create_node_iterator(Node& root, unsigned what_to_show, NodeFilter* filter)
{
- return NodeIterator::create(root, what_to_show, move(filter));
+ return NodeIterator::create(root, what_to_show, filter);
}
// https://dom.spec.whatwg.org/#dom-document-createtreewalker
-NonnullRefPtr<TreeWalker> Document::create_tree_walker(Node& root, unsigned what_to_show, RefPtr<NodeFilter> filter)
+NonnullRefPtr<TreeWalker> Document::create_tree_walker(Node& root, unsigned what_to_show, NodeFilter* filter)
{
- return TreeWalker::create(root, what_to_show, move(filter));
+ return TreeWalker::create(root, what_to_show, filter);
}
void Document::register_node_iterator(Badge<NodeIterator>, NodeIterator& node_iterator)
diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h
index ee8cd13dbc..8a54391068 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.h
+++ b/Userland/Libraries/LibWeb/DOM/Document.h
@@ -350,8 +350,8 @@ public:
};
static ExceptionOr<PrefixAndTagName> validate_qualified_name(String const& qualified_name);
- NonnullRefPtr<NodeIterator> create_node_iterator(Node& root, unsigned what_to_show, RefPtr<NodeFilter>);
- NonnullRefPtr<TreeWalker> create_tree_walker(Node& root, unsigned what_to_show, RefPtr<NodeFilter>);
+ NonnullRefPtr<NodeIterator> create_node_iterator(Node& root, unsigned what_to_show, NodeFilter*);
+ NonnullRefPtr<TreeWalker> create_tree_walker(Node& root, unsigned what_to_show, NodeFilter*);
void register_node_iterator(Badge<NodeIterator>, NodeIterator&);
void unregister_node_iterator(Badge<NodeIterator>, NodeIterator&);
diff --git a/Userland/Libraries/LibWeb/DOM/EventDispatcher.cpp b/Userland/Libraries/LibWeb/DOM/EventDispatcher.cpp
index b37bc4fde8..6324301e7c 100644
--- a/Userland/Libraries/LibWeb/DOM/EventDispatcher.cpp
+++ b/Userland/Libraries/LibWeb/DOM/EventDispatcher.cpp
@@ -57,7 +57,7 @@ static EventTarget* retarget(EventTarget* left, EventTarget* right)
}
// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
-bool EventDispatcher::inner_invoke(Event& event, Vector<NonnullRefPtr<DOM::DOMEventListener>>& listeners, Event::Phase phase, bool invocation_target_in_shadow_tree)
+bool EventDispatcher::inner_invoke(Event& event, Vector<JS::Handle<DOM::DOMEventListener>>& listeners, Event::Phase phase, bool invocation_target_in_shadow_tree)
{
// 1. Let found be false.
bool found = false;
@@ -84,11 +84,11 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<NonnullRefPtr<DOM::DOMEv
// 5. If listener’s once is true, then remove listener from event’s currentTarget attribute value’s event listener list.
if (listener->once)
- event.current_target()->remove_from_event_listener_list(listener);
+ event.current_target()->remove_from_event_listener_list(*listener);
// 6. Let global be listener callback’s associated Realm’s global object.
auto& callback = listener->callback->callback();
- auto& realm = callback.callback->shape().realm();
+ auto& realm = callback.callback.shape().realm();
auto& global = realm.global_object();
// 7. Let currentEvent be undefined.
diff --git a/Userland/Libraries/LibWeb/DOM/EventDispatcher.h b/Userland/Libraries/LibWeb/DOM/EventDispatcher.h
index 045bbaeb46..13ac65efb4 100644
--- a/Userland/Libraries/LibWeb/DOM/EventDispatcher.h
+++ b/Userland/Libraries/LibWeb/DOM/EventDispatcher.h
@@ -18,7 +18,7 @@ public:
private:
static void invoke(Event::PathEntry&, Event&, Event::Phase);
- static bool inner_invoke(Event&, Vector<NonnullRefPtr<DOM::DOMEventListener>>&, Event::Phase, bool);
+ static bool inner_invoke(Event&, Vector<JS::Handle<DOM::DOMEventListener>>&, Event::Phase, bool);
};
}
diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp
index 3c4851390c..3fa4f53160 100644
--- a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp
+++ b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp
@@ -20,6 +20,7 @@
#include <LibWeb/Bindings/IDLAbstractOperations.h>
#include <LibWeb/Bindings/MainThreadVM.h>
#include <LibWeb/DOM/AbortSignal.h>
+#include <LibWeb/DOM/DOMEventListener.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Event.h>
#include <LibWeb/DOM/EventDispatcher.h>
@@ -99,89 +100,91 @@ static FlattenedAddEventListenerOptions flatten_add_event_listener_options(Varia
}
// https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener
-void EventTarget::add_event_listener(FlyString const& type, RefPtr<IDLEventListener> callback, Variant<AddEventListenerOptions, bool> const& options)
+void EventTarget::add_event_listener(FlyString const& type, IDLEventListener* callback, Variant<AddEventListenerOptions, bool> const& options)
{
// 1. Let capture, passive, once, and signal be the result of flattening more options.
auto flattened_options = flatten_add_event_listener_options(options);
// 2. Add an event listener with this and an event listener whose type is type, callback is callback, capture is capture, passive is passive,
// once is once, and signal is signal.
- auto event_listener = adopt_ref(*new DOMEventListener);
+
+ // FIXME: Don't use main_thread_internal_window_object() when EventTarget can find its own heap.
+ auto* event_listener = Bindings::main_thread_internal_window_object().heap().allocate_without_realm<DOMEventListener>();
event_listener->type = type;
- event_listener->callback = move(callback);
+ event_listener->callback = callback;
event_listener->signal = move(flattened_options.signal);
event_listener->capture = flattened_options.capture;
event_listener->passive = flattened_options.passive;
event_listener->once = flattened_options.once;
- add_an_event_listener(move(event_listener));
+ add_an_event_listener(*event_listener);
}
-void EventTarget::add_event_listener_without_options(FlyString const& type, RefPtr<IDLEventListener> callback)
+void EventTarget::add_event_listener_without_options(FlyString const& type, IDLEventListener& callback)
{
- add_event_listener(type, move(callback), AddEventListenerOptions {});
+ add_event_listener(type, &callback, AddEventListenerOptions {});
}
// https://dom.spec.whatwg.org/#add-an-event-listener
-void EventTarget::add_an_event_listener(NonnullRefPtr<DOMEventListener> listener)
+void EventTarget::add_an_event_listener(DOMEventListener& listener)
{
// FIXME: 1. If eventTarget is a ServiceWorkerGlobalScope object, its service worker’s script resource’s has ever been evaluated flag is set,
// and listener’s type matches the type attribute value of any of the service worker events, then report a warning to the console
// that this might not give the expected results. [SERVICE-WORKERS]
// 2. If listener’s signal is not null and is aborted, then return.
- if (listener->signal && listener->signal->aborted())
+ if (listener.signal && listener.signal->aborted())
return;
// 3. If listener’s callback is null, then return.
- if (listener->callback.is_null())
+ if (!listener.callback)
return;
// 4. If eventTarget’s event listener list does not contain an event listener whose type is listener’s type, callback is listener’s callback,
// and capture is listener’s capture, then append listener to eventTarget’s event listener list.
auto it = m_event_listener_list.find_if([&](auto& entry) {
- return entry->type == listener->type
- && entry->callback->callback().callback.cell() == listener->callback->callback().callback.cell()
- && entry->capture == listener->capture;
+ return entry->type == listener.type
+ && &entry->callback->callback().callback == &listener.callback->callback().callback
+ && entry->capture == listener.capture;
});
if (it == m_event_listener_list.end())
- m_event_listener_list.append(listener);
+ m_event_listener_list.append(JS::make_handle(listener));
// 5. If listener’s signal is not null, then add the following abort steps to it:
- if (listener->signal) {
- listener->signal->add_abort_algorithm([strong_event_target = NonnullRefPtr(*this), listener]() mutable {
+ if (listener.signal) {
+ listener.signal->add_abort_algorithm([strong_event_target = NonnullRefPtr(*this), listener = JS::make_handle(&listener)]() mutable {
// 1. Remove an event listener with eventTarget and listener.
- strong_event_target->remove_an_event_listener(listener);
+ strong_event_target->remove_an_event_listener(*listener);
});
}
}
// https://dom.spec.whatwg.org/#dom-eventtarget-removeeventlistener
-void EventTarget::remove_event_listener(FlyString const& type, RefPtr<IDLEventListener> callback, Variant<EventListenerOptions, bool> const& options)
+void EventTarget::remove_event_listener(FlyString const& type, IDLEventListener* callback, Variant<EventListenerOptions, bool> const& options)
{
// 1. Let capture be the result of flattening options.
bool capture = flatten_event_listener_options(options);
// 2. If this’s event listener list contains an event listener whose type is type, callback is callback, and capture is capture,
// then remove an event listener with this and that event listener.
- auto callbacks_match = [&](NonnullRefPtr<DOMEventListener>& entry) {
- if (entry->callback.is_null() && callback.is_null())
+ auto callbacks_match = [&](DOMEventListener& entry) {
+ if (!entry.callback && !callback)
return true;
- if (entry->callback.is_null() || callback.is_null())
+ if (!entry.callback || !callback)
return false;
- return entry->callback->callback().callback.cell() == callback->callback().callback.cell();
+ return &entry.callback->callback().callback == &callback->callback().callback;
};
auto it = m_event_listener_list.find_if([&](auto& entry) {
return entry->type == type
- && callbacks_match(entry)
+ && callbacks_match(*entry)
&& entry->capture == capture;
});
if (it != m_event_listener_list.end())
- remove_an_event_listener(*it);
+ remove_an_event_listener(**it);
}
-void EventTarget::remove_event_listener_without_options(FlyString const& type, RefPtr<IDLEventListener> callback)
+void EventTarget::remove_event_listener_without_options(FlyString const& type, IDLEventListener& callback)
{
- remove_event_listener(type, move(callback), EventListenerOptions {});
+ remove_event_listener(type, &callback, EventListenerOptions {});
}
// https://dom.spec.whatwg.org/#remove-an-event-listener
@@ -192,12 +195,12 @@ void EventTarget::remove_an_event_listener(DOMEventListener& listener)
// 2. Set listener’s removed to true and remove listener from eventTarget’s event listener list.
listener.removed = true;
- m_event_listener_list.remove_first_matching([&](auto& entry) { return entry.ptr() == &listener; });
+ m_event_listener_list.remove_first_matching([&](auto& entry) { return entry.cell() == &listener; });
}
void EventTarget::remove_from_event_listener_list(DOMEventListener& listener)
{
- m_event_listener_list.remove_first_matching([&](auto& entry) { return entry.ptr() == &listener; });
+ m_event_listener_list.remove_first_matching([&](auto& entry) { return entry.cell() == &listener; });
}
// https://dom.spec.whatwg.org/#dom-eventtarget-dispatchevent
@@ -309,7 +312,7 @@ Bindings::CallbackType* EventTarget::get_current_value_of_event_handler(FlyStrin
auto& event_handler = event_handler_iterator->value;
// 3. If eventHandler's value is an internal raw uncompiled handler, then:
- if (event_handler.value.has<String>()) {
+ if (event_handler->value.has<String>()) {
// 1. If eventTarget is an element, then let element be eventTarget, and document be element's node document.
// Otherwise, eventTarget is a Window object, let element be null, and document be eventTarget's associated Document.
RefPtr<Element> element;
@@ -332,7 +335,7 @@ Bindings::CallbackType* EventTarget::get_current_value_of_event_handler(FlyStrin
return nullptr;
// 3. Let body be the uncompiled script body in eventHandler's value.
- auto& body = event_handler.value.get<String>();
+ auto& body = event_handler->value.get<String>();
// FIXME: 4. Let location be the location where the script body originated, as given by eventHandler's value.
@@ -448,16 +451,16 @@ Bindings::CallbackType* EventTarget::get_current_value_of_event_handler(FlyStrin
function->set_script_or_module({});
// 12. Set eventHandler's value to the result of creating a Web IDL EventHandler callback function object whose object reference is function and whose callback context is settings object.
- event_handler.value = Bindings::CallbackType { JS::make_handle(static_cast<JS::Object*>(function)), settings_object };
+ event_handler->value = realm.heap().allocate_without_realm<Bindings::CallbackType>(*function, settings_object);
}
// 4. Return eventHandler's value.
- VERIFY(event_handler.value.has<Bindings::CallbackType>());
- return event_handler.value.get_pointer<Bindings::CallbackType>();
+ VERIFY(event_handler->value.has<Bindings::CallbackType*>());
+ return *event_handler->value.get_pointer<Bindings::CallbackType*>();
}
// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:event-handler-idl-attributes-3
-void EventTarget::set_event_handler_attribute(FlyString const& name, Optional<Bindings::CallbackType> value)
+void EventTarget::set_event_handler_attribute(FlyString const& name, Bindings::CallbackType* value)
{
// 1. Let eventTarget be the result of determining the target of an event handler given this object and name.
auto event_target = determine_target_of_event_handler(*this, name);
@@ -467,7 +470,7 @@ void EventTarget::set_event_handler_attribute(FlyString const& name, Optional<Bi
return;
// 3. If the given value is null, then deactivate an event handler given eventTarget and name.
- if (!value.has_value()) {
+ if (!value) {
event_target->deactivate_event_handler(name);
return;
}
@@ -482,25 +485,25 @@ void EventTarget::set_event_handler_attribute(FlyString const& name, Optional<Bi
// 3. Set eventHandler's value to the given value.
if (event_handler_iterator == handler_map.end()) {
// NOTE: See the optimization comment in get_current_value_of_event_handler about why this is done.
- HTML::EventHandler new_event_handler { move(value.value()) };
+ auto* new_event_handler = Bindings::main_thread_internal_window_object().heap().allocate_without_realm<HTML::EventHandler>(*value);
// 4. Activate an event handler given eventTarget and name.
// Optimization: We pass in the event handler here instead of having activate_event_handler do another hash map lookup just to get the same object.
// This handles a new event handler while the other path handles an existing event handler. As such, both paths must have their own
// unique call to activate_event_handler.
- event_target->activate_event_handler(name, new_event_handler);
+ event_target->activate_event_handler(name, *new_event_handler);
- handler_map.set(name, move(new_event_handler));
+ handler_map.set(name, JS::make_handle(new_event_handler));
return;
}
auto& event_handler = event_handler_iterator->value;
- event_handler.value = move(value.value());
+ event_handler->value = value;
// 4. Activate an event handler given eventTarget and name.
// NOTE: See the optimization comment above.
- event_target->activate_event_handler(name, event_handler);
+ event_target->activate_event_handler(name, *event_handler);
}
// https://html.spec.whatwg.org/multipage/webappapis.html#activate-an-event-handler
@@ -516,8 +519,8 @@ void EventTarget::activate_event_handler(FlyString const& name, HTML::EventHandl
JS::Realm* realm = nullptr;
// See step 3.1. in get_current_value_of_event_handler(), which explains these assumptions.
- if (event_handler.value.has<Bindings::CallbackType>()) {
- realm = &event_handler.value.get<Bindings::CallbackType>().callback_context.realm();
+ if (event_handler.value.has<Bindings::CallbackType*>()) {
+ realm = &event_handler.value.get<Bindings::CallbackType*>()->callback_context.realm();
} else if (is<Element>(this)) {
realm = &verify_cast<Element>(*this).document().realm();
} else {
@@ -555,15 +558,15 @@ void EventTarget::activate_event_handler(FlyString const& name, HTML::EventHandl
0, "", realm);
// NOTE: As per the spec, the callback context is arbitrary.
- Bindings::CallbackType callback { JS::make_handle(static_cast<JS::Object*>(callback_function)), verify_cast<HTML::EnvironmentSettingsObject>(*realm->host_defined()) };
+ auto* callback = realm->heap().allocate_without_realm<Bindings::CallbackType>(*callback_function, verify_cast<HTML::EnvironmentSettingsObject>(*realm->host_defined()));
// 5. Let listener be a new event listener whose type is the event handler event type corresponding to eventHandler and callback is callback.
- auto listener = adopt_ref(*new DOMEventListener);
+ auto* listener = realm->heap().allocate_without_realm<DOMEventListener>();
listener->type = name;
- listener->callback = adopt_ref(*new IDLEventListener(move(callback)));
+ listener->callback = IDLEventListener::create(*realm, *callback).ptr();
// 6. Add an event listener with eventTarget and listener.
- add_an_event_listener(listener);
+ add_an_event_listener(*listener);
// 7. Set eventHandler's listener to listener.
event_handler.listener = listener;
@@ -585,12 +588,12 @@ void EventTarget::deactivate_event_handler(FlyString const& name)
// 4. Let listener be eventHandler's listener. (NOTE: Not necessary)
// 5. If listener is not null, then remove an event listener with eventTarget and listener.
- if (event_handler.listener) {
- remove_an_event_listener(*event_handler.listener);
+ if (event_handler->listener) {
+ remove_an_event_listener(*event_handler->listener);
}
// 6. Set eventHandler's listener to null.
- event_handler.listener = nullptr;
+ event_handler->listener = nullptr;
// 3. Set eventHandler's value to null.
// NOTE: This is done out of order since our equivalent of setting value to null is removing the event handler from the map.
@@ -617,7 +620,7 @@ JS::ThrowCompletionOr<void> EventTarget::process_event_handler_for_event(FlyStri
JS::Completion return_value_or_error;
// Needed for wrapping.
- auto* callback_object = callback->callback.cell();
+ auto* callback_object = &callback->callback;
auto& realm = callback_object->shape().realm();
if (special_error_event_handling) {
@@ -717,20 +720,20 @@ void EventTarget::element_event_handler_attribute_changed(FlyString const& local
// NOTE: See the optimization comments in set_event_handler_attribute.
if (event_handler_iterator == handler_map.end()) {
- HTML::EventHandler new_event_handler { value };
+ auto* new_event_handler = Bindings::main_thread_internal_window_object().heap().allocate_without_realm<HTML::EventHandler>(value);
// 6. Activate an event handler given eventTarget and name.
- event_target->activate_event_handler(local_name, new_event_handler);
+ event_target->activate_event_handler(local_name, *new_event_handler);
- handler_map.set(local_name, move(new_event_handler));
+ handler_map.set(local_name, JS::make_handle(new_event_handler));
return;
}
auto& event_handler = event_handler_iterator->value;
// 6. Activate an event handler given eventTarget and name.
- event_handler.value = value;
- event_target->activate_event_handler(local_name, event_handler);
+ event_handler->value = value;
+ event_target->activate_event_handler(local_name, *event_handler);
}
bool EventTarget::dispatch_event(NonnullRefPtr<Event> event)
diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.h b/Userland/Libraries/LibWeb/DOM/EventTarget.h
index 854776eb0f..81fa073610 100644
--- a/Userland/Libraries/LibWeb/DOM/EventTarget.h
+++ b/Userland/Libraries/LibWeb/DOM/EventTarget.h
@@ -29,12 +29,12 @@ public:
virtual bool is_focusable() const { return false; }
- void add_event_listener(FlyString const& type, RefPtr<IDLEventListener> callback, Variant<AddEventListenerOptions, bool> const& options);
- void remove_event_listener(FlyString const& type, RefPtr<IDLEventListener> callback, Variant<EventListenerOptions, bool> const& options);
+ void add_event_listener(FlyString const& type, IDLEventListener* callback, Variant<AddEventListenerOptions, bool> const& options);
+ void remove_event_listener(FlyString const& type, IDLEventListener* callback, Variant<EventListenerOptions, bool> const& options);
// NOTE: These are for internal use only. They operate as though addEventListener(type, callback) was called instead of addEventListener(type, callback, options).
- void add_event_listener_without_options(FlyString const& type, RefPtr<IDLEventListener> callback);
- void remove_event_listener_without_options(FlyString const& type, RefPtr<IDLEventListener> callback);
+ void add_event_listener_without_options(FlyString const& type, IDLEventListener& callback);
+ void remove_event_listener_without_options(FlyString const& type, IDLEventListener& callback);
virtual bool dispatch_event(NonnullRefPtr<Event>);
ExceptionOr<bool> dispatch_event_binding(NonnullRefPtr<Event>);
@@ -43,7 +43,7 @@ public:
virtual EventTarget* get_parent(Event const&) { return nullptr; }
- void add_an_event_listener(NonnullRefPtr<DOMEventListener>);
+ void add_an_event_listener(DOMEventListener&);
void remove_an_event_listener(DOMEventListener&);
void remove_from_event_listener_list(DOMEventListener&);
@@ -58,7 +58,7 @@ public:
virtual void legacy_cancelled_activation_behavior_was_not_called() { }
Bindings::CallbackType* event_handler_attribute(FlyString const& name);
- void set_event_handler_attribute(FlyString const& name, Optional<Bindings::CallbackType>);
+ void set_event_handler_attribute(FlyString const& name, Bindings::CallbackType*);
protected:
EventTarget();
@@ -69,11 +69,11 @@ protected:
void element_event_handler_attribute_changed(FlyString const& local_name, String const& value);
private:
- Vector<NonnullRefPtr<DOMEventListener>> m_event_listener_list;
+ Vector<JS::Handle<DOMEventListener>> m_event_listener_list;
// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-map
// Spec Note: The order of the entries of event handler map could be arbitrary. It is not observable through any algorithms that operate on the map.
- HashMap<FlyString, HTML::EventHandler> m_event_handler_map;
+ HashMap<FlyString, JS::Handle<HTML::EventHandler>> m_event_handler_map;
Bindings::CallbackType* get_current_value_of_event_handler(FlyString const& name);
void activate_event_handler(FlyString const& name, HTML::EventHandler& event_handler);
diff --git a/Userland/Libraries/LibWeb/DOM/IDLEventListener.cpp b/Userland/Libraries/LibWeb/DOM/IDLEventListener.cpp
new file mode 100644
index 0000000000..5c4c75f582
--- /dev/null
+++ b/Userland/Libraries/LibWeb/DOM/IDLEventListener.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/Bindings/WindowObject.h>
+#include <LibWeb/DOM/IDLEventListener.h>
+
+namespace Web::DOM {
+
+JS::NonnullGCPtr<IDLEventListener> IDLEventListener::create(JS::Realm& realm, JS::NonnullGCPtr<Bindings::CallbackType> callback)
+{
+ return *realm.heap().allocate<IDLEventListener>(realm, realm, move(callback));
+}
+
+IDLEventListener::IDLEventListener(JS::Realm& realm, JS::NonnullGCPtr<Bindings::CallbackType> callback)
+ : JS::Object(*realm.intrinsics().object_prototype())
+ , m_callback(move(callback))
+{
+}
+
+void IDLEventListener::visit_edges(Cell::Visitor& visitor)
+{
+ Base::visit_edges(visitor);
+ visitor.visit(m_callback.ptr());
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/DOM/IDLEventListener.h b/Userland/Libraries/LibWeb/DOM/IDLEventListener.h
index 2ed2b6c78c..f372353462 100644
--- a/Userland/Libraries/LibWeb/DOM/IDLEventListener.h
+++ b/Userland/Libraries/LibWeb/DOM/IDLEventListener.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -25,23 +25,28 @@ struct AddEventListenerOptions : public EventListenerOptions {
Optional<NonnullRefPtr<AbortSignal>> signal;
};
-class IDLEventListener
- : public RefCounted<IDLEventListener>
- , public Bindings::Wrappable {
+class IDLEventListener final : public JS::Object {
+ JS_OBJECT(IDLEventListener, JS::Object);
+
public:
- using WrapperType = Bindings::EventListenerWrapper;
+ IDLEventListener& impl() { return *this; }
- explicit IDLEventListener(Bindings::CallbackType callback)
- : m_callback(move(callback))
- {
- }
+ static JS::NonnullGCPtr<IDLEventListener> create(JS::Realm&, JS::NonnullGCPtr<Bindings::CallbackType>);
+ IDLEventListener(JS::Realm&, JS::NonnullGCPtr<Bindings::CallbackType>);
virtual ~IDLEventListener() = default;
- Bindings::CallbackType& callback() { return m_callback; }
+ Bindings::CallbackType& callback() { return *m_callback; }
private:
- Bindings::CallbackType m_callback;
+ virtual void visit_edges(Cell::Visitor&) override;
+
+ JS::NonnullGCPtr<Bindings::CallbackType> m_callback;
};
}
+
+namespace Web::Bindings {
+inline JS::Object* wrap(JS::Realm&, Web::DOM::IDLEventListener& object) { return &object; }
+using EventListenerWrapper = Web::DOM::IDLEventListener;
+}
diff --git a/Userland/Libraries/LibWeb/DOM/MutationObserver.cpp b/Userland/Libraries/LibWeb/DOM/MutationObserver.cpp
index f489a7d016..e600ac58d9 100644
--- a/Userland/Libraries/LibWeb/DOM/MutationObserver.cpp
+++ b/Userland/Libraries/LibWeb/DOM/MutationObserver.cpp
@@ -12,7 +12,7 @@
namespace Web::DOM {
// https://dom.spec.whatwg.org/#dom-mutationobserver-mutationobserver
-MutationObserver::MutationObserver(Bindings::WindowObject& window_object, Bindings::CallbackType callback)
+MutationObserver::MutationObserver(Bindings::WindowObject& window_object, JS::Handle<Bindings::CallbackType> callback)
: m_callback(move(callback))
{
// 1. Set this’s callback to callback.
diff --git a/Userland/Libraries/LibWeb/DOM/MutationObserver.h b/Userland/Libraries/LibWeb/DOM/MutationObserver.h
index e7dcf942ee..961220fda6 100644
--- a/Userland/Libraries/LibWeb/DOM/MutationObserver.h
+++ b/Userland/Libraries/LibWeb/DOM/MutationObserver.h
@@ -34,9 +34,9 @@ class MutationObserver final
public:
using WrapperType = Bindings::MutationObserverWrapper;
- static NonnullRefPtr<MutationObserver> create_with_global_object(Bindings::WindowObject& window_object, Bindings::CallbackType callback)
+ static NonnullRefPtr<MutationObserver> create_with_global_object(Bindings::WindowObject& window_object, Bindings::CallbackType* callback)
{
- return adopt_ref(*new MutationObserver(window_object, move(callback)));
+ return adopt_ref(*new MutationObserver(window_object, JS::make_handle(callback)));
}
virtual ~MutationObserver() override = default;
@@ -48,7 +48,7 @@ public:
Vector<WeakPtr<Node>>& node_list() { return m_node_list; }
Vector<WeakPtr<Node>> const& node_list() const { return m_node_list; }
- Bindings::CallbackType& callback() { return m_callback; }
+ Bindings::CallbackType& callback() { return *m_callback; }
void enqueue_record(Badge<Node>, NonnullRefPtr<MutationRecord> mutation_record)
{
@@ -56,10 +56,10 @@ public:
}
private:
- MutationObserver(Bindings::WindowObject& window_object, Bindings::CallbackType callback);
+ MutationObserver(Bindings::WindowObject& window_object, JS::Handle<Bindings::CallbackType> callback);
// https://dom.spec.whatwg.org/#concept-mo-callback
- Bindings::CallbackType m_callback;
+ JS::Handle<Bindings::CallbackType> m_callback;
// https://dom.spec.whatwg.org/#mutationobserver-node-list
Vector<WeakPtr<Node>> m_node_list;
diff --git a/Userland/Libraries/LibWeb/DOM/NodeFilter.cpp b/Userland/Libraries/LibWeb/DOM/NodeFilter.cpp
new file mode 100644
index 0000000000..d1dbec9136
--- /dev/null
+++ b/Userland/Libraries/LibWeb/DOM/NodeFilter.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/Bindings/WindowObject.h>
+#include <LibWeb/DOM/NodeFilter.h>
+
+namespace Web::DOM {
+
+JS::NonnullGCPtr<NodeFilter> NodeFilter::create(JS::Realm& realm, Bindings::CallbackType& callback)
+{
+ return *realm.heap().allocate<NodeFilter>(realm, realm, callback);
+}
+
+NodeFilter::NodeFilter(JS::Realm& realm, Bindings::CallbackType& callback)
+ : PlatformObject(*realm.intrinsics().object_prototype())
+ , m_callback(callback)
+{
+}
+
+void NodeFilter::visit_edges(Cell::Visitor& visitor)
+{
+ Base::visit_edges(visitor);
+ visitor.visit(&m_callback);
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/DOM/NodeFilter.h b/Userland/Libraries/LibWeb/DOM/NodeFilter.h
index 189dd359ce..89b7aa1354 100644
--- a/Userland/Libraries/LibWeb/DOM/NodeFilter.h
+++ b/Userland/Libraries/LibWeb/DOM/NodeFilter.h
@@ -6,26 +6,22 @@
#pragma once
-#include <AK/RefCounted.h>
-#include <LibJS/Heap/Handle.h>
#include <LibWeb/Bindings/CallbackType.h>
-#include <LibWeb/Bindings/Wrappable.h>
+#include <LibWeb/Bindings/PlatformObject.h>
namespace Web::DOM {
-class NodeFilter
- : public RefCounted<NodeFilter>
- , public Bindings::Wrappable {
-public:
- using WrapperType = Bindings::NodeFilterWrapper;
+class NodeFilter final : public Bindings::PlatformObject {
+ JS_OBJECT(NodeFilter, Bindings::PlatformObject);
- explicit NodeFilter(Bindings::CallbackType callback)
- : m_callback(move(callback))
- {
- }
+public:
+ static JS::NonnullGCPtr<NodeFilter> create(JS::Realm&, Bindings::CallbackType&);
+ NodeFilter(JS::Realm&, Bindings::CallbackType&);
virtual ~NodeFilter() = default;
+ NodeFilter& impl() { return *this; }
+
Bindings::CallbackType& callback() { return m_callback; }
enum Result {
@@ -35,12 +31,14 @@ public:
};
private:
- Bindings::CallbackType m_callback;
+ virtual void visit_edges(Cell::Visitor&) override;
+
+ Bindings::CallbackType& m_callback;
};
inline JS::Object* wrap(JS::Realm&, Web::DOM::NodeFilter& filter)
{
- return filter.callback().callback.cell();
+ return &filter.callback().callback;
}
}
diff --git a/Userland/Libraries/LibWeb/DOM/NodeIterator.cpp b/Userland/Libraries/LibWeb/DOM/NodeIterator.cpp
index ebf01cf928..31611c9e1b 100644
--- a/Userland/Libraries/LibWeb/DOM/NodeIterator.cpp
+++ b/Userland/Libraries/LibWeb/DOM/NodeIterator.cpp
@@ -26,7 +26,7 @@ NodeIterator::~NodeIterator()
}
// https://dom.spec.whatwg.org/#dom-document-createnodeiterator
-NonnullRefPtr<NodeIterator> NodeIterator::create(Node& root, unsigned what_to_show, RefPtr<NodeFilter> filter)
+NonnullRefPtr<NodeIterator> NodeIterator::create(Node& root, unsigned what_to_show, NodeFilter* filter)
{
// 1. Let iterator be a new NodeIterator object.
// 2. Set iterator’s root and iterator’s reference to root.
@@ -37,7 +37,7 @@ NonnullRefPtr<NodeIterator> NodeIterator::create(Node& root, unsigned what_to_sh
iterator->m_what_to_show = what_to_show;
// 5. Set iterator’s filter to filter.
- iterator->m_filter = move(filter);
+ iterator->m_filter = JS::make_handle(filter);
// 6. Return iterator.
return iterator;
@@ -133,7 +133,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> NodeIterator::filter(Node& node)
return NodeFilter::FILTER_SKIP;
// 4. If traverser’s filter is null, then return FILTER_ACCEPT.
- if (!m_filter)
+ if (!m_filter.cell())
return NodeFilter::FILTER_ACCEPT;
// 5. Set traverser’s active flag.
diff --git a/Userland/Libraries/LibWeb/DOM/NodeIterator.h b/Userland/Libraries/LibWeb/DOM/NodeIterator.h
index 0423eaa64d..1c0123b8d0 100644
--- a/Userland/Libraries/LibWeb/DOM/NodeIterator.h
+++ b/Userland/Libraries/LibWeb/DOM/NodeIterator.h
@@ -21,14 +21,14 @@ public:
virtual ~NodeIterator() override;
- static NonnullRefPtr<NodeIterator> create(Node& root, unsigned what_to_show, RefPtr<NodeFilter>);
+ static NonnullRefPtr<NodeIterator> create(Node& root, unsigned what_to_show, NodeFilter*);
NonnullRefPtr<Node> root() { return m_root; }
NonnullRefPtr<Node> reference_node() { return m_reference.node; }
bool pointer_before_reference_node() const { return m_reference.is_before_node; }
unsigned what_to_show() const { return m_what_to_show; }
- NodeFilter* filter() { return m_filter; }
+ NodeFilter* filter() { return m_filter.cell(); }
JS::ThrowCompletionOr<RefPtr<Node>> next_node();
JS::ThrowCompletionOr<RefPtr<Node>> previous_node();
@@ -72,7 +72,7 @@ private:
unsigned m_what_to_show { 0 };
// https://dom.spec.whatwg.org/#concept-traversal-filter
- RefPtr<DOM::NodeFilter> m_filter;
+ JS::Handle<DOM::NodeFilter> m_filter;
// https://dom.spec.whatwg.org/#concept-traversal-active
bool m_active { false };
diff --git a/Userland/Libraries/LibWeb/DOM/TreeWalker.cpp b/Userland/Libraries/LibWeb/DOM/TreeWalker.cpp
index cbcaadd8b0..e63c2e67a5 100644
--- a/Userland/Libraries/LibWeb/DOM/TreeWalker.cpp
+++ b/Userland/Libraries/LibWeb/DOM/TreeWalker.cpp
@@ -23,7 +23,7 @@ TreeWalker::TreeWalker(Node& root)
}
// https://dom.spec.whatwg.org/#dom-document-createtreewalker
-NonnullRefPtr<TreeWalker> TreeWalker::create(Node& root, unsigned what_to_show, RefPtr<NodeFilter> filter)
+NonnullRefPtr<TreeWalker> TreeWalker::create(Node& root, unsigned what_to_show, NodeFilter* filter)
{
// 1. Let walker be a new TreeWalker object.
// 2. Set walker’s root and walker’s current to root.
@@ -33,7 +33,7 @@ NonnullRefPtr<TreeWalker> TreeWalker::create(Node& root, unsigned what_to_show,
walker->m_what_to_show = what_to_show;
// 4. Set walker’s filter to filter.
- walker->m_filter = move(filter);
+ walker->m_filter = JS::make_handle(filter);
// 5. Return walker.
return walker;
@@ -236,7 +236,7 @@ JS::ThrowCompletionOr<NodeFilter::Result> TreeWalker::filter(Node& node)
return NodeFilter::FILTER_SKIP;
// 4. If traverser’s filter is null, then return FILTER_ACCEPT.
- if (!m_filter)
+ if (!m_filter.cell())
return NodeFilter::FILTER_ACCEPT;
// 5. Set traverser’s active flag.
diff --git a/Userland/Libraries/LibWeb/DOM/TreeWalker.h b/Userland/Libraries/LibWeb/DOM/TreeWalker.h
index 2a132fbb8a..7c4c322dce 100644
--- a/Userland/Libraries/LibWeb/DOM/TreeWalker.h
+++ b/Userland/Libraries/LibWeb/DOM/TreeWalker.h
@@ -19,7 +19,7 @@ class TreeWalker
public:
using WrapperType = Bindings::TreeWalkerWrapper;
- static NonnullRefPtr<TreeWalker> create(Node& root, unsigned what_to_show, RefPtr<NodeFilter>);
+ static NonnullRefPtr<TreeWalker> create(Node& root, unsigned what_to_show, NodeFilter*);
virtual ~TreeWalker() override = default;
NonnullRefPtr<Node> current_node() const;
@@ -35,7 +35,7 @@ public:
NonnullRefPtr<Node> root() { return m_root; }
- NodeFilter* filter() { return m_filter; }
+ NodeFilter* filter() { return m_filter.cell(); }
unsigned what_to_show() const { return m_what_to_show; }
@@ -66,7 +66,7 @@ private:
unsigned m_what_to_show { 0 };
// https://dom.spec.whatwg.org/#concept-traversal-filter
- RefPtr<DOM::NodeFilter> m_filter;
+ JS::Handle<DOM::NodeFilter> m_filter;
// https://dom.spec.whatwg.org/#concept-traversal-active
bool m_active { false };
diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h
index ed97f604f2..4cfb1359e2 100644
--- a/Userland/Libraries/LibWeb/Forward.h
+++ b/Userland/Libraries/LibWeb/Forward.h
@@ -217,7 +217,7 @@ class DOMStringMap;
struct Environment;
struct EnvironmentSettingsObject;
class ErrorEvent;
-struct EventHandler;
+class EventHandler;
class EventLoop;
class HTMLAnchorElement;
class HTMLAreaElement;
@@ -451,7 +451,6 @@ class AbortControllerWrapper;
class AbortSignalWrapper;
class AttributeWrapper;
class BlobWrapper;
-struct CallbackType;
class CanvasGradientWrapper;
class CanvasRenderingContext2DWrapper;
class CDATASectionWrapper;
@@ -472,7 +471,6 @@ class DOMRectReadOnlyWrapper;
class DOMRectWrapper;
class ElementWrapper;
class ErrorEventWrapper;
-class EventListenerWrapper;
class EventTargetWrapper;
class EventWrapper;
class FileWrapper;
diff --git a/Userland/Libraries/LibWeb/HTML/EventHandler.cpp b/Userland/Libraries/LibWeb/HTML/EventHandler.cpp
new file mode 100644
index 0000000000..8e421c3e88
--- /dev/null
+++ b/Userland/Libraries/LibWeb/HTML/EventHandler.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/Bindings/WindowObject.h>
+#include <LibWeb/DOM/DOMEventListener.h>
+#include <LibWeb/HTML/EventHandler.h>
+
+namespace Web::HTML {
+
+EventHandler::EventHandler(String s)
+ : value(move(s))
+{
+}
+
+EventHandler::EventHandler(Bindings::CallbackType& c)
+ : value(&c)
+{
+}
+
+void EventHandler::visit_edges(Cell::Visitor& visitor)
+{
+ Cell::visit_edges(visitor);
+ visitor.visit(listener);
+
+ if (auto* callback = value.get_pointer<Bindings::CallbackType*>())
+ visitor.visit(*callback);
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/HTML/EventHandler.h b/Userland/Libraries/LibWeb/HTML/EventHandler.h
index 888c6b8bb8..a7be161c6e 100644
--- a/Userland/Libraries/LibWeb/HTML/EventHandler.h
+++ b/Userland/Libraries/LibWeb/HTML/EventHandler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -8,33 +8,29 @@
#include <AK/String.h>
#include <AK/Variant.h>
-#include <LibJS/Heap/Handle.h>
-#include <LibJS/Runtime/FunctionObject.h>
+#include <LibJS/Heap/Cell.h>
#include <LibWeb/Bindings/CallbackType.h>
-#include <LibWeb/DOM/DOMEventListener.h>
namespace Web::HTML {
-struct EventHandler {
- EventHandler(String s)
- : value(move(s))
- {
- }
-
- EventHandler(Bindings::CallbackType c)
- : value(move(c))
- {
- }
+class EventHandler final : public JS::Cell {
+public:
+ explicit EventHandler(String);
+ explicit EventHandler(Bindings::CallbackType&);
// Either uncompiled source code or a callback.
// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-value
// NOTE: This does not contain Empty as part of the optimization of not allocating all event handler attributes up front.
// FIXME: The string should actually be an "internal raw uncompiled handler" struct. This struct is just the uncompiled source code plus a source location for reporting parse errors.
// https://html.spec.whatwg.org/multipage/webappapis.html#internal-raw-uncompiled-handler
- Variant<String, Bindings::CallbackType> value;
+ Variant<String, Bindings::CallbackType*> value;
// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-listener
- RefPtr<DOM::DOMEventListener> listener;
+ DOM::DOMEventListener* listener { nullptr };
+
+private:
+ virtual StringView class_name() const override { return "EventHandler"sv; }
+ virtual void visit_edges(Cell::Visitor&) override;
};
}
diff --git a/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.cpp b/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.cpp
index fb39485202..76eb8c2edb 100644
--- a/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.cpp
+++ b/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.cpp
@@ -12,14 +12,14 @@
namespace Web::HTML {
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void GlobalEventHandlers::set_##attribute_name(Optional<Bindings::CallbackType> value) \
- { \
- global_event_handlers_to_event_target(event_name).set_event_handler_attribute(event_name, move(value)); \
- } \
- Bindings::CallbackType* GlobalEventHandlers::attribute_name() \
- { \
- return global_event_handlers_to_event_target(event_name).event_handler_attribute(event_name); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void GlobalEventHandlers::set_##attribute_name(Bindings::CallbackType* value) \
+ { \
+ global_event_handlers_to_event_target(event_name).set_event_handler_attribute(event_name, value); \
+ } \
+ Bindings::CallbackType* GlobalEventHandlers::attribute_name() \
+ { \
+ return global_event_handlers_to_event_target(event_name).event_handler_attribute(event_name); \
}
ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.h b/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.h
index facdc97a23..11c99dddee 100644
--- a/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.h
+++ b/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.h
@@ -84,8 +84,8 @@ public:
virtual ~GlobalEventHandlers();
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void set_##attribute_name(Optional<Bindings::CallbackType>); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void set_##attribute_name(Bindings::CallbackType*); \
Bindings::CallbackType* attribute_name();
ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/HTML/MessagePort.cpp b/Userland/Libraries/LibWeb/HTML/MessagePort.cpp
index cbbc0e230d..52e527ec0f 100644
--- a/Userland/Libraries/LibWeb/HTML/MessagePort.cpp
+++ b/Userland/Libraries/LibWeb/HTML/MessagePort.cpp
@@ -106,14 +106,14 @@ void MessagePort::close()
}
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void MessagePort::set_##attribute_name(Optional<Bindings::CallbackType> value) \
- { \
- set_event_handler_attribute(event_name, move(value)); \
- } \
- Bindings::CallbackType* MessagePort::attribute_name() \
- { \
- return event_handler_attribute(event_name); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void MessagePort::set_##attribute_name(Bindings::CallbackType* value) \
+ { \
+ set_event_handler_attribute(event_name, value); \
+ } \
+ Bindings::CallbackType* MessagePort::attribute_name() \
+ { \
+ return event_handler_attribute(event_name); \
}
ENUMERATE_MESSAGE_PORT_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/HTML/MessagePort.h b/Userland/Libraries/LibWeb/HTML/MessagePort.h
index d2b5a476fb..3cebac0aa2 100644
--- a/Userland/Libraries/LibWeb/HTML/MessagePort.h
+++ b/Userland/Libraries/LibWeb/HTML/MessagePort.h
@@ -53,8 +53,8 @@ public:
void close();
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void set_##attribute_name(Optional<Bindings::CallbackType>); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void set_##attribute_name(Bindings::CallbackType*); \
Bindings::CallbackType* attribute_name();
ENUMERATE_MESSAGE_PORT_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp
index 2916345848..0e2d5c5fc5 100644
--- a/Userland/Libraries/LibWeb/HTML/Window.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Window.cpp
@@ -173,8 +173,8 @@ i32 Window::run_timer_initialization_steps(Bindings::TimerHandler handler, i32 t
handler.visit(
// 2. If handler is a Function, then invoke handler given arguments with the callback this value set to thisArg. If this throws an exception, catch it, and report the exception.
- [&](Bindings::CallbackType& callback) {
- if (auto result = Bindings::IDL::invoke_callback(callback, window->wrapper(), arguments); result.is_error())
+ [&](JS::Handle<Bindings::CallbackType> callback) {
+ if (auto result = Bindings::IDL::invoke_callback(*callback, window->wrapper(), arguments); result.is_error())
HTML::report_exception(result);
},
// 3. Otherwise:
@@ -237,9 +237,9 @@ i32 Window::run_timer_initialization_steps(Bindings::TimerHandler handler, i32 t
}
// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#run-the-animation-frame-callbacks
-i32 Window::request_animation_frame(NonnullOwnPtr<Bindings::CallbackType> js_callback)
+i32 Window::request_animation_frame(Bindings::CallbackType& js_callback)
{
- return m_animation_frame_callback_driver.add([this, js_callback = move(js_callback)](auto) mutable {
+ return m_animation_frame_callback_driver.add([this, js_callback = JS::make_handle(js_callback)](auto) mutable {
// 3. Invoke callback, passing now as the only argument,
auto result = Bindings::IDL::invoke_callback(*js_callback, {}, JS::Value(performance().now()));
@@ -471,10 +471,10 @@ void Window::fire_a_page_transition_event(FlyString const& event_name, bool pers
}
// https://html.spec.whatwg.org/#dom-queuemicrotask
-void Window::queue_microtask(NonnullOwnPtr<Bindings::CallbackType> callback)
+void Window::queue_microtask(Bindings::CallbackType& callback)
{
// The queueMicrotask(callback) method must queue a microtask to invoke callback,
- HTML::queue_a_microtask(&associated_document(), [callback = move(callback)]() mutable {
+ HTML::queue_a_microtask(&associated_document(), [callback = JS::make_handle(callback)]() mutable {
auto result = Bindings::IDL::invoke_callback(*callback, {});
// and if callback throws an exception, report the exception.
if (result.is_error())
@@ -643,7 +643,7 @@ void Window::invoke_idle_callbacks()
}
// https://w3c.github.io/requestidlecallback/#the-requestidlecallback-method
-u32 Window::request_idle_callback(NonnullOwnPtr<Bindings::CallbackType> callback)
+u32 Window::request_idle_callback(Bindings::CallbackType& callback)
{
// 1. Let window be this Window object.
auto& window = *this;
@@ -652,8 +652,8 @@ u32 Window::request_idle_callback(NonnullOwnPtr<Bindings::CallbackType> callback
// 3. Let handle be the current value of window's idle callback identifier.
auto handle = window.m_idle_callback_identifier;
// 4. Push callback to the end of window's list of idle request callbacks, associated with handle.
- auto handler = [callback = move(callback)](NonnullRefPtr<RequestIdleCallback::IdleDeadline> deadline) -> JS::Completion {
- auto& realm = callback->callback.cell()->shape().realm();
+ auto handler = [callback = JS::make_handle(callback)](NonnullRefPtr<RequestIdleCallback::IdleDeadline> deadline) -> JS::Completion {
+ auto& realm = callback->callback.shape().realm();
auto* wrapped_deadline = Bindings::wrap(realm, *deadline);
return Bindings::IDL::invoke_callback(const_cast<Bindings::CallbackType&>(*callback), {}, JS::Value(wrapped_deadline));
};
diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h
index be5b9793ed..e3d8c467e7 100644
--- a/Userland/Libraries/LibWeb/HTML/Window.h
+++ b/Userland/Libraries/LibWeb/HTML/Window.h
@@ -61,7 +61,7 @@ public:
void alert(String const&);
bool confirm(String const&);
String prompt(String const&, String const&);
- i32 request_animation_frame(NonnullOwnPtr<Bindings::CallbackType> js_callback);
+ i32 request_animation_frame(Bindings::CallbackType& js_callback);
void cancel_animation_frame(i32);
bool has_animation_frame_callbacks() const { return m_animation_frame_callback_driver.has_callbacks(); }
@@ -70,7 +70,7 @@ public:
void clear_timeout(i32);
void clear_interval(i32);
- void queue_microtask(NonnullOwnPtr<Bindings::CallbackType> callback);
+ void queue_microtask(Bindings::CallbackType& callback);
int inner_width() const;
int inner_height() const;
@@ -123,7 +123,7 @@ public:
void start_an_idle_period();
- u32 request_idle_callback(NonnullOwnPtr<Bindings::CallbackType> callback);
+ u32 request_idle_callback(Bindings::CallbackType& callback);
void cancel_idle_callback(u32);
AnimationFrameCallbackDriver& animation_frame_callback_driver() { return m_animation_frame_callback_driver; }
diff --git a/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.cpp b/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.cpp
index bd99461a9d..b33318e45d 100644
--- a/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.cpp
+++ b/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.cpp
@@ -11,14 +11,14 @@
namespace Web::HTML {
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void WindowEventHandlers::set_##attribute_name(Optional<Bindings::CallbackType> value) \
- { \
- window_event_handlers_to_event_target().set_event_handler_attribute(event_name, move(value)); \
- } \
- Bindings::CallbackType* WindowEventHandlers::attribute_name() \
- { \
- return window_event_handlers_to_event_target().event_handler_attribute(event_name); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void WindowEventHandlers::set_##attribute_name(Bindings::CallbackType* value) \
+ { \
+ window_event_handlers_to_event_target().set_event_handler_attribute(event_name, value); \
+ } \
+ Bindings::CallbackType* WindowEventHandlers::attribute_name() \
+ { \
+ return window_event_handlers_to_event_target().event_handler_attribute(event_name); \
}
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.h b/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.h
index 9c9291dc88..a6d0009b7a 100644
--- a/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.h
+++ b/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.h
@@ -34,8 +34,8 @@ public:
virtual ~WindowEventHandlers();
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void set_##attribute_name(Optional<Bindings::CallbackType>); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void set_##attribute_name(Bindings::CallbackType*); \
Bindings::CallbackType* attribute_name();
ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/HTML/Worker.cpp b/Userland/Libraries/LibWeb/HTML/Worker.cpp
index b84aba47cf..0dc8b821be 100644
--- a/Userland/Libraries/LibWeb/HTML/Worker.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Worker.cpp
@@ -324,14 +324,14 @@ JS::Object* Worker::create_wrapper(JS::Realm& realm)
}
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void Worker::set_##attribute_name(Optional<Bindings::CallbackType> value) \
- { \
- set_event_handler_attribute(event_name, move(value)); \
- } \
- Bindings::CallbackType* Worker::attribute_name() \
- { \
- return event_handler_attribute(event_name); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void Worker::set_##attribute_name(Bindings::CallbackType* value) \
+ { \
+ set_event_handler_attribute(event_name, move(value)); \
+ } \
+ Bindings::CallbackType* Worker::attribute_name() \
+ { \
+ return event_handler_attribute(event_name); \
}
ENUMERATE_WORKER_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/HTML/Worker.h b/Userland/Libraries/LibWeb/HTML/Worker.h
index 0b7be28446..eb7a56bf3f 100644
--- a/Userland/Libraries/LibWeb/HTML/Worker.h
+++ b/Userland/Libraries/LibWeb/HTML/Worker.h
@@ -64,8 +64,8 @@ public:
RefPtr<MessagePort> outside_message_port() { return m_outside_port; }
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void set_##attribute_name(Optional<Bindings::CallbackType>); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void set_##attribute_name(Bindings::CallbackType*); \
Bindings::CallbackType* attribute_name();
ENUMERATE_WORKER_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp
index 1515d32640..0da867be35 100644
--- a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp
+++ b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp
@@ -75,14 +75,14 @@ NonnullRefPtr<WorkerNavigator const> WorkerGlobalScope::navigator() const
}
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void WorkerGlobalScope::set_##attribute_name(Optional<Bindings::CallbackType> value) \
- { \
- set_event_handler_attribute(event_name, move(value)); \
- } \
- Bindings::CallbackType* WorkerGlobalScope::attribute_name() \
- { \
- return event_handler_attribute(event_name); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void WorkerGlobalScope::set_##attribute_name(Bindings::CallbackType* value) \
+ { \
+ set_event_handler_attribute(event_name, move(value)); \
+ } \
+ Bindings::CallbackType* WorkerGlobalScope::attribute_name() \
+ { \
+ return event_handler_attribute(event_name); \
}
ENUMERATE_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h
index 29802976f1..d92358e0d1 100644
--- a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h
+++ b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h
@@ -57,8 +57,8 @@ public:
DOM::ExceptionOr<void> import_scripts(Vector<String> urls);
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void set_##attribute_name(Optional<Bindings::CallbackType>); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void set_##attribute_name(Bindings::CallbackType*); \
Bindings::CallbackType* attribute_name();
ENUMERATE_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.cpp b/Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.cpp
index bd21e60034..25e37455e0 100644
--- a/Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.cpp
+++ b/Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.cpp
@@ -10,7 +10,7 @@
namespace Web::IntersectionObserver {
// https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-intersectionobserver
-NonnullRefPtr<IntersectionObserver> IntersectionObserver::create_with_global_object(JS::GlobalObject& global_object, Bindings::CallbackType const& callback, IntersectionObserverInit const& options)
+NonnullRefPtr<IntersectionObserver> IntersectionObserver::create_with_global_object(JS::GlobalObject& global_object, Bindings::CallbackType* callback, IntersectionObserverInit const& options)
{
// FIXME: Implement
(void)global_object;
diff --git a/Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.h b/Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.h
index 9039205418..d18594f1a4 100644
--- a/Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.h
+++ b/Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.h
@@ -25,7 +25,7 @@ class IntersectionObserver
public:
using WrapperType = Bindings::IntersectionObserverWrapper;
- static NonnullRefPtr<IntersectionObserver> create_with_global_object(JS::GlobalObject&, Bindings::CallbackType const& callback, IntersectionObserverInit const& options = {});
+ static NonnullRefPtr<IntersectionObserver> create_with_global_object(JS::GlobalObject&, Bindings::CallbackType* callback, IntersectionObserverInit const& options = {});
void observe(DOM::Element& target);
void unobserve(DOM::Element& target);
diff --git a/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.cpp b/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.cpp
index ace98e0743..32e7cf5afd 100644
--- a/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.cpp
+++ b/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.cpp
@@ -10,7 +10,7 @@
namespace Web::ResizeObserver {
// https://drafts.csswg.org/resize-observer/#dom-resizeobserver-resizeobserver
-NonnullRefPtr<ResizeObserver> ResizeObserver::create_with_global_object(JS::GlobalObject& global_object, Bindings::CallbackType const& callback)
+NonnullRefPtr<ResizeObserver> ResizeObserver::create_with_global_object(JS::GlobalObject& global_object, Bindings::CallbackType* callback)
{
// FIXME: Implement
(void)global_object;
diff --git a/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.h b/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.h
index 409fe9be9d..d7675dc347 100644
--- a/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.h
+++ b/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserver.h
@@ -24,7 +24,7 @@ class ResizeObserver
public:
using WrapperType = Bindings::ResizeObserverWrapper;
- static NonnullRefPtr<ResizeObserver> create_with_global_object(JS::GlobalObject&, Bindings::CallbackType const& callback);
+ static NonnullRefPtr<ResizeObserver> create_with_global_object(JS::GlobalObject&, Bindings::CallbackType* callback);
void observe(DOM::Element& target, ResizeObserverOptions);
void unobserve(DOM::Element& target);
diff --git a/Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp b/Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp
index ca1197f25e..07be6b1499 100644
--- a/Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp
+++ b/Userland/Libraries/LibWeb/WebSockets/WebSocket.cpp
@@ -232,14 +232,14 @@ JS::Object* WebSocket::create_wrapper(JS::Realm& realm)
}
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void WebSocket::set_##attribute_name(Optional<Bindings::CallbackType> value) \
- { \
- set_event_handler_attribute(event_name, move(value)); \
- } \
- Bindings::CallbackType* WebSocket::attribute_name() \
- { \
- return event_handler_attribute(event_name); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void WebSocket::set_##attribute_name(Bindings::CallbackType* value) \
+ { \
+ set_event_handler_attribute(event_name, value); \
+ } \
+ Bindings::CallbackType* WebSocket::attribute_name() \
+ { \
+ return event_handler_attribute(event_name); \
}
ENUMERATE_WEBSOCKET_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/WebSockets/WebSocket.h b/Userland/Libraries/LibWeb/WebSockets/WebSocket.h
index c12662ca72..f082d28424 100644
--- a/Userland/Libraries/LibWeb/WebSockets/WebSocket.h
+++ b/Userland/Libraries/LibWeb/WebSockets/WebSocket.h
@@ -58,8 +58,8 @@ public:
String url() const { return m_url.to_string(); }
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void set_##attribute_name(Optional<Bindings::CallbackType>); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void set_##attribute_name(Bindings::CallbackType*); \
Bindings::CallbackType* attribute_name();
ENUMERATE_WEBSOCKET_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp
index 260eab4e84..a1d1868a35 100644
--- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp
+++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp
@@ -577,9 +577,9 @@ Bindings::CallbackType* XMLHttpRequest::onreadystatechange()
return event_handler_attribute(Web::XHR::EventNames::readystatechange);
}
-void XMLHttpRequest::set_onreadystatechange(Optional<Bindings::CallbackType> value)
+void XMLHttpRequest::set_onreadystatechange(Bindings::CallbackType* value)
{
- set_event_handler_attribute(Web::XHR::EventNames::readystatechange, move(value));
+ set_event_handler_attribute(Web::XHR::EventNames::readystatechange, value);
}
// https://xhr.spec.whatwg.org/#the-getallresponseheaders()-method
diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h
index c2894d6743..bba94589bf 100644
--- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h
+++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h
@@ -72,7 +72,7 @@ public:
String get_all_response_headers() const;
Bindings::CallbackType* onreadystatechange();
- void set_onreadystatechange(Optional<Bindings::CallbackType>);
+ void set_onreadystatechange(Bindings::CallbackType*);
DOM::ExceptionOr<void> override_mime_type(String const& mime);
diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.cpp b/Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.cpp
index ee2114d7b9..afedb06cc5 100644
--- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.cpp
+++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.cpp
@@ -11,14 +11,14 @@
namespace Web::XHR {
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void XMLHttpRequestEventTarget::set_##attribute_name(Optional<Bindings::CallbackType> value) \
- { \
- set_event_handler_attribute(event_name, move(value)); \
- } \
- Bindings::CallbackType* XMLHttpRequestEventTarget::attribute_name() \
- { \
- return event_handler_attribute(event_name); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void XMLHttpRequestEventTarget::set_##attribute_name(Bindings::CallbackType* value) \
+ { \
+ set_event_handler_attribute(event_name, value); \
+ } \
+ Bindings::CallbackType* XMLHttpRequestEventTarget::attribute_name() \
+ { \
+ return event_handler_attribute(event_name); \
}
ENUMERATE_XML_HTTP_REQUEST_EVENT_TARGET_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.h b/Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.h
index 5858299305..5307dd558d 100644
--- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.h
+++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequestEventTarget.h
@@ -30,8 +30,8 @@ public:
virtual ~XMLHttpRequestEventTarget() override {};
#undef __ENUMERATE
-#define __ENUMERATE(attribute_name, event_name) \
- void set_##attribute_name(Optional<Bindings::CallbackType>); \
+#define __ENUMERATE(attribute_name, event_name) \
+ void set_##attribute_name(Bindings::CallbackType*); \
Bindings::CallbackType* attribute_name();
ENUMERATE_XML_HTTP_REQUEST_EVENT_TARGET_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE