/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::cell::Cell; use dom_struct::dom_struct; use js::rust::HandleObject; use crate::dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods; use crate::dom::bindings::codegen::Bindings::WheelEventBinding; use crate::dom::bindings::codegen::Bindings::WheelEventBinding::WheelEventMethods; use crate::dom::bindings::error::Fallible; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::num::Finite; 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::mouseevent::MouseEvent; use crate::dom::window::Window; use crate::script_runtime::CanGc; #[dom_struct] pub(crate) struct WheelEvent { mouseevent: MouseEvent, delta_x: Cell>, delta_y: Cell>, delta_z: Cell>, delta_mode: Cell, } impl WheelEvent { fn new_inherited() -> WheelEvent { WheelEvent { mouseevent: MouseEvent::new_inherited(), delta_x: Cell::new(Finite::wrap(0.0)), delta_y: Cell::new(Finite::wrap(0.0)), delta_z: Cell::new(Finite::wrap(0.0)), delta_mode: Cell::new(0), } } fn new_unintialized( window: &Window, proto: Option, can_gc: CanGc, ) -> DomRoot { reflect_dom_object_with_proto(Box::new(WheelEvent::new_inherited()), window, proto, can_gc) } #[allow(clippy::too_many_arguments)] pub(crate) fn new( window: &Window, type_: DOMString, can_bubble: EventBubbles, cancelable: EventCancelable, view: Option<&Window>, detail: i32, delta_x: Finite, delta_y: Finite, delta_z: Finite, delta_mode: u32, 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, ) } #[allow(clippy::too_many_arguments)] fn new_with_proto( window: &Window, proto: Option, type_: DOMString, can_bubble: EventBubbles, cancelable: EventCancelable, view: Option<&Window>, detail: i32, delta_x: Finite, delta_y: Finite, delta_z: Finite, delta_mode: u32, can_gc: CanGc, ) -> DomRoot { let ev = WheelEvent::new_unintialized(window, proto, can_gc); ev.InitWheelEvent( type_, bool::from(can_bubble), bool::from(cancelable), view, detail, delta_x, delta_y, delta_z, delta_mode, ); ev } } impl WheelEventMethods for WheelEvent { // https://w3c.github.io/uievents/#dom-wheelevent-wheelevent fn Constructor( window: &Window, proto: Option, can_gc: CanGc, type_: DOMString, init: &WheelEventBinding::WheelEventInit, ) -> Fallible> { 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), init.parent.parent.parent.view.as_deref(), init.parent.parent.parent.detail, init.deltaX, init.deltaY, init.deltaZ, init.deltaMode, can_gc, ); Ok(event) } // https://w3c.github.io/uievents/#widl-WheelEvent-deltaX fn DeltaX(&self) -> Finite { self.delta_x.get() } // https://w3c.github.io/uievents/#widl-WheelEvent-deltaY fn DeltaY(&self) -> Finite { self.delta_y.get() } // https://w3c.github.io/uievents/#widl-WheelEvent-deltaZ fn DeltaZ(&self) -> Finite { self.delta_z.get() } // https://w3c.github.io/uievents/#widl-WheelEvent-deltaMode fn DeltaMode(&self) -> u32 { self.delta_mode.get() } // https://w3c.github.io/uievents/#widl-WheelEvent-initWheelEvent fn InitWheelEvent( &self, type_arg: DOMString, can_bubble_arg: bool, cancelable_arg: bool, view_arg: Option<&Window>, detail_arg: i32, delta_x_arg: Finite, delta_y_arg: Finite, delta_z_arg: Finite, delta_mode_arg: u32, ) { if self.upcast::().dispatching() { return; } self.upcast::().InitMouseEvent( type_arg, can_bubble_arg, cancelable_arg, view_arg, detail_arg, self.mouseevent.ScreenX(), self.mouseevent.ScreenY(), self.mouseevent.ClientX(), self.mouseevent.ClientY(), self.mouseevent.CtrlKey(), self.mouseevent.AltKey(), self.mouseevent.ShiftKey(), self.mouseevent.MetaKey(), self.mouseevent.Button(), self.mouseevent.GetRelatedTarget().as_deref(), ); self.delta_x.set(delta_x_arg); self.delta_y.set(delta_y_arg); self.delta_z.set(delta_z_arg); self.delta_mode.set(delta_mode_arg); } // https://dom.spec.whatwg.org/#dom-event-istrusted fn IsTrusted(&self) -> bool { self.mouseevent.IsTrusted() } }