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

LibWeb: Make DOM::Event and all its subclasses GC-allocated

This commit is contained in:
Andreas Kling 2022-08-08 22:29:40 +02:00
parent a4ddb0ef87
commit 7c3db526b0
76 changed files with 892 additions and 565 deletions

View file

@ -4,13 +4,21 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/FocusEventPrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/UIEvents/FocusEvent.h>
namespace Web::UIEvents {
FocusEvent::FocusEvent(FlyString const& event_name, FocusEventInit const& event_init)
: UIEvent(event_name)
FocusEvent* FocusEvent::create_with_global_object(Bindings::WindowObject& 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)
: UIEvent(window_object, event_name)
{
set_prototype(&window_object.ensure_web_prototype<Bindings::FocusEventPrototype>("FocusEvent"));
set_related_target(const_cast<DOM::EventTarget*>(event_init.related_target.ptr()));
}

View file

@ -15,18 +15,20 @@ struct FocusEventInit : public UIEventInit {
};
class FocusEvent final : public UIEvent {
public:
using WrapperType = Bindings::FocusEventWrapper;
JS_OBJECT(FocusEvent, UIEvent);
public:
static FocusEvent* create_with_global_object(Bindings::WindowObject&, FlyString const& event_name, FocusEventInit const& event_init);
FocusEvent(Bindings::WindowObject&, FlyString const& event_name, FocusEventInit const&);
virtual ~FocusEvent() override;
static NonnullRefPtr<FocusEvent> create_with_global_object(Bindings::WindowObject&, FlyString const& event_name, FocusEventInit const& event_init)
{
return adopt_ref(*new FocusEvent(event_name, event_init));
}
private:
FocusEvent(FlyString const& event_name, FocusEventInit const&);
FocusEvent& impl() { return *this; }
};
}
namespace Web::Bindings {
inline JS::Object* wrap(JS::Realm&, Web::UIEvents::FocusEvent& object) { return &object; }
using FocusEventWrapper = Web::UIEvents::FocusEvent;
}

View file

@ -1,6 +1,6 @@
#import <UIEvents/UIEvent.idl>
[Exposed=Window]
[Exposed=Window, NoInstanceWrapper]
interface FocusEvent : UIEvent {
constructor(DOMString type, optional FocusEventInit eventInitDict = {});

View file

@ -1,10 +1,12 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/CharacterTypes.h>
#include <LibWeb/Bindings/KeyboardEventPrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/UIEvents/KeyboardEvent.h>
namespace Web::UIEvents {
@ -65,7 +67,7 @@ static unsigned long determine_key_code(KeyCode platform_key, u32 code_point)
return platform_key;
}
NonnullRefPtr<KeyboardEvent> KeyboardEvent::create_from_platform_event(FlyString const& event_name, KeyCode platform_key, unsigned modifiers, u32 code_point)
KeyboardEvent* KeyboardEvent::create_from_platform_event(Bindings::WindowObject& 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);
@ -87,7 +89,7 @@ NonnullRefPtr<KeyboardEvent> KeyboardEvent::create_from_platform_event(FlyString
event_init.bubbles = true;
event_init.cancelable = true;
event_init.composed = true;
return KeyboardEvent::create(event_name, event_init);
return KeyboardEvent::create(window_object, event_name, event_init);
}
bool KeyboardEvent::get_modifier_state(String const& key_arg)
@ -102,4 +104,34 @@ bool KeyboardEvent::get_modifier_state(String const& key_arg)
return m_meta_key;
return false;
}
KeyboardEvent* KeyboardEvent::create(Bindings::WindowObject& 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)
{
return create(window_object, event_name, event_init);
}
KeyboardEvent::KeyboardEvent(Bindings::WindowObject& 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)
, m_location(event_init.location)
, m_ctrl_key(event_init.ctrl_key)
, m_shift_key(event_init.shift_key)
, m_alt_key(event_init.alt_key)
, m_meta_key(event_init.meta_key)
, m_repeat(event_init.repeat)
, m_is_composing(event_init.is_composing)
, m_key_code(event_init.key_code)
, m_char_code(event_init.char_code)
{
set_prototype(&window_object.ensure_web_prototype<Bindings::KeyboardEventPrototype>("KeyboardEvent"));
}
KeyboardEvent::~KeyboardEvent() = default;
}

