test_all_synthetic_events.html (33693B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Test all synthetic events</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script 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 (aName, aProps) { 28 return new Event(aName, aProps); 29 }, 30 }, 31 AnimationEvent: { create (aName, aProps) { 32 return new AnimationEvent(aName, aProps); 33 }, 34 }, 35 AnimationPlaybackEvent: { create (aName, aProps) { 36 return new AnimationPlaybackEvent(aName, aProps); 37 }, 38 }, 39 AudioProcessingEvent: { create: null, // Cannot create untrusted event from JS. 40 }, 41 BeforeUnloadEvent: { create (aName, aProps) { 42 var e = document.createEvent("beforeunloadevent"); 43 e.initEvent(aName, aProps.bubbles, aProps.cancelable); 44 return e; 45 }, 46 }, 47 BlobEvent: { create (aName, aProps) { 48 return new BlobEvent(aName, { 49 data: new Blob([]), 50 }); 51 }, 52 }, 53 CallEvent: { create (aName, aProps) { 54 return new CallEvent(aName, aProps); 55 }, 56 }, 57 CallGroupErrorEvent: { create (aName, aProps) { 58 return new CallGroupErrorEvent(aName, aProps); 59 }, 60 }, 61 CFStateChangeEvent: { create (aName, aProps) { 62 return new CFStateChangeEvent(aName, aProps); 63 }, 64 }, 65 CloseEvent: { create (aName, aProps) { 66 return new CloseEvent(aName, aProps); 67 }, 68 }, 69 ClipboardEvent: { create (aName, aProps) { 70 return new ClipboardEvent(aName, aProps); 71 }, 72 }, 73 CommandEvent: { create (aName, aProps) { 74 return new CommandEvent(aName, aProps); 75 }, 76 }, 77 CompositionEvent: { create (aName, aProps) { 78 var e = document.createEvent("compositionevent"); 79 e.initCompositionEvent(aName, aProps.bubbles, aProps.cancelable, 80 aProps.view, aProps.data); 81 return e; 82 }, 83 }, 84 ContentVisibilityAutoStateChangeEvent: { create (aName, aProps) { 85 return new ContentVisibilityAutoStateChangeEvent(aName, aProps); 86 }, 87 }, 88 CustomEvent: { create (aName, aProps) { 89 return new CustomEvent(aName, aProps); 90 }, 91 }, 92 DataErrorEvent: { create (aName, aProps) { 93 return new DataErrorEvent(aName, aProps); 94 }, 95 }, 96 DeviceLightEvent: { create (aName, aProps) { 97 return new DeviceLightEvent(aName, aProps); 98 }, 99 }, 100 DeviceMotionEvent: { create (aName, aProps) { 101 var e = document.createEvent("devicemotionevent"); 102 e.initDeviceMotionEvent(aName, aProps.bubbles, aProps.cancelable, aProps.acceleration, 103 aProps.accelerationIncludingGravity, aProps.rotationRate, 104 aProps.interval || 0.0); 105 return e; 106 }, 107 }, 108 DeviceOrientationEvent: { create (aName, aProps) { 109 return new DeviceOrientationEvent(aName, aProps); 110 }, 111 }, 112 DeviceProximityEvent: { create (aName, aProps) { 113 return new DeviceProximityEvent(aName, aProps); 114 }, 115 }, 116 DownloadEvent: { create (aName, aProps) { 117 return new DownloadEvent(aName, aProps); 118 }, 119 }, 120 DragEvent: { create (aName, aProps) { 121 var e = document.createEvent("dragevent"); 122 e.initDragEvent(aName, aProps.bubbles, aProps.cancelable, 123 aProps.view, aProps.detail, 124 aProps.screenX, aProps.screenY, 125 aProps.clientX, aProps.clientY, 126 aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey, 127 aProps.button, aProps.relatedTarget, aProps.dataTransfer); 128 return e; 129 }, 130 }, 131 ErrorEvent: { create (aName, aProps) { 132 return new ErrorEvent(aName, aProps); 133 }, 134 }, 135 FocusEvent: { create (aName, aProps) { 136 return new FocusEvent(aName, aProps); 137 }, 138 }, 139 FontFaceSetLoadEvent: { create (aName, aProps) { 140 return new FontFaceSetLoadEvent(aName, aProps); 141 }, 142 }, 143 FormDataEvent: { create (aName, aProps) { 144 return new FormDataEvent(aName, { 145 formData: new FormData() 146 }); 147 }, 148 }, 149 GamepadEvent: { create (aName, aProps) { 150 return new GamepadEvent(aName, aProps); 151 }, 152 }, 153 GamepadAxisMoveEvent: { create (aName, aProps) { 154 return new GamepadAxisMoveEvent(aName, aProps); 155 }, 156 }, 157 GamepadButtonEvent: { create (aName, aProps) { 158 return new GamepadButtonEvent(aName, aProps); 159 }, 160 }, 161 GPUUncapturedErrorEvent: { create: null, //TODO: constructor test 162 }, 163 HashChangeEvent: { create (aName, aProps) { 164 return new HashChangeEvent(aName, aProps); 165 }, 166 }, 167 IDBVersionChangeEvent: { create (aName, aProps) { 168 return new IDBVersionChangeEvent(aName, aProps); 169 }, 170 }, 171 ImageCaptureErrorEvent: { create (aName, aProps) { 172 return new ImageCaptureErrorEvent(aName, aProps); 173 }, 174 }, 175 InputEvent: { create (aName, aProps) { 176 return new InputEvent(aName, aProps); 177 }, 178 }, 179 KeyEvent: { create (aName, aProps) { 180 return new KeyboardEvent(aName, aProps); 181 }, 182 }, 183 KeyboardEvent: { create (aName, aProps) { 184 return new KeyboardEvent(aName, aProps); 185 }, 186 }, 187 MediaEncryptedEvent: { create (aName, aProps) { 188 return new MediaEncryptedEvent(aName, aProps); 189 }, 190 }, 191 MediaKeyMessageEvent: { create (aName, aProps) { 192 return new MediaKeyMessageEvent(aName, { 193 messageType: "license-request", 194 message: new ArrayBuffer(0) 195 }); 196 }, 197 }, 198 MediaQueryListEvent: { create (aName, aProps) { 199 return new MediaQueryListEvent(aName, aProps); 200 }, 201 }, 202 MediaRecorderErrorEvent: { create (aName, aProps) { 203 aProps.error = new DOMException(); 204 return new MediaRecorderErrorEvent(aName, aProps); 205 }, 206 }, 207 MediaStreamEvent: { create (aName, aProps) { 208 return new MediaStreamEvent(aName, aProps); 209 }, 210 }, 211 MediaStreamTrackEvent: { 212 // Difficult to test required arguments. 213 }, 214 MessageEvent: { create (aName, aProps) { 215 var e = new MessageEvent("messageevent", { bubbles: aProps.bubbles, 216 cancelable: aProps.cancelable, data: aProps.data, origin: aProps.origin, 217 lastEventId: aProps.lastEventId, source: aProps.source }); 218 return e; 219 }, 220 }, 221 MouseEvent: { create (aName, aProps) { 222 return new MouseEvent(aName, aProps); 223 }, 224 }, 225 MouseScrollEvent: { create: null 226 // Cannot create untrusted event from JS 227 }, 228 MozClirModeEvent: { create (aName, aProps) { 229 return new MozClirModeEvent(aName, aProps); 230 }, 231 }, 232 MozContactChangeEvent: { create (aName, aProps) { 233 return new MozContactChangeEvent(aName, aProps); 234 }, 235 }, 236 MozEmergencyCbModeEvent: { create (aName, aProps) { 237 return new MozEmergencyCbModeEvent(aName, aProps); 238 }, 239 }, 240 MozMessageDeletedEvent: { create (aName, aProps) { 241 return new MozMessageDeletedEvent(aName, aProps); 242 }, 243 }, 244 MozMmsEvent: { create (aName, aProps) { 245 return new MozMmsEvent(aName, aProps); 246 }, 247 }, 248 MozOtaStatusEvent: { create (aName, aProps) { 249 return new MozOtaStatusEvent(aName, aProps); 250 }, 251 }, 252 MozSmsEvent: { create (aName, aProps) { 253 return new MozSmsEvent(aName, aProps); 254 }, 255 }, 256 MozStkCommandEvent: { create (aName, aProps) { 257 return new MozStkCommandEvent(aName, aProps); 258 }, 259 }, 260 MutationEvent: { create (aName, aProps) { 261 var e = document.createEvent("mutationevent"); 262 e.initMutationEvent(aName, aProps.bubbles, aProps.cancelable, 263 aProps.relatedNode, aProps.prevValue, aProps.newValue, 264 aProps.attrName, aProps.attrChange); 265 return e; 266 }, 267 }, 268 NavigateEvent: { create: null 269 // Cannot create NavigateEvent without NavigationDestination which can't be created 270 }, 271 NavigationCurrentEntryChangeEvent: { create: null 272 // Cannot create NavigationCurrentEntryChangeEvent without window.navigation 273 }, 274 OfflineAudioCompletionEvent: { create: "AudioContext" in self 275 ? function (aName, aProps) { 276 var ac = new AudioContext(); 277 var ab = new AudioBuffer({ length: 42, sampleRate: ac.sampleRate }); 278 aProps.renderedBuffer = ab; 279 return new OfflineAudioCompletionEvent(aName, aProps); 280 } 281 : null, 282 }, 283 PageTransitionEvent: { create (aName, aProps) { 284 return new PageTransitionEvent(aName, aProps); 285 }, 286 }, 287 PointerEvent: { create (aName, aProps) { 288 return new PointerEvent(aName, aProps); 289 }, 290 }, 291 PopStateEvent: { create (aName, aProps) { 292 return new PopStateEvent(aName, aProps); 293 }, 294 }, 295 PopupBlockedEvent: { create (aName, aProps) { 296 return new PopupBlockedEvent(aName, aProps); 297 }, 298 }, 299 ProgressEvent: { create (aName, aProps) { 300 return new ProgressEvent(aName, aProps); 301 }, 302 }, 303 PromiseRejectionEvent: { create (aName, aProps) { 304 aProps.promise = new Promise(() => {}); 305 return new PromiseRejectionEvent(aName, aProps); 306 }, 307 }, 308 RTCDataChannelEvent: { create (aName, aProps) { 309 let pc = new RTCPeerConnection(); 310 aProps.channel = pc.createDataChannel("foo"); 311 let e = new RTCDataChannelEvent(aName, aProps); 312 aProps.channel.close(); 313 pc.close(); 314 return e; 315 }, 316 }, 317 RTCDTMFToneChangeEvent: { create (aName, aProps) { 318 return new RTCDTMFToneChangeEvent(aName, aProps); 319 }, 320 }, 321 RTCPeerConnectionIceEvent: { create (aName, aProps) { 322 return new RTCPeerConnectionIceEvent(aName, aProps); 323 }, 324 }, 325 RTCTrackEvent: { 326 // Difficult to test required arguments. 327 }, 328 ScrollAreaEvent: { create: null 329 // Cannot create untrusted event from JS 330 }, 331 SpeechRecognitionError: { create (aName, aProps) { 332 return new SpeechRecognitionError(aName, aProps); 333 }, 334 }, 335 SpeechRecognitionEvent: { create (aName, aProps) { 336 return new SpeechRecognitionEvent(aName, aProps); 337 }, 338 }, 339 SpeechSynthesisErrorEvent: { create (aName, aProps) { 340 aProps.error = "synthesis-unavailable"; 341 aProps.utterance = new SpeechSynthesisUtterance("Hello World"); 342 return new SpeechSynthesisErrorEvent(aName, aProps); 343 }, 344 }, 345 SpeechSynthesisEvent: { create (aName, aProps) { 346 aProps.utterance = new SpeechSynthesisUtterance("Hello World"); 347 return new SpeechSynthesisEvent(aName, aProps); 348 }, 349 }, 350 StorageEvent: { create (aName, aProps) { 351 return new StorageEvent(aName, aProps); 352 }, 353 }, 354 StyleSheetApplicableStateChangeEvent: { create (aName, aProps) { 355 return new StyleSheetApplicableStateChangeEvent(aName, aProps); 356 }, 357 chromeOnly: true, 358 }, 359 StyleSheetRemovedEvent: { create (aName, aProps) { 360 return new StyleSheetRemovedEvent(aName, aProps); 361 }, 362 chromeOnly: true, 363 }, 364 SubmitEvent: { create (aName, aProps) { 365 return new SubmitEvent(aName, aProps); 366 }, 367 }, 368 TaskPriorityChangeEvent: { create (aName, aProps) { 369 aProps.previousPriority = "user-blocking"; 370 return new TaskPriorityChangeEvent(aName, aProps); 371 }, 372 }, 373 TCPSocketErrorEvent: { create(aName, aProps) { 374 return new TCPSocketErrorEvent(aName, aProps); 375 }, 376 }, 377 TCPSocketEvent: { create(aName, aProps) { 378 return new TCPSocketEvent(aName, aProps); 379 }, 380 }, 381 TCPServerSocketEvent: { create(aName, aProps) { 382 return new TCPServerSocketEvent(aName, aProps); 383 }, 384 }, 385 TextEvent : { create (aName, aProps) { 386 var e = document.createEvent("textevent"); 387 e.initTextEvent("textInput", aProps.bubbles, aProps.cancelable, 388 aProps.view, aProps.data); 389 return e; 390 }, 391 }, 392 TimeEvent: { create: null 393 // Cannot create untrusted event from JS 394 }, 395 ToggleEvent: { create(aName, aProps) { 396 return new ToggleEvent(aName, aProps); 397 }, 398 }, 399 TouchEvent: { create (aName, aProps) { 400 var e = document.createEvent("touchevent"); 401 e.initTouchEvent(aName, aProps.bubbles, aProps.cancelable, 402 aProps.view, aProps.detail, 403 aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey, 404 aProps.touches, aProps.targetTouches, aProps.changedTouches); 405 return e; 406 }, 407 }, 408 TrackEvent: { create (aName, aProps) { 409 return new TrackEvent(aName, aProps); 410 }, 411 }, 412 TransitionEvent: { create (aName, aProps) { 413 return new TransitionEvent(aName, aProps); 414 }, 415 }, 416 UIEvent: { create (aName, aProps) { 417 return new UIEvent(aName, aProps); 418 }, 419 }, 420 UserProximityEvent: { create (aName, aProps) { 421 return new UserProximityEvent(aName, aProps); 422 }, 423 }, 424 USSDReceivedEvent: { create (aName, aProps) { 425 return new USSDReceivedEvent(aName, aProps); 426 }, 427 }, 428 VRDisplayEvent: { create: null, 429 // Required argument expects a VRDisplay that can not 430 // be created from Javascript without physical VR hardware 431 // connected. When Bug 1229480 lands, this test can be 432 // updated to use the puppet VR device. 433 }, 434 WheelEvent: { create (aName, aProps) { 435 return new WheelEvent(aName, aProps); 436 }, 437 }, 438 WebGLContextEvent: { create (aName, aProps) { 439 return new WebGLContextEvent(aName, aProps); 440 }, 441 }, 442 SecurityPolicyViolationEvent: { create (aName, aProps) { 443 return new SecurityPolicyViolationEvent(aName, aProps); 444 }, 445 }, 446 }; 447 448 function test() { 449 for (var name of Object.keys(kEventConstructors)) { 450 if (!kEventConstructors[name].chromeOnly) { 451 continue; 452 } 453 if (window[name]) { 454 ok(false, name + " should be chrome only."); 455 } 456 window[name] = SpecialPowers.unwrap(SpecialPowers.wrap(window)[name]); 457 } 458 459 var props = Object.getOwnPropertyNames(window); 460 for (var i = 0; i < props.length; i++) { 461 // Assume that event object must be named as "FooBarEvent". 462 if (!props[i].match(/^([A-Z][a-zA-Z]+)?Event$/)) { 463 continue; 464 } 465 if (!kEventConstructors[props[i]]) { 466 ok(false, "Unknown event found: " + props[i]); 467 continue; 468 } 469 if (!kEventConstructors[props[i]].create) { 470 todo(false, "Cannot create untrusted event of " + props[i]); 471 continue; 472 } 473 ok(true, "Creating " + props[i] + "..."); 474 var event = kEventConstructors[props[i]].create("foo", {}); 475 if (!event) { 476 ok(false, "Failed to create untrusted event: " + props[i]); 477 continue; 478 } 479 if (typeof(event.getModifierState) == "function") { 480 const kModifiers = [ "Shift", "Control", "Alt", "AltGr", "Meta", "CapsLock", "ScrollLock", "NumLock", "Fn", "FnLock", "Symbol", "SymbolLock" ]; 481 for (var j = 0; j < kModifiers.length; j++) { 482 ok(true, "Calling " + props[i] + ".getModifierState(" + kModifiers[j] + ")..."); 483 var modifierState = event.getModifierState(kModifiers[j]); 484 ok(true, props[i] + ".getModifierState(" + kModifiers[j] + ") = " + modifierState); 485 } 486 } 487 } 488 } 489 490 SimpleTest.waitForExplicitFinish(); 491 SpecialPowers.pushPrefEnv( 492 {"set": [["dom.w3c_touch_events.legacy_apis.enabled", true], 493 ["dom.events.textevent.enabled", true], 494 ["dom.navigation.webidl.enabled", true]]}, 495 function() { 496 test(); 497 SimpleTest.finish(); 498 }); 499 </script> 500 </pre> 501 </body> 502 </html>