mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
Previously, the LibWeb bindings generator would output multiple per interface files like Prototype/Constructor/Namespace/GlobalMixin depending on the contents of that IDL file. This complicates the build system as it means that it does not know what files will be generated without knowledge of the contents of that IDL file. Instead, for each IDL file only generate a single Bindings/<IDLFile>.h and Bindings/<IDLFile>.cpp.
199 lines
7.6 KiB
C++
199 lines
7.6 KiB
C++
/*
|
||
* Copyright (c) 2020, the SerenityOS developers.
|
||
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
|
||
*
|
||
* SPDX-License-Identifier: BSD-2-Clause
|
||
*/
|
||
|
||
#include <LibWeb/Bindings/Intrinsics.h>
|
||
#include <LibWeb/Bindings/MouseEvent.h>
|
||
#include <LibWeb/HTML/EventNames.h>
|
||
#include <LibWeb/UIEvents/EventNames.h>
|
||
#include <LibWeb/UIEvents/KeyCode.h>
|
||
#include <LibWeb/UIEvents/MouseButton.h>
|
||
#include <LibWeb/UIEvents/MouseEvent.h>
|
||
|
||
namespace Web::UIEvents {
|
||
|
||
GC_DEFINE_ALLOCATOR(MouseEvent);
|
||
|
||
MouseEvent::MouseEvent(JS::Realm& realm, FlyString const& event_name, MouseEventInit const& event_init, double page_x, double page_y, double offset_x, double offset_y)
|
||
: UIEvent(realm, event_name, event_init)
|
||
, m_screen_x(event_init.screen_x)
|
||
, m_screen_y(event_init.screen_y)
|
||
, m_page_x(page_x)
|
||
, m_page_y(page_y)
|
||
, m_client_x(event_init.client_x)
|
||
, m_client_y(event_init.client_y)
|
||
, m_offset_x(offset_x)
|
||
, m_offset_y(offset_y)
|
||
, 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_modifier_alt_graph(event_init.modifier_alt_graph)
|
||
, m_modifier_caps_lock(event_init.modifier_caps_lock)
|
||
, m_modifier_fn(event_init.modifier_fn)
|
||
, m_modifier_fn_lock(event_init.modifier_fn_lock)
|
||
, m_modifier_hyper(event_init.modifier_hyper)
|
||
, m_modifier_num_lock(event_init.modifier_num_lock)
|
||
, m_modifier_scroll_lock(event_init.modifier_scroll_lock)
|
||
, m_modifier_super(event_init.modifier_super)
|
||
, m_modifier_symbol(event_init.modifier_symbol)
|
||
, m_modifier_symbol_lock(event_init.modifier_symbol_lock)
|
||
, m_movement_x(event_init.movement_x)
|
||
, m_movement_y(event_init.movement_y)
|
||
, m_button(event_init.button)
|
||
, m_buttons(event_init.buttons)
|
||
, m_related_target(event_init.related_target)
|
||
{
|
||
}
|
||
|
||
MouseEvent::~MouseEvent() = default;
|
||
|
||
void MouseEvent::initialize(JS::Realm& realm)
|
||
{
|
||
WEB_SET_PROTOTYPE_FOR_INTERFACE(MouseEvent);
|
||
Base::initialize(realm);
|
||
}
|
||
|
||
void MouseEvent::visit_edges(Cell::Visitor& visitor)
|
||
{
|
||
Base::visit_edges(visitor);
|
||
visitor.visit(m_related_target);
|
||
}
|
||
|
||
bool MouseEvent::get_modifier_state(String const& key_arg) const
|
||
{
|
||
if (key_arg == "Control")
|
||
return m_ctrl_key;
|
||
if (key_arg == "Shift")
|
||
return m_shift_key;
|
||
if (key_arg == "Alt")
|
||
return m_alt_key;
|
||
if (key_arg == "Meta")
|
||
return m_meta_key;
|
||
if (key_arg == "AltGraph")
|
||
return m_modifier_alt_graph;
|
||
if (key_arg == "CapsLock")
|
||
return m_modifier_caps_lock;
|
||
if (key_arg == "Fn")
|
||
return m_modifier_fn;
|
||
if (key_arg == "FnLock")
|
||
return m_modifier_fn_lock;
|
||
if (key_arg == "Hyper")
|
||
return m_modifier_hyper;
|
||
if (key_arg == "NumLock")
|
||
return m_modifier_num_lock;
|
||
if (key_arg == "ScrollLock")
|
||
return m_modifier_scroll_lock;
|
||
if (key_arg == "Super")
|
||
return m_modifier_super;
|
||
if (key_arg == "Symbol")
|
||
return m_modifier_symbol;
|
||
if (key_arg == "SymbolLock")
|
||
return m_modifier_symbol_lock;
|
||
return false;
|
||
}
|
||
|
||
// https://w3c.github.io/uievents/#dom-mouseevent-initmouseevent
|
||
void MouseEvent::init_mouse_event(String const& type, bool bubbles, bool cancelable, GC::Ptr<HTML::WindowProxy> view, WebIDL::Long detail, WebIDL::Long screen_x, WebIDL::Long screen_y, WebIDL::Long client_x, WebIDL::Long client_y, bool ctrl_key, bool alt_key, bool shift_key, bool meta_key, WebIDL::Short button, DOM::EventTarget* related_target)
|
||
{
|
||
// Initializes attributes of a MouseEvent object. This method has the same behavior as UIEvent.initUIEvent().
|
||
|
||
// 1. If this’s dispatch flag is set, then return.
|
||
if (dispatched())
|
||
return;
|
||
|
||
// 2. Initialize this with type, bubbles, and cancelable.
|
||
initialize_event(type, bubbles, cancelable);
|
||
|
||
// Implementation Defined: Initialise other values.
|
||
m_view = view;
|
||
m_detail = detail;
|
||
m_screen_x = screen_x;
|
||
m_screen_y = screen_y;
|
||
m_client_x = client_x;
|
||
m_client_y = client_y;
|
||
m_ctrl_key = ctrl_key;
|
||
m_shift_key = shift_key;
|
||
m_alt_key = alt_key;
|
||
m_meta_key = meta_key;
|
||
m_button = button;
|
||
m_related_target = related_target;
|
||
}
|
||
|
||
GC::Ref<MouseEvent> MouseEvent::create(JS::Realm& realm, FlyString const& event_name, MouseEventInit const& event_init, double page_x, double page_y, double offset_x, double offset_y)
|
||
{
|
||
return realm.create<MouseEvent>(realm, event_name, event_init, page_x, page_y, offset_x, offset_y);
|
||
}
|
||
|
||
WebIDL::ExceptionOr<GC::Ref<MouseEvent>> MouseEvent::construct_impl(JS::Realm& realm, FlyString const& event_name, MouseEventInit const& event_init)
|
||
{
|
||
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-pagex
|
||
// For a newly constructed event, pageX/pageY default to clientX/clientY (scrollX/scrollY are 0).
|
||
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
|
||
// For a newly constructed event with no target, offsetX/offsetY default to clientX/clientY.
|
||
return create(realm, event_name, event_init, event_init.client_x, event_init.client_y, event_init.client_x, event_init.client_y);
|
||
}
|
||
|
||
GC::Ref<MouseEvent> MouseEvent::clone() const
|
||
{
|
||
MouseEventInit init {};
|
||
init.screen_x = m_screen_x;
|
||
init.screen_y = m_screen_y;
|
||
init.client_x = m_client_x;
|
||
init.client_y = m_client_y;
|
||
init.movement_x = m_movement_x;
|
||
init.movement_y = m_movement_y;
|
||
init.button = m_button;
|
||
init.buttons = m_buttons;
|
||
init.related_target = m_related_target;
|
||
init.ctrl_key = m_ctrl_key;
|
||
init.shift_key = m_shift_key;
|
||
init.alt_key = m_alt_key;
|
||
init.meta_key = m_meta_key;
|
||
init.modifier_alt_graph = m_modifier_alt_graph;
|
||
init.modifier_caps_lock = m_modifier_caps_lock;
|
||
init.modifier_fn = m_modifier_fn;
|
||
init.modifier_fn_lock = m_modifier_fn_lock;
|
||
init.modifier_hyper = m_modifier_hyper;
|
||
init.modifier_num_lock = m_modifier_num_lock;
|
||
init.modifier_scroll_lock = m_modifier_scroll_lock;
|
||
init.modifier_super = m_modifier_super;
|
||
init.modifier_symbol = m_modifier_symbol;
|
||
init.modifier_symbol_lock = m_modifier_symbol_lock;
|
||
init.view = view();
|
||
init.detail = detail();
|
||
return create(realm(), type(), init, m_page_x, m_page_y, m_offset_x, m_offset_y);
|
||
}
|
||
|
||
WebIDL::ExceptionOr<GC::Ref<MouseEvent>> MouseEvent::create_from_platform_event(JS::Realm& realm, GC::Ptr<HTML::WindowProxy> window_proxy, FlyString const& event_name, CSSPixelPoint screen, CSSPixelPoint page, CSSPixelPoint client, CSSPixelPoint offset, Optional<CSSPixelPoint> movement, unsigned button, unsigned buttons, unsigned modifiers, int detail)
|
||
{
|
||
MouseEventInit event_init {};
|
||
event_init.detail = detail;
|
||
event_init.ctrl_key = modifiers & Mod_Ctrl;
|
||
event_init.shift_key = modifiers & Mod_Shift;
|
||
event_init.alt_key = modifiers & Mod_Alt;
|
||
event_init.meta_key = modifiers & Mod_Super;
|
||
event_init.screen_x = screen.x().to_double();
|
||
event_init.screen_y = screen.y().to_double();
|
||
event_init.client_x = client.x().to_double();
|
||
event_init.client_y = client.y().to_double();
|
||
event_init.view = window_proxy;
|
||
if (movement.has_value()) {
|
||
event_init.movement_x = movement.value().x().to_double();
|
||
event_init.movement_y = movement.value().y().to_double();
|
||
}
|
||
event_init.button = mouse_button_to_button_code(static_cast<MouseButton>(button));
|
||
event_init.buttons = buttons;
|
||
auto event = MouseEvent::create(realm, event_name, event_init, page.x().to_double(), page.y().to_double(), offset.x().to_double(), offset.y().to_double());
|
||
event->set_is_trusted(true);
|
||
event->set_bubbles(true);
|
||
event->set_cancelable(true);
|
||
event->set_composed(true);
|
||
return event;
|
||
}
|
||
|
||
}
|