test_bug687787.html (20994B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=687787 5 --> 6 <head> 7 <title>Test for Bug 687787</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 10 </head> 11 <body> 12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=687787">Mozilla Bug 687787</a> 13 <p id="display"></p> 14 <div id="content" style="display: none"> 15 16 </div> 17 18 <pre id="test"> 19 <script class="testbody" type="text/javascript"> 20 21 var eventStack = []; 22 23 function _callback(e){ 24 var event = {'type' : e.type, 'target' : e.target, 'relatedTarget' : e.relatedTarget } 25 eventStack.push(event); 26 } 27 28 function clearEventStack(){ 29 eventStack = []; 30 } 31 32 window.addEventListener("focus", _callback, true); 33 window.addEventListener("focusin", _callback, true); 34 window.addEventListener("focusout", _callback, true); 35 window.addEventListener("blur", _callback, true); 36 37 function CompareEventToExpected(e, expected) { 38 if (expected == null || e == null) 39 return false; 40 if (e.type == expected.type && e.target == expected.target && e.relatedTarget == expected.relatedTarget) 41 return true; 42 return false; 43 } 44 45 function TestEventOrderNormal() { 46 47 var input1 = document.createElement('input'); 48 var input2 = document.createElement('input'); 49 var input3 = document.createElement('input'); 50 var content = document.getElementById('content'); 51 52 input1.setAttribute('id', 'input1'); 53 input2.setAttribute('id', 'input2'); 54 input3.setAttribute('id', 'input3'); 55 input1.setAttribute('type', 'text'); 56 input2.setAttribute('type', 'text'); 57 input3.setAttribute('type', 'text'); 58 input1.setAttribute('inputmode', 'none'); 59 input2.setAttribute('inputmode', 'none'); 60 input3.setAttribute('inputmode', 'none'); 61 62 content.appendChild(input1); 63 content.appendChild(input2); 64 content.appendChild(input3); 65 content.style.display = 'block' 66 67 let expectedEventOrder = [ 68 {'type' : 'blur', 69 'target' : input1, 70 'relatedTarget' : input2}, 71 {'type' : 'focusout', 72 'target' : input1, 73 'relatedTarget' : input2}, 74 {'type' : 'focus', 75 'target' : input2, 76 'relatedTarget' : input1}, 77 {'type' : 'focusin', 78 'target' : input2, 79 'relatedTarget' : input1}, 80 {'type' : 'blur', 81 'target' : input2, 82 'relatedTarget' : input3}, 83 {'type' : 'focusout', 84 'target' : input2, 85 'relatedTarget' : input3}, 86 {'type' : 'focus', 87 'target' : input3, 88 'relatedTarget' : input2}, 89 {'type' : 'focusin', 90 'target' : input3, 91 'relatedTarget' : input2}, 92 ] 93 94 input1.focus(); 95 clearEventStack(); 96 97 input2.focus(); 98 input3.focus(); 99 100 for (var i = 0; i < expectedEventOrder.length || i < eventStack.length ; i++) { 101 ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': ' 102 + 'Expected (' 103 + expectedEventOrder[i].type + ',' 104 + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ',' 105 + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), ' 106 + 'Actual (' 107 + eventStack[i].type + ',' 108 + (eventStack[i].target ? eventStack[i].target.id : null) + ',' 109 + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')'); 110 } 111 112 content.innerHTML = ''; 113 } 114 115 function TestEventOrderNormalFiresAtRightTime() { 116 117 var input1 = document.createElement('input'); 118 var input2 = document.createElement('input'); 119 var input3 = document.createElement('input'); 120 var content = document.getElementById('content'); 121 122 input1.setAttribute('id', 'input1'); 123 input2.setAttribute('id', 'input2'); 124 input3.setAttribute('id', 'input3'); 125 input1.setAttribute('type', 'text'); 126 input2.setAttribute('type', 'text'); 127 input3.setAttribute('type', 'text'); 128 129 input1.onblur = function(e) 130 { 131 ok(document.activeElement == document.body, 'input1: not focused when blur fires') 132 } 133 134 input1.addEventListener('focusout', function(e) 135 { 136 ok(document.activeElement == document.body, 'input1: not focused when focusout fires') 137 }); 138 139 input2.onfocus = function(e) 140 { 141 ok(document.activeElement == input2, 'input2: focused when focus fires') 142 } 143 144 input2.addEventListener('focusin', function(e) 145 { 146 ok(document.activeElement == input2, 'input2: focused when focusin fires') 147 }); 148 149 content.appendChild(input1); 150 content.appendChild(input2); 151 content.style.display = 'block' 152 153 let expectedEventOrder = [ 154 {'type' : 'blur', 155 'target' : input1, 156 'relatedTarget' : input2}, 157 {'type' : 'focusout', 158 'target' : input1, 159 'relatedTarget' : input2}, 160 {'type' : 'focus', 161 'target' : input2, 162 'relatedTarget' : input1}, 163 {'type' : 'focusin', 164 'target' : input2, 165 'relatedTarget' : input1}, 166 ] 167 168 input1.focus(); 169 clearEventStack(); 170 171 input2.focus(); 172 173 for (var i = 0; i < expectedEventOrder.length || i < eventStack.length ; i++) { 174 ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': ' 175 + 'Expected (' 176 + expectedEventOrder[i].type + ',' 177 + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ',' 178 + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), ' 179 + 'Actual (' 180 + eventStack[i].type + ',' 181 + (eventStack[i].target ? eventStack[i].target.id : null) + ',' 182 + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')'); 183 } 184 185 content.innerHTML = ''; 186 } 187 188 function TestFocusOutRedirectsFocus() { 189 190 var input1 = document.createElement('input'); 191 var input2 = document.createElement('input'); 192 var input3 = document.createElement('input'); 193 var content = document.getElementById('content'); 194 195 input1.setAttribute('id', 'input1'); 196 input2.setAttribute('id', 'input2'); 197 input3.setAttribute('id', 'input3'); 198 input1.setAttribute('type', 'text'); 199 input2.setAttribute('type', 'text'); 200 input3.setAttribute('type', 'text'); 201 input1.addEventListener('focusout', function () { 202 input3.focus(); 203 }); 204 205 content.appendChild(input1); 206 content.appendChild(input2); 207 content.appendChild(input3); 208 content.style.display = 'block' 209 210 let expectedEventOrder = [ 211 {'type' : 'blur', 212 'target' : input1, 213 'relatedTarget' : input2}, 214 {'type' : 'focusout', 215 'target' : input1, 216 'relatedTarget' : input2}, 217 {'type' : 'focus', 218 'target' : input3, 219 'relatedTarget' : null}, 220 {'type' : 'focusin', 221 'target' : input3, 222 'relatedTarget' : null}, 223 ] 224 225 input1.focus(); 226 clearEventStack(); 227 input2.focus(); 228 229 for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) { 230 ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': ' 231 + 'Expected (' 232 + expectedEventOrder[i].type + ',' 233 + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ',' 234 + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), ' 235 + 'Actual (' 236 + eventStack[i].type + ',' 237 + (eventStack[i].target ? eventStack[i].target.id : null) + ',' 238 + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')'); 239 } 240 241 content.innerHTML = ''; 242 } 243 244 function TestFocusInRedirectsFocus() { 245 246 var input1 = document.createElement('input'); 247 var input2 = document.createElement('input'); 248 var input3 = document.createElement('input'); 249 var content = document.getElementById('content'); 250 251 input1.setAttribute('id', 'input1'); 252 input2.setAttribute('id', 'input2'); 253 input3.setAttribute('id', 'input3'); 254 input1.setAttribute('type', 'text'); 255 input2.setAttribute('type', 'text'); 256 input3.setAttribute('type', 'text'); 257 input2.addEventListener('focusin', function () { 258 input3.focus(); 259 }); 260 261 content.appendChild(input1); 262 content.appendChild(input2); 263 content.appendChild(input3); 264 content.style.display = 'block' 265 266 let expectedEventOrder = [ 267 {'type' : 'blur', 268 'target' : input1, 269 'relatedTarget' : input2}, 270 {'type' : 'focusout', 271 'target' : input1, 272 'relatedTarget' : input2}, 273 {'type' : 'focus', 274 'target' : input2, 275 'relatedTarget' : input1}, 276 {'type' : 'focusin', 277 'target' : input2, 278 'relatedTarget' : input1}, 279 {'type' : 'blur', 280 'target' : input2, 281 'relatedTarget' : input3}, 282 {'type' : 'focusout', 283 'target' : input2, 284 'relatedTarget' : input3}, 285 {'type' : 'focus', 286 'target' : input3, 287 'relatedTarget' : input2}, 288 {'type' : 'focusin', 289 'target' : input3, 290 'relatedTarget' : input2}, 291 ] 292 293 input1.focus(); 294 clearEventStack(); 295 input2.focus(); 296 297 for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) { 298 ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': ' 299 + 'Expected (' 300 + expectedEventOrder[i].type + ',' 301 + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ',' 302 + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), ' 303 + 'Actual (' 304 + eventStack[i].type + ',' 305 + (eventStack[i].target ? eventStack[i].target.id : null) + ',' 306 + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')'); 307 } 308 309 content.innerHTML = ''; 310 } 311 312 function TestBlurRedirectsFocus() { 313 314 var input1 = document.createElement('input'); 315 var input2 = document.createElement('input'); 316 var input3 = document.createElement('input'); 317 var content = document.getElementById('content'); 318 319 input1.setAttribute('id', 'input1'); 320 input2.setAttribute('id', 'input2'); 321 input3.setAttribute('id', 'input3'); 322 input1.setAttribute('type', 'text'); 323 input2.setAttribute('type', 'text'); 324 input3.setAttribute('type', 'text'); 325 input1.onblur = function () { 326 input3.focus(); 327 } 328 329 content.appendChild(input1); 330 content.appendChild(input2); 331 content.appendChild(input3); 332 content.style.display = 'block' 333 334 let expectedEventOrder = [ 335 {'type' : 'blur', 336 'target' : input1, 337 'relatedTarget' : input2}, 338 {'type' : 'focus', 339 'target' : input3, 340 'relatedTarget' : null}, 341 {'type' : 'focusin', 342 'target' : input3, 343 'relatedTarget' : null}, 344 {'type' : 'focusout', 345 'target' : input1, 346 'relatedTarget' : input2}, 347 ] 348 349 input1.focus(); 350 clearEventStack(); 351 input2.focus(); 352 353 for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) { 354 ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': ' 355 + 'Expected (' 356 + expectedEventOrder[i].type + ',' 357 + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ',' 358 + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), ' 359 + 'Actual (' 360 + eventStack[i].type + ',' 361 + (eventStack[i].target ? eventStack[i].target.id : null) + ',' 362 + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')'); 363 } 364 365 content.innerHTML = ''; 366 } 367 368 function TestFocusRedirectsFocus() { 369 370 var input1 = document.createElement('input'); 371 var input2 = document.createElement('input'); 372 var input3 = document.createElement('input'); 373 var content = document.getElementById('content'); 374 375 input1.setAttribute('id', 'input1'); 376 input2.setAttribute('id', 'input2'); 377 input3.setAttribute('id', 'input3'); 378 input1.setAttribute('type', 'text'); 379 input2.setAttribute('type', 'text'); 380 input3.setAttribute('type', 'text'); 381 input2.onfocus = function () { 382 input3.focus(); 383 } 384 385 content.appendChild(input1); 386 content.appendChild(input2); 387 content.appendChild(input3); 388 content.style.display = 'block' 389 390 let expectedEventOrder = [ 391 {'type' : 'blur', 392 'target' : input1, 393 'relatedTarget' : input2}, 394 {'type' : 'focusout', 395 'target' : input1, 396 'relatedTarget' : input2}, 397 {'type' : 'focus', 398 'target' : input2, 399 'relatedTarget' : input1}, 400 {'type' : 'blur', 401 'target' : input2, 402 'relatedTarget' : input3}, 403 {'type' : 'focusout', 404 'target' : input2, 405 'relatedTarget' : input3}, 406 {'type' : 'focus', 407 'target' : input3, 408 'relatedTarget' : input2}, 409 {'type' : 'focusin', 410 'target' : input3, 411 'relatedTarget' : input2}, 412 ] 413 414 input1.focus(); 415 clearEventStack(); 416 input2.focus(); 417 418 for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) { 419 ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': ' 420 + 'Expected (' 421 + expectedEventOrder[i].type + ',' 422 + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ',' 423 + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), ' 424 + 'Actual (' 425 + eventStack[i].type + ',' 426 + (eventStack[i].target ? eventStack[i].target.id : null) + ',' 427 + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')'); 428 } 429 430 content.innerHTML = ''; 431 } 432 433 function TestEventOrderDifferentDocument() { 434 435 var input1 = document.createElement('input'); 436 var input2 = document.createElement('input'); 437 var iframe1 = document.createElement('iframe'); 438 var content = document.getElementById('content'); 439 440 input1.setAttribute('id', 'input1'); 441 input2.setAttribute('id', 'input2'); 442 iframe1.setAttribute('id', 'iframe1'); 443 input1.setAttribute('type', 'text'); 444 input2.setAttribute('type', 'text'); 445 446 content.appendChild(input1); 447 content.appendChild(iframe1); 448 iframe1.contentDocument.body.appendChild(input2); 449 content.style.display = 'block' 450 451 iframe1.contentDocument.addEventListener("focus", _callback, true); 452 iframe1.contentDocument.addEventListener("focusin", _callback, true); 453 iframe1.contentDocument.addEventListener("focusout", _callback, true); 454 iframe1.contentDocument.addEventListener("blur", _callback, true); 455 456 let expectedEventOrder = [ 457 {'type' : 'blur', 458 'target' : input1, 459 'relatedTarget' : null}, 460 {'type' : 'focusout', 461 'target' : input1, 462 'relatedTarget' : null}, 463 {'type' : 'blur', 464 'target' : document, 465 'relatedTarget' : null}, 466 {'type' : 'blur', 467 'target' : window, 468 'relatedTarget' : null}, 469 {'type' : 'focus', 470 'target' : iframe1.contentDocument, 471 'relatedTarget' : null}, 472 {'type' : 'focus', 473 'target' : input2, 474 'relatedTarget' : null}, 475 {'type' : 'focusin', 476 'target' : input2, 477 'relatedTarget' : null}, 478 ] 479 480 input1.focus(); 481 clearEventStack(); 482 input2.focus(); 483 484 for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) { 485 ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': ' 486 + 'Expected (' 487 + expectedEventOrder[i].type + ',' 488 + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ',' 489 + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), ' 490 + 'Actual (' 491 + eventStack[i].type + ',' 492 + (eventStack[i].target ? eventStack[i].target.id : null) + ',' 493 + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')'); 494 } 495 496 content.innerHTML = ''; 497 } 498 499 500 function TestFocusOutMovesTarget() { 501 502 var input1 = document.createElement('input'); 503 var input2 = document.createElement('input'); 504 var iframe1 = document.createElement('iframe'); 505 var content = document.getElementById('content'); 506 507 input1.setAttribute('id', 'input1'); 508 input2.setAttribute('id', 'input2'); 509 iframe1.setAttribute('id', 'iframe1'); 510 input1.setAttribute('type', 'text'); 511 input2.setAttribute('type', 'text'); 512 513 input1.addEventListener('focusout', function () { 514 iframe1.contentDocument.body.appendChild(input2); 515 }); 516 517 content.appendChild(input1); 518 content.appendChild(input2); 519 content.appendChild(iframe1); 520 content.style.display = 'block' 521 522 iframe1.contentDocument.addEventListener("focus", _callback, true); 523 iframe1.contentDocument.addEventListener("focusin", _callback, true); 524 iframe1.contentDocument.addEventListener("focusout", _callback, true); 525 iframe1.contentDocument.addEventListener("blur", _callback, true); 526 527 let expectedEventOrder = [ 528 {'type' : 'blur', 529 'target' : input1, 530 'relatedTarget' : input2}, 531 {'type' : 'focusout', 532 'target' : input1, 533 'relatedTarget' : input2}, 534 ] 535 536 input1.focus(); 537 clearEventStack(); 538 input2.focus(); 539 540 for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) { 541 ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': ' 542 + 'Expected (' 543 + expectedEventOrder[i].type + ',' 544 + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ',' 545 + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), ' 546 + 'Actual (' 547 + eventStack[i].type + ',' 548 + (eventStack[i].target ? eventStack[i].target.id : null) + ',' 549 + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')'); 550 } 551 552 content.innerHTML = ''; 553 } 554 555 function TestBlurWindowAndRefocusInputOnlyFiresFocusInOnInput() { 556 557 var input1 = document.createElement('input'); 558 var content = document.getElementById('content'); 559 560 input1.setAttribute('id', 'input1'); 561 input1.setAttribute('type', 'text'); 562 563 content.appendChild(input1); 564 565 let expectedEventOrder = [ 566 {'type' : 'focus', 567 'target' : document, 568 'relatedTarget' : null}, 569 {'type' : 'focus', 570 'target' : window, 571 'relatedTarget' : null}, 572 {'type' : 'focus', 573 'target' : input1, 574 'relatedTarget' : null}, 575 {'type' : 'focusin', 576 'target' : input1, 577 'relatedTarget' : null}, 578 ] 579 580 window.blur(); 581 clearEventStack(); 582 input1.focus(); 583 584 for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) { 585 ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': ' 586 + 'Expected (' 587 + expectedEventOrder[i].type + ',' 588 + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ',' 589 + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), ' 590 + 'Actual (' 591 + eventStack[i].type + ',' 592 + (eventStack[i].target ? eventStack[i].target.id : null) + ',' 593 + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')'); 594 } 595 596 content.innerHTML = ''; 597 } 598 599 TestEventOrderNormal(); 600 TestEventOrderNormalFiresAtRightTime(); 601 TestFocusOutRedirectsFocus(); 602 TestFocusInRedirectsFocus(); 603 TestBlurRedirectsFocus(); 604 TestFocusRedirectsFocus(); 605 TestFocusOutMovesTarget(); 606 TestEventOrderDifferentDocument(); 607 TestBlurWindowAndRefocusInputOnlyFiresFocusInOnInput(); 608 609 </script> 610 </pre> 611 </body> 612 </html>