Backed out changeset 06f41c22f3a6 (bug 1888460) for causing linux xpcshell failures...
[gecko.git] / widget / tests / test_assign_event_data.html
blob1da9bb535fdeff41c8ef6d5f156bf8be3bf1f7e7
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Testing ns*Event::Assign*EventData()</title>
5 <script src="/tests/SimpleTest/SimpleTest.js"></script>
6 <script src="/tests/SimpleTest/EventUtils.js"></script>
7 <script src="/tests/SimpleTest/NativeKeyCodes.js"></script>
8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
9 <style>
10 #a {
11 background-color: transparent;
12 transition: background-color 0.1s linear;
14 #a:focus {
15 background-color: red;
17 .slidin {
18 border: green 1px solid;
19 width: 10px;
20 height: 10px;
21 animation-name: slidein;
22 animation-duration: 1s;
24 @keyframes slidein {
25 from {
26 margin-left: 100%;
28 to {
29 margin-left: 0;
32 #pointer-target {
33 border: 1px dashed red;
34 background: yellow;
35 margin: 0px 10px;
36 padding: 0px 10px;
38 #scrollable-div {
39 background: green;
40 overflow: auto;
41 width: 30px;
42 height: 30px;
44 #scrolled-div {
45 background: magenta;
46 width: 10px;
47 height: 10px;
49 #form {
50 background: silver;
51 padding: 0px 10px;
53 #animated-div {
54 background: cyan;
55 padding: 0px 10px;
57 </style>
58 </head>
59 <body>
60 <div id="display">
61 <input id="input-text">
62 <button id="button">button</button>
63 <a id="a" href="about:blank">hyper link</a>
64 <span id="pointer-target">span</span>
65 <div id="scrollable-div"><div id="scrolled-div"></div></div>
66 <form id="form">form</form>
67 <div id="animated-div">&nbsp;</div>
68 </div>
69 <div id="content" style="display: none">
70 </div>
71 <pre id="test">
72 </pre>
74 <script class="testbody" type="application/javascript">
76 SimpleTest.waitForExplicitFinish();
77 SimpleTest.expectAssertions(0, 34);
79 const kIsMac = (navigator.platform.indexOf("Mac") == 0);
80 const kIsWin = (navigator.platform.indexOf("Win") == 0);
82 var gDescription = "";
83 var gEvent = null;
84 var gCopiedEvent = [];
85 var gCallback = null;
86 var gCallPreventDefault = false;
88 function onEvent(aEvent) {
89 if (gCallPreventDefault) {
90 aEvent.preventDefault();
92 ok(gEvent === null, gDescription + `: We should receive only one event to check per test: already got: ${gEvent ? gEvent.type : "null"}, got: ${aEvent.type}`);
93 gEvent = aEvent;
94 for (var attr in aEvent) {
95 if (!attr.match(/^[A-Z0-9_]+$/) && // ignore const attributes
96 attr != "multipleActionsPrevented" && // multipleActionsPrevented isn't defined in any DOM event specs.
97 typeof(aEvent[attr]) != "function") {
98 gCopiedEvent.push({ name: attr, value: aEvent[attr]});
101 setTimeout(gCallback, 0);
104 function observeKeyUpOnContent(aKeyCode, aCallback) {
105 document.addEventListener("keyup", function keyUp(ev) {
106 if (ev.keyCode == aKeyCode) {
107 document.removeEventListener("keyup", keyUp);
108 SimpleTest.executeSoon(aCallback);
113 const kTests = [
114 { description: "InternalScrollPortEvent (overflow, vertical)",
115 targetID: "scrollable-div", eventType: "overflow",
116 dispatchEvent() {
117 document.getElementById("scrolled-div").style.height = "500px";
119 canRun() {
120 return true;
122 todoMismatch: [],
124 { description: "InternalScrollPortEvent (overflow, horizontal)",
125 targetID: "scrollable-div", eventType: "overflow",
126 dispatchEvent() {
127 document.getElementById("scrolled-div").style.width = "500px";
129 canRun() {
130 return true;
132 todoMismatch: [],
134 { description: "InternalScrollAreaEvent (MozScrolledAreaChanged, spreading)",
135 target() { return document; }, eventType: "MozScrolledAreaChanged",
136 dispatchEvent() {
137 document.getElementById("scrollable-div").style.width = "50000px";
138 document.getElementById("scrollable-div").style.height = "50000px";
140 canRun() {
141 return true;
143 todoMismatch: [],
145 { description: "InternalScrollAreaEvent (MozScrolledAreaChanged, shrinking)",
146 target() { return document; }, eventType: "MozScrolledAreaChanged",
147 dispatchEvent() {
148 document.getElementById("scrollable-div").style.width = "30px";
149 document.getElementById("scrollable-div").style.height = "30px";
151 canRun() {
152 return true;
154 todoMismatch: [],
156 { description: "WidgetKeyboardEvent (keydown of 'a' key without modifiers)",
157 targetID: "input-text", eventType: "keydown",
158 dispatchEvent() {
159 document.getElementById(this.targetID).value = "";
160 document.getElementById(this.targetID).focus();
161 synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_A : MAC_VK_ANSI_A,
162 {}, "a", "a");
163 observeKeyUpOnContent(KeyboardEvent.DOM_VK_A, runNextTest);
164 return true;
166 canRun() {
167 return (kIsMac || kIsWin);
169 todoMismatch: [],
171 { description: "WidgetKeyboardEvent (keyup of 'a' key without modifiers)",
172 targetID: "input-text", eventType: "keydown",
173 dispatchEvent() {
174 document.getElementById(this.targetID).value = "";
175 document.getElementById(this.targetID).focus();
176 synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_A : MAC_VK_ANSI_A,
177 {}, "a", "a");
178 observeKeyUpOnContent(KeyboardEvent.DOM_VK_A, runNextTest);
179 return true;
181 canRun() {
182 return (kIsMac || kIsWin);
184 todoMismatch: [],
186 { description: "WidgetKeyboardEvent (keypress of 'b' key with Shift)",
187 targetID: "input-text", eventType: "keypress",
188 dispatchEvent() {
189 document.getElementById(this.targetID).value = "";
190 document.getElementById(this.targetID).focus();
191 synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_B : MAC_VK_ANSI_B,
192 { shiftKey: true }, "B", "B");
194 // On Windows, synthesizeNativeKey will also fire keyup for shiftKey.
195 // We have to wait for it to prevent the key event break the next test case.
196 let waitKeyCode = _EU_isWin(window) ? KeyboardEvent.DOM_VK_SHIFT :
197 KeyboardEvent.DOM_VK_B;
198 observeKeyUpOnContent(waitKeyCode, runNextTest);
199 return true;
201 canRun() {
202 return (kIsMac || kIsWin);
204 todoMismatch: [],
206 { description: "WidgetKeyboardEvent (keyup during composition)",
207 targetID: "input-text", eventType: "keyup",
208 dispatchEvent() {
209 document.getElementById(this.targetID).value = "";
210 document.getElementById(this.targetID).focus();
211 synthesizeCompositionChange({ "composition":
212 { "string": "\u306D",
213 "clauses":
215 { "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE },
218 "caret": { "start": 1, "length": 0 },
219 "key": { key: "a" },
221 synthesizeComposition({ type: "compositioncommitasis", key: {} });
223 canRun() {
224 return true;
226 todoMismatch: [ ],
228 { description: "WidgetKeyboardEvent (keydown during composition)",
229 targetID: "input-text", eventType: "keydown",
230 dispatchEvent() {
231 document.getElementById(this.targetID).value = "";
232 document.getElementById(this.targetID).focus();
233 synthesizeCompositionChange({ "composition":
234 { "string": "\u306D",
235 "clauses":
237 { "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE },
240 "caret": { "start": 1, "length": 0 },
241 "key": {},
243 synthesizeComposition({ type: "compositioncommitasis",
244 key: { key: "KEY_Enter" } });
246 canRun() {
247 return true;
249 todoMismatch: [ ],
251 { description: "WidgetMouseEvent (mousedown of left button without modifier)",
252 targetID: "button", eventType: "mousedown",
253 dispatchEvent() {
254 synthesizeMouseAtCenter(document.getElementById(this.targetID),
255 { button: 0 });
257 canRun() {
258 return true;
260 todoMismatch: [],
262 { description: "WidgetMouseEvent (click of middle button with Shift)",
263 targetID: "button", eventType: "auxclick",
264 dispatchEvent() {
265 document.getElementById(this.targetID).value = "";
266 synthesizeMouseAtCenter(document.getElementById(this.targetID),
267 { button: 1, shiftKey: true, pressure: 0.5 });
269 canRun() {
270 return true;
272 todoMismatch: [],
274 { description: "WidgetMouseEvent (mouseup of right button with Alt)",
275 targetID: "button", eventType: "mouseup",
276 dispatchEvent() {
277 document.getElementById(this.targetID).value = "";
278 synthesizeMouseAtCenter(document.getElementById(this.targetID),
279 { button: 2, altKey: true });
281 canRun() {
282 return true;
284 todoMismatch: [],
286 { description: "WidgetDragEvent",
287 targetID: "input-text", eventType: "dragstart",
288 dispatchEvent() {
291 canRun() {
292 todo(false, "WidgetDragEvent isn't tested");
293 return false;
295 todoMismatch: [],
297 { description: "WidgetCompositionEvent (compositionupdate)",
298 targetID: "input-text", eventType: "compositionupdate",
299 dispatchEvent() {
300 document.getElementById(this.targetID).value = "";
301 document.getElementById(this.targetID).focus();
302 synthesizeComposition({ type: "compositioncommit", data: "\u30E9\u30FC\u30E1\u30F3", key: { key: "KEY_Enter" } });
304 canRun() {
305 return true;
307 todoMismatch: [ ],
309 { description: "InternalEditorInputEvent (input at key input)",
310 targetID: "input-text", eventType: "input",
311 dispatchEvent() {
312 document.getElementById(this.targetID).value = "";
313 document.getElementById(this.targetID).focus();
314 synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US, kIsWin ? WIN_VK_B : MAC_VK_ANSI_B,
315 { shiftKey: true }, "B", "B");
316 observeKeyUpOnContent(KeyboardEvent.DOM_VK_B, runNextTest);
317 return true;
319 canRun() {
320 return (kIsMac || kIsWin);
322 todoMismatch: [],
324 { description: "InternalEditorInputEvent (input at composing)",
325 targetID: "input-text", eventType: "input",
326 dispatchEvent() {
327 document.getElementById(this.targetID).value = "";
328 document.getElementById(this.targetID).focus();
329 synthesizeCompositionChange({ "composition":
330 { "string": "\u30E9\u30FC\u30E1\u30F3",
331 "clauses":
333 { "length": 4, "attr": COMPOSITION_ATTR_RAW_CLAUSE },
336 "caret": { "start": 4, "length": 0 },
337 "key": { key: "y" },
340 canRun() {
341 return true;
343 todoMismatch: [ ],
345 { description: "InternalEditorInputEvent (input at committing)",
346 targetID: "input-text", eventType: "input",
347 dispatchEvent() {
348 synthesizeComposition({ type: "compositioncommitasis", key: { key: "KEY_Enter" } });
350 canRun() {
351 return true;
353 todoMismatch: [ ],
355 { description: "WidgetMouseScrollEvent (DOMMouseScroll, vertical)",
356 targetID: "input-text", eventType: "DOMMouseScroll",
357 dispatchEvent() {
358 document.getElementById(this.targetID).value = "";
359 synthesizeWheel(document.getElementById(this.targetID), 3, 4,
360 { deltaY: 30, lineOrPageDeltaY: 2 });
362 canRun() {
363 return true;
365 todoMismatch: [ ],
367 { description: "WidgetMouseScrollEvent (DOMMouseScroll, horizontal)",
368 targetID: "input-text", eventType: "DOMMouseScroll",
369 dispatchEvent() {
370 document.getElementById(this.targetID).value = "";
371 synthesizeWheel(document.getElementById(this.targetID), 4, 5,
372 { deltaX: 30, lineOrPageDeltaX: 2, shiftKey: true });
374 canRun() {
375 return true;
377 todoMismatch: [ ],
379 { description: "WidgetMouseScrollEvent (MozMousePixelScroll, vertical)",
380 targetID: "input-text", eventType: "MozMousePixelScroll",
381 dispatchEvent() {
382 document.getElementById(this.targetID).value = "";
383 synthesizeWheel(document.getElementById(this.targetID), 3, 4,
384 { deltaY: 20, lineOrPageDeltaY: 1, altKey: true });
386 canRun() {
387 return true;
389 todoMismatch: [ ],
391 { description: "WidgetMouseScrollEvent (MozMousePixelScroll, horizontal)",
392 targetID: "input-text", eventType: "MozMousePixelScroll",
393 dispatchEvent() {
394 document.getElementById(this.targetID).value = "";
395 synthesizeWheel(document.getElementById(this.targetID), 4, 5,
396 { deltaX: 20, lineOrPageDeltaX: 1, ctrlKey: true });
398 canRun() {
399 return true;
401 todoMismatch: [ ],
403 { description: "WidgetWheelEvent (wheel, vertical)",
404 targetID: "input-text", eventType: "wheel",
405 dispatchEvent() {
406 document.getElementById(this.targetID).value = "";
407 synthesizeWheel(document.getElementById(this.targetID), 3, 4,
408 { deltaY: 20, lineOrPageDeltaY: 1, altKey: true });
410 canRun() {
411 return true;
413 todoMismatch: [ ],
415 { description: "WidgetWheelEvent (wheel, horizontal)",
416 targetID: "input-text", eventType: "wheel",
417 dispatchEvent() {
418 document.getElementById(this.targetID).value = "";
419 synthesizeWheel(document.getElementById(this.targetID), 4, 5,
420 { deltaX: 20, lineOrPageDeltaX: 1, ctrlKey: true });
422 canRun() {
423 return true;
425 todoMismatch: [ ],
427 { description: "WidgetWheelEvent (wheel, both)",
428 targetID: "input-text", eventType: "wheel",
429 dispatchEvent() {
430 document.getElementById(this.targetID).value = "";
431 synthesizeWheel(document.getElementById(this.targetID), 4, 5,
432 { deltaX: 20, deltaY: 10,
433 lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 });
435 canRun() {
436 return true;
438 todoMismatch: [ ],
440 { description: "WidgetTouchEvent (touchstart)",
441 target() { return document; }, eventType: "touchstart",
442 dispatchEvent() {
443 synthesizeTouchAtPoint(1, 2, { id: 10, rx: 4, ry: 3, angle: 0, force: 1, shiftKey: true});
445 canRun() {
446 return true;
448 todoMismatch: [ ],
450 { description: "WidgetTouchEvent (touchend)",
451 target() { return document; }, eventType: "touchend",
452 dispatchEvent() {
453 synthesizeTouchAtPoint(4, 6, { id: 5, rx: 1, ry: 2, angle: 0.5, force: 0.8, ctrlKey: true});
455 canRun() {
456 return true;
458 todoMismatch: [ ],
460 { description: "InternalFormEvent (reset)",
461 targetID: "form", eventType: "reset",
462 dispatchEvent() {
463 document.getElementById("form").reset();
465 canRun() {
466 return true;
468 todoMismatch: [ ],
470 { description: "WidgetCommandEvent",
471 targetID: "input-text", eventType: "",
472 dispatchEvent() {
475 canRun() {
476 todo(false, "WidgetCommandEvent isn't tested");
477 return false;
479 todoMismatch: [],
481 { description: "InternalClipboardEvent (copy)",
482 targetID: "input-text", eventType: "copy",
483 dispatchEvent() {
484 document.getElementById("input-text").value = "go to clipboard!";
485 document.getElementById("input-text").focus();
486 document.getElementById("input-text").select();
487 synthesizeKey("c", { accelKey: true });
489 canRun() {
490 return true;
492 todoMismatch: [ ],
494 { description: "InternalUIEvent (DOMActivate)",
495 targetID: "button", eventType: "DOMActivate",
496 dispatchEvent() {
497 synthesizeMouseAtCenter(document.getElementById(this.targetID),
498 { button: 0, shiftKey: true });
500 canRun() {
501 return true;
503 todoMismatch: [],
505 { description: "InternalFocusEvent (focus)",
506 targetID: "input-text", eventType: "focus",
507 dispatchEvent() {
508 document.getElementById(this.targetID).focus();
510 canRun() {
511 return true;
513 todoMismatch: [],
515 { description: "InternalFocusEvent (blur)",
516 targetID: "input-text", eventType: "blur",
517 dispatchEvent() {
518 document.getElementById(this.targetID).blur();
520 canRun() {
521 return true;
523 todoMismatch: [],
525 { description: "WidgetSimpleGestureEvent",
526 targetID: "", eventType: "",
527 dispatchEvent() {
530 canRun() {
531 // Simple gesture event may be handled before it comes content.
532 // So, we cannot test it in this test.
533 todo(false, "WidgetSimpleGestureEvent isn't tested");
534 return false;
536 todoMismatch: [],
538 { description: "InternalTransitionEvent (transitionend)",
539 targetID: "a", eventType: "transitionend",
540 dispatchEvent() {
541 document.getElementById(this.targetID).focus();
543 canRun() {
544 return true;
546 todoMismatch: [],
548 { description: "InternalAnimationEvent (animationend)",
549 targetID: "animated-div", eventType: "animationend",
550 dispatchEvent() {
551 document.getElementById(this.targetID).className = "slidin";
553 canRun() {
554 return true;
556 todoMismatch: [],
558 { description: "InternalMutationEvent (DOMAttrModified)",
559 targetID: "animated-div", eventType: "DOMAttrModified",
560 dispatchEvent() {
561 document.getElementById(this.targetID).setAttribute("x-data", "foo");
563 canRun() {
564 return true;
566 todoMismatch: [],
568 { description: "InternalMutationEvent (DOMNodeInserted)",
569 targetID: "animated-div", eventType: "DOMNodeInserted",
570 dispatchEvent() {
571 var div = document.createElement("div");
572 div.id = "inserted-div";
573 document.getElementById("animated-div").appendChild(div);
575 canRun() {
576 return true;
578 todoMismatch: [],
580 { description: "InternalMutationEvent (DOMNodeRemoved)",
581 targetID: "animated-div", eventType: "DOMNodeRemoved",
582 dispatchEvent() {
583 document.getElementById("animated-div").removeChild(document.getElementById("inserted-div"));
585 canRun() {
586 return true;
588 todoMismatch: [],
590 { description: "PointerEvent (pointerdown)",
591 targetID: "pointer-target", eventType: "mousedown",
592 dispatchEvent() {
593 var elem = document.getElementById(this.targetID);
594 var rect = elem.getBoundingClientRect();
595 synthesizeMouse(elem, rect.width / 2, rect.height / 2,
596 { type: this.eventType, button: 1, clickCount: 1, inputSource: 2, pressure: 0.25, isPrimary: true });
598 canRun() {
599 return true;
601 todoMismatch: [],
603 { description: "PointerEvent (pointerup)",
604 targetID: "pointer-target", eventType: "mouseup",
605 dispatchEvent() {
606 var elem = document.getElementById(this.targetID);
607 var rect = elem.getBoundingClientRect();
608 synthesizeMouse(elem, rect.width / 2, rect.height / 2,
609 { type: this.eventType, button: -1, ctrlKey: true, shiftKey: true, altKey: true, isSynthesized: false });
611 canRun() {
612 return true;
614 todoMismatch: [],
618 function doTest(aTest) {
619 if (!aTest.canRun()) {
620 SimpleTest.executeSoon(runNextTest);
621 return;
623 gEvent = null;
624 gCopiedEvent = [];
625 gDescription = aTest.description + " (gCallPreventDefault=" + gCallPreventDefault + ")";
626 var target = aTest.target ? aTest.target() : document.getElementById(aTest.targetID);
627 target.addEventListener(aTest.eventType, onEvent, true);
628 gCallback = function() {
629 target.removeEventListener(aTest.eventType, onEvent, true);
630 ok(gEvent !== null, gDescription + ": failed to get duplicated event");
631 ok(!!gCopiedEvent.length, gDescription + ": count of attribute of the event must be larger than 0");
632 for (var i = 0; i < gCopiedEvent.length; ++i) {
633 var name = gCopiedEvent[i].name;
634 if (name == "rangeOffset") {
635 todo(false, gDescription + ": " + name + " attribute value is never reset (" + gEvent[name] + ")");
636 } else if (name == "eventPhase") {
637 is(gEvent[name], 0, gDescription + ": mismatch with fixed value (" + name + ")");
638 } else if (name == "rangeParent" || name == "currentTarget") {
639 is(gEvent[name], null, gDescription + ": mismatch with fixed value (" + name + ")");
640 } else if (aTest.todoMismatch.includes(name)) {
641 todo_is(gEvent[name], gCopiedEvent[i].value, gDescription + ": mismatch (" + name + ")");
642 } else if (name == "offsetX" || name == "offsetY") {
643 // do nothing; these are defined to return different values during event dispatch
644 // vs not during event dispatch
645 } else {
646 is(gEvent[name], gCopiedEvent[i].value, gDescription + ": mismatch (" + name + ")");
649 if (!testWillCallRunNextTest) {
650 runNextTest();
653 var testWillCallRunNextTest = aTest.dispatchEvent();
656 var gIndex = -1;
657 function runNextTest() {
658 if (++gIndex == kTests.length) {
659 if (gCallPreventDefault) {
660 finish();
661 return;
663 // Test with a call of preventDefault() of the events.
664 gCallPreventDefault = true;
665 gIndex = -1;
666 // Restoring the initial state of all elements.
667 document.getElementById("scrollable-div").style.height = "30px";
668 document.getElementById("scrollable-div").style.width = "30px";
669 document.getElementById("scrolled-div").style.height = "10px";
670 document.getElementById("scrolled-div").style.width = "10px";
671 document.getElementById("input-text").value = "";
672 document.getElementById("animated-div").className = "";
673 document.getElementById("animated-div").removeAttribute("x-data");
674 if (document.activeElement) {
675 document.activeElement.blur();
677 window.requestAnimationFrame(function() {
678 setTimeout(runNextTest, 0);
680 return;
682 doTest(kTests[gIndex]);
685 function init() {
686 SpecialPowers.pushPrefEnv({"set": [["middlemouse.contentLoadURL", false],
687 ["middlemouse.paste", false],
688 ["general.autoScroll", false],
689 ["mousewheel.default.action", 0],
690 ["mousewheel.default.action.override_x", -1],
691 ["mousewheel.with_shift.action", 0],
692 ["mousewheel.with_shift.action.override_x", -1],
693 ["mousewheel.with_control.action", 0],
694 ["mousewheel.with_control.action.override_x", -1],
695 ["mousewheel.with_alt.action", 0],
696 ["mousewheel.with_alt.action.override_x", -1],
697 ["mousewheel.with_meta.action", 0],
698 ["mousewheel.with_meta.action.override_x", -1]]}, runNextTest);
701 function finish() {
702 SimpleTest.finish();
705 SimpleTest.waitForFocus(init);
707 </script>
708 </body>