1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 17:17:45 +00:00

LibWeb+LibJS: Make the EventTarget hierarchy (incl. DOM) GC-allocated

This is a monster patch that turns all EventTargets into GC-allocated
PlatformObjects. Their C++ wrapper classes are removed, and the LibJS
garbage collector is now responsible for their lifetimes.

There's a fair amount of hacks and band-aids in this patch, and we'll
have a lot of cleanup to do after this.
This commit is contained in:
Andreas Kling 2022-08-28 13:42:07 +02:00
parent bb547ce1c4
commit 6f433c8656
445 changed files with 4797 additions and 4268 deletions

View file

@ -5,17 +5,17 @@
*/
#include <LibWeb/Bindings/FocusEventPrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/UIEvents/FocusEvent.h>
namespace Web::UIEvents {
FocusEvent* FocusEvent::create_with_global_object(Bindings::WindowObject& window_object, FlyString const& event_name, FocusEventInit const& event_init)
FocusEvent* FocusEvent::create_with_global_object(HTML::Window& window_object, FlyString const& event_name, FocusEventInit const& event_init)
{
return window_object.heap().allocate<FocusEvent>(window_object.realm(), window_object, event_name, event_init);
}
FocusEvent::FocusEvent(Bindings::WindowObject& window_object, FlyString const& event_name, FocusEventInit const& event_init)
FocusEvent::FocusEvent(HTML::Window& window_object, FlyString const& event_name, FocusEventInit const& event_init)
: UIEvent(window_object, event_name)
{
set_prototype(&window_object.ensure_web_prototype<Bindings::FocusEventPrototype>("FocusEvent"));

View file

@ -11,19 +11,17 @@
namespace Web::UIEvents {
struct FocusEventInit : public UIEventInit {
RefPtr<DOM::EventTarget> related_target;
JS::GCPtr<DOM::EventTarget> related_target;
};
class FocusEvent final : public UIEvent {
JS_OBJECT(FocusEvent, UIEvent);
WEB_PLATFORM_OBJECT(FocusEvent, UIEvent);
public:
static FocusEvent* create_with_global_object(Bindings::WindowObject&, FlyString const& event_name, FocusEventInit const& event_init);
static FocusEvent* create_with_global_object(HTML::Window&, FlyString const& event_name, FocusEventInit const& event_init);
FocusEvent(Bindings::WindowObject&, FlyString const& event_name, FocusEventInit const&);
FocusEvent(HTML::Window&, FlyString const& event_name, FocusEventInit const&);
virtual ~FocusEvent() override;
FocusEvent& impl() { return *this; }
};
}

View file

@ -6,7 +6,7 @@
#include <AK/CharacterTypes.h>
#include <LibWeb/Bindings/KeyboardEventPrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/UIEvents/KeyboardEvent.h>
namespace Web::UIEvents {
@ -67,7 +67,7 @@ static unsigned long determine_key_code(KeyCode platform_key, u32 code_point)
return platform_key;
}
KeyboardEvent* KeyboardEvent::create_from_platform_event(Bindings::WindowObject& window_object, FlyString const& event_name, KeyCode platform_key, unsigned modifiers, u32 code_point)
KeyboardEvent* KeyboardEvent::create_from_platform_event(HTML::Window& window_object, FlyString const& event_name, KeyCode platform_key, unsigned modifiers, u32 code_point)
{
// FIXME: Figure out what these should actually contain.
String event_key = key_code_to_string(platform_key);
@ -105,17 +105,17 @@ bool KeyboardEvent::get_modifier_state(String const& key_arg)
return false;
}
KeyboardEvent* KeyboardEvent::create(Bindings::WindowObject& window_object, FlyString const& event_name, KeyboardEventInit const& event_init)
KeyboardEvent* KeyboardEvent::create(HTML::Window& window_object, FlyString const& event_name, KeyboardEventInit const& event_init)
{
return window_object.heap().allocate<KeyboardEvent>(window_object.realm(), window_object, event_name, event_init);
}
KeyboardEvent* KeyboardEvent::create_with_global_object(Bindings::WindowObject& window_object, FlyString const& event_name, KeyboardEventInit const& event_init)
KeyboardEvent* KeyboardEvent::create_with_global_object(HTML::Window& window_object, FlyString const& event_name, KeyboardEventInit const& event_init)
{
return create(window_object, event_name, event_init);
}
KeyboardEvent::KeyboardEvent(Bindings::WindowObject& window_object, FlyString const& event_name, KeyboardEventInit const& event_init)
KeyboardEvent::KeyboardEvent(HTML::Window& window_object, FlyString const& event_name, KeyboardEventInit const& event_init)
: UIEvent(window_object, event_name, event_init)
, m_key(event_init.key)
, m_code(event_init.code)

View file

@ -25,19 +25,17 @@ struct KeyboardEventInit : public EventModifierInit {
// https://www.w3.org/TR/uievents/#interface-keyboardevent
class KeyboardEvent final : public UIEvent {
JS_OBJECT(KeyboardEvent, UIEvent);
WEB_PLATFORM_OBJECT(KeyboardEvent, UIEvent);
public:
static KeyboardEvent* create(Bindings::WindowObject&, FlyString const& event_name, KeyboardEventInit const& event_init = {});
static KeyboardEvent* create_with_global_object(Bindings::WindowObject&, FlyString const& event_name, KeyboardEventInit const& event_init);
static KeyboardEvent* create_from_platform_event(Bindings::WindowObject&, FlyString const& event_name, KeyCode, unsigned modifiers, u32 code_point);
static KeyboardEvent* create(HTML::Window&, FlyString const& event_name, KeyboardEventInit const& event_init = {});
static KeyboardEvent* create_with_global_object(HTML::Window&, FlyString const& event_name, KeyboardEventInit const& event_init);
static KeyboardEvent* create_from_platform_event(HTML::Window&, FlyString const& event_name, KeyCode, unsigned modifiers, u32 code_point);
KeyboardEvent(Bindings::WindowObject&, FlyString const& event_name, KeyboardEventInit const& event_init);
KeyboardEvent(HTML::Window&, FlyString const& event_name, KeyboardEventInit const& event_init);
virtual ~KeyboardEvent() override;
KeyboardEvent& impl() { return *this; }
u32 key_code() const { return m_key_code; }
u32 char_code() const { return m_char_code; }

View file

@ -7,14 +7,14 @@
#include <LibGUI/Event.h>
#include <LibWeb/Bindings/MouseEventPrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/HTML/EventNames.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/UIEvents/EventNames.h>
#include <LibWeb/UIEvents/MouseEvent.h>
namespace Web::UIEvents {
MouseEvent::MouseEvent(Bindings::WindowObject& window_object, FlyString const& event_name, MouseEventInit const& event_init)
MouseEvent::MouseEvent(HTML::Window& window_object, FlyString const& event_name, MouseEventInit const& event_init)
: UIEvent(window_object, event_name, event_init)
, m_offset_x(event_init.offset_x)
, m_offset_y(event_init.offset_y)
@ -47,12 +47,12 @@ static i16 determine_button(unsigned mouse_button)
}
}
MouseEvent* MouseEvent::create(Bindings::WindowObject& window_object, FlyString const& event_name, MouseEventInit const& event_init)
MouseEvent* MouseEvent::create(HTML::Window& window_object, FlyString const& event_name, MouseEventInit const& event_init)
{
return window_object.heap().allocate<MouseEvent>(window_object.realm(), window_object, event_name, event_init);
}
MouseEvent* MouseEvent::create_from_platform_event(Bindings::WindowObject& window_object, FlyString const& event_name, double offset_x, double offset_y, double client_x, double client_y, unsigned mouse_button)
MouseEvent* MouseEvent::create_from_platform_event(HTML::Window& window_object, FlyString const& event_name, double offset_x, double offset_y, double client_x, double client_y, unsigned mouse_button)
{
MouseEventInit event_init {};
event_init.offset_x = offset_x;

View file

@ -22,18 +22,16 @@ struct MouseEventInit : public EventModifierInit {
};
class MouseEvent final : public UIEvent {
JS_OBJECT(MouseEvent, UIEvent);
WEB_PLATFORM_OBJECT(MouseEvent, UIEvent);
public:
static MouseEvent* create(Bindings::WindowObject&, FlyString const& event_name, MouseEventInit const& event_init = {});
static MouseEvent* create_from_platform_event(Bindings::WindowObject&, FlyString const& event_name, double offset_x, double offset_y, double client_x, double client_y, unsigned mouse_button = 1);
static MouseEvent* create(HTML::Window&, FlyString const& event_name, MouseEventInit const& event_init = {});
static MouseEvent* create_from_platform_event(HTML::Window&, FlyString const& event_name, double offset_x, double offset_y, double client_x, double client_y, unsigned mouse_button = 1);
MouseEvent(Bindings::WindowObject&, FlyString const& event_name, MouseEventInit const& event_init);
MouseEvent(HTML::Window&, FlyString const& event_name, MouseEventInit const& event_init);
virtual ~MouseEvent() override;
MouseEvent& impl() { return *this; }
double offset_x() const { return m_offset_x; }
double offset_y() const { return m_offset_y; }

View file

@ -5,28 +5,28 @@
*/
#include <LibWeb/Bindings/UIEventPrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/UIEvents/UIEvent.h>
namespace Web::UIEvents {
UIEvent* UIEvent::create(Bindings::WindowObject& window_object, FlyString const& event_name)
UIEvent* UIEvent::create(HTML::Window& window_object, FlyString const& event_name)
{
return window_object.heap().allocate<UIEvent>(window_object.realm(), window_object, event_name);
}
UIEvent* UIEvent::create_with_global_object(Bindings::WindowObject& window_object, FlyString const& event_name, UIEventInit const& event_init)
UIEvent* UIEvent::create_with_global_object(HTML::Window& window_object, FlyString const& event_name, UIEventInit const& event_init)
{
return window_object.heap().allocate<UIEvent>(window_object.realm(), window_object, event_name, event_init);
}
UIEvent::UIEvent(Bindings::WindowObject& window_object, FlyString const& event_name)
UIEvent::UIEvent(HTML::Window& window_object, FlyString const& event_name)
: Event(window_object, event_name)
{
set_prototype(&window_object.ensure_web_prototype<Bindings::UIEventPrototype>("UIEvent"));
}
UIEvent::UIEvent(Bindings::WindowObject& window_object, FlyString const& event_name, UIEventInit const& event_init)
UIEvent::UIEvent(HTML::Window& window_object, FlyString const& event_name, UIEventInit const& event_init)
: Event(window_object, event_name, event_init)
, m_view(event_init.view)
, m_detail(event_init.detail)
@ -36,4 +36,10 @@ UIEvent::UIEvent(Bindings::WindowObject& window_object, FlyString const& event_n
UIEvent::~UIEvent() = default;
void UIEvent::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_view.ptr());
}
}

View file

@ -13,25 +13,23 @@
namespace Web::UIEvents {
struct UIEventInit : public DOM::EventInit {
RefPtr<HTML::Window> view { nullptr };
JS::GCPtr<HTML::Window> view;
int detail { 0 };
};
class UIEvent : public DOM::Event {
JS_OBJECT(UIEvent, DOM::Event);
WEB_PLATFORM_OBJECT(UIEvent, DOM::Event);
public:
static UIEvent* create(Bindings::WindowObject&, FlyString const& type);
static UIEvent* create_with_global_object(Bindings::WindowObject&, FlyString const& event_name, UIEventInit const& event_init);
static UIEvent* create(HTML::Window&, FlyString const& type);
static UIEvent* create_with_global_object(HTML::Window&, FlyString const& event_name, UIEventInit const& event_init);
UIEvent(Bindings::WindowObject&, FlyString const& event_name);
UIEvent(Bindings::WindowObject&, FlyString const& event_name, UIEventInit const& event_init);
UIEvent(HTML::Window&, FlyString const& event_name);
UIEvent(HTML::Window&, FlyString const& event_name, UIEventInit const& event_init);
virtual ~UIEvent() override;
UIEvent& impl() { return *this; }
HTML::Window const* view() const { return m_view; }
HTML::Window const* view() const { return m_view.ptr(); }
int detail() const { return m_detail; }
virtual u32 which() const { return 0; }
@ -43,7 +41,9 @@ public:
}
protected:
RefPtr<HTML::Window> m_view;
virtual void visit_edges(Cell::Visitor&) override;
JS::GCPtr<HTML::Window> m_view;
int m_detail { 0 };
};