Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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">
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 };
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 }
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 }
469 </script>
470 </pre>
471 </body>
472 </html>