LibWeb: Use WindowProxy instead of Window in UI Events IDL

I believe this is an error in the UI Events spec, and it should be
updated to match the HTML spec (which uses WindowProxy everywhere).

This fixes a bunch of issues already covered by existing WPT tests.

Spec bug: https://github.com/w3c/uievents/issues/388

Note that WebKit has been using WindowProxy instead of Window in
UI Events IDL since 2018:
816158b4aa
This commit is contained in:
Andreas Kling 2024-11-17 21:54:03 +01:00 committed by Andreas Kling
parent 5bcba896c2
commit 3e8c8b185e
Notes: github-actions[bot] 2024-11-17 23:00:48 +00:00
20 changed files with 32 additions and 32 deletions

View file

@ -27,7 +27,7 @@ static void fire_a_focus_event(GC::Ptr<DOM::EventTarget> focus_event_target, GC:
// object, and the composed flag set. // object, and the composed flag set.
UIEvents::FocusEventInit focus_event_init {}; UIEvents::FocusEventInit focus_event_init {};
focus_event_init.related_target = related_focus_target; focus_event_init.related_target = related_focus_target;
focus_event_init.view = verify_cast<HTML::Window>(focus_event_target->realm().global_object()); focus_event_init.view = verify_cast<HTML::Window>(focus_event_target->realm().global_object()).window();
auto focus_event = UIEvents::FocusEvent::create(focus_event_target->realm(), event_name, focus_event_init); auto focus_event = UIEvents::FocusEvent::create(focus_event_target->realm(), event_name, focus_event_init);
// AD-HOC: support bubbling focus events, used for focusin & focusout. // AD-HOC: support bubbling focus events, used for focusin & focusout.

View file

@ -561,7 +561,7 @@ GC::Ref<HTML::DragEvent> DragAndDropEventHandler::fire_a_drag_and_drop_event(
if (target) { if (target) {
auto& window = static_cast<HTML::Window&>(HTML::relevant_global_object(*target)); auto& window = static_cast<HTML::Window&>(HTML::relevant_global_object(*target));
event_init.view = window; event_init.view = window.window();
} }
// If e is not dragleave or dragend, then initialize event's cancelable attribute to true. // If e is not dragleave or dragend, then initialize event's cancelable attribute to true.

View file

@ -37,7 +37,7 @@ void CompositionEvent::initialize(JS::Realm& realm)
} }
// https://w3c.github.io/uievents/#dom-compositionevent-initcompositionevent // https://w3c.github.io/uievents/#dom-compositionevent-initcompositionevent
void CompositionEvent::init_composition_event(String const& type, bool bubbles, bool cancelable, HTML::Window* view, String const& data) void CompositionEvent::init_composition_event(String const& type, bool bubbles, bool cancelable, GC::Ptr<HTML::WindowProxy> view, String const& data)
{ {
// Initializes attributes of a CompositionEvent object. This method has the same behavior as UIEvent.initUIEvent(). // Initializes attributes of a CompositionEvent object. This method has the same behavior as UIEvent.initUIEvent().
// The value of detail remains undefined. // The value of detail remains undefined.

View file

@ -27,7 +27,7 @@ public:
// https://w3c.github.io/uievents/#dom-compositionevent-data // https://w3c.github.io/uievents/#dom-compositionevent-data
String data() const { return m_data; } String data() const { return m_data; }
void init_composition_event(String const& type, bool bubbles, bool cancelable, HTML::Window* view, String const& data); void init_composition_event(String const& type, bool bubbles, bool cancelable, GC::Ptr<HTML::WindowProxy> view, String const& data);
private: private:
CompositionEvent(JS::Realm&, FlyString const& event_name, CompositionEventInit const&); CompositionEvent(JS::Realm&, FlyString const& event_name, CompositionEventInit const&);

View file

@ -8,7 +8,7 @@ interface CompositionEvent : UIEvent {
// https://w3c.github.io/uievents/#dom-compositionevent-initcompositionevent // https://w3c.github.io/uievents/#dom-compositionevent-initcompositionevent
// FIXME: The spec uses WindowProxy rather than Window (see https://github.com/w3c/uievents/pull/379). // FIXME: The spec uses WindowProxy rather than Window (see https://github.com/w3c/uievents/pull/379).
undefined initCompositionEvent(DOMString typeArg, optional boolean bubblesArg = false, optional boolean cancelableArg = false, optional Window? viewArg = null, optional DOMString dataArg = ""); undefined initCompositionEvent(DOMString typeArg, optional boolean bubblesArg = false, optional boolean cancelableArg = false, optional WindowProxy? viewArg = null, optional DOMString dataArg = "");
}; };
// https://w3c.github.io/uievents/#dictdef-compositioneventinit // https://w3c.github.io/uievents/#dictdef-compositioneventinit

View file

@ -730,7 +730,7 @@ bool KeyboardEvent::get_modifier_state(String const& key_arg) const
} }
// https://w3c.github.io/uievents/#dom-keyboardevent-initkeyboardevent // https://w3c.github.io/uievents/#dom-keyboardevent-initkeyboardevent
void KeyboardEvent::init_keyboard_event(String const& type, bool bubbles, bool cancelable, HTML::Window* view, String const& key, WebIDL::UnsignedLong location, bool ctrl_key, bool alt_key, bool shift_key, bool meta_key) void KeyboardEvent::init_keyboard_event(String const& type, bool bubbles, bool cancelable, GC::Ptr<HTML::WindowProxy> view, String const& key, WebIDL::UnsignedLong location, bool ctrl_key, bool alt_key, bool shift_key, bool meta_key)
{ {
// Initializes attributes of a KeyboardEvent object. This method has the same behavior as UIEvent.initUIEvent(). // Initializes attributes of a KeyboardEvent object. This method has the same behavior as UIEvent.initUIEvent().
// The value of detail remains undefined. // The value of detail remains undefined.

View file

@ -62,7 +62,7 @@ public:
virtual u32 which() const override { return m_key_code; } virtual u32 which() const override { return m_key_code; }
void init_keyboard_event(String const& type, bool bubbles, bool cancelable, HTML::Window* view, String const& key, WebIDL::UnsignedLong location, bool ctrl_key, bool alt_key, bool shift_key, bool meta_key); void init_keyboard_event(String const& type, bool bubbles, bool cancelable, GC::Ptr<HTML::WindowProxy> view, String const& key, WebIDL::UnsignedLong location, bool ctrl_key, bool alt_key, bool shift_key, bool meta_key);
private: private:
KeyboardEvent(JS::Realm&, FlyString const& event_name, KeyboardEventInit const& event_init); KeyboardEvent(JS::Realm&, FlyString const& event_name, KeyboardEventInit const& event_init);

View file

@ -30,7 +30,7 @@ interface KeyboardEvent : UIEvent {
boolean getModifierState(DOMString keyArg); boolean getModifierState(DOMString keyArg);
// https://w3c.github.io/uievents/#dom-keyboardevent-initkeyboardevent // https://w3c.github.io/uievents/#dom-keyboardevent-initkeyboardevent
undefined initKeyboardEvent(DOMString typeArg, optional boolean bubblesArg = false, optional boolean cancelableArg = false, optional Window? viewArg = null, optional DOMString keyArg = "", optional unsigned long locationArg = 0, optional boolean ctrlKey = false, optional boolean altKey = false, optional boolean shiftKey = false, optional boolean metaKey = false); undefined initKeyboardEvent(DOMString typeArg, optional boolean bubblesArg = false, optional boolean cancelableArg = false, optional WindowProxy? viewArg = null, optional DOMString keyArg = "", optional unsigned long locationArg = 0, optional boolean ctrlKey = false, optional boolean altKey = false, optional boolean shiftKey = false, optional boolean metaKey = false);
}; };

View file

@ -97,7 +97,7 @@ bool MouseEvent::get_modifier_state(String const& key_arg) const
} }
// https://w3c.github.io/uievents/#dom-mouseevent-initmouseevent // https://w3c.github.io/uievents/#dom-mouseevent-initmouseevent
void MouseEvent::init_mouse_event(String const& type, bool bubbles, bool cancelable, HTML::Window* 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) 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(). // Initializes attributes of a MouseEvent object. This method has the same behavior as UIEvent.initUIEvent().

