summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-01-18 12:15:02 +0100
committerAndreas Kling <kling@serenityos.org>2021-01-18 12:18:29 +0100
commit0639e778986877ef0a6883eb9011ad8b4f56b642 (patch)
tree32afd1a67fa823a59d25e4181c3503471b63c8f6 /Userland/Libraries/LibWeb
parentfd83918476dd4d91a07df44c831275f0b5cdd7e9 (diff)
downloadserenity-0639e778986877ef0a6883eb9011ad8b4f56b642.zip
LibWeb: Make the Window object "inherit" from EventTarget :^)
Since Web::Bindings::WindowObject inherits from JS::GlobalObject, it cannot also inherit from Web::Bindings::EventTargetWrapper. However, that's not actually necessary. Instead, we simply set the Window object's prototype to the EventTargetPrototype, and add a little extra branch in the impl_from() function that turns the JS "this" value into a DOM::EventTarget*. With this, you can now call window.addEventListener()! Very cool :^) Fixes #4758.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.h2
-rw-r--r--Userland/Libraries/LibWeb/Bindings/WindowObject.cpp2
-rw-r--r--Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp14
-rw-r--r--Userland/Libraries/LibWeb/DOM/EventTarget.h2
-rw-r--r--Userland/Libraries/LibWeb/DOM/Node.cpp2
-rw-r--r--Userland/Libraries/LibWeb/DOM/Node.h2
-rw-r--r--Userland/Libraries/LibWeb/DOM/Window.cpp4
-rw-r--r--Userland/Libraries/LibWeb/DOM/Window.h2
-rw-r--r--Userland/Libraries/LibWeb/DOM/XMLHttpRequest.cpp2
-rw-r--r--Userland/Libraries/LibWeb/DOM/XMLHttpRequest.h2
-rw-r--r--Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp2
-rw-r--r--Userland/Libraries/LibWeb/HighResolutionTime/Performance.h2
13 files changed, 26 insertions, 14 deletions
diff --git a/Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.cpp b/Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.cpp
index 4a6e6344e9..a7152b522c 100644
--- a/Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.cpp
+++ b/Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.cpp
@@ -29,7 +29,7 @@
namespace Web::Bindings {
-EventTargetWrapper* wrap(JS::GlobalObject& global_object, DOM::EventTarget& target)
+JS::Object* wrap(JS::GlobalObject& global_object, DOM::EventTarget& target)
{
return target.create_wrapper(global_object);
}
diff --git a/Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.h b/Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.h
index c28c7724ca..193c2d812d 100644
--- a/Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.h
+++ b/Userland/Libraries/LibWeb/Bindings/EventTargetWrapperFactory.h
@@ -31,6 +31,6 @@
namespace Web::Bindings {
-EventTargetWrapper* wrap(JS::GlobalObject&, DOM::EventTarget&);
+JS::Object* wrap(JS::GlobalObject&, DOM::EventTarget&);
}
diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp
index b4e27233dc..072b494370 100644
--- a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp
+++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp
@@ -67,6 +67,8 @@ void WindowObject::initialize()
{
GlobalObject::initialize();
+ set_prototype(&ensure_web_prototype<EventTargetPrototype>("EventTarget"));
+
define_property("window", this, JS::Attribute::Enumerable);
define_property("frames", this, JS::Attribute::Enumerable);
define_property("self", this, JS::Attribute::Enumerable);
diff --git a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp
index d008fc41ad..7578776aec 100644
--- a/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp
+++ b/Userland/Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp
@@ -840,6 +840,7 @@ void generate_prototype_implementation(const IDL::Interface& interface)
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/DOM/Element.h>
#include <LibWeb/DOM/EventListener.h>
+#include <LibWeb/DOM/Window.h>
#include <LibWeb/HTML/HTMLElement.h>
#include <LibWeb/Origin.h>
@@ -927,9 +928,18 @@ static @fully_qualified_name@* impl_from(JS::VM& vm, JS::GlobalObject& global_ob
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
+)~~~");
+
+ if (interface.name == "EventTarget") {
+ generator.append(R"~~~(
+ if (is<WindowObject>(this_object)) {
+ return &static_cast<WindowObject*>(this_object)->impl();
+ }
+)~~~");
+ }
+
+ generator.append(R"~~~(
if (!is<@wrapper_class@>(this_object)) {
- dbgln("expected @wrapper_class@ but got {}", this_object->class_name());
- ASSERT_NOT_REACHED();
vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "@fully_qualified_name@");
return nullptr;
}
diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.h b/Userland/Libraries/LibWeb/DOM/EventTarget.h
index 32399a6a7a..f03d4a4fb2 100644
--- a/Userland/Libraries/LibWeb/DOM/EventTarget.h
+++ b/Userland/Libraries/LibWeb/DOM/EventTarget.h
@@ -51,7 +51,7 @@ public:
void remove_from_event_listener_list(NonnullRefPtr<EventListener>);
virtual bool dispatch_event(NonnullRefPtr<Event>) = 0;
- virtual Bindings::EventTargetWrapper* create_wrapper(JS::GlobalObject&) = 0;
+ virtual JS::Object* create_wrapper(JS::GlobalObject&) = 0;
Bindings::ScriptExecutionContext* script_execution_context() { return m_script_execution_context; }
virtual EventTarget* get_parent(const Event&) { return nullptr; }
diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp
index 6890e4fda5..9bfe3aecca 100644
--- a/Userland/Libraries/LibWeb/DOM/Node.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Node.cpp
@@ -213,7 +213,7 @@ bool Node::is_editable() const
return parent() && parent()->is_editable();
}
-Bindings::EventTargetWrapper* Node::create_wrapper(JS::GlobalObject& global_object)
+JS::Object* Node::create_wrapper(JS::GlobalObject& global_object)
{
return wrap(global_object, *this);
}
diff --git a/Userland/Libraries/LibWeb/DOM/Node.h b/Userland/Libraries/LibWeb/DOM/Node.h
index d3eaab1b8b..d29f0a471f 100644
--- a/Userland/Libraries/LibWeb/DOM/Node.h
+++ b/Userland/Libraries/LibWeb/DOM/Node.h
@@ -61,7 +61,7 @@ public:
virtual void ref_event_target() final { ref(); }
virtual void unref_event_target() final { unref(); }
virtual bool dispatch_event(NonnullRefPtr<Event>) final;
- virtual Bindings::EventTargetWrapper* create_wrapper(JS::GlobalObject&) override;
+ virtual JS::Object* create_wrapper(JS::GlobalObject&) override;
virtual ~Node();
diff --git a/Userland/Libraries/LibWeb/DOM/Window.cpp b/Userland/Libraries/LibWeb/DOM/Window.cpp
index d10620bc1e..648d083696 100644
--- a/Userland/Libraries/LibWeb/DOM/Window.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Window.cpp
@@ -169,9 +169,9 @@ bool Window::dispatch_event(NonnullRefPtr<Event> event)
return EventDispatcher::dispatch(*this, event, true);
}
-Bindings::EventTargetWrapper* Window::create_wrapper(JS::GlobalObject&)
+JS::Object* Window::create_wrapper(JS::GlobalObject& global_object)
{
- ASSERT_NOT_REACHED();
+ return &global_object;
}
}
diff --git a/Userland/Libraries/LibWeb/DOM/Window.h b/Userland/Libraries/LibWeb/DOM/Window.h
index 4118bebbe2..725da546d7 100644
--- a/Userland/Libraries/LibWeb/DOM/Window.h
+++ b/Userland/Libraries/LibWeb/DOM/Window.h
@@ -50,7 +50,7 @@ public:
virtual void ref_event_target() override { RefCounted::ref(); }
virtual void unref_event_target() override { RefCounted::unref(); }
virtual bool dispatch_event(NonnullRefPtr<Event>) override;
- virtual Bindings::EventTargetWrapper* create_wrapper(JS::GlobalObject&) override;
+ virtual JS::Object* create_wrapper(JS::GlobalObject&) override;
const Document& document() const { return m_document; }
Document& document() { return m_document; }
diff --git a/Userland/Libraries/LibWeb/DOM/XMLHttpRequest.cpp b/Userland/Libraries/LibWeb/DOM/XMLHttpRequest.cpp
index e763a2f337..a6485d33f4 100644
--- a/Userland/Libraries/LibWeb/DOM/XMLHttpRequest.cpp
+++ b/Userland/Libraries/LibWeb/DOM/XMLHttpRequest.cpp
@@ -113,7 +113,7 @@ bool XMLHttpRequest::dispatch_event(NonnullRefPtr<DOM::Event> event)
return DOM::EventDispatcher::dispatch(*this, move(event));
}
-Bindings::EventTargetWrapper* XMLHttpRequest::create_wrapper(JS::GlobalObject& global_object)
+JS::Object* XMLHttpRequest::create_wrapper(JS::GlobalObject& global_object)
{
return wrap(global_object, *this);
}
diff --git a/Userland/Libraries/LibWeb/DOM/XMLHttpRequest.h b/Userland/Libraries/LibWeb/DOM/XMLHttpRequest.h
index 33a6038863..2bb7b73e28 100644
--- a/Userland/Libraries/LibWeb/DOM/XMLHttpRequest.h
+++ b/Userland/Libraries/LibWeb/DOM/XMLHttpRequest.h
@@ -66,7 +66,7 @@ private:
virtual void ref_event_target() override { ref(); }
virtual void unref_event_target() override { unref(); }
virtual bool dispatch_event(NonnullRefPtr<DOM::Event>) override;
- virtual Bindings::EventTargetWrapper* create_wrapper(JS::GlobalObject&) override;
+ virtual JS::Object* create_wrapper(JS::GlobalObject&) override;
void set_ready_state(ReadyState);
diff --git a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp
index cdefa63eff..1de64d81fb 100644
--- a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp
+++ b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp
@@ -65,7 +65,7 @@ bool Performance::dispatch_event(NonnullRefPtr<DOM::Event> event)
return DOM::EventDispatcher::dispatch(*this, event);
}
-Bindings::EventTargetWrapper* Performance::create_wrapper(JS::GlobalObject& global_object)
+JS::Object* Performance::create_wrapper(JS::GlobalObject& global_object)
{
return Bindings::wrap(global_object, *this);
}
diff --git a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h
index d5a9effbf5..7848beedcc 100644
--- a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h
+++ b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h
@@ -50,7 +50,7 @@ public:
virtual void unref_event_target() override;
virtual bool dispatch_event(NonnullRefPtr<DOM::Event>) override;
- virtual Bindings::EventTargetWrapper* create_wrapper(JS::GlobalObject&) override;
+ virtual JS::Object* create_wrapper(JS::GlobalObject&) override;
private:
DOM::Window& m_window;