blob: 2c9bdb7a42d476fa6f305c567e3eb1f581282405 [file] [log] [blame] [edit]
/* 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 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;
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::eventtarget::EventTarget;
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<Finite<f64>>,
delta_y: Cell<Finite<f64>>,
delta_z: Cell<Finite<f64>>,
delta_mode: Cell<u32>,
}
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<HandleObject>,
can_gc: CanGc,
) -> DomRoot<WheelEvent> {
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,
screen_point: Point2D<i32, CSSPixel>,
client_point: Point2D<i32, CSSPixel>,
page_point: Point2D<i32, CSSPixel>,
modifiers: Modifiers,
button: i16,
buttons: u16,
related_target: Option<&EventTarget>,
point_in_target: Option<Point2D<f32, CSSPixel>>,
delta_x: Finite<f64>,
delta_y: Finite<f64>,
delta_z: Finite<f64>,
delta_mode: u32,
can_gc: CanGc,
) -> DomRoot<WheelEvent> {
Self::new_with_proto(
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,
)
}
#[allow(clippy::too_many_arguments)]
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
can_bubble: EventBubbles,
cancelable: EventCancelable,
view: Option<&Window>,
detail: i32,
screen_point: Point2D<i32, CSSPixel>,
client_point: Point2D<i32, CSSPixel>,
page_point: Point2D<i32, CSSPixel>,
modifiers: Modifiers,
button: i16,
buttons: u16,
related_target: Option<&EventTarget>,
point_in_target: Option<Point2D<f32, CSSPixel>>,
delta_x: Finite<f64>,
delta_y: Finite<f64>,
delta_z: Finite<f64>,
delta_mode: u32,
can_gc: CanGc,
) -> DomRoot<WheelEvent> {
let ev = WheelEvent::new_unintialized(window, proto, can_gc);
ev.intitialize_wheel_event(
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,
);
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<i32, CSSPixel>,
client_point: Point2D<i32, CSSPixel>,
page_point: Point2D<i32, CSSPixel>,
modifiers: Modifiers,
button: i16,
buttons: u16,
related_target: Option<&EventTarget>,
point_in_target: Option<Point2D<f32, CSSPixel>>,
delta_x: Finite<f64>,
delta_y: Finite<f64>,
delta_z: Finite<f64>,
delta_mode: u32,
) {
if self.upcast::<Event>().dispatching() {
return;
}
self.upcast::<MouseEvent>().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<crate::DomTypeHolder> for WheelEvent {
// https://w3c.github.io/uievents/#dom-wheelevent-wheelevent
fn Constructor(
window: &Window,
proto: Option<HandleObject>,
can_gc: CanGc,
type_: DOMString,
init: &WheelEventBinding::WheelEventInit,
) -> Fallible<DomRoot<WheelEvent>> {
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();
let page_point = Point2D::<i32, CSSPixel>::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_,
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,
init.deltaMode,
can_gc,
);
Ok(event)
}
// https://w3c.github.io/uievents/#widl-WheelEvent-deltaX
fn DeltaX(&self) -> Finite<f64> {
self.delta_x.get()
}
// https://w3c.github.io/uievents/#widl-WheelEvent-deltaY
fn DeltaY(&self) -> Finite<f64> {
self.delta_y.get()
}
// https://w3c.github.io/uievents/#widl-WheelEvent-deltaZ
fn DeltaZ(&self) -> Finite<f64> {
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<f64>,
delta_y_arg: Finite<f64>,
delta_z_arg: Finite<f64>,
delta_mode_arg: u32,
) {
if self.upcast::<Event>().dispatching() {
return;
}
self.upcast::<MouseEvent>().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()
}
}