View file

@ -77,7 +77,7 @@ public:
virtual u32 which() const override { return m_button + 1; } virtual u32 which() const override { return m_button + 1; }
void init_mouse_event(String const& type, bool bubbles, bool cancelable, HTML::Window* 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); void 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);
protected: protected:
MouseEvent(JS::Realm&, FlyString const& event_name, MouseEventInit const& event_init, double page_x, double page_y, double offset_x, double offset_y); MouseEvent(JS::Realm&, FlyString const& event_name, MouseEventInit const& event_init, double page_x, double page_y, double offset_x, double offset_y);

View file

@ -34,7 +34,7 @@ interface MouseEvent : UIEvent {
boolean getModifierState(DOMString keyArg); boolean getModifierState(DOMString keyArg);
// https://w3c.github.io/uievents/#dom-mouseevent-initmouseevent // https://w3c.github.io/uievents/#dom-mouseevent-initmouseevent
undefined initMouseEvent(DOMString typeArg, optional boolean bubblesArg = false, optional boolean cancelableArg = false, optional Window? viewArg = null, optional long detailArg = 0, optional long screenXArg = 0, optional long screenYArg = 0, optional long clientXArg = 0, optional long clientYArg = 0, optional boolean ctrlKeyArg = false, optional boolean altKeyArg = false, optional boolean shiftKeyArg = false, optional boolean metaKeyArg = false, optional short buttonArg = 0, optional EventTarget? relatedTargetArg = null); undefined initMouseEvent(DOMString typeArg, optional boolean bubblesArg = false, optional boolean cancelableArg = false, optional WindowProxy? viewArg = null, optional long detailArg = 0, optional long screenXArg = 0, optional long screenYArg = 0, optional long clientXArg = 0, optional long clientYArg = 0, optional boolean ctrlKeyArg = false, optional boolean altKeyArg = false, optional boolean shiftKeyArg = false, optional boolean metaKeyArg = false, optional short buttonArg = 0, optional EventTarget? relatedTargetArg = null);
}; };
// https://w3c.github.io/uievents/#idl-mouseeventinit // https://w3c.github.io/uievents/#idl-mouseeventinit

