diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 30a67590507..9eef30aa0a4 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -2186,11 +2186,11 @@ impl Document { pub(crate) fn handle_wheel_event( &self, event: WheelEvent, - hit_test_result: Option, + input_event: &ConstellationInputEvent, can_gc: CanGc, ) { // Ignore all incoming events without a hit test. - let Some(hit_test_result) = hit_test_result else { + let Some(hit_test_result) = &input_event.hit_test_result else { return; }; @@ -2220,6 +2220,16 @@ impl Document { EventCancelable::Cancelable, Some(&self.window), 0i32, + hit_test_result.point_in_viewport.to_i32(), + hit_test_result.point_in_viewport.to_i32(), + hit_test_result + .point_relative_to_initial_containing_block + .to_i32(), + input_event.active_keyboard_modifiers, + 0i16, + input_event.pressed_mouse_buttons, + None, + None, // winit defines positive wheel delta values as revealing more content left/up. // https://docs.rs/winit-gtk/latest/winit/event/enum.MouseScrollDelta.html // This is the opposite of wheel delta in uievents diff --git a/components/script/dom/wheelevent.rs b/components/script/dom/wheelevent.rs index 2923e49d5a2..05d8cd2c03a 100644 --- a/components/script/dom/wheelevent.rs +++ b/components/script/dom/wheelevent.rs @@ -5,7 +5,10 @@ use std::cell::Cell; use dom_struct::dom_struct; +use euclid::Point2D; use js::rust::HandleObject; +use keyboard_types::Modifiers; +use style_traits::CSSPixel; use crate::dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods; use crate::dom::bindings::codegen::Bindings::WheelEventBinding; @@ -17,6 +20,7 @@ use crate::dom::bindings::reflector::reflect_dom_object_with_proto; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; use crate::dom::event::{Event, EventBubbles, EventCancelable}; +use crate::dom::eventtarget::EventTarget; use crate::dom::mouseevent::MouseEvent; use crate::dom::window::Window; use crate::script_runtime::CanGc; @@ -57,6 +61,14 @@ impl WheelEvent { cancelable: EventCancelable, view: Option<&Window>, detail: i32, + screen_point: Point2D, + client_point: Point2D, + page_point: Point2D, + modifiers: Modifiers, + button: i16, + buttons: u16, + related_target: Option<&EventTarget>, + point_in_target: Option>, delta_x: Finite, delta_y: Finite, delta_z: Finite, @@ -64,8 +76,26 @@ impl WheelEvent { can_gc: CanGc, ) -> DomRoot { Self::new_with_proto( - window, None, type_, can_bubble, cancelable, view, detail, delta_x, delta_y, delta_z, - delta_mode, can_gc, + window, + None, + type_, + can_bubble, + cancelable, + view, + detail, + screen_point, + client_point, + page_point, + modifiers, + button, + buttons, + related_target, + point_in_target, + delta_x, + delta_y, + delta_z, + delta_mode, + can_gc, ) } @@ -78,6 +108,14 @@ impl WheelEvent { cancelable: EventCancelable, view: Option<&Window>, detail: i32, + screen_point: Point2D, + client_point: Point2D, + page_point: Point2D, + modifiers: Modifiers, + button: i16, + buttons: u16, + related_target: Option<&EventTarget>, + point_in_target: Option>, delta_x: Finite, delta_y: Finite, delta_z: Finite, @@ -85,21 +123,74 @@ impl WheelEvent { can_gc: CanGc, ) -> DomRoot { let ev = WheelEvent::new_unintialized(window, proto, can_gc); - ev.InitWheelEvent( + ev.intitialize_wheel_event( type_, - bool::from(can_bubble), - bool::from(cancelable), + can_bubble, + cancelable, view, detail, + screen_point, + client_point, + page_point, + modifiers, + button, + buttons, + related_target, + point_in_target, delta_x, delta_y, delta_z, delta_mode, - can_gc, ); ev } + + #[allow(clippy::too_many_arguments)] + pub(crate) fn intitialize_wheel_event( + &self, + type_: DOMString, + can_bubble: EventBubbles, + cancelable: EventCancelable, + view: Option<&Window>, + detail: i32, + screen_point: Point2D, + client_point: Point2D, + page_point: Point2D, + modifiers: Modifiers, + button: i16, + buttons: u16, + related_target: Option<&EventTarget>, + point_in_target: Option>, + delta_x: Finite, + delta_y: Finite, + delta_z: Finite, + delta_mode: u32, + ) { + if self.upcast::().dispatching() { + return; + } + + self.upcast::().initialize_mouse_event( + type_, + can_bubble, + cancelable, + view, + detail, + screen_point, + client_point, + page_point, + modifiers, + button, + buttons, + related_target, + point_in_target, + ); + self.delta_x.set(delta_x); + self.delta_y.set(delta_y); + self.delta_z.set(delta_z); + self.delta_mode.set(delta_mode); + } } impl WheelEventMethods for WheelEvent { @@ -111,14 +202,31 @@ impl WheelEventMethods for WheelEvent { type_: DOMString, init: &WheelEventBinding::WheelEventInit, ) -> Fallible> { + let bubbles = EventBubbles::from(init.parent.parent.parent.parent.bubbles); + let cancelable = EventCancelable::from(init.parent.parent.parent.parent.cancelable); + let scroll_offset = window.scroll_offset(can_gc); + + let page_point = Point2D::::new( + scroll_offset.x as i32 + init.parent.clientX, + scroll_offset.y as i32 + init.parent.clientY, + ); + let event = WheelEvent::new_with_proto( window, proto, type_, - EventBubbles::from(init.parent.parent.parent.parent.bubbles), - EventCancelable::from(init.parent.parent.parent.parent.cancelable), + bubbles, + cancelable, init.parent.parent.parent.view.as_deref(), init.parent.parent.parent.detail, + Point2D::new(init.parent.screenX, init.parent.screenY), + Point2D::new(init.parent.clientX, init.parent.clientY), + Point2D::new(page_point.x, page_point.y), + init.parent.parent.modifiers(), + init.parent.button, + init.parent.buttons, + init.parent.relatedTarget.as_deref(), + None, init.deltaX, init.deltaY, init.deltaZ, diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 18bf170f1f3..f25966a215f 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1133,7 +1133,7 @@ impl ScriptThread { } }, InputEvent::Wheel(wheel_event) => { - document.handle_wheel_event(wheel_event, event.hit_test_result, can_gc); + document.handle_wheel_event(wheel_event, &event, can_gc); }, InputEvent::Keyboard(keyboard_event) => { document.dispatch_key_event(keyboard_event, can_gc); diff --git a/tests/wpt/meta/dom/events/Event-subclasses-constructors.html.ini b/tests/wpt/meta/dom/events/Event-subclasses-constructors.html.ini index 266d22518a2..42a81c01e0c 100644 --- a/tests/wpt/meta/dom/events/Event-subclasses-constructors.html.ini +++ b/tests/wpt/meta/dom/events/Event-subclasses-constructors.html.ini @@ -1,7 +1,4 @@ [Event-subclasses-constructors.html] - [WheelEvent constructor (argument with non-default values)] - expected: FAIL - [KeyboardEvent constructor (argument with non-default values)] expected: FAIL diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/wheel.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/wheel.py.ini index a170a1026cd..d886b85b230 100644 --- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/wheel.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/wheel.py.ini @@ -5,9 +5,6 @@ [test_scroll_shadow_tree[inner-closed\]] expected: FAIL - [test_scroll_with_key_pressed] - expected: FAIL - [test_scroll_shadow_tree[outer-open\]] expected: FAIL