|
1 <!DOCTYPE html> |
|
2 <html> |
|
3 <head> |
|
4 <title>Test all synthetic events</title> |
|
5 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
6 <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> |
|
7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> |
|
8 </head> |
|
9 <body> |
|
10 <p id="display"></p> |
|
11 <div id="content" style="display: none"> |
|
12 </div> |
|
13 <pre id="test"> |
|
14 <script type="application/javascript"> |
|
15 |
|
16 /** |
|
17 * kEventConstructors is a helper and database of all events. |
|
18 * The sort order of the definition is by A to Z (ignore the Event postfix). |
|
19 * |
|
20 * XXX: should we move this into EventUtils.js? |
|
21 * |
|
22 * create: function or null. If this is null, it's impossible to create untrusted event for it. |
|
23 * Otherwise, create(aName, aProps) returns an instance of the event initialized with aProps. |
|
24 * aName specifies the event's type name. See each create() code for the detail of aProps. |
|
25 */ |
|
26 const kEventConstructors = { |
|
27 Event: { create: function (aName, aProps) { |
|
28 return new Event(aName, aProps); |
|
29 }, |
|
30 }, |
|
31 AnimationEvent: { create: function (aName, aProps) { |
|
32 return new AnimationEvent(aName, aProps); |
|
33 }, |
|
34 }, |
|
35 AudioProcessingEvent: { create: null, // Cannot create untrusted event from JS. |
|
36 }, |
|
37 BeforeUnloadEvent: { create: function (aName, aProps) { |
|
38 var e = document.createEvent("beforeunloadevent"); |
|
39 e.initEvent(aName, aProps.bubbles, aProps.cancelable); |
|
40 return e; |
|
41 }, |
|
42 }, |
|
43 BlobEvent: { create: function (aName, aProps) { |
|
44 return new BlobEvent(aName, aProps); |
|
45 }, |
|
46 }, |
|
47 BluetoothDeviceEvent: { create: function (aName, aProps) { |
|
48 return new BluetoothDeviceEvent(aName, aProps); |
|
49 }, |
|
50 }, |
|
51 BluetoothStatusChangedEvent: { create: function (aName, aProps) { |
|
52 return new BluetoothStatusChangedEvent(aName, aProps); |
|
53 }, |
|
54 }, |
|
55 CallEvent: { create: function (aName, aProps) { |
|
56 return new CallEvent(aName, aProps); |
|
57 }, |
|
58 }, |
|
59 CallGroupErrorEvent: { create: function (aName, aProps) { |
|
60 return new CallGroupErrorEvent(aName, aProps); |
|
61 }, |
|
62 }, |
|
63 CFStateChangeEvent: { create: function (aName, aProps) { |
|
64 return new CFStateChangeEvent(aName, aProps); |
|
65 }, |
|
66 }, |
|
67 CloseEvent: { create: function (aName, aProps) { |
|
68 return new CloseEvent(aName, aProps); |
|
69 }, |
|
70 }, |
|
71 ClipboardEvent: { create: function (aName, aProps) { |
|
72 return new ClipboardEvent(aName, aProps); |
|
73 }, |
|
74 }, |
|
75 CommandEvent: { create: function (aName, aProps) { |
|
76 var e = document.createEvent("commandevent"); |
|
77 e.initCommandEvent(aName, aProps.bubbles, aProps.cancelable, |
|
78 aProps.command); |
|
79 return e; |
|
80 }, |
|
81 }, |
|
82 CompositionEvent: { create: function (aName, aProps) { |
|
83 var e = document.createEvent("compositionevent"); |
|
84 e.initCompositionEvent(aName, aProps.bubbles, aProps.cancelable, |
|
85 aProps.view, aProps.data, aProps.locale); |
|
86 return e; |
|
87 }, |
|
88 }, |
|
89 CustomEvent: { create: function (aName, aProps) { |
|
90 return new CustomEvent(aName, aProps); |
|
91 }, |
|
92 }, |
|
93 DataErrorEvent: { create: function (aName, aProps) { |
|
94 return new DataErrorEvent(aName, aProps); |
|
95 }, |
|
96 }, |
|
97 DataContainerEvent: { create: function (aName, aProps) { |
|
98 var e = document.createEvent("datacontainerevent"); |
|
99 e.initEvent(aName, aProps.bubbles, aProps.cancelable); |
|
100 return e; |
|
101 }, |
|
102 }, |
|
103 DataStoreChangeEvent: { create: function (aName, aProps) { |
|
104 return new DataStoreChangeEvent(aProps); |
|
105 }, |
|
106 }, |
|
107 DeviceLightEvent: { create: function (aName, aProps) { |
|
108 return new DeviceLightEvent(aName, aProps); |
|
109 }, |
|
110 }, |
|
111 DeviceMotionEvent: { create: function (aName, aProps) { |
|
112 var e = document.createEvent("devicemotionevent"); |
|
113 e.initDeviceMotionEvent(aName, aProps.bubbles, aProps.cancelable, aProps.acceleration, |
|
114 aProps.accelerationIncludingGravity, aProps.rotationRate, |
|
115 aProps.interval || 0.0); |
|
116 return e; |
|
117 }, |
|
118 }, |
|
119 DeviceOrientationEvent: { create: function (aName, aProps) { |
|
120 return new DeviceOrientationEvent(aName, aProps); |
|
121 }, |
|
122 }, |
|
123 DeviceProximityEvent: { create: function (aName, aProps) { |
|
124 return new DeviceProximityEvent(aName, aProps); |
|
125 }, |
|
126 }, |
|
127 DeviceStorageChangeEvent: { create: function (aName, aProps) { |
|
128 return new DeviceStorageChangeEvent(aName, aProps); |
|
129 }, |
|
130 }, |
|
131 DownloadEvent: { create: function (aName, aProps) { |
|
132 return new DownloadEvent(aName, aProps); |
|
133 }, |
|
134 }, |
|
135 DOMTransactionEvent: { create: function (aName, aProps) { |
|
136 return new DOMTransactionEvent(aName, aProps); |
|
137 }, |
|
138 }, |
|
139 DragEvent: { create: function (aName, aProps) { |
|
140 var e = document.createEvent("dragevent"); |
|
141 e.initDragEvent(aName, aProps.bubbles, aProps.cancelable, |
|
142 aProps.view, aProps.detail, |
|
143 aProps.screenX, aProps.screenY, |
|
144 aProps.clientX, aProps.clientY, |
|
145 aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey, |
|
146 aProps.button, aProps.relatedTarget, aProps.dataTransfer); |
|
147 return e; |
|
148 }, |
|
149 }, |
|
150 ErrorEvent: { create: function (aName, aProps) { |
|
151 return new ErrorEvent(aName, aProps); |
|
152 }, |
|
153 }, |
|
154 ElementReplaceEvent: { create: function (aName, aProps) { |
|
155 return new ElementReplaceEvent(aName, aProps); |
|
156 }, |
|
157 }, |
|
158 FocusEvent: { create: function (aName, aProps) { |
|
159 return new FocusEvent(aName, aProps); |
|
160 }, |
|
161 }, |
|
162 GamepadEvent: { create: function (aName, aProps) { |
|
163 return new GamepadEvent(aName, aProps); |
|
164 }, |
|
165 }, |
|
166 GamepadAxisMoveEvent: { create: function (aName, aProps) { |
|
167 return new GamepadAxisMoveEvent(aName, aProps); |
|
168 }, |
|
169 }, |
|
170 GamepadButtonEvent: { create: function (aName, aProps) { |
|
171 return new GamepadButtonEvent(aName, aProps); |
|
172 }, |
|
173 }, |
|
174 HashChangeEvent: { create: function (aName, aProps) { |
|
175 return new HashChangeEvent(aName, aProps); |
|
176 }, |
|
177 }, |
|
178 IccChangeEvent: { create: function (aName, aProps) { |
|
179 return new IccChangeEvent(aName, aProps); |
|
180 }, |
|
181 }, |
|
182 IDBVersionChangeEvent: { create: function (aName, aProps) { |
|
183 return new IDBVersionChangeEvent(aName, aProps); |
|
184 }, |
|
185 }, |
|
186 InputEvent: { create: function (aName, aProps) { |
|
187 return new InputEvent(aName, aProps); |
|
188 }, |
|
189 }, |
|
190 KeyEvent: { create: function (aName, aProps) { |
|
191 return new KeyboardEvent(aName, aProps); |
|
192 }, |
|
193 }, |
|
194 KeyboardEvent: { create: function (aName, aProps) { |
|
195 return new KeyboardEvent(aName, aProps); |
|
196 }, |
|
197 }, |
|
198 MediaStreamEvent: { create: function (aName, aProps) { |
|
199 return new MediaStreamEvent(aName, aProps); |
|
200 }, |
|
201 }, |
|
202 MessageEvent: { create: function (aName, aProps) { |
|
203 var e = new MessageEvent("messageevent", { bubbles: aProps.bubbles, |
|
204 cancelable: aProps.cancelable, data: aProps.data, origin: aProps.origin, |
|
205 lastEventId: aProps.lastEventId, source: aProps.source }); |
|
206 return e; |
|
207 }, |
|
208 }, |
|
209 MouseEvent: { create: function (aName, aProps) { |
|
210 return new MouseEvent(aName, aProps); |
|
211 }, |
|
212 }, |
|
213 MouseScrollEvent: { create: function (aName, aProps) { |
|
214 var e = document.createEvent("mousescrollevents"); |
|
215 e.initMouseScrollEvent(aName, aProps.bubbles, aProps.cancelable, |
|
216 aProps.view, aProps.detail, |
|
217 aProps.screenX, aProps.screenY, |
|
218 aProps.clientX, aProps.clientY, |
|
219 aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey, |
|
220 aProps.button, aProps.relatedTarget, aProps.axis); |
|
221 return e; |
|
222 }, |
|
223 }, |
|
224 MozApplicationEvent: { create: function (aName, aProps) { |
|
225 return new MozApplicationEvent(aName, aProps); |
|
226 }, |
|
227 }, |
|
228 MozCellBroadcastEvent: { create: function (aName, aProps) { |
|
229 return new MozCellBroadcastEvent(aName, aProps); |
|
230 }, |
|
231 }, |
|
232 MozContactChangeEvent: { create: function (aName, aProps) { |
|
233 return new MozContactChangeEvent(aName, aProps); |
|
234 }, |
|
235 }, |
|
236 MozEmergencyCbModeEvent: { create: function (aName, aProps) { |
|
237 return new MozEmergencyCbModeEvent(aName, aProps); |
|
238 }, |
|
239 }, |
|
240 MozMmsEvent: { create: function (aName, aProps) { |
|
241 return new MozMmsEvent(aName, aProps); |
|
242 }, |
|
243 }, |
|
244 MozOtaStatusEvent: { create: function (aName, aProps) { |
|
245 return new MozOtaStatusEvent(aName, aProps); |
|
246 }, |
|
247 }, |
|
248 MozSettingsEvent: { create: function (aName, aProps) { |
|
249 return new MozSettingsEvent(aName, aProps); |
|
250 }, |
|
251 }, |
|
252 MozSmsEvent: { create: function (aName, aProps) { |
|
253 return new MozSmsEvent(aName, aProps); |
|
254 }, |
|
255 }, |
|
256 MozStkCommandEvent: { create: function (aName, aProps) { |
|
257 return new MozStkCommandEvent(aName, aProps); |
|
258 }, |
|
259 }, |
|
260 MozVoicemailEvent: { create: function (aName, aProps) { |
|
261 return new MozVoicemailEvent(aName, aProps); |
|
262 }, |
|
263 }, |
|
264 MozWifiConnectionInfoEvent: { create: function (aName, aProps) { |
|
265 return new MozWifiConnectionInfoEvent(aName, aProps); |
|
266 }, |
|
267 }, |
|
268 MozWifiStatusChangeEvent: { create: function (aName, aProps) { |
|
269 return new MozWifiStatusChangeEvent(aName, aProps); |
|
270 }, |
|
271 }, |
|
272 MutationEvent: { create: function (aName, aProps) { |
|
273 var e = document.createEvent("mutationevent"); |
|
274 e.initMutationEvent(aName, aProps.bubbles, aProps.cancelable, |
|
275 aProps.relatedNode, aProps.prevValue, aProps.newValue, |
|
276 aProps.attrName, aProps.attrChange); |
|
277 return e; |
|
278 }, |
|
279 }, |
|
280 NotifyPaintEvent: { create: function (aName, aProps) { |
|
281 var e = document.createEvent("notifypaintevent"); |
|
282 e.initEvent(aName, aProps.bubbles, aProps.cancelable); |
|
283 return e; |
|
284 }, |
|
285 }, |
|
286 OfflineAudioCompletionEvent: { create: null, // Cannot create untrusted event from JS. |
|
287 }, |
|
288 PageTransitionEvent: { create: function (aName, aProps) { |
|
289 return new PageTransitionEvent(aName, aProps); |
|
290 }, |
|
291 }, |
|
292 PointerEvent: { create: function (aName, aProps) { |
|
293 return new PointerEvent(aName, aProps); |
|
294 }, |
|
295 }, |
|
296 PopStateEvent: { create: function (aName, aProps) { |
|
297 return new PopStateEvent(aName, aProps); |
|
298 }, |
|
299 }, |
|
300 PopupBlockedEvent: { create: function (aName, aProps) { |
|
301 return new PopupBlockedEvent(aName, aProps); |
|
302 }, |
|
303 }, |
|
304 ProgressEvent: { create: function (aName, aProps) { |
|
305 return new ProgressEvent(aName, aProps); |
|
306 }, |
|
307 }, |
|
308 RecordErrorEvent: { create: function (aName, aProps) { |
|
309 return new RecordErrorEvent(aName, aProps); |
|
310 }, |
|
311 }, |
|
312 RTCDataChannelEvent: { create: function (aName, aProps) { |
|
313 return new RTCDataChannelEvent(aName, aProps); |
|
314 }, |
|
315 }, |
|
316 RTCPeerConnectionIceEvent: { create: function (aName, aProps) { |
|
317 return new RTCPeerConnectionIceEvent(aName, aProps); |
|
318 }, |
|
319 }, |
|
320 RTCPeerConnectionIdentityEvent: { create: function (aName, aProps) { |
|
321 return new RTCPeerConnectionIdentityEvent(aName, aProps); |
|
322 }, |
|
323 }, |
|
324 RTCPeerConnectionIdentityErrorEvent: { create: function (aName, aProps) { |
|
325 return new RTCPeerConnectionIdentityErrorEvent(aName, aProps); |
|
326 }, |
|
327 }, |
|
328 ScrollAreaEvent: { create: function (aName, aProps) { |
|
329 var e = document.createEvent("scrollareaevent"); |
|
330 e.initScrollAreaEvent(aName, aProps.bubbles, aProps.cancelable, |
|
331 aProps.view, aProps.details, |
|
332 aProps.x || 0.0, aProps.y || 0.0, |
|
333 aProps.width || 0.0, aProps.height || 0.0); |
|
334 return e; |
|
335 }, |
|
336 }, |
|
337 SimpleGestureEvent: { create: function (aName, aProps) { |
|
338 var e = document.createEvent("simplegestureevent"); |
|
339 e.initSimpleGestureEvent(aName, aProps.bubbles, aProps.cancelable, |
|
340 aProps.view, aProps.detail, |
|
341 aProps.screenX, aProps.screenY, |
|
342 aProps.clientX, aProps.clientY, |
|
343 aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey, |
|
344 aProps.button, aProps.relatedTarget, |
|
345 aProps.allowedDirections, aProps.direction, aProps.delta || 0.0, |
|
346 aProps.clickCount); |
|
347 return e; |
|
348 }, |
|
349 }, |
|
350 SmartCardEvent: { create: function (aName, aProps) { |
|
351 return new SmartCardEvent(aName, aProps); |
|
352 }, |
|
353 }, |
|
354 SpeechRecognitionEvent: { create: function (aName, aProps) { |
|
355 return new SpeechRecognitionEvent(aName, aProps); |
|
356 }, |
|
357 }, |
|
358 SpeechSynthesisEvent: { create: function (aName, aProps) { |
|
359 return new SpeechSynthesisEvent(aName, aProps); |
|
360 }, |
|
361 }, |
|
362 StorageEvent: { create: function (aName, aProps) { |
|
363 return new StorageEvent(aName, aProps); |
|
364 }, |
|
365 }, |
|
366 StyleRuleChangeEvent: { create: function (aName, aProps) { |
|
367 return new StyleRuleChangeEvent(aName, aProps); |
|
368 }, |
|
369 chromeOnly: true, |
|
370 }, |
|
371 StyleSheetApplicableStateChangeEvent: { create: function (aName, aProps) { |
|
372 return new StyleSheetApplicableStateChangeEvent(aName, aProps); |
|
373 }, |
|
374 chromeOnly: true, |
|
375 }, |
|
376 StyleSheetChangeEvent: { create: function (aName, aProps) { |
|
377 return new StyleSheetChangeEvent(aName, aProps); |
|
378 }, |
|
379 chromeOnly: true, |
|
380 }, |
|
381 SVGZoomEvent: { create: function (aName, aProps) { |
|
382 var e = document.createEvent("svgzoomevent"); |
|
383 e.initUIEvent(aName, aProps.bubbles, aProps.cancelable, |
|
384 aProps.view, aProps.detail); |
|
385 return e; |
|
386 }, |
|
387 }, |
|
388 TimeEvent: { create: function (aName, aProps) { |
|
389 var e = document.createEvent("timeevent"); |
|
390 e.initTimeEvent(aName, aProps.view, aProps.detail); |
|
391 return e; |
|
392 }, |
|
393 }, |
|
394 TouchEvent: { create: function (aName, aProps) { |
|
395 var e = document.createEvent("touchevent"); |
|
396 e.initTouchEvent(aName, aProps.bubbles, aProps.cancelable, |
|
397 aProps.view, aProps.detail, |
|
398 aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey, |
|
399 aProps.touches, aProps.targetTouches, aProps.changedTouches); |
|
400 return e; |
|
401 }, |
|
402 }, |
|
403 TrackEvent: { create: function (aName, aProps) { |
|
404 return new TrackEvent(aName, aProps); |
|
405 }, |
|
406 }, |
|
407 TransitionEvent: { create: function (aName, aProps) { |
|
408 return new TransitionEvent(aName, aProps); |
|
409 }, |
|
410 }, |
|
411 UIEvent: { create: function (aName, aProps) { |
|
412 return new UIEvent(aName, aProps); |
|
413 }, |
|
414 }, |
|
415 UserProximityEvent: { create: function (aName, aProps) { |
|
416 return new UserProximityEvent(aName, aProps); |
|
417 }, |
|
418 }, |
|
419 USSDReceivedEvent: { create: function (aName, aProps) { |
|
420 return new USSDReceivedEvent(aName, aProps); |
|
421 }, |
|
422 }, |
|
423 WheelEvent: { create: function (aName, aProps) { |
|
424 return new WheelEvent(aName, aProps); |
|
425 }, |
|
426 }, |
|
427 }; |
|
428 |
|
429 for (var name of Object.keys(kEventConstructors)) { |
|
430 if (!kEventConstructors[name].chromeOnly) { |
|
431 continue; |
|
432 } |
|
433 if (window[name]) { |
|
434 ok(false, name + " should be chrome only."); |
|
435 } |
|
436 window[name] = SpecialPowers.unwrap(SpecialPowers.wrap(window)[name]); |
|
437 } |
|
438 |
|
439 var props = Object.getOwnPropertyNames(window); |
|
440 for (var i = 0; i < props.length; i++) { |
|
441 // Assume that event object must be named as "FooBarEvent". |
|
442 if (!props[i].match(/^([A-Z][a-zA-Z]+)?Event$/)) { |
|
443 continue; |
|
444 } |
|
445 if (!kEventConstructors[props[i]]) { |
|
446 ok(false, "Unknown event found: " + props[i]); |
|
447 continue; |
|
448 } |
|
449 if (!kEventConstructors[props[i]].create) { |
|
450 todo(false, "Cannot create untrusted event of " + props[i]); |
|
451 continue; |
|
452 } |
|
453 ok(true, "Creating " + props[i] + "..."); |
|
454 var event = kEventConstructors[props[i]].create("foo", {}); |
|
455 if (!event) { |
|
456 ok(false, "Failed to create untrusted event: " + props[i]); |
|
457 continue; |
|
458 } |
|
459 if (typeof(event.getModifierState) == "function") { |
|
460 const kModifiers = [ "Shift", "Control", "Alt", "AltGr", "Meta", "CapsLock", "ScrollLock", "NumLock", "OS", "Fn", "SymbolLock" ]; |
|
461 for (var j = 0; j < kModifiers.length; j++) { |
|
462 ok(true, "Calling " + props[i] + ".getModifierState(" + kModifiers[j] + ")..."); |
|
463 var modifierState = event.getModifierState(kModifiers[j]); |
|
464 ok(true, props[i] + ".getModifierState(" + kModifiers[j] + ") = " + modifierState); |
|
465 } |
|
466 } |
|
467 } |
|
468 |
|
469 </script> |
|
470 </pre> |
|
471 </body> |
|
472 </html> |