1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use dom::bindings::codegen::Bindings::MouseEventBinding; 6 use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods; 7 use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; 8 use dom::bindings::error::Fallible; 9 use dom::bindings::inheritance::Castable; 10 use dom::bindings::reflector::reflect_dom_object; 11 use dom::bindings::root::{DomRoot, MutNullableDom, RootedReference}; 12 use dom::bindings::str::DOMString; 13 use dom::event::{Event, EventBubbles, EventCancelable}; 14 use dom::eventtarget::EventTarget; 15 use dom::uievent::UIEvent; 16 use dom::window::Window; 17 use dom_struct::dom_struct; 18 use euclid::Point2D; 19 use servo_config::prefs::PREFS; 20 use std::cell::Cell; 21 use std::default::Default; 22 23 #[dom_struct] 24 pub struct MouseEvent { 25 uievent: UIEvent, 26 screen_x: Cell<i32>, 27 screen_y: Cell<i32>, 28 client_x: Cell<i32>, 29 client_y: Cell<i32>, 30 ctrl_key: Cell<bool>, 31 shift_key: Cell<bool>, 32 alt_key: Cell<bool>, 33 meta_key: Cell<bool>, 34 button: Cell<i16>, 35 related_target: MutNullableDom<EventTarget>, 36 point_in_target: Cell<Option<Point2D<f32>>> 37 } 38 39 impl MouseEvent { new_inherited() -> MouseEvent40 fn new_inherited() -> MouseEvent { 41 MouseEvent { 42 uievent: UIEvent::new_inherited(), 43 screen_x: Cell::new(0), 44 screen_y: Cell::new(0), 45 client_x: Cell::new(0), 46 client_y: Cell::new(0), 47 ctrl_key: Cell::new(false), 48 shift_key: Cell::new(false), 49 alt_key: Cell::new(false), 50 meta_key: Cell::new(false), 51 button: Cell::new(0), 52 related_target: Default::default(), 53 point_in_target: Cell::new(None), 54 } 55 } 56 new_uninitialized(window: &Window) -> DomRoot<MouseEvent>57 pub fn new_uninitialized(window: &Window) -> DomRoot<MouseEvent> { 58 reflect_dom_object(Box::new(MouseEvent::new_inherited()), 59 window, 60 MouseEventBinding::Wrap) 61 } 62 new( window: &Window, type_: DOMString, can_bubble: EventBubbles, cancelable: EventCancelable, view: Option<&Window>, detail: i32, screen_x: i32, screen_y: i32, client_x: i32, client_y: i32, ctrl_key: bool, alt_key: bool, shift_key: bool, meta_key: bool, button: i16, related_target: Option<&EventTarget>, point_in_target: Option<Point2D<f32>> ) -> DomRoot<MouseEvent>63 pub fn new( 64 window: &Window, 65 type_: DOMString, 66 can_bubble: EventBubbles, 67 cancelable: EventCancelable, 68 view: Option<&Window>, 69 detail: i32, 70 screen_x: i32, 71 screen_y: i32, 72 client_x: i32, 73 client_y: i32, 74 ctrl_key: bool, 75 alt_key: bool, 76 shift_key: bool, 77 meta_key: bool, 78 button: i16, 79 related_target: Option<&EventTarget>, 80 point_in_target: Option<Point2D<f32>> 81 ) -> DomRoot<MouseEvent> { 82 let ev = MouseEvent::new_uninitialized(window); 83 ev.InitMouseEvent( 84 type_, bool::from(can_bubble), bool::from(cancelable), 85 view, detail, 86 screen_x, screen_y, client_x, client_y, 87 ctrl_key, alt_key, shift_key, meta_key, 88 button, related_target, 89 ); 90 ev.point_in_target.set(point_in_target); 91 ev 92 } 93 Constructor(window: &Window, type_: DOMString, init: &MouseEventBinding::MouseEventInit) -> Fallible<DomRoot<MouseEvent>>94 pub fn Constructor(window: &Window, 95 type_: DOMString, 96 init: &MouseEventBinding::MouseEventInit) -> Fallible<DomRoot<MouseEvent>> { 97 let bubbles = EventBubbles::from(init.parent.parent.parent.bubbles); 98 let cancelable = EventCancelable::from(init.parent.parent.parent.cancelable); 99 let event = MouseEvent::new( 100 window, 101 type_, 102 bubbles, 103 cancelable, 104 init.parent.parent.view.r(), 105 init.parent.parent.detail, 106 init.screenX, init.screenY, 107 init.clientX, init.clientY, init.parent.ctrlKey, 108 init.parent.altKey, init.parent.shiftKey, init.parent.metaKey, 109 init.button, init.relatedTarget.r(), None 110 ); 111 Ok(event) 112 } 113 point_in_target(&self) -> Option<Point2D<f32>>114 pub fn point_in_target(&self) -> Option<Point2D<f32>> { 115 self.point_in_target.get() 116 } 117 } 118 119 impl MouseEventMethods for MouseEvent { 120 // https://w3c.github.io/uievents/#widl-MouseEvent-screenX ScreenX(&self) -> i32121 fn ScreenX(&self) -> i32 { 122 self.screen_x.get() 123 } 124 125 // https://w3c.github.io/uievents/#widl-MouseEvent-screenY ScreenY(&self) -> i32126 fn ScreenY(&self) -> i32 { 127 self.screen_y.get() 128 } 129 130 // https://w3c.github.io/uievents/#widl-MouseEvent-clientX ClientX(&self) -> i32131 fn ClientX(&self) -> i32 { 132 self.client_x.get() 133 } 134 135 // https://w3c.github.io/uievents/#widl-MouseEvent-clientY ClientY(&self) -> i32136 fn ClientY(&self) -> i32 { 137 self.client_y.get() 138 } 139 140 // https://w3c.github.io/uievents/#widl-MouseEvent-ctrlKey CtrlKey(&self) -> bool141 fn CtrlKey(&self) -> bool { 142 self.ctrl_key.get() 143 } 144 145 // https://w3c.github.io/uievents/#widl-MouseEvent-shiftKey ShiftKey(&self) -> bool146 fn ShiftKey(&self) -> bool { 147 self.shift_key.get() 148 } 149 150 // https://w3c.github.io/uievents/#widl-MouseEvent-altKey AltKey(&self) -> bool151 fn AltKey(&self) -> bool { 152 self.alt_key.get() 153 } 154 155 // https://w3c.github.io/uievents/#widl-MouseEvent-metaKey MetaKey(&self) -> bool156 fn MetaKey(&self) -> bool { 157 self.meta_key.get() 158 } 159 160 // https://w3c.github.io/uievents/#widl-MouseEvent-button Button(&self) -> i16161 fn Button(&self) -> i16 { 162 self.button.get() 163 } 164 165 // https://w3c.github.io/uievents/#widl-MouseEvent-relatedTarget GetRelatedTarget(&self) -> Option<DomRoot<EventTarget>>166 fn GetRelatedTarget(&self) -> Option<DomRoot<EventTarget>> { 167 self.related_target.get() 168 } 169 170 // See discussion at: 171 // - https://github.com/servo/servo/issues/6643 172 // - https://bugzilla.mozilla.org/show_bug.cgi?id=1186125 173 // This returns the same result as current gecko. 174 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/which Which(&self) -> i32175 fn Which(&self) -> i32 { 176 if PREFS.get("dom.mouseevent.which.enabled").as_boolean().unwrap_or(false) { 177 (self.button.get() + 1) as i32 178 } else { 179 0 180 } 181 } 182 183 // https://w3c.github.io/uievents/#widl-MouseEvent-initMouseEvent InitMouseEvent( &self, type_arg: DOMString, can_bubble_arg: bool, cancelable_arg: bool, view_arg: Option<&Window>, detail_arg: i32, screen_x_arg: i32, screen_y_arg: i32, client_x_arg: i32, client_y_arg: i32, ctrl_key_arg: bool, alt_key_arg: bool, shift_key_arg: bool, meta_key_arg: bool, button_arg: i16, related_target_arg: Option<&EventTarget>, )184 fn InitMouseEvent( 185 &self, 186 type_arg: DOMString, 187 can_bubble_arg: bool, 188 cancelable_arg: bool, 189 view_arg: Option<&Window>, 190 detail_arg: i32, 191 screen_x_arg: i32, 192 screen_y_arg: i32, 193 client_x_arg: i32, 194 client_y_arg: i32, 195 ctrl_key_arg: bool, 196 alt_key_arg: bool, 197 shift_key_arg: bool, 198 meta_key_arg: bool, 199 button_arg: i16, 200 related_target_arg: Option<&EventTarget>, 201 ) { 202 if self.upcast::<Event>().dispatching() { 203 return; 204 } 205 206 self.upcast::<UIEvent>() 207 .InitUIEvent(type_arg, can_bubble_arg, cancelable_arg, view_arg, detail_arg); 208 self.screen_x.set(screen_x_arg); 209 self.screen_y.set(screen_y_arg); 210 self.client_x.set(client_x_arg); 211 self.client_y.set(client_y_arg); 212 self.ctrl_key.set(ctrl_key_arg); 213 self.alt_key.set(alt_key_arg); 214 self.shift_key.set(shift_key_arg); 215 self.meta_key.set(meta_key_arg); 216 self.button.set(button_arg); 217 self.related_target.set(related_target_arg); 218 } 219 220 // https://dom.spec.whatwg.org/#dom-event-istrusted IsTrusted(&self) -> bool221 fn IsTrusted(&self) -> bool { 222 self.uievent.IsTrusted() 223 } 224 } 225