|
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 strict"; |
|
6 |
|
7 module.metadata = { |
|
8 "stability": "unstable" |
|
9 }; |
|
10 |
|
11 // Utility function that returns copy of the given `text` with last character |
|
12 // removed if it is `"s"`. |
|
13 function singularify(text) { |
|
14 return text[text.length - 1] === "s" ? text.substr(0, text.length - 1) : text; |
|
15 } |
|
16 |
|
17 // Utility function that takes event type, argument is passed to |
|
18 // `document.createEvent` and returns name of the initializer method of the |
|
19 // given event. Please note that there are some event types whose initializer |
|
20 // methods can't be guessed by this function. For more details see following |
|
21 // link: https://developer.mozilla.org/En/DOM/Document.createEvent |
|
22 function getInitializerName(category) { |
|
23 return "init" + singularify(category); |
|
24 } |
|
25 |
|
26 /** |
|
27 * Registers an event `listener` on a given `element`, that will be called |
|
28 * when events of specified `type` is dispatched on the `element`. |
|
29 * @param {Element} element |
|
30 * Dom element to register listener on. |
|
31 * @param {String} type |
|
32 * A string representing the |
|
33 * [event type](https://developer.mozilla.org/en/DOM/event.type) to |
|
34 * listen for. |
|
35 * @param {Function} listener |
|
36 * Function that is called whenever an event of the specified `type` |
|
37 * occurs. |
|
38 * @param {Boolean} capture |
|
39 * If true, indicates that the user wishes to initiate capture. After |
|
40 * initiating capture, all events of the specified type will be dispatched |
|
41 * to the registered listener before being dispatched to any `EventTarget`s |
|
42 * beneath it in the DOM tree. Events which are bubbling upward through |
|
43 * the tree will not trigger a listener designated to use capture. |
|
44 * See [DOM Level 3 Events](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow) |
|
45 * for a detailed explanation. |
|
46 */ |
|
47 function on(element, type, listener, capture) { |
|
48 // `capture` defaults to `false`. |
|
49 capture = capture || false; |
|
50 element.addEventListener(type, listener, capture); |
|
51 } |
|
52 exports.on = on; |
|
53 |
|
54 /** |
|
55 * Registers an event `listener` on a given `element`, that will be called |
|
56 * only once, next time event of specified `type` is dispatched on the |
|
57 * `element`. |
|
58 * @param {Element} element |
|
59 * Dom element to register listener on. |
|
60 * @param {String} type |
|
61 * A string representing the |
|
62 * [event type](https://developer.mozilla.org/en/DOM/event.type) to |
|
63 * listen for. |
|
64 * @param {Function} listener |
|
65 * Function that is called whenever an event of the specified `type` |
|
66 * occurs. |
|
67 * @param {Boolean} capture |
|
68 * If true, indicates that the user wishes to initiate capture. After |
|
69 * initiating capture, all events of the specified type will be dispatched |
|
70 * to the registered listener before being dispatched to any `EventTarget`s |
|
71 * beneath it in the DOM tree. Events which are bubbling upward through |
|
72 * the tree will not trigger a listener designated to use capture. |
|
73 * See [DOM Level 3 Events](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow) |
|
74 * for a detailed explanation. |
|
75 */ |
|
76 function once(element, type, listener, capture) { |
|
77 on(element, type, function selfRemovableListener(event) { |
|
78 removeListener(element, type, selfRemovableListener, capture); |
|
79 listener.apply(this, arguments); |
|
80 }, capture); |
|
81 } |
|
82 exports.once = once; |
|
83 |
|
84 /** |
|
85 * Unregisters an event `listener` on a given `element` for the events of the |
|
86 * specified `type`. |
|
87 * |
|
88 * @param {Element} element |
|
89 * Dom element to unregister listener from. |
|
90 * @param {String} type |
|
91 * A string representing the |
|
92 * [event type](https://developer.mozilla.org/en/DOM/event.type) to |
|
93 * listen for. |
|
94 * @param {Function} listener |
|
95 * Function that is called whenever an event of the specified `type` |
|
96 * occurs. |
|
97 * @param {Boolean} capture |
|
98 * If true, indicates that the user wishes to initiate capture. After |
|
99 * initiating capture, all events of the specified type will be dispatched |
|
100 * to the registered listener before being dispatched to any `EventTarget`s |
|
101 * beneath it in the DOM tree. Events which are bubbling upward through |
|
102 * the tree will not trigger a listener designated to use capture. |
|
103 * See [DOM Level 3 Events](http://www.w3.org/TR/DOM-Level-3-Events/#event-flow) |
|
104 * for a detailed explanation. |
|
105 */ |
|
106 function removeListener(element, type, listener, capture) { |
|
107 element.removeEventListener(type, listener, capture); |
|
108 } |
|
109 exports.removeListener = removeListener; |
|
110 |
|
111 /** |
|
112 * Emits event of the specified `type` and `category` on the given `element`. |
|
113 * Specified `settings` are used to initialize event before dispatching it. |
|
114 * @param {Element} element |
|
115 * Dom element to dispatch event on. |
|
116 * @param {String} type |
|
117 * A string representing the |
|
118 * [event type](https://developer.mozilla.org/en/DOM/event.type). |
|
119 * @param {Object} options |
|
120 * Options object containing following properties: |
|
121 * - `category`: String passed to the `document.createEvent`. Option is |
|
122 * optional and defaults to "UIEvents". |
|
123 * - `initializer`: If passed it will be used as name of the method used |
|
124 * to initialize event. If omitted name will be generated from the |
|
125 * `category` field by prefixing it with `"init"` and removing last |
|
126 * character if it matches `"s"`. |
|
127 * - `settings`: Array of settings that are forwarded to the event |
|
128 * initializer after firs `type` argument. |
|
129 * @see https://developer.mozilla.org/En/DOM/Document.createEvent |
|
130 */ |
|
131 function emit(element, type, { category, initializer, settings }) { |
|
132 category = category || "UIEvents"; |
|
133 initializer = initializer || getInitializerName(category); |
|
134 let document = element.ownerDocument; |
|
135 let event = document.createEvent(category); |
|
136 event[initializer].apply(event, [type].concat(settings)); |
|
137 element.dispatchEvent(event); |
|
138 }; |
|
139 exports.emit = emit; |