View file

@ -31,7 +31,7 @@ void TextEvent::initialize(JS::Realm& realm)
} }
// https://w3c.github.io/uievents/#dom-textevent-inittextevent // https://w3c.github.io/uievents/#dom-textevent-inittextevent
void TextEvent::init_text_event(String const& type, bool bubbles, bool cancelable, HTML::Window* view, String const& data) void TextEvent::init_text_event(String const& type, bool bubbles, bool cancelable, GC::Ptr<HTML::WindowProxy> view, String const& data)
{ {
// Initializes attributes of a TextEvent object. This method has the same behavior as UIEvent.initUIEvent(). // Initializes attributes of a TextEvent object. This method has the same behavior as UIEvent.initUIEvent().
// The value of detail remains undefined. // The value of detail remains undefined.

View file

@ -22,7 +22,7 @@ public:
// https://w3c.github.io/uievents/#dom-textevent-data // https://w3c.github.io/uievents/#dom-textevent-data
String data() const { return m_data; } String data() const { return m_data; }
void init_text_event(String const& type, bool bubbles, bool cancelable, HTML::Window* view, String const& data); void init_text_event(String const& type, bool bubbles, bool cancelable, GC::Ptr<HTML::WindowProxy> view, String const& data);
private: private:
TextEvent(JS::Realm&, FlyString const& event_name); TextEvent(JS::Realm&, FlyString const& event_name);

View file

@ -4,5 +4,5 @@
[Exposed=Window] [Exposed=Window]
interface TextEvent : UIEvent { interface TextEvent : UIEvent {
readonly attribute DOMString data; readonly attribute DOMString data;
undefined initTextEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional Window? view = null, optional DOMString data = "undefined"); undefined initTextEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional WindowProxy? view = null, optional DOMString data = "undefined");
}; };

View file

