accessible/tests/mochitest/events/test_coalescence.html

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

michael@0 1 <html>
michael@0 2
michael@0 3 <head>
michael@0 4 <title>Accessible mutation events coalescence testing</title>
michael@0 5
michael@0 6 <link rel="stylesheet" type="text/css"
michael@0 7 href="chrome://mochikit/content/tests/SimpleTest/test.css" />
michael@0 8
michael@0 9 <script type="application/javascript"
michael@0 10 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
michael@0 11 <script type="application/javascript"
michael@0 12 src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
michael@0 13
michael@0 14 <script type="application/javascript"
michael@0 15 src="../common.js"></script>
michael@0 16 <script type="application/javascript"
michael@0 17 src="../events.js"></script>
michael@0 18
michael@0 19 <script type="application/javascript">
michael@0 20
michael@0 21 ////////////////////////////////////////////////////////////////////////////
michael@0 22 // Invoker base classes
michael@0 23
michael@0 24 const kRemoveElm = 1;
michael@0 25 const kHideElm = 2;
michael@0 26 const kAddElm = 3;
michael@0 27 const kShowElm = 4;
michael@0 28
michael@0 29 const kToDo = true;
michael@0 30
michael@0 31 /**
michael@0 32 * Base class to test of mutation events coalescence.
michael@0 33 */
michael@0 34 function coalescenceBase(aChildAction, aParentAction,
michael@0 35 aPerformActionOnChildInTheFirstPlace,
michael@0 36 aIsChildsToDo)
michael@0 37 {
michael@0 38 // Invoker interface
michael@0 39
michael@0 40 this.invoke = function coalescenceBase_invoke()
michael@0 41 {
michael@0 42 if (aPerformActionOnChildInTheFirstPlace) {
michael@0 43 this.invokeAction(this.childNode, aChildAction);
michael@0 44 this.invokeAction(this.parentNode, aParentAction);
michael@0 45 } else {
michael@0 46 this.invokeAction(this.parentNode, aParentAction);
michael@0 47 this.invokeAction(this.childNode, aChildAction);
michael@0 48 }
michael@0 49 }
michael@0 50
michael@0 51 this.getID = function coalescenceBase_getID()
michael@0 52 {
michael@0 53 var childAction = this.getActionName(aChildAction) + " child";
michael@0 54 var parentAction = this.getActionName(aParentAction) + " parent";
michael@0 55
michael@0 56 if (aPerformActionOnChildInTheFirstPlace)
michael@0 57 return childAction + " and then " + parentAction;
michael@0 58
michael@0 59 return parentAction + " and then " + childAction;
michael@0 60 }
michael@0 61
michael@0 62 this.finalCheck = function coalescenceBase_check()
michael@0 63 {
michael@0 64 if (!aIsChildsToDo)
michael@0 65 return;
michael@0 66
michael@0 67 var eventType = eventTypeToString(this.getEventType(aChildAction));
michael@0 68 todo(false,
michael@0 69 "Unexpected event " + eventType +
michael@0 70 " for child in the test '" + this.getID() + "'");
michael@0 71 }
michael@0 72
michael@0 73 // Implementation details
michael@0 74
michael@0 75 this.invokeAction = function coalescenceBase_invokeAction(aNode, aAction)
michael@0 76 {
michael@0 77 switch (aAction) {
michael@0 78 case kRemoveElm:
michael@0 79 aNode.parentNode.removeChild(aNode);
michael@0 80 break;
michael@0 81
michael@0 82 case kHideElm:
michael@0 83 aNode.style.display = "none";
michael@0 84 break;
michael@0 85
michael@0 86 case kAddElm:
michael@0 87 if (aNode == this.parentNode)
michael@0 88 this.hostNode.appendChild(this.parentNode);
michael@0 89 else
michael@0 90 this.parentNode.appendChild(this.childNode);
michael@0 91 break;
michael@0 92
michael@0 93 case kShowElm:
michael@0 94 aNode.style.display = "block";
michael@0 95 break;
michael@0 96
michael@0 97 default:
michael@0 98 return INVOKER_ACTION_FAILED;
michael@0 99 }
michael@0 100 }
michael@0 101
michael@0 102 this.getEventType = function coalescenceBase_getEventType(aAction)
michael@0 103 {
michael@0 104 switch (aAction) {
michael@0 105 case kRemoveElm: case kHideElm:
michael@0 106 return EVENT_HIDE;
michael@0 107 case kAddElm: case kShowElm:
michael@0 108 return EVENT_SHOW;
michael@0 109 }
michael@0 110 }
michael@0 111
michael@0 112 this.getActionName = function coalescenceBase_getActionName(aAction)
michael@0 113 {
michael@0 114 switch (aAction) {
michael@0 115 case kRemoveElm:
michael@0 116 return "remove";
michael@0 117 case kHideElm:
michael@0 118 return "hide";
michael@0 119 case kAddElm:
michael@0 120 return "add";
michael@0 121 case kShowElm:
michael@0 122 return "show";
michael@0 123 default:
michael@0 124 return "??";
michael@0 125 }
michael@0 126 }
michael@0 127
michael@0 128 this.initSequence = function coalescenceBase_initSequence()
michael@0 129 {
michael@0 130 // expected events
michael@0 131 var eventType = this.getEventType(aParentAction);
michael@0 132 this.eventSeq = [
michael@0 133 new invokerChecker(eventType, this.parentNode),
michael@0 134 new invokerChecker(EVENT_REORDER, this.hostNode)
michael@0 135 ];
michael@0 136
michael@0 137 // unexpected events
michael@0 138 this.unexpectedEventSeq = [
michael@0 139 new invokerChecker(EVENT_REORDER, this.parentNode)
michael@0 140 ];
michael@0 141
michael@0 142 if (!aIsChildsToDo) {
michael@0 143 var eventType = this.getEventType(aChildAction);
michael@0 144 var checker = new invokerChecker(eventType, this.childNode);
michael@0 145 this.unexpectedEventSeq.unshift(checker);
michael@0 146 }
michael@0 147 }
michael@0 148 }
michael@0 149
michael@0 150 /**
michael@0 151 * Remove or hide mutation events coalescence testing.
michael@0 152 */
michael@0 153 function removeOrHideCoalescenceBase(aChildID, aParentID,
michael@0 154 aChildAction, aParentAction,
michael@0 155 aPerformActionOnChildInTheFirstPlace,
michael@0 156 aIsChildsToDo)
michael@0 157 {
michael@0 158 this.__proto__ = new coalescenceBase(aChildAction, aParentAction,
michael@0 159 aPerformActionOnChildInTheFirstPlace,
michael@0 160 aIsChildsToDo);
michael@0 161
michael@0 162 this.init = function removeOrHideCoalescenceBase_init()
michael@0 163 {
michael@0 164 this.childNode = getNode(aChildID);
michael@0 165 this.parentNode = getNode(aParentID);
michael@0 166 this.hostNode = this.parentNode.parentNode;
michael@0 167
michael@0 168 // ensure child accessible is created
michael@0 169 getAccessible(this.childNode);
michael@0 170 }
michael@0 171
michael@0 172 // Initalization
michael@0 173
michael@0 174 this.init();
michael@0 175 this.initSequence();
michael@0 176 }
michael@0 177
michael@0 178 ////////////////////////////////////////////////////////////////////////////
michael@0 179 // Invokers
michael@0 180
michael@0 181 /**
michael@0 182 * Remove child node and then its parent node from DOM tree.
michael@0 183 */
michael@0 184 function removeChildNParent(aChildID, aParentID)
michael@0 185 {
michael@0 186 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
michael@0 187 kRemoveElm, kRemoveElm,
michael@0 188 true, kToDo);
michael@0 189 }
michael@0 190
michael@0 191 /**
michael@0 192 * Remove parent node and then its child node from DOM tree.
michael@0 193 */
michael@0 194 function removeParentNChild(aChildID, aParentID)
michael@0 195 {
michael@0 196 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
michael@0 197 kRemoveElm, kRemoveElm,
michael@0 198 false);
michael@0 199 }
michael@0 200
michael@0 201 /**
michael@0 202 * Hide child node and then its parent node.
michael@0 203 */
michael@0 204 function hideChildNParent(aChildID, aParentID)
michael@0 205 {
michael@0 206 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
michael@0 207 kHideElm, kHideElm,
michael@0 208 true);
michael@0 209 }
michael@0 210
michael@0 211 /**
michael@0 212 * Hide parent node and then its child node.
michael@0 213 */
michael@0 214 function hideParentNChild(aChildID, aParentID)
michael@0 215 {
michael@0 216 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
michael@0 217 kHideElm, kHideElm,
michael@0 218 false);
michael@0 219 }
michael@0 220
michael@0 221 /**
michael@0 222 * Hide child node and then remove its parent node.
michael@0 223 */
michael@0 224 function hideChildNRemoveParent(aChildID, aParentID)
michael@0 225 {
michael@0 226 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
michael@0 227 kHideElm, kRemoveElm,
michael@0 228 true);
michael@0 229 }
michael@0 230
michael@0 231 /**
michael@0 232 * Hide parent node and then remove its child node.
michael@0 233 */
michael@0 234 function hideParentNRemoveChild(aChildID, aParentID)
michael@0 235 {
michael@0 236 // Because of async layout changes we handle remove child node change
michael@0 237 // before than hide parent node change even we hide parent before we
michael@0 238 // remove a child. Therefore mark this as todo until we have more smart
michael@0 239 // events coalescence.
michael@0 240 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
michael@0 241 kRemoveElm, kHideElm,
michael@0 242 false, kToDo);
michael@0 243 }
michael@0 244
michael@0 245 /**
michael@0 246 * Remove child node and then hide its parent node.
michael@0 247 */
michael@0 248 function removeChildNHideParent(aChildID, aParentID)
michael@0 249 {
michael@0 250 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
michael@0 251 kRemoveElm, kHideElm,
michael@0 252 true, kToDo);
michael@0 253 }
michael@0 254
michael@0 255 /**
michael@0 256 * Remove parent node and then hide its child node.
michael@0 257 */
michael@0 258 function removeParentNHideChild(aChildID, aParentID)
michael@0 259 {
michael@0 260 this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
michael@0 261 kHideElm, kRemoveElm,
michael@0 262 false);
michael@0 263 }
michael@0 264
michael@0 265 /**
michael@0 266 * Create and append parent node and create and append child node to it.
michael@0 267 */
michael@0 268 function addParentNChild(aHostID, aPerformActionOnChildInTheFirstPlace)
michael@0 269 {
michael@0 270 this.init = function addParentNChild_init()
michael@0 271 {
michael@0 272 this.hostNode = getNode(aHostID);
michael@0 273 this.parentNode = document.createElement("select");
michael@0 274 this.childNode = document.createElement("option");
michael@0 275 this.childNode.textContent = "testing";
michael@0 276 }
michael@0 277
michael@0 278 this.__proto__ = new coalescenceBase(kAddElm, kAddElm,
michael@0 279 aPerformActionOnChildInTheFirstPlace);
michael@0 280
michael@0 281 this.init();
michael@0 282 this.initSequence();
michael@0 283 }
michael@0 284
michael@0 285 /**
michael@0 286 * Show parent node and show child node to it.
michael@0 287 */
michael@0 288 function showParentNChild(aParentID, aChildID,
michael@0 289 aPerformActionOnChildInTheFirstPlace)
michael@0 290 {
michael@0 291 this.init = function showParentNChild_init()
michael@0 292 {
michael@0 293 this.parentNode = getNode(aParentID);
michael@0 294 this.hostNode = this.parentNode.parentNode;
michael@0 295 this.childNode = getNode(aChildID);
michael@0 296 }
michael@0 297
michael@0 298 this.__proto__ = new coalescenceBase(kShowElm, kShowElm,
michael@0 299 aPerformActionOnChildInTheFirstPlace);
michael@0 300
michael@0 301 this.init();
michael@0 302 this.initSequence();
michael@0 303 }
michael@0 304
michael@0 305 /**
michael@0 306 * Create and append child node to the DOM and then show parent node.
michael@0 307 */
michael@0 308 function showParentNAddChild(aParentID,
michael@0 309 aPerformActionOnChildInTheFirstPlace)
michael@0 310 {
michael@0 311 this.init = function showParentNAddChild_init()
michael@0 312 {
michael@0 313 this.parentNode = getNode(aParentID);
michael@0 314 this.hostNode = this.parentNode.parentNode;
michael@0 315 this.childNode = document.createElement("option");
michael@0 316 this.childNode.textContent = "testing";
michael@0 317 }
michael@0 318
michael@0 319 this.__proto__ = new coalescenceBase(kAddElm, kShowElm,
michael@0 320 aPerformActionOnChildInTheFirstPlace);
michael@0 321
michael@0 322 this.init();
michael@0 323 this.initSequence();
michael@0 324 }
michael@0 325
michael@0 326 ////////////////////////////////////////////////////////////////////////////
michael@0 327 // Do tests.
michael@0 328
michael@0 329 var gQueue = null;
michael@0 330 //gA11yEventDumpToConsole = true; // debug stuff
michael@0 331
michael@0 332 function doTests()
michael@0 333 {
michael@0 334 gQueue = new eventQueue();
michael@0 335
michael@0 336 gQueue.push(new removeChildNParent("option1", "select1"));
michael@0 337 gQueue.push(new removeParentNChild("option2", "select2"));
michael@0 338 gQueue.push(new hideChildNParent("option3", "select3"));
michael@0 339 gQueue.push(new hideParentNChild("option4", "select4"));
michael@0 340 gQueue.push(new hideChildNRemoveParent("option5", "select5"));
michael@0 341 gQueue.push(new hideParentNRemoveChild("option6", "select6"));
michael@0 342 gQueue.push(new removeChildNHideParent("option7", "select7"));
michael@0 343 gQueue.push(new removeParentNHideChild("option8", "select8"));
michael@0 344
michael@0 345 gQueue.push(new addParentNChild("testContainer", false));
michael@0 346 gQueue.push(new addParentNChild("testContainer", true));
michael@0 347 gQueue.push(new showParentNChild("select9", "option9", false));
michael@0 348 gQueue.push(new showParentNChild("select10", "option10", true));
michael@0 349 gQueue.push(new showParentNAddChild("select11", false));
michael@0 350 gQueue.push(new showParentNAddChild("select12", true));
michael@0 351
michael@0 352 gQueue.invoke(); // Will call SimpleTest.finish();
michael@0 353 }
michael@0 354
michael@0 355 SimpleTest.waitForExplicitFinish();
michael@0 356 addA11yLoadEvent(doTests);
michael@0 357 </script>
michael@0 358 </head>
michael@0 359
michael@0 360 <body>
michael@0 361
michael@0 362 <a target="_blank"
michael@0 363 href="https://bugzilla.mozilla.org/show_bug.cgi?id=513213"
michael@0 364 title="coalesce events when new event is appended to the queue">
michael@0 365 Mozilla Bug 513213
michael@0 366 </a><br>
michael@0 367 <a target="_blank"
michael@0 368 title="Rework accessible tree update code"
michael@0 369 href="https://bugzilla.mozilla.org/show_bug.cgi?id=570275">
michael@0 370 Mozilla Bug 570275
michael@0 371 </a>
michael@0 372
michael@0 373 <p id="display"></p>
michael@0 374 <div id="content" style="display: none"></div>
michael@0 375 <pre id="test">
michael@0 376 </pre>
michael@0 377 <div id="eventdump"></div>
michael@0 378
michael@0 379 <div id="testContainer">
michael@0 380 <select id="select1">
michael@0 381 <option id="option1">option</option>
michael@0 382 </select>
michael@0 383 <select id="select2">
michael@0 384 <option id="option2">option</option>
michael@0 385 </select>
michael@0 386 <select id="select3">
michael@0 387 <option id="option3">option</option>
michael@0 388 </select>
michael@0 389 <select id="select4">
michael@0 390 <option id="option4">option</option>
michael@0 391 </select>
michael@0 392 <select id="select5">
michael@0 393 <option id="option5">option</option>
michael@0 394 </select>
michael@0 395 <select id="select6">
michael@0 396 <option id="option6">option</option>
michael@0 397 </select>
michael@0 398 <select id="select7">
michael@0 399 <option id="option7">option</option>
michael@0 400 </select>
michael@0 401 <select id="select8">
michael@0 402 <option id="option8">option</option>
michael@0 403 </select>
michael@0 404
michael@0 405 <select id="select9" style="display: none">
michael@0 406 <option id="option9" style="display: none">testing</option>
michael@0 407 </select>
michael@0 408 <select id="select10" style="display: none">
michael@0 409 <option id="option10" style="display: none">testing</option>
michael@0 410 </select>
michael@0 411 <select id="select11" style="display: none"></select>
michael@0 412 <select id="select12" style="display: none"></select>
michael@0 413 </div>
michael@0 414 </body>
michael@0 415 </html>

mercurial