test_coalescence.html (27700B)
1 <html> 2 3 <head> 4 <title>Accessible mutation events coalescence testing</title> 5 6 <link rel="stylesheet" type="text/css" 7 href="chrome://mochikit/content/tests/SimpleTest/test.css" /> 8 9 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 10 <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> 11 12 <script type="application/javascript" 13 src="../common.js"></script> 14 <script type="application/javascript" 15 src="../states.js"></script> 16 <script type="application/javascript" 17 src="../events.js"></script> 18 19 <script type="application/javascript"> 20 21 // ////////////////////////////////////////////////////////////////////////// 22 // Invoker base classes 23 24 const kRemoveElm = 1; 25 const kHideElm = 2; 26 const kAddElm = 3; 27 const kShowElm = 4; 28 29 /** 30 * Base class to test of mutation events coalescence. 31 */ 32 function coalescenceBase(aChildAction, aParentAction, 33 aPerformActionOnChildInTheFirstPlace) { 34 // Invoker interface 35 36 this.invoke = function coalescenceBase_invoke() { 37 if (aPerformActionOnChildInTheFirstPlace) { 38 this.invokeAction(this.childNode, aChildAction); 39 this.invokeAction(this.parentNode, aParentAction); 40 } else { 41 this.invokeAction(this.parentNode, aParentAction); 42 this.invokeAction(this.childNode, aChildAction); 43 } 44 }; 45 46 this.getID = function coalescenceBase_getID() { 47 var childAction = this.getActionName(aChildAction) + " child"; 48 var parentAction = this.getActionName(aParentAction) + " parent"; 49 50 if (aPerformActionOnChildInTheFirstPlace) 51 return childAction + " and then " + parentAction; 52 53 return parentAction + " and then " + childAction; 54 }; 55 56 this.finalCheck = function coalescenceBase_check() { 57 if (this.getEventType(aChildAction) == EVENT_HIDE) { 58 testIsDefunct(this.child); 59 } 60 if (this.getEventType(aParentAction) == EVENT_HIDE) { 61 testIsDefunct(this.parent); 62 } 63 }; 64 65 // Implementation details 66 67 this.invokeAction = function coalescenceBase_invokeAction(aNode, aAction) { 68 switch (aAction) { 69 case kRemoveElm: 70 aNode.remove(); 71 break; 72 73 case kHideElm: 74 aNode.style.display = "none"; 75 break; 76 77 case kAddElm: 78 if (aNode == this.parentNode) 79 this.hostNode.appendChild(this.parentNode); 80 else 81 this.parentNode.appendChild(this.childNode); 82 break; 83 84 case kShowElm: 85 aNode.style.display = "block"; 86 break; 87 88 default: 89 return INVOKER_ACTION_FAILED; 90 } 91 // 0 means the action succeeded. 92 return 0; 93 }; 94 95 this.getEventType = function coalescenceBase_getEventType(aAction) { 96 switch (aAction) { 97 case kRemoveElm: case kHideElm: 98 return EVENT_HIDE; 99 case kAddElm: case kShowElm: 100 return EVENT_SHOW; 101 } 102 return 0; 103 }; 104 105 this.getActionName = function coalescenceBase_getActionName(aAction) { 106 switch (aAction) { 107 case kRemoveElm: 108 return "remove"; 109 case kHideElm: 110 return "hide"; 111 case kAddElm: 112 return "add"; 113 case kShowElm: 114 return "show"; 115 default: 116 return "??"; 117 } 118 }; 119 120 this.initSequence = function coalescenceBase_initSequence() { 121 // expected events 122 var eventType = this.getEventType(aParentAction); 123 this.eventSeq = [ 124 new invokerChecker(eventType, this.parentNode), 125 new invokerChecker(EVENT_REORDER, this.hostNode), 126 ]; 127 128 // unexpected events 129 this.unexpectedEventSeq = [ 130 new invokerChecker(this.getEventType(aChildAction), this.childNode), 131 new invokerChecker(EVENT_REORDER, this.parentNode), 132 ]; 133 }; 134 } 135 136 /** 137 * Remove or hide mutation events coalescence testing. 138 */ 139 function removeOrHideCoalescenceBase(aChildID, aParentID, 140 aChildAction, aParentAction, 141 aPerformActionOnChildInTheFirstPlace) { 142 this.__proto__ = new coalescenceBase(aChildAction, aParentAction, 143 aPerformActionOnChildInTheFirstPlace); 144 145 this.init = function removeOrHideCoalescenceBase_init() { 146 this.childNode = getNode(aChildID); 147 this.parentNode = getNode(aParentID); 148 this.child = getAccessible(this.childNode); 149 this.parent = getAccessible(this.parentNode); 150 this.hostNode = this.parentNode.parentNode; 151 }; 152 153 // Initalization 154 155 this.init(); 156 this.initSequence(); 157 } 158 159 // ////////////////////////////////////////////////////////////////////////// 160 // Invokers 161 162 /** 163 * Remove child node and then its parent node from DOM tree. 164 */ 165 function removeChildNParent(aChildID, aParentID) { 166 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID, 167 kRemoveElm, kRemoveElm, 168 true); 169 } 170 171 /** 172 * Remove parent node and then its child node from DOM tree. 173 */ 174 function removeParentNChild(aChildID, aParentID) { 175 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID, 176 kRemoveElm, kRemoveElm, 177 false); 178 } 179 180 /** 181 * Hide child node and then its parent node. 182 */ 183 function hideChildNParent(aChildID, aParentID) { 184 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID, 185 kHideElm, kHideElm, 186 true); 187 } 188 189 /** 190 * Hide parent node and then its child node. 191 */ 192 function hideParentNChild(aChildID, aParentID) { 193 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID, 194 kHideElm, kHideElm, 195 false); 196 } 197 198 /** 199 * Hide child node and then remove its parent node. 200 */ 201 function hideChildNRemoveParent(aChildID, aParentID) { 202 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID, 203 kHideElm, kRemoveElm, 204 true); 205 } 206 207 /** 208 * Hide parent node and then remove its child node. 209 */ 210 function hideParentNRemoveChild(aChildID, aParentID) { 211 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID, 212 kRemoveElm, kHideElm, 213 false); 214 } 215 216 /** 217 * Remove child node and then hide its parent node. 218 */ 219 function removeChildNHideParent(aChildID, aParentID) { 220 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID, 221 kRemoveElm, kHideElm, 222 true); 223 } 224 225 /** 226 * Remove parent node and then hide its child node. 227 */ 228 function removeParentNHideChild(aChildID, aParentID) { 229 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID, 230 kHideElm, kRemoveElm, 231 false); 232 } 233 234 /** 235 * Create and append parent node and create and append child node to it. 236 */ 237 function addParentNChild(aHostID, aPerformActionOnChildInTheFirstPlace) { 238 this.init = function addParentNChild_init() { 239 this.hostNode = getNode(aHostID); 240 this.parentNode = document.createElement("select"); 241 this.childNode = document.createElement("option"); 242 this.childNode.textContent = "testing"; 243 }; 244 245 this.__proto__ = new coalescenceBase(kAddElm, kAddElm, 246 aPerformActionOnChildInTheFirstPlace); 247 248 this.init(); 249 this.initSequence(); 250 } 251 252 /** 253 * Show parent node and show child node to it. 254 */ 255 function showParentNChild(aParentID, aChildID, 256 aPerformActionOnChildInTheFirstPlace) { 257 this.init = function showParentNChild_init() { 258 this.parentNode = getNode(aParentID); 259 this.hostNode = this.parentNode.parentNode; 260 this.childNode = getNode(aChildID); 261 }; 262 263 this.__proto__ = new coalescenceBase(kShowElm, kShowElm, 264 aPerformActionOnChildInTheFirstPlace); 265 266 this.init(); 267 this.initSequence(); 268 } 269 270 /** 271 * Create and append child node to the DOM and then show parent node. 272 */ 273 function showParentNAddChild(aParentID, 274 aPerformActionOnChildInTheFirstPlace) { 275 this.init = function showParentNAddChild_init() { 276 this.parentNode = getNode(aParentID); 277 this.hostNode = this.parentNode.parentNode; 278 this.childNode = document.createElement("option"); 279 this.childNode.textContent = "testing"; 280 }; 281 282 this.__proto__ = new coalescenceBase(kAddElm, kShowElm, 283 aPerformActionOnChildInTheFirstPlace); 284 285 this.init(); 286 this.initSequence(); 287 } 288 289 /** 290 * Remove children and parent 291 */ 292 function removeGrandChildrenNHideParent(aChild1Id, aChild2Id, aParentId) { 293 this.child1 = getNode(aChild1Id); 294 this.child2 = getNode(aChild2Id); 295 this.parent = getNode(aParentId); 296 297 this.eventSeq = [ 298 new invokerChecker(EVENT_HIDE, getAccessible(aParentId)), 299 new invokerChecker(EVENT_REORDER, getNode(aParentId).parentNode), 300 new unexpectedInvokerChecker(EVENT_HIDE, getAccessible(aChild1Id)), 301 new unexpectedInvokerChecker(EVENT_HIDE, getAccessible(aChild2Id)), 302 new unexpectedInvokerChecker(EVENT_REORDER, getAccessible(aParentId)), 303 ]; 304 305 this.invoke = function removeGrandChildrenNHideParent_invoke() { 306 this.child1.remove(); 307 this.child2.remove(); 308 this.parent.hidden = true; 309 }; 310 311 this.getID = function removeGrandChildrenNHideParent_getID() { 312 return "remove grand children of different parents and then hide their grand parent"; 313 }; 314 } 315 316 /** 317 * Remove a child, and then its parent. 318 */ 319 function test3() { 320 this.o = getAccessible("t3_o"); 321 this.ofc = getAccessible("t3_o").firstChild; 322 323 this.eventSeq = [ 324 new invokerChecker(EVENT_HIDE, this.o), 325 new invokerChecker(EVENT_REORDER, "t3_lb"), 326 new unexpectedInvokerChecker(EVENT_HIDE, this.ofc), 327 new unexpectedInvokerChecker(EVENT_REORDER, this.o), 328 ]; 329 330 this.invoke = function test3_invoke() { 331 getNode("t3_o").textContent = ""; 332 getNode("t3_lb").removeChild(getNode("t3_o")); 333 }; 334 335 this.finalCheck = function test3_finalCheck() { 336 testIsDefunct(this.o); 337 testIsDefunct(this.ofc); 338 }; 339 340 this.getID = function test3_getID() { 341 return "remove a child, and then its parent"; 342 }; 343 } 344 345 /** 346 * Remove children, and then a parent of 2nd child. 347 */ 348 function test4() { 349 this.o1 = getAccessible("t4_o1"); 350 this.o1fc = this.o1.firstChild; 351 this.o2 = getAccessible("t4_o2"); 352 this.o2fc = this.o2.firstChild; 353 354 this.eventSeq = [ 355 new invokerChecker(EVENT_HIDE, this.o1fc), 356 new invokerChecker(EVENT_HIDE, this.o2), 357 new invokerChecker(EVENT_REORDER, "t4_lb"), 358 new unexpectedInvokerChecker(EVENT_HIDE, this.o2fc), 359 new unexpectedInvokerChecker(EVENT_REORDER, this.o1), 360 new unexpectedInvokerChecker(EVENT_REORDER, this.o2), 361 ]; 362 363 this.invoke = function test4_invoke() { 364 getNode("t4_o1").textContent = ""; 365 getNode("t4_o2").textContent = ""; 366 getNode("t4_lb").removeChild(getNode("t4_o2")); 367 }; 368 369 this.finalCheck = function test4_finalCheck() { 370 testIsDefunct(this.o1fc); 371 testIsDefunct(this.o2); 372 testIsDefunct(this.o2fc); 373 }; 374 375 this.getID = function test4_getID() { 376 return "remove children, and then a parent of 2nd child"; 377 }; 378 } 379 380 /** 381 * Remove a child, remove a parent sibling, remove the parent 382 */ 383 function test5() { 384 this.o = getAccessible("t5_o"); 385 this.ofc = this.o.firstChild; 386 this.b = getAccessible("t5_b"); 387 this.lb = getAccessible("t5_lb"); 388 389 this.eventSeq = [ 390 new invokerChecker(EVENT_HIDE, this.b), 391 new invokerChecker(EVENT_HIDE, this.o), 392 new invokerChecker(EVENT_REORDER, "t5"), 393 new unexpectedInvokerChecker(EVENT_HIDE, this.ofc), 394 new unexpectedInvokerChecker(EVENT_REORDER, this.o), 395 new unexpectedInvokerChecker(EVENT_REORDER, this.lb), 396 ]; 397 398 this.invoke = function test5_invoke() { 399 getNode("t5_o").textContent = ""; 400 getNode("t5").removeChild(getNode("t5_b")); 401 getNode("t5_lb").removeChild(getNode("t5_o")); 402 }; 403 404 this.finalCheck = function test5_finalCheck() { 405 testIsDefunct(this.ofc); 406 testIsDefunct(this.o); 407 testIsDefunct(this.b); 408 }; 409 410 this.getID = function test5_getID() { 411 return "remove a child, remove a parent sibling, remove the parent"; 412 }; 413 } 414 415 /** 416 * Insert accessibles with a child node moved by aria-owns 417 * Markup: 418 * <div id="t6_fc"> 419 * <div id="t6_owns"></div> 420 * </div> 421 * <div id="t6_sc" aria-owns="t6_owns"></div> 422 */ 423 function test6() { 424 this.parent = getNode("t6"); 425 this.fc = document.createElement("div"); 426 this.fc.setAttribute("id", "t6_fc"); 427 this.owns = document.createElement("div"); 428 this.owns.setAttribute("id", "t6_owns"); 429 this.sc = document.createElement("div"); 430 this.sc.setAttribute("id", "t6_sc"); 431 432 this.eventSeq = [ 433 new invokerChecker(EVENT_SHOW, this.fc), 434 new invokerChecker(EVENT_SHOW, this.sc), 435 new invokerChecker(EVENT_REORDER, this.parent), 436 new unexpectedInvokerChecker(EVENT_REORDER, this.fc), 437 new unexpectedInvokerChecker(EVENT_REORDER, this.sc), 438 new unexpectedInvokerChecker(EVENT_HIDE, this.owns), 439 new unexpectedInvokerChecker(EVENT_SHOW, this.owns), 440 ]; 441 442 this.invoke = function test6_invoke() { 443 getNode("t6").appendChild(this.fc); 444 getNode("t6_fc").appendChild(this.owns); 445 getNode("t6").appendChild(this.sc); 446 getNode("t6_sc").setAttribute("aria-owns", "t6_owns"); 447 }; 448 449 this.getID = function test6_getID() { 450 return "Insert accessibles with a child node moved by aria-owns"; 451 }; 452 } 453 454 /** 455 * Insert text nodes under direct and grand children, and then hide 456 * their container by means of aria-owns. 457 * 458 * Markup: 459 * <div id="t7_moveplace" aria-owns="t7_c"></div> 460 * <div id="t7_c"> 461 * <div id="t7_c_directchild">ha</div> 462 * <div><div id="t7_c_grandchild">ha</div></div> 463 * </div> 464 */ 465 function test7() { 466 this.eventSeq = [ 467 new invokerChecker(EVENT_HIDE, getNode("t7_c")), 468 new invokerChecker(EVENT_SHOW, getNode("t7_c")), 469 new invokerChecker(EVENT_REORDER, getNode("t7")), 470 new unexpectedInvokerChecker(EVENT_REORDER, getNode("t7_c_directchild")), 471 new unexpectedInvokerChecker(EVENT_REORDER, getNode("t7_c_grandchild")), 472 new unexpectedInvokerChecker(EVENT_SHOW, () => getNode("t7_c_directchild").firstChild), 473 new unexpectedInvokerChecker(EVENT_SHOW, () => getNode("t7_c_grandchild").firstChild), 474 ]; 475 476 this.invoke = function test7_invoke() { 477 getNode("t7_c_directchild").textContent = "ha"; 478 getNode("t7_c_grandchild").textContent = "ha"; 479 getNode("t7_moveplace").setAttribute("aria-owns", "t7_c"); 480 }; 481 482 this.getID = function test7_getID() { 483 return "Show child accessibles and then hide their container"; 484 }; 485 } 486 487 /** 488 * Move a node by aria-owns from right to left in the tree, so that 489 * the eventing looks this way: 490 * reorder for 't8_c1' 491 * hide for 't8_c1_child' 492 * show for 't8_c2_moved' 493 * reorder for 't8_c2' 494 * hide for 't8_c2_moved' 495 * 496 * The hide event should be delivered before the paired show event. 497 */ 498 function test8() { 499 this.eventSeq = [ 500 new invokerChecker(EVENT_HIDE, getNode("t8_c1_child")), 501 new invokerChecker(EVENT_HIDE, "t8_c2_moved"), 502 new invokerChecker(EVENT_SHOW, "t8_c2_moved"), 503 new invokerChecker(EVENT_REORDER, "t8_c2"), 504 new invokerChecker(EVENT_REORDER, "t8_c1"), 505 ]; 506 507 this.invoke = function test8_invoke() { 508 // Remove a node from 't8_c1' container to give the event tree a 509 // desired structure (the 't8_c1' container node goes first in the event 510 // tree) 511 getNode("t8_c1_child").remove(); 512 // then move 't8_c2_moved' from 't8_c2' to 't8_c1'. 513 getNode("t8_c1").setAttribute("aria-owns", "t8_c2_moved"); 514 }; 515 516 this.getID = function test8_getID() { 517 return "Move a node by aria-owns to left within the tree"; 518 }; 519 } 520 521 /** 522 * Move 't9_c3_moved' node under 't9_c2_moved', and then move 't9_c2_moved' 523 * node by aria-owns (same as test10 but has different aria-owns 524 * ordering), the eventing looks same way as in test10: 525 * reorder for 't9_c1' 526 * hide for 't9_c1_child' 527 * show for 't9_c2_moved' 528 * reorder for 't9_c2' 529 * hide for 't9_c2_child' 530 * hide for 't9_c2_moved' 531 * reorder for 't9_c3' 532 * hide for 't9_c3_moved' 533 * 534 * The hide events for 't9_c2_moved' and 't9_c3_moved' should be delivered 535 * before the show event for 't9_c2_moved'. 536 */ 537 function test9() { 538 this.eventSeq = [ 539 new invokerChecker(EVENT_HIDE, getNode("t9_c1_child")), 540 new invokerChecker(EVENT_HIDE, getNode("t9_c2_child")), 541 new invokerChecker(EVENT_HIDE, "t9_c3_moved"), 542 new invokerChecker(EVENT_HIDE, "t9_c2_moved"), 543 new invokerChecker(EVENT_SHOW, "t9_c2_moved"), 544 new invokerChecker(EVENT_REORDER, "t9_c3"), 545 new invokerChecker(EVENT_REORDER, "t9_c2"), 546 new invokerChecker(EVENT_REORDER, "t9_c1"), 547 new unexpectedInvokerChecker(EVENT_SHOW, "t9_c3_moved"), 548 ]; 549 550 this.invoke = function test9_invoke() { 551 // Remove child nodes from 't9_c1' and 't9_c2' containers to give 552 // the event tree a needed structure ('t9_c1' and 't9_c2' nodes go 553 // first in the event tree), 554 getNode("t9_c1_child").remove(); 555 getNode("t9_c2_child").remove(); 556 // then do aria-owns magic. 557 getNode("t9_c2_moved").setAttribute("aria-owns", "t9_c3_moved"); 558 getNode("t9_c1").setAttribute("aria-owns", "t9_c2_moved"); 559 }; 560 561 this.getID = function test9_getID() { 562 return "Move node #1 by aria-owns and then move node #2 into node #1"; 563 }; 564 } 565 566 /** 567 * Move a node 't10_c3_moved' by aria-owns under a node 't10_c2_moved', 568 * moved by under 't10_1', so that the eventing looks this way: 569 * reorder for 't10_c1' 570 * hide for 't10_c1_child' 571 * show for 't10_c2_moved' 572 * reorder for 't10_c2' 573 * hide for 't10_c2_child' 574 * hide for 't10_c2_moved' 575 * reorder for 't10_c3' 576 * hide for 't10_c3_moved' 577 * 578 * The hide events for 't10_c2_moved' and 't10_c3_moved' should be delivered 579 * before the show event for 't10_c2_moved'. 580 */ 581 function test10() { 582 this.eventSeq = [ 583 new invokerChecker(EVENT_HIDE, getNode("t10_c1_child")), 584 new invokerChecker(EVENT_HIDE, getNode("t10_c2_child")), 585 new invokerChecker(EVENT_HIDE, getNode("t10_c2_moved")), 586 new invokerChecker(EVENT_HIDE, getNode("t10_c3_moved")), 587 new invokerChecker(EVENT_SHOW, getNode("t10_c2_moved")), 588 new invokerChecker(EVENT_REORDER, "t10_c2"), 589 new invokerChecker(EVENT_REORDER, "t10_c1"), 590 new invokerChecker(EVENT_REORDER, "t10_c3"), 591 ]; 592 593 this.invoke = function test10_invoke() { 594 // Remove child nodes from 't10_c1' and 't10_c2' containers to give 595 // the event tree a needed structure ('t10_c1' and 't10_c2' nodes go first 596 // in the event tree), 597 getNode("t10_c1_child").remove(); 598 getNode("t10_c2_child").remove(); 599 // then do aria-owns stuff. 600 getNode("t10_c1").setAttribute("aria-owns", "t10_c2_moved"); 601 getNode("t10_c2_moved").setAttribute("aria-owns", "t10_c3_moved"); 602 }; 603 604 this.getID = function test10_getID() { 605 return "Move a node by aria-owns into a node moved by aria-owns to left within the tree"; 606 }; 607 } 608 609 /** 610 * Move a node by aria-owns from right to left in the tree, and then 611 * move its parent too by aria-owns. No hide event should be fired for 612 * original node. 613 */ 614 function test11() { 615 this.eventSeq = [ 616 new invokerChecker(EVENT_HIDE, getNode("t11_c1_child")), 617 new invokerChecker(EVENT_HIDE, getNode("t11_c2")), 618 new orderChecker(), 619 new asyncInvokerChecker(EVENT_SHOW, "t11_c2_child"), 620 new asyncInvokerChecker(EVENT_SHOW, "t11_c2"), 621 new orderChecker(), 622 new invokerChecker(EVENT_REORDER, "t11"), 623 new unexpectedInvokerChecker(EVENT_HIDE, "t11_c2_child"), 624 new unexpectedInvokerChecker(EVENT_REORDER, "t11_c1"), 625 new unexpectedInvokerChecker(EVENT_REORDER, "t11_c2"), 626 new unexpectedInvokerChecker(EVENT_REORDER, "t11_c3"), 627 ]; 628 629 this.invoke = function test11_invoke() { 630 // Remove a node from 't11_c1' container to give the event tree a 631 // desired structure (the 't11_c1' container node goes first in 632 // the event tree), 633 getNode("t11_c1_child").remove(); 634 // then move 't11_c2_moved' from 't11_c2' to 't11_c1', and then move 635 // 't11_c2' to 't11_c3'. 636 getNode("t11_c1").setAttribute("aria-owns", "t11_c2_child"); 637 getNode("t11_c3").setAttribute("aria-owns", "t11_c2"); 638 }; 639 640 this.getID = function test11_getID() { 641 return "Move a node by aria-owns to left within the tree"; 642 }; 643 } 644 645 // ////////////////////////////////////////////////////////////////////////// 646 // Do tests. 647 648 gA11yEventDumpToConsole = true; // debug stuff 649 // enableLogging("eventTree"); 650 651 var gQueue = null; 652 function doTests() { 653 gQueue = new eventQueue(); 654 655 gQueue.push(new removeChildNParent("option1", "select1")); 656 gQueue.push(new removeParentNChild("option2", "select2")); 657 gQueue.push(new hideChildNParent("option3", "select3")); 658 gQueue.push(new hideParentNChild("option4", "select4")); 659 gQueue.push(new hideChildNRemoveParent("option5", "select5")); 660 gQueue.push(new hideParentNRemoveChild("option6", "select6")); 661 gQueue.push(new removeChildNHideParent("option7", "select7")); 662 gQueue.push(new removeParentNHideChild("option8", "select8")); 663 664 gQueue.push(new addParentNChild("testContainer", false)); 665 gQueue.push(new addParentNChild("testContainer", true)); 666 gQueue.push(new showParentNChild("select9", "option9", false)); 667 gQueue.push(new showParentNChild("select10", "option10", true)); 668 gQueue.push(new showParentNAddChild("select11", false)); 669 gQueue.push(new showParentNAddChild("select12", true)); 670 671 gQueue.push(new removeGrandChildrenNHideParent("t1_child1", "t1_child2", "t1_parent")); 672 gQueue.push(new test3()); 673 gQueue.push(new test4()); 674 gQueue.push(new test5()); 675 gQueue.push(new test6()); 676 gQueue.push(new test7()); 677 gQueue.push(new test8()); 678 gQueue.push(new test9()); 679 gQueue.push(new test10()); 680 gQueue.push(new test11()); 681 682 gQueue.invoke(); // Will call SimpleTest.finish(); 683 } 684 685 SimpleTest.waitForExplicitFinish(); 686 addA11yLoadEvent(doTests); 687 </script> 688 </head> 689 690 <body> 691 692 <a target="_blank" 693 href="https://bugzilla.mozilla.org/show_bug.cgi?id=513213" 694 title="coalesce events when new event is appended to the queue"> 695 Mozilla Bug 513213 696 </a><br> 697 <a target="_blank" 698 title="Rework accessible tree update code" 699 href="https://bugzilla.mozilla.org/show_bug.cgi?id=570275"> 700 Mozilla Bug 570275 701 </a> 702 703 <p id="display"></p> 704 <div id="content" style="display: none"></div> 705 <pre id="test"> 706 </pre> 707 708 <div id="testContainer"> 709 <select id="select1"> 710 <option id="option1">option</option> 711 </select> 712 <select id="select2"> 713 <option id="option2">option</option> 714 </select> 715 <select id="select3"> 716 <option id="option3">option</option> 717 </select> 718 <select id="select4"> 719 <option id="option4">option</option> 720 </select> 721 <select id="select5"> 722 <option id="option5">option</option> 723 </select> 724 <select id="select6"> 725 <option id="option6">option</option> 726 </select> 727 <select id="select7"> 728 <option id="option7">option</option> 729 </select> 730 <select id="select8"> 731 <option id="option8">option</option> 732 </select> 733 734 <select id="select9" style="display: none"> 735 <option id="option9" style="display: none">testing</option> 736 </select> 737 <select id="select10" style="display: none"> 738 <option id="option10" style="display: none">testing</option> 739 </select> 740 <select id="select11" style="display: none"></select> 741 <select id="select12" style="display: none"></select> 742 </div> 743 744 <div id="testContainer2"> 745 <div id="t1_parent"> 746 <div id="t1_mid1"><div id="t1_child1"></div></div> 747 <div id="t1_mid2"><div id="t1_child2"></div></div> 748 </div> 749 </div> 750 751 <div id="t3"> 752 <div role="listbox" id="t3_lb"> 753 <div role="option" id="t3_o">opt</div> 754 </div> 755 </div> 756 757 <div id="t4"> 758 <div role="listbox" id="t4_lb"> 759 <div role="option" id="t4_o1">opt1</div> 760 <div role="option" id="t4_o2">opt2</div> 761 </div> 762 </div> 763 764 <div id="t5"> 765 <div role="button" id="t5_b">btn</div> 766 <div role="listbox" id="t5_lb"> 767 <div role="option" id="t5_o">opt</div> 768 </div> 769 </div> 770 771 <div id="t6"> 772 </div> 773 774 <div id="t7"> 775 <div id="t7_moveplace"></div> 776 <div id="t7_c"> 777 <div><div id="t7_c_grandchild"></div></div> 778 <div id="t7_c_directchild"></div> 779 </div> 780 </div> 781 782 <div id="t8"> 783 <div id="t8_c1"><div id="t8_c1_child"></div></div> 784 <div id="t8_c2"> 785 <div id="t8_c2_moved"></div> 786 </div> 787 </div> 788 789 <div id="t9"> 790 <div id="t9_c1"><div id="t9_c1_child"></div></div> 791 <div id="t9_c2"> 792 <div id="t9_c2_child"></div> 793 <div id="t9_c2_moved"></div> 794 </div> 795 <div id="t9_c3"> 796 <div id="t9_c3_moved"></div> 797 </div> 798 </div> 799 800 <div id="t10"> 801 <div id="t10_c1"><div id="t10_c1_child"></div></div> 802 <div id="t10_c2"> 803 <div id="t10_c2_child"></div> 804 <div id="t10_c2_moved"></div> 805 </div> 806 <div id="t10_c3"> 807 <div id="t10_c3_moved"></div> 808 </div> 809 </div> 810 811 <div id="t11"> 812 <div id="t11_c1"><div id="t11_c1_child"></div></div> 813 <div id="t11_c2"><div id="t11_c2_child"></div></div> 814 <div id="t11_c3"></div> 815 </div> 816 </body> 817 </html>