Set composed flag for mouse events dispatched by the UA (#36010)

* Add doc comments to mouse event methods

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

* Make MouseEvents composed by default

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-03-18 10:35:24 +01:00 committed by GitHub
parent bcdd34e2aa
commit 2113e54819
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 98 additions and 54 deletions

View file

@ -1284,14 +1284,9 @@ impl Document {
return;
};
let mouse_event_type_string = match event.action {
MouseButtonAction::Click => "click".to_owned(),
MouseButtonAction::Up => "mouseup".to_owned(),
MouseButtonAction::Down => "mousedown".to_owned(),
};
debug!(
"{}: at {:?}",
mouse_event_type_string, hit_test_result.point_in_viewport
"{:?}: at {:?}",
event.action, hit_test_result.point_in_viewport
);
let node = unsafe { node::from_untrusted_compositor_node_address(hit_test_result.node) };
@ -1304,7 +1299,7 @@ impl Document {
};
let node = el.upcast::<Node>();
debug!("{} on {:?}", mouse_event_type_string, node.debug_str());
debug!("{:?} on {:?}", event.action, node.debug_str());
// Prevent click event if form control element is disabled.
if let MouseButtonAction::Click = event.action {
// The click event is filtered by the disabled state.
@ -1316,35 +1311,14 @@ impl Document {
self.request_focus(Some(&*el), FocusType::Element, can_gc);
}
// https://w3c.github.io/uievents/#event-type-click
let client_x = hit_test_result.point_in_viewport.x as i32;
let client_y = hit_test_result.point_in_viewport.y as i32;
let click_count = 1;
let dom_event = MouseEvent::new(
&self.window,
DOMString::from(mouse_event_type_string),
EventBubbles::Bubbles,
EventCancelable::Cancelable,
Some(&self.window),
click_count,
client_x,
client_y,
client_x,
client_y, // TODO: Get real screen coordinates?
false,
false,
false,
false,
event.button.into(),
let dom_event = DomRoot::upcast::<Event>(MouseEvent::for_platform_mouse_event(
event,
pressed_mouse_buttons,
None,
Some(hit_test_result.point_relative_to_item),
&self.window,
&hit_test_result,
can_gc,
);
let dom_event = dom_event.upcast::<Event>();
));
// https://w3c.github.io/uievents/#trusted-events
dom_event.set_trusted(true);
// https://html.spec.whatwg.org/multipage/#run-authentic-click-activation-steps
let activatable = el.as_maybe_activatable();
match event.action {

View file

@ -9,6 +9,7 @@ use dom_struct::dom_struct;
use euclid::default::Point2D;
use js::rust::HandleObject;
use servo_config::pref;
use webrender_traits::CompositorHitTestResult;
use crate::dom::bindings::codegen::Bindings::EventBinding::Event_Binding::EventMethods;
use crate::dom::bindings::codegen::Bindings::MouseEventBinding;
@ -26,25 +27,49 @@ use crate::dom::uievent::UIEvent;
use crate::dom::window::Window;
use crate::script_runtime::CanGc;
/// <https://w3c.github.io/uievents/#interface-mouseevent>
#[dom_struct]
pub(crate) struct MouseEvent {
uievent: UIEvent,
/// <https://w3c.github.io/uievents/#dom-mouseevent-screenx>
screen_x: Cell<i32>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-screeny>
screen_y: Cell<i32>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-clientx>
client_x: Cell<i32>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-clienty>
client_y: Cell<i32>,
page_x: Cell<i32>,
page_y: Cell<i32>,
x: Cell<i32>,
y: Cell<i32>,
offset_x: Cell<i32>,
offset_y: Cell<i32>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-ctrlkey>
ctrl_key: Cell<bool>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-shiftkey>
shift_key: Cell<bool>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-altkey>
alt_key: Cell<bool>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-metakey>
meta_key: Cell<bool>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-button>
button: Cell<i16>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-buttons>
buttons: Cell<u16>,
/// <https://w3c.github.io/uievents/#dom-mouseevent-relatedtarget>
related_target: MutNullableDom<EventTarget>,
#[no_trace]
point_in_target: Cell<Option<Point2D<f32>>>,
@ -237,10 +262,55 @@ impl MouseEvent {
pub(crate) fn point_in_target(&self) -> Option<Point2D<f32>> {
self.point_in_target.get()
}
/// Create a [MouseEvent] triggered by the embedder
pub(crate) fn for_platform_mouse_event(
event: embedder_traits::MouseButtonEvent,
pressed_mouse_buttons: u16,
window: &Window,
hit_test_result: &CompositorHitTestResult,
can_gc: CanGc,
) -> DomRoot<Self> {
let mouse_event_type_string = match event.action {
embedder_traits::MouseButtonAction::Click => "click",
embedder_traits::MouseButtonAction::Up => "mouseup",
embedder_traits::MouseButtonAction::Down => "mousedown",
};
let client_x = hit_test_result.point_in_viewport.x as i32;
let client_y = hit_test_result.point_in_viewport.y as i32;
let click_count = 1;
let mouse_event = MouseEvent::new(
window,
mouse_event_type_string.into(),
EventBubbles::Bubbles,
EventCancelable::Cancelable,
Some(window),
click_count,
client_x,
client_y,
client_x,
client_y, // TODO: Get real screen coordinates?
false,
false,
false,
false,
event.button.into(),
pressed_mouse_buttons,
None,
Some(hit_test_result.point_relative_to_item),
can_gc,
);
mouse_event.upcast::<Event>().set_trusted(true);
mouse_event.upcast::<Event>().set_composed(true);
mouse_event
}
}
impl MouseEventMethods<crate::DomTypeHolder> for MouseEvent {
// https://w3c.github.io/uievents/#dom-mouseevent-mouseevent
/// <https://w3c.github.io/uievents/#dom-mouseevent-mouseevent>
fn Constructor(
window: &Window,
proto: Option<HandleObject>,
@ -275,27 +345,27 @@ impl MouseEventMethods<crate::DomTypeHolder> for MouseEvent {
Ok(event)
}
// https://w3c.github.io/uievents/#widl-MouseEvent-screenX
/// <https://w3c.github.io/uievents/#widl-MouseEvent-screenX>
fn ScreenX(&self) -> i32 {
self.screen_x.get()
}
// https://w3c.github.io/uievents/#widl-MouseEvent-screenY
/// <https://w3c.github.io/uievents/#widl-MouseEvent-screenY>
fn ScreenY(&self) -> i32 {
self.screen_y.get()
}
// https://w3c.github.io/uievents/#widl-MouseEvent-clientX
/// <https://w3c.github.io/uievents/#widl-MouseEvent-clientX>
fn ClientX(&self) -> i32 {
self.client_x.get()
}
// https://w3c.github.io/uievents/#widl-MouseEvent-clientY
/// <https://w3c.github.io/uievents/#widl-MouseEvent-clientY>
fn ClientY(&self) -> i32 {
self.client_y.get()
}
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-pagex
/// <https://drafts.csswg.org/cssom-view/#dom-mouseevent-pagex>
fn PageX(&self) -> i32 {
if self.upcast::<Event>().dispatching() {
self.page_x.get()
@ -306,7 +376,7 @@ impl MouseEventMethods<crate::DomTypeHolder> for MouseEvent {
}
}
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-pagey
/// <https://drafts.csswg.org/cssom-view/#dom-mouseevent-pagey>
fn PageY(&self) -> i32 {
if self.upcast::<Event>().dispatching() {
self.page_y.get()
@ -317,17 +387,17 @@ impl MouseEventMethods<crate::DomTypeHolder> for MouseEvent {
}
}
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-x
/// <https://drafts.csswg.org/cssom-view/#dom-mouseevent-x>
fn X(&self) -> i32 {
self.client_x.get()
}
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-y
/// <https://drafts.csswg.org/cssom-view/#dom-mouseevent-y>
fn Y(&self) -> i32 {
self.client_y.get()
}
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
/// <https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx>
fn OffsetX(&self, can_gc: CanGc) -> i32 {
let event = self.upcast::<Event>();
if event.dispatching() {
@ -347,7 +417,7 @@ impl MouseEventMethods<crate::DomTypeHolder> for MouseEvent {
}
}
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsety
/// <https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsety>
fn OffsetY(&self, can_gc: CanGc) -> i32 {
let event = self.upcast::<Event>();
if event.dispatching() {
@ -367,37 +437,37 @@ impl MouseEventMethods<crate::DomTypeHolder> for MouseEvent {
}
}
// https://w3c.github.io/uievents/#widl-MouseEvent-ctrlKey
/// <https://w3c.github.io/uievents/#dom-mouseevent-ctrlkey>
fn CtrlKey(&self) -> bool {
self.ctrl_key.get()
}
// https://w3c.github.io/uievents/#widl-MouseEvent-shiftKey
/// <https://w3c.github.io/uievents/#dom-mouseevent-shiftkey>
fn ShiftKey(&self) -> bool {
self.shift_key.get()
}
// https://w3c.github.io/uievents/#widl-MouseEvent-altKey
/// <https://w3c.github.io/uievents/#dom-mouseevent-altkey>
fn AltKey(&self) -> bool {
self.alt_key.get()
}
// https://w3c.github.io/uievents/#widl-MouseEvent-metaKey
/// <https://w3c.github.io/uievents/#dom-mouseevent-metakey>
fn MetaKey(&self) -> bool {
self.meta_key.get()
}
// https://w3c.github.io/uievents/#widl-MouseEvent-button
/// <https://w3c.github.io/uievents/#dom-mouseevent-button>
fn Button(&self) -> i16 {
self.button.get()
}
// https://w3c.github.io/uievents/#dom-mouseevent-buttons
/// <https://w3c.github.io/uievents/#dom-mouseevent-buttons>
fn Buttons(&self) -> u16 {
self.buttons.get()
}
// https://w3c.github.io/uievents/#widl-MouseEvent-relatedTarget
/// <https://w3c.github.io/uievents/#widl-MouseEvent-relatedTarget>
fn GetRelatedTarget(&self) -> Option<DomRoot<EventTarget>> {
self.related_target.get()
}
@ -415,7 +485,7 @@ impl MouseEventMethods<crate::DomTypeHolder> for MouseEvent {
}
}
// https://w3c.github.io/uievents/#widl-MouseEvent-initMouseEvent
/// <https://w3c.github.io/uievents/#widl-MouseEvent-initMouseEvent>
fn InitMouseEvent(
&self,
type_arg: DOMString,
@ -457,7 +527,7 @@ impl MouseEventMethods<crate::DomTypeHolder> for MouseEvent {
self.related_target.set(related_target_arg);
}
// https://dom.spec.whatwg.org/#dom-event-istrusted
/// <https://dom.spec.whatwg.org/#dom-event-istrusted>
fn IsTrusted(&self) -> bool {
self.uievent.IsTrusted()
}