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