View file

@ -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
*/
@ -25,21 +25,18 @@ struct KeyboardEventInit : public EventModifierInit {
// https://www.w3.org/TR/uievents/#interface-keyboardevent
class KeyboardEvent final : public UIEvent {
JS_OBJECT(KeyboardEvent, UIEvent);
public:
using WrapperType = Bindings::KeyboardEventWrapper;
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 NonnullRefPtr<KeyboardEvent> create(FlyString const& event_name, KeyboardEventInit const& event_init = {})
{
return adopt_ref(*new KeyboardEvent(event_name, event_init));
}
static NonnullRefPtr<KeyboardEvent> create_with_global_object(Bindings::WindowObject&, FlyString const& event_name, KeyboardEventInit const& event_init)
{
return KeyboardEvent::create(event_name, event_init);
}
KeyboardEvent(Bindings::WindowObject&, FlyString const& event_name, KeyboardEventInit const& event_init);
static NonnullRefPtr<KeyboardEvent> create_from_platform_event(FlyString const& event_name, KeyCode, unsigned modifiers, u32 code_point);
virtual ~KeyboardEvent() override;
virtual ~KeyboardEvent() override = default;
KeyboardEvent& impl() { return *this; }
u32 key_code() const { return m_key_code; }
u32 char_code() const { return m_char_code; }
@ -61,20 +58,6 @@ public:
virtual u32 which() const override { return m_key_code; }
private:
KeyboardEvent(FlyString const& event_name, KeyboardEventInit const& event_init)
: UIEvent(event_name, event_init)
, m_key(event_init.key)
, m_code(event_init.code)
, m_location(event_init.location)
, m_ctrl_key(event_init.ctrl_key)
, m_shift_key(event_init.shift_key)
, m_alt_key(event_init.alt_key)
, m_meta_key(event_init.meta_key)
, m_repeat(event_init.repeat)
, m_is_composing(event_init.is_composing)
, m_key_code(event_init.key_code)
, m_char_code(event_init.char_code) {};
String m_key;
String m_code;
u32 m_location { 0 };
@ -89,3 +72,8 @@ private:
};
}
namespace Web::Bindings {
inline JS::Object* wrap(JS::Realm&, Web::UIEvents::KeyboardEvent& object) { return &object; }
using KeyboardEventWrapper = Web::UIEvents::KeyboardEvent;
}

View file