@ -6,6 +6,7 @@
#include <LibWeb/Bindings/Intrinsics.h> #include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/UIEventPrototype.h> #include <LibWeb/Bindings/UIEventPrototype.h>
#include <LibWeb/HTML/WindowProxy.h>
#include <LibWeb/UIEvents/UIEvent.h> #include <LibWeb/UIEvents/UIEvent.h>
namespace Web::UIEvents { namespace Web::UIEvents {

View file

@ -13,7 +13,7 @@
namespace Web::UIEvents { namespace Web::UIEvents {
struct UIEventInit : public DOM::EventInit { struct UIEventInit : public DOM::EventInit {
GC::Ptr<HTML::Window> view; GC::Ptr<HTML::WindowProxy> view;
int detail { 0 }; int detail { 0 };
}; };
@ -27,11 +27,11 @@ public:
virtual ~UIEvent() override; virtual ~UIEvent() override;
HTML::Window const* view() const { return m_view.ptr(); } GC::Ptr<HTML::WindowProxy> const view() const { return m_view; }
int detail() const { return m_detail; } int detail() const { return m_detail; }
virtual u32 which() const { return 0; } virtual u32 which() const { return 0; }
void init_ui_event(String const& type, bool bubbles, bool cancelable, HTML::Window* view, int detail) void init_ui_event(String const& type, bool bubbles, bool cancelable, GC::Ptr<HTML::WindowProxy> view, int detail)
{ {
// Initializes attributes of an UIEvent object. This method has the same behavior as initEvent(). // Initializes attributes of an UIEvent object. This method has the same behavior as initEvent().
@ -54,7 +54,7 @@ protected:
virtual void initialize(JS::Realm&) override; virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override; virtual void visit_edges(Cell::Visitor&) override;
GC::Ptr<HTML::Window> m_view; GC::Ptr<HTML::WindowProxy> m_view;
int m_detail { 0 }; int m_detail { 0 };
}; };

View file

@ -5,16 +5,16 @@
[Exposed=Window] [Exposed=Window]
interface UIEvent : Event { interface UIEvent : Event {
constructor(DOMString type, optional UIEventInit eventInitDict = {}); constructor(DOMString type, optional UIEventInit eventInitDict = {});
readonly attribute Window? view; readonly attribute WindowProxy? view;
readonly attribute long detail; readonly attribute long detail;
// Obsolete // Obsolete
[ImplementedAs=init_ui_event] undefined initUIEvent(DOMString typeArg, optional boolean bubblesArg = false, optional boolean cancelableArg = false, optional Window? viewArg = null, optional long detailArg = 0); [ImplementedAs=init_ui_event] undefined initUIEvent(DOMString typeArg, optional boolean bubblesArg = false, optional boolean cancelableArg = false, optional WindowProxy? viewArg = null, optional long detailArg = 0);
readonly attribute unsigned long which; readonly attribute unsigned long which;
}; };
// https://w3c.github.io/uievents/#idl-uieventinit // https://w3c.github.io/uievents/#idl-uieventinit
dictionary UIEventInit : EventInit { dictionary UIEventInit : EventInit {
Window? view = null; WindowProxy? view = null;
long detail = 0; long detail = 0;
}; };

View file

@ -102,6 +102,7 @@ static bool is_platform_object(Type const& type)
"VideoTrackList"sv, "VideoTrackList"sv,
"WebGLRenderingContext"sv, "WebGLRenderingContext"sv,
"Window"sv, "Window"sv,
"WindowProxy"sv,
"WritableStream"sv, "WritableStream"sv,
}; };
if (type.name().ends_with("Element"sv)) if (type.name().ends_with("Element"sv))

View file

@ -6,11 +6,10 @@ Rerun
Found 5 tests Found 5 tests
4 Pass 5 Pass
1 Fail
Details Details
Result Test Name MessagePass Calling initKeyboardEvent while dispatching. Result Test Name MessagePass Calling initKeyboardEvent while dispatching.
Pass Calling initMouseEvent while dispatching. Pass Calling initMouseEvent while dispatching.
Pass Calling initCustomEvent while dispatching. Pass Calling initCustomEvent while dispatching.
Fail Calling initUIEvent while dispatching. Not an object of type Window Pass Calling initUIEvent while dispatching.
Pass Calling initEvent while dispatching. Pass Calling initEvent while dispatching.

View file

@ -6,8 +6,7 @@ Rerun
Found 49 tests Found 49 tests
43 Pass 49 Pass
6 Fail
Details Details
Result Test Name MessagePass Event constructor (no argument) Result Test Name MessagePass Event constructor (no argument)
Pass Event constructor (undefined argument) Pass Event constructor (undefined argument)
@ -20,37 +19,37 @@ Pass UIEvent constructor (undefined argument)
Pass UIEvent constructor (null argument) Pass UIEvent constructor (null argument)
Pass UIEvent constructor (empty argument) Pass UIEvent constructor (empty argument)
Pass UIEvent constructor (argument with default values) Pass UIEvent constructor (argument with default values)
Fail UIEvent constructor (argument with non-default values) Not an object of type Window Pass UIEvent constructor (argument with non-default values)
Pass FocusEvent constructor (no argument) Pass FocusEvent constructor (no argument)
Pass FocusEvent constructor (undefined argument) Pass FocusEvent constructor (undefined argument)
Pass FocusEvent constructor (null argument) Pass FocusEvent constructor (null argument)
Pass FocusEvent constructor (empty argument) Pass FocusEvent constructor (empty argument)
Pass FocusEvent constructor (argument with default values) Pass FocusEvent constructor (argument with default values)
Fail FocusEvent constructor (argument with non-default values) Not an object of type Window Pass FocusEvent constructor (argument with non-default values)
Pass MouseEvent constructor (no argument) Pass MouseEvent constructor (no argument)
Pass MouseEvent constructor (undefined argument) Pass MouseEvent constructor (undefined argument)
Pass MouseEvent constructor (null argument) Pass MouseEvent constructor (null argument)
Pass MouseEvent constructor (empty argument) Pass MouseEvent constructor (empty argument)
Pass MouseEvent constructor (argument with default values) Pass MouseEvent constructor (argument with default values)
Fail MouseEvent constructor (argument with non-default values) Not an object of type Window Pass MouseEvent constructor (argument with non-default values)
Pass WheelEvent constructor (no argument) Pass WheelEvent constructor (no argument)
Pass WheelEvent constructor (undefined argument) Pass WheelEvent constructor (undefined argument)
Pass WheelEvent constructor (null argument) Pass WheelEvent constructor (null argument)
Pass WheelEvent constructor (empty argument) Pass WheelEvent constructor (empty argument)
Pass WheelEvent constructor (argument with default values) Pass WheelEvent constructor (argument with default values)
Fail WheelEvent constructor (argument with non-default values) Not an object of type Window Pass WheelEvent constructor (argument with non-default values)
Pass KeyboardEvent constructor (no argument) Pass KeyboardEvent constructor (no argument)
Pass KeyboardEvent constructor (undefined argument) Pass KeyboardEvent constructor (undefined argument)
Pass KeyboardEvent constructor (null argument) Pass KeyboardEvent constructor (null argument)
Pass KeyboardEvent constructor (empty argument) Pass KeyboardEvent constructor (empty argument)
Pass KeyboardEvent constructor (argument with default values) Pass KeyboardEvent constructor (argument with default values)
Fail KeyboardEvent constructor (argument with non-default values) Not an object of type Window Pass KeyboardEvent constructor (argument with non-default values)
Pass CompositionEvent constructor (no argument) Pass CompositionEvent constructor (no argument)
Pass CompositionEvent constructor (undefined argument) Pass CompositionEvent constructor (undefined argument)
Pass CompositionEvent constructor (null argument) Pass CompositionEvent constructor (null argument)
Pass CompositionEvent constructor (empty argument) Pass CompositionEvent constructor (empty argument)
Pass CompositionEvent constructor (argument with default values) Pass CompositionEvent constructor (argument with default values)
Fail CompositionEvent constructor (argument with non-default values) Not an object of type Window Pass CompositionEvent constructor (argument with non-default values)
Pass SubclassedEvent constructor (no argument) Pass SubclassedEvent constructor (no argument)
Pass SubclassedEvent constructor (undefined argument) Pass SubclassedEvent constructor (undefined argument)
Pass SubclassedEvent constructor (null argument) Pass SubclassedEvent constructor (null argument)