1 use webcore::value::{Reference, Value};
2 use webcore::try_from::{TryFrom, TryInto};
3 use webapi::event_target::EventTarget;
4 use webapi::window::Window;
5 
6 /// The `IEvent` interface represents any event which takes place in the DOM; some
7 /// are user-generated (such as mouse or keyboard events), while others are
8 /// generated by APIs (such as events that indicate an animation has finished
9 /// running, a video has been paused, and so forth). There are many types of event,
10 /// some of which use other interfaces based on the main `IEvent` interface. `IEvent`
11 /// itself contains the properties and methods which are common to all events.
12 ///
13 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event)
14 pub trait IEvent: AsRef< Reference > + TryFrom< Value > {
15     /// Indicates whether this event bubbles upward through the DOM.
16     ///
17     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event)
18     #[inline]
bubbles( &self ) -> bool19     fn bubbles( &self ) -> bool {
20         js!(
21             return @{self.as_ref()}.bubbles;
22         ).try_into().unwrap()
23     }
24 
25     /// A historical alias to `Event.stopPropagation()`.
26     ///
27     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/cancelBubble)
28     #[inline]
cancel_bubble( &self ) -> bool29     fn cancel_bubble( &self ) -> bool {
30         js!(
31             return @{self.as_ref()}.cancelBubble;
32         ).try_into().unwrap()
33     }
34 
35     /// A historical alias to `Event.stopPropagation()`.
36     /// Setting this to `true` before returning from an event handler will stop propagation
37     /// of the event.
38     ///
39     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/cancelBubble)
40     #[inline]
set_cancel_bubble( &self, value: bool )41     fn set_cancel_bubble( &self, value: bool ) {
42         js! { @(no_return)
43             @{self.as_ref()}.cancelBubble = @{value};
44         }
45     }
46 
47     /// Indicates whether the event is cancelable.
48     ///
49     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/cancelable)
50     #[inline]
cancelable( &self ) -> bool51     fn cancelable( &self ) -> bool {
52         js!(
53             return @{self.as_ref()}.cancelable;
54         ).try_into().unwrap()
55     }
56 
57     /// A reference to the currently registered target of this event.
58     ///
59     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget)
60     #[inline]
current_target( &self ) -> Option< EventTarget >61     fn current_target( &self ) -> Option< EventTarget > {
62         js!(
63             return @{self.as_ref()}.currentTarget;
64         ).try_into().ok()
65     }
66 
67     /// Indicates whether `preventDefault` has been called on this event.
68     ///
69     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/defaultPrevented)
70     #[inline]
default_prevented( &self ) -> bool71     fn default_prevented( &self ) -> bool {
72         js!(
73             return @{self.as_ref()}.defaultPrevented;
74         ).try_into().unwrap()
75     }
76 
77     /// Indicates which phase of event flow is currently being evaluated.
78     ///
79     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/eventPhase)
event_phase( &self ) -> EventPhase80     fn event_phase( &self ) -> EventPhase {
81         match js!(
82             return @{self.as_ref()}.eventPhase;
83         ).try_into().unwrap() {
84             0 => EventPhase::None,
85             1 => EventPhase::Capturing,
86             2 => EventPhase::AtTarget,
87             3 => EventPhase::Bubbling,
88             _ => unreachable!("Unexpected EventPhase type"),
89         }
90     }
91 
92     /// Prevents any further listeners from being called for this event.
93     ///
94     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/stopImmediatePropagation)
95     #[inline]
stop_immediate_propagation( &self )96     fn stop_immediate_propagation( &self ) {
97         js! { @(no_return)
98             @{self.as_ref()}.stopImmediatePropagation();
99         }
100     }
101 
102     /// Stops the propagation of this event to descendants in the DOM.
103     ///
104     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation)
105     #[inline]
stop_propagation( &self )106     fn stop_propagation( &self ) {
107         js! { @(no_return)
108             @{self.as_ref()}.stopPropagation();
109         }
110     }
111 
112 
113     /// Returns a reference to the target to which this event was originally registered.
114     ///
115     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/target)
116     #[inline]
target( &self ) -> Option< EventTarget >117     fn target( &self ) -> Option< EventTarget > {
118         js!(
119             return @{self.as_ref()}.target;
120         ).try_into().ok()
121     }
122 
123     /// Returns the time in milliseconds at which this event was created.
124     ///
125     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/timeStamp)
126     #[inline]
time_stamp( &self ) -> Option< f64 >127     fn time_stamp( &self ) -> Option< f64 > {
128         js!(
129             return @{self.as_ref()}.timeStamp;
130         ).try_into().ok()
131     }
132 
133     /// Indicates whether the event was generated by a user action.
134     #[inline]
is_trusted( &self ) -> bool135     fn is_trusted( &self ) -> bool {
136         js!(
137             return @{self.as_ref()}.isTrusted;
138         ).try_into().unwrap()
139     }
140 
141     /// Returns a string containing the type of event. It is set when
142     /// the event is constructed and is the name commonly used to refer
143     /// to the specific event.
144     ///
145     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/type)
146     #[inline]
event_type( &self ) -> String147     fn event_type( &self ) -> String {
148         js!(
149             return @{self.as_ref()}.type;
150         ).try_into().unwrap()
151     }
152 
153     /// Cancels the event if it is cancelable, without
154     /// stopping further propagation of the event.
155     ///
156     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
157     #[inline]
prevent_default( &self )158     fn prevent_default( &self ) {
159         js! { @(no_return)
160             @{self.as_ref()}.preventDefault();
161         }
162     }
163 }
164 
165 /// Indicates the phase of event flow during event proessing.
166 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
167 pub enum EventPhase {
168     /// No event is currently being processed.
169     None,
170     /// The event is being propagated down through the target's ancestors.
171     Capturing,
172     /// The target is currently processing the event.
173     AtTarget,
174     /// The event is propagating back up through the target's ancestors.
175     Bubbling,
176 }
177 
178 pub trait ConcreteEvent: IEvent {
179     /// A string representing the event type.
180     ///
181     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event/type)
182     const EVENT_TYPE: &'static str;
183 }
184 
185 /// A reference to a JavaScript object which implements the [IEvent](trait.IEvent.html)
186 /// interface.
187 ///
188 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Event)
189 pub struct Event( Reference );
190 
191 impl IEvent for Event {}
192 
193 reference_boilerplate! {
194     Event,
195     instanceof Event
196 }
197 
198 /// The `ChangeEvent` is fired for input, select, and textarea
199 /// elements when a change to the element's value is committed
200 /// by the user. Unlike the input event, the change event is not
201 /// necessarily fired for each change to an element's value.
202 ///
203 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/change)
204 pub struct ChangeEvent( Reference );
205 
206 impl IEvent for ChangeEvent {}
207 impl ConcreteEvent for ChangeEvent {
208     const EVENT_TYPE: &'static str = "change";
209 }
210 
211 reference_boilerplate! {
212     ChangeEvent,
213     instanceof Event
214     convertible to Event
215 }
216 
217 /// The `IUiEvent` interface represents simple user interface events.
218 ///
219 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent)
220 pub trait IUiEvent: IEvent {
221     /// Provides the current click count for this event, if applicable.
222     ///
223     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail)
224     #[inline]
detail( &self ) -> i32225     fn detail( &self ) -> i32 {
226         js!(
227             return @{self.as_ref()}.detail;
228         ).try_into().unwrap()
229     }
230 
231     /// Returns the `WindowProxy` that generated the event.
232     ///
233     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/view)
234     #[inline]
view( &self ) -> Option< Window >235     fn view( &self ) -> Option< Window > {
236         js!(
237             return @{self.as_ref()}.view;
238         ).try_into().ok()
239     }
240 }
241 
242 /// A reference to a JavaScript object which implements the [IUiEvent](trait.IUiEvent.html)
243 /// interface.
244 ///
245 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent)
246 pub struct UiEvent( Reference );
247 
248 impl IEvent for UiEvent {}
249 impl IUiEvent for UiEvent {}
250 
251 reference_boilerplate! {
252     UiEvent,
253     instanceof UIEvent
254     convertible to Event
255 }
256 
257 /// The `LoadEvent` is fired when a resource and its dependent resources have finished loading.
258 ///
259 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/load)
260 pub struct LoadEvent( Reference );
261 
262 impl IEvent for LoadEvent {}
263 impl IUiEvent for LoadEvent {}
264 impl ConcreteEvent for LoadEvent {
265     const EVENT_TYPE: &'static str = "load";
266 }
267 
268 reference_boilerplate! {
269     LoadEvent,
270     instanceof UiEvent
271     convertible to Event
272     convertible to UiEvent
273 }
274 
275 /// The `IMouseEvent` interface represents events that occur due to the user
276 /// interacting with a pointing device (such as a mouse).
277 ///
278 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
279 pub trait IMouseEvent: IUiEvent {
280     /// Returns whether the Alt key was down when this event was fired.
281     ///
282     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/altKey)
283     #[inline]
alt_key( &self ) -> bool284     fn alt_key( &self ) -> bool {
285         js!(
286             return @{self.as_ref()}.altKey;
287         ).try_into().unwrap()
288     }
289 
290     /// Indicates the mouse button that fired this event.
291     ///
292     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button)
button( &self ) -> MouseButton293     fn button( &self ) -> MouseButton {
294         match js!(
295             return @{self.as_ref()}.button;
296         ).try_into().unwrap() {
297             0 => MouseButton::Left,
298             1 => MouseButton::Wheel,
299             2 => MouseButton::Right,
300             3 => MouseButton::Button4,
301             4 => MouseButton::Button5,
302             _ => unreachable!("Unexpected MouseEvent.button value"),
303         }
304     }
305 
306     /// Indicates which mouse buttons were down when this event was fired.
307     ///
308     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons)
buttons( &self ) -> MouseButtonsState309     fn buttons( &self ) -> MouseButtonsState {
310         MouseButtonsState(
311             js!(
312                 return @{self.as_ref()}.buttons;
313             ).try_into().unwrap()
314         )
315     }
316 
317     /// Returns the X position in the application's client area where this event occured.
318     ///
319     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX)
320     #[inline]
client_x( &self ) -> f64321     fn client_x( &self ) -> f64 {
322         js!(
323             return @{self.as_ref()}.clientX;
324         ).try_into().unwrap()
325     }
326 
327     /// Returns the Y position in the application's client area where this event occured.
328     ///
329     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientY)
330     #[inline]
client_y( &self ) -> f64331     fn client_y( &self ) -> f64 {
332         js!(
333             return @{self.as_ref()}.clientY;
334         ).try_into().unwrap()
335     }
336 
337     /// Indicates whether the Ctrl key was down when this event fired.
338     ///
339     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/ctrlKey)
340     #[inline]
ctrl_key( &self ) -> bool341     fn ctrl_key( &self ) -> bool {
342         js!(
343             return @{self.as_ref()}.ctrlKey;
344         ).try_into().unwrap()
345     }
346 
347     /// Returns the current state of the specified modifier key.
348     ///
349     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/getModifierState)
350     #[inline]
get_modifier_state( &self, key: ModifierKey ) -> bool351     fn get_modifier_state( &self, key: ModifierKey ) -> bool {
352         get_event_modifier_state( self, key )
353     }
354 
355     /// Indicates whether the Meta key was down when this event fired.
356     ///
357     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/metaKey)
358     #[inline]
meta_key( &self ) -> bool359     fn meta_key( &self ) -> bool {
360         js!(
361             return @{self.as_ref()}.metaKey;
362         ).try_into().unwrap()
363     }
364 
365     /// Returns the change in X coordinate of the pointer between this event and the previous
366     /// MouseMove event.
367     ///
368     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX)
369     #[inline]
movement_x( &self ) -> f64370     fn movement_x( &self ) -> f64 {
371         js!(
372             return @{self.as_ref()}.movementX;
373         ).try_into().unwrap()
374     }
375 
376     /// Returns the change in Y coordinate of the pointer between this event and the previous
377     /// MouseMove event.
378     ///
379     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX)
380     #[inline]
movement_y( &self ) -> f64381     fn movement_y( &self ) -> f64 {
382         js!(
383             return @{self.as_ref()}.movementY;
384         ).try_into().unwrap()
385     }
386 
387     /// Returns the ID of the hit region affected by the event.
388     ///
389     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/region)
390     #[inline]
region( &self ) -> Option< String >391     fn region( &self ) -> Option< String > {
392         js!(
393             return @{self.as_ref()}.region;
394         ).try_into().ok()
395     }
396 
397     /// Returns the secondary target of this event, if any.
398     ///
399     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/relatedTarget)
400     #[inline]
related_target( &self ) -> Option< EventTarget >401     fn related_target( &self ) -> Option< EventTarget > {
402         js!(
403             return @{self.as_ref()}.relatedTarget;
404         ).try_into().ok()
405     }
406 
407      /// Returns the X position of the pointer in screen coordinates.
408     ///
409     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/screenX)
410     #[inline]
screen_x( &self ) -> f64411     fn screen_x( &self ) -> f64 {
412         js!(
413             return @{self.as_ref()}.screenX;
414         ).try_into().unwrap()
415     }
416 
417     /// Returns the Y position of the pointer in screen coordinates.
418     ///
419     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/screenY)
420     #[inline]
screen_y( &self ) -> f64421     fn screen_y( &self ) -> f64 {
422         js!(
423             return @{self.as_ref()}.screenY;
424         ).try_into().unwrap()
425     }
426 
427     /// Indicates whether the Shift key was down when this event was fired.
428     ///
429     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/shiftKey)
430     #[inline]
shift_key( &self ) -> bool431     fn shift_key( &self ) -> bool {
432         js!(
433             return @{self.as_ref()}.shiftKey;
434         ).try_into().unwrap()
435     }
436 }
437 
438 /// Represents buttons on a mouse during mouse events.
439 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
440 pub enum MouseButton {
441     /// The left mouse button.
442     Left,
443     /// The mouse wheel/middle mouse button.
444     Wheel,
445     /// The right mouse button.
446     Right,
447     /// The fourth mouse button (browser back).
448     Button4,
449     /// The fifth mouse button (browser forward).
450     Button5,
451 }
452 
453 /// Represents the state of mouse buttons in a `MouseEvent`.
454 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
455 pub struct MouseButtonsState(u8);
456 
457 impl MouseButtonsState {
is_down(&self, button: MouseButton) -> bool458     pub fn is_down(&self, button: MouseButton) -> bool {
459         match button {
460             MouseButton::Left => self.0 & 0b1 != 0,
461             MouseButton::Right => self.0 & 0b10 != 0,
462             MouseButton::Wheel => self.0 & 0b100 != 0,
463             MouseButton::Button4 => self.0 & 0b1000 != 0,
464             MouseButton::Button5 => self.0 & 0b1_0000 != 0,
465         }
466     }
467 }
468 
469 /// A reference to a JavaScript object which implements the [IMouseEvent](trait.IMouseEvent.html)
470 /// interface.
471 ///
472 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
473 pub struct MouseEvent( Reference );
474 
475 impl IEvent for MouseEvent {}
476 impl IUiEvent for MouseEvent {}
477 impl IMouseEvent for MouseEvent {}
478 
479 reference_boilerplate! {
480     MouseEvent,
481     instanceof MouseEvent
482     convertible to Event
483     convertible to UiEvent
484 }
485 
486 /// The `ClickEvent` is fired when a pointing device button (usually a
487 /// mouse's primary button) is pressed and released on a single element.
488 ///
489 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/click)
490 pub struct ClickEvent( Reference );
491 
492 impl IEvent for ClickEvent {}
493 impl IUiEvent for ClickEvent {}
494 impl IMouseEvent for ClickEvent {}
495 impl ConcreteEvent for ClickEvent {
496     const EVENT_TYPE: &'static str = "click";
497 }
498 
499 reference_boilerplate! {
500     ClickEvent,
501     instanceof MouseEvent
502     convertible to Event
503     convertible to UiEvent
504     convertible to MouseEvent
505 }
506 
507 /// The `DoubleClickEvent` is fired when a pointing device button
508 /// (usually a mouse's primary button) is clicked twice on a single
509 /// element.
510 ///
511 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/dblclick)
512 pub struct DoubleClickEvent( Reference );
513 
514 impl IEvent for DoubleClickEvent {}
515 impl IUiEvent for DoubleClickEvent {}
516 impl IMouseEvent for DoubleClickEvent {}
517 impl ConcreteEvent for DoubleClickEvent {
518     const EVENT_TYPE: &'static str = "dblclick";
519 }
520 
521 reference_boilerplate! {
522     DoubleClickEvent,
523     instanceof MouseEvent
524     convertible to Event
525     convertible to UiEvent
526     convertible to MouseEvent
527 }
528 
529 /// `IKeyboardEvent` objects describe a user interaction with the
530 /// keyboard. Each event describes a key; the event type identifies
531 /// what kind of activity was performed.
532 ///
533 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent)
534 pub trait IKeyboardEvent: IEvent {
535     /// Indicates whether the Alt key was down when this event was fired.
536     ///
537     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/altKey)
538     #[inline]
alt_key( &self ) -> bool539     fn alt_key( &self ) -> bool {
540         js!(
541             return @{self.as_ref()}.altKey;
542         ).try_into().unwrap()
543     }
544 
545     /// Returns a code value that indicates the physical key pressed on the keyboard.
546     ///
547     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code)
548     #[inline]
code( &self ) -> String549     fn code( &self ) -> String {
550         js!(
551             return @{self.as_ref()}.code;
552         ).try_into().unwrap()
553     }
554 
555     /// Returns whether the Ctrl key was down when this event was fired.
556     ///
557     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/ctrlKey)
558     #[inline]
ctrl_key( &self ) -> bool559     fn ctrl_key( &self ) -> bool {
560         js!(
561             return @{self.as_ref()}.ctrlKey;
562         ).try_into().unwrap()
563     }
564 
565 
566     /// Returns whether a modifier key was down when this event was fired.
567     ///
568     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState)
569     #[inline]
get_modifier_state( &self, key: ModifierKey ) -> bool570     fn get_modifier_state( &self, key: ModifierKey ) -> bool {
571         get_event_modifier_state( self, key )
572     }
573 
574     /// Returns whether this event was fired during composition.
575     ///
576     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/isComposing)
577     #[inline]
is_composing( &self ) -> bool578     fn is_composing( &self ) -> bool {
579         js!(
580             return @{self.as_ref()}.isComposing;
581         ).try_into().unwrap()
582     }
583 
584     /// Returns the location of the key on the keyboard.
585     ///
586     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/location)
location( &self ) -> KeyboardLocation587     fn location( &self ) -> KeyboardLocation {
588         match js!(
589             return @{self.as_ref()}.location;
590         ).try_into().unwrap() {
591             0 => KeyboardLocation::Standard,
592             1 => KeyboardLocation::Left,
593             2 => KeyboardLocation::Right,
594             3 => KeyboardLocation::Numpad,
595             4 => KeyboardLocation::Mobile,
596             5 => KeyboardLocation::Joystick,
597             _ => unreachable!("Unexpected KeyboardEvent.location value"),
598         }
599     }
600 
601     /// Returns the value of a key or keys pressed by the user.
602     ///
603     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)
604     #[inline]
key( &self ) -> String605     fn key( &self ) -> String {
606         js!(
607             return @{self.as_ref()}.key;
608         ).into_string().unwrap()
609     }
610 
611     /// Indicates whether the Meta key was down when this event was fired.
612     ///
613     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/metaKey)
614     #[inline]
meta_key( &self ) -> bool615     fn meta_key( &self ) -> bool {
616         js!(
617             return @{self.as_ref()}.metaKey;
618         ).try_into().unwrap()
619     }
620 
621     /// Indicates whether the key is held down such that it is repeating.
622     ///
623     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat)
624     #[inline]
repeat( &self ) -> bool625     fn repeat( &self ) -> bool {
626         js!(
627             return @{self.as_ref()}.repeat;
628         ).try_into().unwrap()
629     }
630 
631     /// Indicates whether the Shift key was down when this event was fired.
632     ///
633     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/shiftKey)
634     #[inline]
shift_key( &self ) -> bool635     fn shift_key( &self ) -> bool {
636         js!(
637             return @{self.as_ref()}.shiftKey;
638         ).try_into().unwrap()
639     }
640 }
641 
642 /// A modifier key on the keyboard.
643 #[allow(missing_docs)]
644 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
645 pub enum ModifierKey {
646     Alt,
647     AltGr,
648     CapsLock,
649     Ctrl,
650     Function,
651     FunctionLock,
652     Hyper,
653     Meta,
654     NumLock,
655     OS,
656     ScrollLock,
657     Shift,
658     Super,
659     Symbol,
660     SymbolLock,
661 }
662 
663 /// Used by KeyboardEvent and MouseEvent to get the state of a modifier key.
get_event_modifier_state< T: IEvent >( event: &T, key: ModifierKey ) -> bool664 fn get_event_modifier_state< T: IEvent >( event: &T, key: ModifierKey ) -> bool {
665     js!(
666         return @{event.as_ref()}.getModifierState( @{
667             match key {
668                 ModifierKey::Alt => "Alt",
669                 ModifierKey::AltGr => "AltGraph",
670                 ModifierKey::CapsLock => "CapsLock",
671                 ModifierKey::Ctrl => "Control",
672                 ModifierKey::Function => "Fn",
673                 ModifierKey::FunctionLock => "FnLock",
674                 ModifierKey::Hyper => "Hyper",
675                 ModifierKey::Meta => "Meta",
676                 ModifierKey::NumLock => "NumLock",
677                 ModifierKey::OS => "OS",
678                 ModifierKey::ScrollLock => "ScrollLock",
679                 ModifierKey::Shift => "Shift",
680                 ModifierKey::Super => "Super",
681                 ModifierKey::Symbol => "Symbol",
682                 ModifierKey::SymbolLock => "SymbolLock",
683             }
684         } );
685     ).try_into().unwrap()
686 }
687 
688 /// The location on the keyboard of a key.
689 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
690 pub enum KeyboardLocation {
691     /// The key has only one version, or the location can't be distinguished.
692     Standard,
693     /// The left-hand version of a key.
694     Left,
695     /// The right-hand version of a key.
696     Right,
697     /// The key was on a numeric pad.
698     Numpad,
699     /// The key was on a mobile device.
700     Mobile,
701     /// The key was on a joystick.
702     Joystick,
703 }
704 
705 /// A reference to a JavaScript object which implements the [IKeyboardEvent](trait.IKeyboardEvent.html)
706 /// interface.
707 ///
708 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent)
709 pub struct KeyboardEvent( Reference );
710 
711 impl IEvent for KeyboardEvent {}
712 impl IKeyboardEvent for KeyboardEvent {}
713 
714 reference_boilerplate! {
715     KeyboardEvent,
716     instanceof KeyboardEvent
717     convertible to Event
718 }
719 
720 /// The `KeypressEvent` is fired when a key is pressed down, and that
721 /// key normally produces a character value.
722 ///
723 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/keypress)
724 pub struct KeypressEvent( Reference );
725 
726 impl IEvent for KeypressEvent {}
727 impl IKeyboardEvent for KeypressEvent {}
728 impl ConcreteEvent for KeypressEvent {
729     const EVENT_TYPE: &'static str = "keypress";
730 }
731 
732 reference_boilerplate! {
733     KeypressEvent,
734     instanceof KeyboardEvent
735     convertible to Event
736     convertible to KeyboardEvent
737 }
738 
739 /// The `IFocusEvent` interface represents focus-related
740 /// events.
741 ///
742 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent)
743 pub trait IFocusEvent: IEvent {
744     /// Returns the secondary target of this event, if any.
745     ///
746     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/relatedTarget)
747     #[inline]
related_target( &self ) -> Option< EventTarget >748     fn related_target( &self ) -> Option< EventTarget > {
749         js!(
750             return @{self.as_ref()}.relatedTarget;
751         ).try_into().ok()
752     }
753 }
754 
755 /// A reference to a JavaScript object which implements the [IFocusEvent](trait.IFocusEvent.html)
756 /// interface.
757 ///
758 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent)
759 pub struct FocusRelatedEvent( Reference );
760 
761 impl IEvent for FocusRelatedEvent {}
762 impl IFocusEvent for FocusRelatedEvent {}
763 
764 reference_boilerplate! {
765     FocusRelatedEvent,
766     instanceof FocusEvent
767     convertible to Event
768 }
769 
770 /// The `FocusEvent` is fired when an element has received focus. The main
771 /// difference between this event and focusin is that only the latter bubbles.
772 ///
773 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/focus)
774 pub struct FocusEvent( Reference );
775 
776 impl IEvent for FocusEvent {}
777 impl IFocusEvent for FocusEvent {}
778 impl ConcreteEvent for FocusEvent {
779     const EVENT_TYPE: &'static str = "focus";
780 }
781 
782 reference_boilerplate! {
783     FocusEvent,
784     instanceof FocusEvent
785     convertible to Event
786     convertible to FocusRelatedEvent
787 }
788 
789 /// The `BlurEvent` is fired when an element has lost focus. The main difference
790 /// between this event and focusout is that only the latter bubbles.
791 ///
792 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/blur)
793 pub struct BlurEvent( Reference );
794 
795 impl IEvent for BlurEvent {}
796 impl IFocusEvent for BlurEvent {}
797 impl ConcreteEvent for BlurEvent {
798     const EVENT_TYPE: &'static str = "blur";
799 }
800 
801 reference_boilerplate! {
802     BlurEvent,
803     instanceof FocusEvent
804     convertible to Event
805     convertible to FocusRelatedEvent
806 }
807 
808 /// The `HashChangeEvent` is fired when the fragment
809 /// identifier of the URL has changed (the part of the URL
810 /// that follows the # symbol, including the # symbol).
811 ///
812 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/hashchange)
813 pub struct HashChangeEvent( Reference );
814 
815 impl IEvent for HashChangeEvent {}
816 impl ConcreteEvent for HashChangeEvent {
817     const EVENT_TYPE: &'static str = "hashchange";
818 }
819 
820 reference_boilerplate! {
821     HashChangeEvent,
822     instanceof HashChangeEvent
823     convertible to Event
824 }
825 
826 impl HashChangeEvent {
827     /// The previous URL from which the window was navigated.
828     ///
829     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/HashChangeEvent)
830     #[inline]
old_url( &self ) -> String831     pub fn old_url( &self ) -> String {
832         js!(
833             return @{self.as_ref()}.oldURL;
834         ).try_into().unwrap()
835     }
836 
837     /// The new URL to which the window was navigated.
838     ///
839     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/HashChangeEvent)
840     #[inline]
new_url( &self ) -> String841     pub fn new_url( &self ) -> String {
842         js!(
843             return @{self.as_ref()}.newURL;
844         ).try_into().unwrap()
845     }
846 }
847 
848 /// The `IProgressEvent` interface represents progress-related
849 /// events.
850 ///
851 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent)
852 pub trait IProgressEvent: IEvent {
853     /// Indicates whether the progress is measureable.
854     ///
855     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/lengthComputable)
856     #[inline]
length_computable( &self ) -> bool857     fn length_computable( &self ) -> bool {
858         js!(
859             return @{self.as_ref()}.lengthComputable;
860         ).try_into().unwrap()
861     }
862 
863     /// Returns the amount of work already performed by the underlying process.
864     ///
865     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/loaded)
866     #[inline]
loaded( &self ) -> u64867     fn loaded( &self ) -> u64 {
868         js!(
869             return @{self.as_ref()}.loaded;
870         ).try_into().unwrap()
871     }
872 
873     /// Returns the total amount of work that the underlying process will perform.
874     ///
875     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/total)
876     #[inline]
total( &self ) -> u64877     fn total( &self ) -> u64 {
878         js!(
879             return @{self.as_ref()}.total;
880         ).try_into().unwrap()
881     }
882 }
883 
884 /// A reference to a JavaScript object which implements the [IProgressEvent](trait.IProgressEvent.html)
885 /// interface.
886 ///
887 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent)
888 pub struct ProgressRelatedEvent( Reference );
889 
890 impl IEvent for ProgressRelatedEvent {}
891 impl IProgressEvent for ProgressRelatedEvent {}
892 
893 reference_boilerplate! {
894     ProgressRelatedEvent,
895     instanceof ProgressEvent
896     convertible to Event
897 }
898 
899 /// The `ProgressEvent` is fired to indicate that an operation is in progress.
900 ///
901 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/progress)
902 pub struct ProgressEvent( Reference );
903 
904 impl IEvent for ProgressEvent {}
905 impl IProgressEvent for ProgressEvent {}
906 impl ConcreteEvent for ProgressEvent {
907     const EVENT_TYPE: &'static str = "progress";
908 }
909 
910 reference_boilerplate! {
911     ProgressEvent,
912     instanceof ProgressEvent
913     convertible to Event
914     convertible to ProgressRelatedEvent
915 }
916 
917 /// The `LoadStartEvent` is fired when progress has begun on the loading of a resource.
918 ///
919 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/loadstart)
920 pub struct LoadStartEvent( Reference );
921 
922 impl IEvent for LoadStartEvent {}
923 impl IProgressEvent for LoadStartEvent {}
924 impl ConcreteEvent for LoadStartEvent {
925     const EVENT_TYPE: &'static str = "loadstart";
926 }
927 
928 reference_boilerplate! {
929     LoadStartEvent,
930     instanceof ProgressEvent
931     convertible to Event
932     convertible to ProgressRelatedEvent
933 }
934 
935 /// The `LoadEndEvent` is fired when progress has stopped on the loading of a resource,
936 /// e.g. after `ErrorEvent`, `AbortEvent` or `LoadEvent` have been dispatched.
937 ///
938 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/loadend)
939 pub struct LoadEndEvent( Reference );
940 
941 impl IEvent for LoadEndEvent {}
942 impl IProgressEvent for LoadEndEvent {}
943 impl ConcreteEvent for LoadEndEvent {
944     const EVENT_TYPE: &'static str = "loadend";
945 }
946 
947 reference_boilerplate! {
948     LoadEndEvent,
949     instanceof ProgressEvent
950     convertible to Event
951     convertible to ProgressRelatedEvent
952 }
953 
954 /// The `AbortEvent` is fired when the loading of a resource has been aborted.
955 ///
956 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/abort)
957 pub struct AbortEvent( Reference );
958 
959 // TODO: This event is sometimes an UiEvent; what to do here?
960 impl IEvent for AbortEvent {}
961 impl ConcreteEvent for AbortEvent {
962     const EVENT_TYPE: &'static str = "abort";
963 }
964 
965 reference_boilerplate! {
966     AbortEvent,
967     instanceof Event
968     convertible to Event
969 }
970 
971 /// The `ErrorEvent` is fired when an error occurred; the exact circumstances vary,
972 /// since this event is used from a variety of APIs.
973 ///
974 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/Events/error)
975 pub struct ErrorEvent( Reference );
976 
977 // TODO: This event is sometimes an UiEvent; what to do here?
978 impl IEvent for ErrorEvent {}
979 impl ConcreteEvent for ErrorEvent {
980     const EVENT_TYPE: &'static str = "error";
981 }
982 
983 reference_boilerplate! {
984     ErrorEvent,
985     instanceof Event
986     convertible to Event
987 }
988 
989 impl ErrorEvent {
990     /// Returns a human-readable error message describing the problem.
991     ///
992     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent/message)
993     #[inline]
message( &self ) -> String994     pub fn message( &self ) -> String {
995         return js!(
996             return @{self.as_ref()}.message;
997         ).try_into().unwrap()
998     }
999 
1000     /// Returns the name of the script where the error occurred.
1001     ///
1002     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent/filename)
1003     #[inline]
filename( &self ) -> String1004     pub fn filename( &self ) -> String {
1005         return js!(
1006             return @{self.as_ref()}.filename;
1007         ).try_into().unwrap()
1008     }
1009 
1010     /// Returns the line number of the script file where the error occurred.
1011     ///
1012     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent/lineNo)
1013     #[inline]
lineno( &self ) -> u321014     pub fn lineno( &self ) -> u32 {
1015         return js!(
1016             return @{self.as_ref()}.lineno;
1017         ).try_into().unwrap()
1018     }
1019 
1020     /// Returns the column number of the script file where the error occurred.
1021     ///
1022     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent/colNo)
1023     #[inline]
colno( &self ) -> u321024     pub fn colno( &self ) -> u32 {
1025         return js!(
1026             return @{self.as_ref()}.colno;
1027         ).try_into().unwrap()
1028     }
1029 }
1030 
1031 #[cfg(web_api_tests)]
1032 mod tests {
1033     use super::*;
1034 
1035     #[test]
test_event()1036     fn test_event() {
1037         let event: Event = js!(
1038             return new Event("dummy")
1039         ).try_into().unwrap();
1040 
1041         assert_eq!( event.event_type(), "dummy" );
1042         assert_eq!( event.bubbles(), false );
1043         assert!( !event.cancel_bubble() );
1044         assert!( !event.cancelable(), false );
1045         assert!( event.current_target().is_none() );
1046         assert!( !event.default_prevented() );
1047         assert_eq!( event.event_phase(), EventPhase::None );
1048         assert!( event.target().is_none() );
1049         assert!( event.time_stamp().is_some() );
1050         assert!( !event.is_trusted() );
1051 
1052         event.stop_immediate_propagation();
1053         event.stop_propagation();
1054     }
1055 
1056     #[test]
test_change_event()1057     fn test_change_event() {
1058         let event: ChangeEvent = js!(
1059             return new Event( @{ChangeEvent::EVENT_TYPE} );
1060         ).try_into().unwrap();
1061         assert_eq!( event.event_type(), ChangeEvent::EVENT_TYPE );
1062     }
1063 
1064     #[test]
test_ui_event()1065     fn test_ui_event() {
1066         let event: UiEvent = js!(
1067             return new UIEvent(
1068                 @{ClickEvent::EVENT_TYPE},
1069                 {
1070                     detail: 1,
1071                 }
1072             )
1073         ).try_into().unwrap();
1074         assert_eq!( event.event_type(), ClickEvent::EVENT_TYPE );
1075         assert_eq!( event.detail(), 1 );
1076         assert!( event.view().is_none() );
1077     }
1078 
1079     #[test]
test_load_event()1080     fn test_load_event() {
1081         let event: UiEvent = js!(
1082             return new UIEvent( @{LoadEvent::EVENT_TYPE} );
1083         ).try_into().unwrap();
1084         assert_eq!( event.event_type(), LoadEvent::EVENT_TYPE );
1085     }
1086 
1087     #[test]
test_mouse_event()1088     fn test_mouse_event() {
1089         let event: MouseEvent = js!(
1090             return new MouseEvent(
1091                 @{ClickEvent::EVENT_TYPE},
1092                 {
1093                     altKey: false,
1094                     button: 2,
1095                     buttons: 6,
1096                     clientX: 3.0,
1097                     clientY: 4.0,
1098                     ctrlKey: true,
1099                     metaKey: false,
1100                     screenX: 1.0,
1101                     screenY: 2.0,
1102                     shiftKey: true
1103                 }
1104             );
1105         ).try_into().unwrap();
1106         assert_eq!( event.event_type(), ClickEvent::EVENT_TYPE );
1107         assert_eq!( event.alt_key(), false );
1108         assert_eq!( event.button(), MouseButton::Right );
1109         assert!( !event.buttons().is_down( MouseButton::Left ) );
1110         assert!( event.buttons().is_down( MouseButton::Right ) );
1111         assert!( event.buttons().is_down( MouseButton::Wheel ) );
1112         assert_eq!( event.client_x(), 3.0 );
1113         assert_eq!( event.client_y(), 4.0 );
1114         assert!( event.ctrl_key() );
1115         assert!( !event.get_modifier_state( ModifierKey::Alt ) );
1116         assert!( event.get_modifier_state( ModifierKey::Ctrl ) );
1117         assert!( event.get_modifier_state( ModifierKey::Shift ) );
1118         assert!( !event.meta_key() );
1119         assert_eq!( event.movement_x(), 0.0 );
1120         assert_eq!( event.movement_y(), 0.0 );
1121         assert!( event.region().is_none() );
1122         assert!( event.related_target().is_none() );
1123         assert_eq!( event.screen_x(), 1.0 );
1124         assert_eq!( event.screen_y(), 2.0 );
1125         assert!( event.shift_key() );
1126     }
1127 
1128     #[test]
test_click_event()1129     fn test_click_event() {
1130         let event: ClickEvent = js!(
1131             return new MouseEvent( @{ClickEvent::EVENT_TYPE} );
1132         ).try_into().unwrap();
1133         assert_eq!( event.event_type(), ClickEvent::EVENT_TYPE );
1134     }
1135 
1136     #[test]
test_double_click_event()1137     fn test_double_click_event() {
1138         let event: DoubleClickEvent = js!(
1139             return new MouseEvent( @{DoubleClickEvent::EVENT_TYPE} );
1140         ).try_into().unwrap();
1141         assert_eq!( event.event_type(), DoubleClickEvent::EVENT_TYPE );
1142     }
1143 
1144     #[test]
test_keyboard_event()1145     fn test_keyboard_event() {
1146         let event: KeyboardEvent = js!(
1147             return new KeyboardEvent(
1148                 @{KeypressEvent::EVENT_TYPE},
1149                 {
1150                     key: "A",
1151                     code: "KeyA",
1152                     location: 0,
1153                     ctrlKey: true,
1154                     shiftKey: false,
1155                     altKey: true,
1156                     metaKey: false,
1157                     repeat: true,
1158                     isComposing: false
1159                 }
1160             );
1161         ).try_into().unwrap();
1162         assert!( event.alt_key() );
1163         assert_eq!( event.code(), "KeyA" );
1164         assert!( event.ctrl_key() );
1165         assert!( event.get_modifier_state( ModifierKey::Alt ) );
1166         assert!( event.get_modifier_state( ModifierKey::Ctrl ) );
1167         assert!( !event.get_modifier_state( ModifierKey::Shift ) );
1168         assert!( !event.is_composing() );
1169         assert_eq!( event.location(), KeyboardLocation::Standard );
1170         assert_eq!( event.key(), "A" );
1171         assert!( !event.meta_key() );
1172         assert!( event.repeat() );
1173         assert!( !event.shift_key() );
1174     }
1175 
1176     #[test]
test_keypress_event()1177     fn test_keypress_event() {
1178         let event: KeypressEvent = js!(
1179             return new KeyboardEvent( @{KeypressEvent::EVENT_TYPE} );
1180         ).try_into().unwrap();
1181         assert_eq!( event.event_type(), KeypressEvent::EVENT_TYPE );
1182     }
1183 
1184     #[test]
test_focus_event()1185     fn test_focus_event() {
1186         let event: FocusEvent = js!(
1187             return new FocusEvent( "focus" );
1188         ).try_into().unwrap();
1189         assert_eq!( event.event_type(), "focus" );
1190         assert!( event.related_target().is_none() );
1191     }
1192 
1193     #[test]
test_blur_event()1194     fn test_blur_event() {
1195         let event: BlurEvent = js!(
1196             return new FocusEvent( @{BlurEvent::EVENT_TYPE} );
1197         ).try_into().unwrap();
1198         assert_eq!( event.event_type(), BlurEvent::EVENT_TYPE );
1199     }
1200 
1201     #[test]
test_hash_change_event()1202     fn test_hash_change_event() {
1203         let event: HashChangeEvent = js!(
1204             return new HashChangeEvent(
1205                 @{HashChangeEvent::EVENT_TYPE},
1206                 {
1207                     oldURL: "http://test.com#foo",
1208                     newURL: "http://test.com#bar"
1209                 }
1210             );
1211         ).try_into().unwrap();
1212         assert_eq!( event.event_type(), HashChangeEvent::EVENT_TYPE );
1213         assert_eq!( event.old_url(), "http://test.com#foo" );
1214         assert_eq!( event.new_url(), "http://test.com#bar" );
1215     }
1216 
1217     #[test]
test_progress_event()1218     fn test_progress_event() {
1219         let event: ProgressEvent = js!(
1220             return new ProgressEvent(
1221                 @{ProgressEvent::EVENT_TYPE},
1222                 {
1223                     lengthComputable: true,
1224                     loaded: 10,
1225                     total: 100,
1226                 }
1227             );
1228         ).try_into().unwrap();
1229         assert_eq!( event.event_type(), ProgressEvent::EVENT_TYPE );
1230         assert!( event.length_computable() );
1231         assert_eq!( event.loaded(), 10 );
1232         assert_eq!( event.total(), 100 );
1233     }
1234 
1235     #[test]
test_load_start_event()1236     fn test_load_start_event() {
1237         let event: LoadStartEvent = js!(
1238             return new ProgressEvent( @{LoadStartEvent::EVENT_TYPE} );
1239         ).try_into().unwrap();
1240         assert_eq!( event.event_type(), LoadStartEvent::EVENT_TYPE );
1241     }
1242 
1243     #[test]
test_load_end_event()1244     fn test_load_end_event() {
1245         let event: LoadEndEvent = js!(
1246             return new ProgressEvent( @{LoadEndEvent::EVENT_TYPE} );
1247         ).try_into().unwrap();
1248         assert_eq!( event.event_type(), LoadEndEvent::EVENT_TYPE );
1249     }
1250 
1251     #[test]
test_abort_event()1252     fn test_abort_event() {
1253         let event: AbortEvent = js!(
1254             return new Event( @{AbortEvent::EVENT_TYPE} );
1255         ).try_into().unwrap();
1256         assert_eq!( event.event_type(), AbortEvent::EVENT_TYPE );
1257     }
1258 
1259     #[test]
test_error_event()1260     fn test_error_event() {
1261         let event: ErrorEvent = js!(
1262             return new ErrorEvent(
1263                 @{ErrorEvent::EVENT_TYPE},
1264                 {
1265                     message: "Dummy error",
1266                     filename: "Dummy.js",
1267                     lineno: 5,
1268                     colno: 10
1269                 }
1270             );
1271         ).try_into().unwrap();
1272         assert_eq!( event.event_type(), ErrorEvent::EVENT_TYPE );
1273         assert_eq!( event.message(), "Dummy error".to_string() );
1274         assert_eq!( event.filename(), "Dummy.js".to_string() );
1275         assert_eq!( event.lineno(), 5 );
1276         assert_eq!( event.colno(), 10 );
1277     }
1278 }
1279