@ -1,6 +1,6 @@
#import <UIEvents/EventModifier.idl>
[Exposed=Window]
[Exposed=Window, NoInstanceWrapper]
interface KeyboardEvent : UIEvent {
constructor(DOMString type, optional KeyboardEventInit eventInitDict = {});

View file

@ -1,27 +1,33 @@
/*
* Copyright (c) 2020, the SerenityOS developers.
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGUI/Event.h>
#include <LibWeb/Bindings/MouseEventPrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/HTML/EventNames.h>
#include <LibWeb/UIEvents/EventNames.h>
#include <LibWeb/UIEvents/MouseEvent.h>
namespace Web::UIEvents {
MouseEvent::MouseEvent(FlyString const& event_name, MouseEventInit const& event_init)
: UIEvent(event_name, event_init)
MouseEvent::MouseEvent(Bindings::WindowObject& 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)
, m_client_x(event_init.client_x)
, m_client_y(event_init.client_y)
, m_button(event_init.button)
{
set_prototype(&window_object.ensure_web_prototype<Bindings::MouseEventPrototype>("MouseEvent"));
set_event_characteristics();
}
MouseEvent::~MouseEvent() = default;
// https://www.w3.org/TR/uievents/#dom-mouseevent-button
static i16 determine_button(unsigned mouse_button)
{
@ -41,7 +47,12 @@ static i16 determine_button(unsigned mouse_button)
}
}
NonnullRefPtr<MouseEvent> MouseEvent::create_from_platform_event(FlyString const& event_name, double offset_x, double offset_y, double client_x, double client_y, unsigned mouse_button)
MouseEvent* MouseEvent::create(Bindings::WindowObject& 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)
{
MouseEventInit event_init {};
event_init.offset_x = offset_x;
@ -49,7 +60,7 @@ NonnullRefPtr<MouseEvent> MouseEvent::create_from_platform_event(FlyString const
event_init.client_x = client_x;
event_init.client_y = client_y;
event_init.button = determine_button(mouse_button);
return MouseEvent::create(event_name, event_init);
return MouseEvent::create(window_object, event_name, event_init);
}
void MouseEvent::set_event_characteristics()

View file

@ -22,17 +22,17 @@ struct MouseEventInit : public EventModifierInit {
};
class MouseEvent final : public UIEvent {
JS_OBJECT(MouseEvent, UIEvent);
public:
using WrapperType = Bindings::MouseEventWrapper;
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 NonnullRefPtr<MouseEvent> create(FlyString const& event_name, MouseEventInit const& event_init = {})
{
return adopt_ref(*new MouseEvent(event_name, event_init));
}
MouseEvent(Bindings::WindowObject&, FlyString const& event_name, MouseEventInit const& event_init);
static NonnullRefPtr<MouseEvent> create_from_platform_event(FlyString const& event_name, double offset_x, double offset_y, double client_x, double client_y, unsigned mouse_button = 1);
virtual ~MouseEvent() override;
virtual ~MouseEvent() override = default;
MouseEvent& impl() { return *this; }
double offset_x() const { return m_offset_x; }
double offset_y() const { return m_offset_y; }
@ -48,8 +48,6 @@ public:
virtual u32 which() const override { return m_button + 1; }
private:
MouseEvent(FlyString const& event_name, MouseEventInit const& event_init);
void set_event_characteristics();
double m_offset_x { 0 };
@ -60,3 +58,8 @@ private:
};
}
namespace Web::Bindings {
inline JS::Object* wrap(JS::Realm&, Web::UIEvents::MouseEvent& object) { return &object; }
using MouseEventWrapper = Web::UIEvents::MouseEvent;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/UIEventPrototype.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/UIEvents/UIEvent.h>
namespace Web::UIEvents {
UIEvent* UIEvent::create(Bindings::WindowObject& 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)
{
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)
: 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)
: Event(window_object, event_name, event_init)
, m_view(event_init.view)
, m_detail(event_init.detail)
{
set_prototype(&window_object.ensure_web_prototype<Bindings::UIEventPrototype>("UIEvent"));
}
UIEvent::~UIEvent() = default;
}

View file

@ -18,20 +18,18 @@ struct UIEventInit : public DOM::EventInit {
};
class UIEvent : public DOM::Event {
JS_OBJECT(UIEvent, DOM::Event);
public:
using WrapperType = Bindings::UIEventWrapper;
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 NonnullRefPtr<UIEvent> create(FlyString const& type)
{
return adopt_ref(*new UIEvent(type));
}
UIEvent(Bindings::WindowObject&, FlyString const& event_name);
UIEvent(Bindings::WindowObject&, FlyString const& event_name, UIEventInit const& event_init);
static NonnullRefPtr<UIEvent> create_with_global_object(Bindings::WindowObject&, FlyString const& event_name, UIEventInit const& event_init)
{
return adopt_ref(*new UIEvent(event_name, event_init));
}
virtual ~UIEvent() override;
virtual ~UIEvent() override = default;
UIEvent& impl() { return *this; }
HTML::Window const* view() const { return m_view; }
int detail() const { return m_detail; }
@ -45,19 +43,13 @@ public:
}
protected:
explicit UIEvent(FlyString const& event_name)
: Event(event_name)
{
}
UIEvent(FlyString const& event_name, UIEventInit const& event_init)
: Event(event_name, event_init)
, m_view(event_init.view)
, m_detail(event_init.detail)
{
}
RefPtr<HTML::Window> m_view;
int m_detail { 0 };
};
}
namespace Web::Bindings {
inline JS::Object* wrap(JS::Realm&, Web::UIEvents::UIEvent& object) { return &object; }
using UIEventWrapper = Web::UIEvents::UIEvent;
}

View file

@ -1,5 +1,6 @@
#import <DOM/Event.idl>
[NoInstanceWrapper]
interface UIEvent : Event {
constructor(DOMString type, optional UIEventInit eventInitDict = {});
readonly attribute Window? view;