LibWeb: Use Event storage for MouseEvent relatedTarget
Store MouseEvent's relatedTarget in the inherited Event field instead of keeping a second slot on MouseEvent. Event dispatch retargets and updates the inherited field while building the event path. The second slot left JS listeners observing stale or null relatedTarget values during mouse and pointer boundary events. Add coverage for boundary events between sibling elements.
This commit is contained in:
parent
8ebdd6d41e
commit
4daec8f6e0
4 changed files with 37 additions and 13 deletions
|
|
@ -46,8 +46,8 @@ MouseEvent::MouseEvent(JS::Realm& realm, FlyString const& event_name, Bindings::
|
|||
, m_movement_y(event_init.movement_y)
|
||||
, m_button(event_init.button)
|
||||
, m_buttons(event_init.buttons)
|
||||
, m_related_target(event_init.related_target)
|
||||
{
|
||||
set_related_target(event_init.related_target.ptr());
|
||||
}
|
||||
|
||||
MouseEvent::~MouseEvent() = default;
|
||||
|
|
@ -58,12 +58,6 @@ void MouseEvent::initialize(JS::Realm& realm)
|
|||
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")
|
||||
|
|
@ -121,7 +115,7 @@ void MouseEvent::init_mouse_event(String const& type, bool bubbles, bool cancela
|
|||
m_alt_key = alt_key;
|
||||
m_meta_key = meta_key;
|
||||
m_button = button;
|
||||
m_related_target = related_target;
|
||||
set_related_target(related_target);
|
||||
}
|
||||
|
||||
GC::Ref<MouseEvent> MouseEvent::create(JS::Realm& realm, FlyString const& event_name, Bindings::MouseEventInit const& event_init, double page_x, double page_y, double offset_x, double offset_y)
|
||||
|
|
@ -149,7 +143,7 @@ GC::Ref<MouseEvent> MouseEvent::clone() const
|
|||
init.movement_y = m_movement_y;
|
||||
init.button = m_button;
|
||||
init.buttons = m_buttons;
|
||||
init.related_target = m_related_target;
|
||||
init.related_target = related_target();
|
||||
init.ctrl_key = m_ctrl_key;
|
||||
init.shift_key = m_shift_key;
|
||||
init.alt_key = m_alt_key;
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@ public:
|
|||
i16 button() const { return m_button; }
|
||||
u16 buttons() const { return m_buttons; }
|
||||
|
||||
GC::Ptr<DOM::EventTarget> related_target() const { return m_related_target; }
|
||||
|
||||
bool get_modifier_state(String const& key_arg) const;
|
||||
|
||||
virtual u32 which() const override { return m_button + 1; }
|
||||
|
|
@ -78,7 +76,6 @@ protected:
|
|||
MouseEvent(JS::Realm&, FlyString const& event_name, Bindings::MouseEventInit const& event_init, double page_x, double page_y, double offset_x, double offset_y);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
double m_screen_x { 0 };
|
||||
double m_screen_y { 0 };
|
||||
|
|
@ -110,7 +107,6 @@ private:
|
|||
double m_movement_y { 0 };
|
||||
i16 m_button { 0 };
|
||||
u16 m_buttons { 0 };
|
||||
GC::Ptr<DOM::EventTarget> m_related_target { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
pointerover: target=left, related=null
|
||||
mouseover: target=left, related=null
|
||||
pointerout: target=left, related=right
|
||||
mouseout: target=left, related=right
|
||||
pointerover: target=right, related=left
|
||||
mouseover: target=right, related=left
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#left,
|
||||
#right {
|
||||
float: left;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
<div id="left"></div>
|
||||
<div id="right"></div>
|
||||
<script>
|
||||
test(() => {
|
||||
for (const type of ["pointerover", "mouseover", "pointerout", "mouseout"]) {
|
||||
document.body.addEventListener(type, event => {
|
||||
println(`${type}: target=${event.target.id}, related=${event.relatedTarget?.id ?? "null"}`);
|
||||
});
|
||||
}
|
||||
|
||||
internals.mouseMove(50, 50);
|
||||
internals.mouseMove(150, 50);
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in a new issue