mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-29 16:21:29 +00:00
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.
This commit is contained in:
parent
fd83918476
commit
0639e77898
Notes:
sideshowbarker
2024-07-18 23:07:27 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/0639e778986
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,6 @@
|
|||
|
||||
namespace Web::Bindings {
|
||||
|
||||
EventTargetWrapper* wrap(JS::GlobalObject&, DOM::EventTarget&);
|
||||
JS::Object* wrap(JS::GlobalObject&, DOM::EventTarget&);
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue