Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 <?xml version="1.0"?>
2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
3 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
4 type="text/css"?>
6 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
7 title="DOM TreeRowCountChanged and a11y name change events.">
9 <script type="application/javascript"
10 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
12 <script type="application/javascript"
13 src="../treeview.js" />
15 <script type="application/javascript"
16 src="../common.js" />
17 <script type="application/javascript"
18 src="../events.js" />
20 <script type="application/javascript">
21 <![CDATA[
23 ////////////////////////////////////////////////////////////////////////////
24 // Invoker's checkers
26 /**
27 * Check TreeRowCountChanged event.
28 */
29 function rowCountChangedChecker(aMsg, aIdx, aCount)
30 {
31 this.type = "TreeRowCountChanged";
32 this.target = gTree;
33 this.check = function check(aEvent)
34 {
35 var propBag = aEvent.detail.QueryInterface(Components.interfaces.nsIPropertyBag2);
36 var index = propBag.getPropertyAsInt32("index");
37 is(index, aIdx, "Wrong 'index' data of 'treeRowCountChanged' event.");
39 var count = propBag.getPropertyAsInt32("count");
40 is(count, aCount, "Wrong 'count' data of 'treeRowCountChanged' event.");
41 }
42 this.getID = function getID()
43 {
44 return aMsg + "TreeRowCountChanged";
45 }
46 }
48 /**
49 * Check TreeInvalidated event.
50 */
51 function treeInvalidatedChecker(aMsg, aStartRow, aEndRow, aStartCol, aEndCol)
52 {
53 this.type = "TreeInvalidated";
54 this.target = gTree;
55 this.check = function check(aEvent)
56 {
57 var propBag = aEvent.detail.QueryInterface(Components.interfaces.nsIPropertyBag2);
58 try {
59 var startRow = propBag.getPropertyAsInt32("startrow");
60 } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
61 startRow = null;
62 }
63 is(startRow, aStartRow,
64 "Wrong 'startrow' of 'treeInvalidated' event on " + aMsg);
66 try {
67 var endRow = propBag.getPropertyAsInt32("endrow");
68 } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
69 endRow = null;
70 }
71 is(endRow, aEndRow,
72 "Wrong 'endrow' of 'treeInvalidated' event on " + aMsg);
74 try {
75 var startCol = propBag.getPropertyAsInt32("startcolumn");
76 } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
77 startCol = null;
78 }
79 is(startCol, aStartCol,
80 "Wrong 'startcolumn' of 'treeInvalidated' event on " + aMsg);
82 try {
83 var endCol = propBag.getPropertyAsInt32("endcolumn");
84 } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
85 startCol = null;
86 }
87 is(endCol, aEndCol,
88 "Wrong 'endcolumn' of 'treeInvalidated' event on " + aMsg);
89 }
90 this.getID = function getID()
91 {
92 return "TreeInvalidated on " + aMsg;
93 }
94 }
96 /**
97 * Check name changed a11y event.
98 */
99 function nameChangeChecker(aMsg, aRow, aCol)
100 {
101 this.type = EVENT_NAME_CHANGE;
103 function targetGetter()
104 {
105 var acc = getAccessible(gTree);
107 var tableAcc = getAccessible(acc, [nsIAccessibleTable]);
108 return tableAcc.getCellAt(aRow, aCol);
109 }
110 Object.defineProperty(this, "target", { get: targetGetter });
112 this.getID = function getID()
113 {
114 return aMsg + "name changed";
115 }
116 }
118 /**
119 * Check name changed a11y event for a row.
120 */
121 function rowNameChangeChecker(aMsg, aRow)
122 {
123 this.type = EVENT_NAME_CHANGE;
125 function targetGetter()
126 {
127 var acc = getAccessible(gTree);
128 return acc.getChildAt(aRow + 1);
129 }
130 Object.defineProperty(this, "target", { get: targetGetter });
132 this.getID = function getID()
133 {
134 return aMsg + "name changed";
135 }
136 }
138 ////////////////////////////////////////////////////////////////////////////
139 // Invokers
141 /**
142 * Set tree view.
143 */
144 function setTreeView()
145 {
146 this.invoke = function setTreeView_invoke()
147 {
148 gTreeBox.view = gView;
149 }
151 this.getID = function setTreeView_getID() { return "set tree view"; }
153 this.eventSeq = [
154 new invokerChecker(EVENT_REORDER, gTree)
155 ];
156 };
158 /**
159 * Insert row at 0 index and checks TreeRowCountChanged and TreeInvalidated
160 * event.
161 */
162 function insertRow()
163 {
164 this.invoke = function insertRow_invoke()
165 {
166 gView.appendItem("last");
167 gTreeBox.rowCountChanged(0, 1);
168 }
170 this.eventSeq =
171 [
172 new rowCountChangedChecker("insertRow: ", 0, 1),
173 new treeInvalidatedChecker("insertRow", 0, 5, null, null)
174 ];
176 this.getID = function insertRow_getID()
177 {
178 return "insert row";
179 }
180 }
182 /**
183 * Invalidates first column and checks six name changed events for each
184 * treeitem plus TreeInvalidated event.
185 */
186 function invalidateColumn()
187 {
188 this.invoke = function invalidateColumn_invoke()
189 {
190 // Make sure accessible subtree of XUL tree is created otherwise no
191 // name change events for cell accessibles are emitted.
192 var tree = getAccessible(gTree);
193 var child = tree.firstChild;
194 var walkDown = true;
195 while (child != tree) {
196 if (walkDown) {
197 var grandChild = child.firstChild;
198 if (grandChild) {
199 child = grandChild;
200 continue;
201 }
202 }
204 var sibling = child.nextSibling;
205 if (sibling) {
206 child = sibling;
207 walkDown = true;
208 continue;
209 }
211 child = child.parent;
212 walkDown = false;
213 }
215 // Fire 'TreeInvalidated' event by InvalidateColumn()
216 var firstCol = gTree.columns.getFirstColumn();
217 for (var i = 0; i < gView.rowCount; i++)
218 gView.setCellText(i, firstCol, "hey " + String(i) + "x0");
220 gTreeBox.invalidateColumn(firstCol);
221 }
223 this.eventSeq =
224 [
225 new nameChangeChecker("invalidateColumn: ", 0, 0),
226 new nameChangeChecker("invalidateColumn: ", 1, 0),
227 new nameChangeChecker("invalidateColumn: ", 2, 0),
228 new nameChangeChecker("invalidateColumn: ", 3, 0),
229 new nameChangeChecker("invalidateColumn: ", 4, 0),
230 new nameChangeChecker("invalidateColumn: ", 5, 0),
231 new treeInvalidatedChecker("invalidateColumn", null, null, 0, 0)
232 ];
234 this.getID = function invalidateColumn_getID()
235 {
236 return "invalidate column";
237 }
238 }
240 /**
241 * Invalidates second row and checks name changed event for first treeitem
242 * (note, there are two name changed events on linux due to different
243 * accessible tree for xul:tree element) plus TreeInvalidated event.
244 */
245 function invalidateRow()
246 {
247 this.invoke = function invalidateRow_invoke()
248 {
249 // Fire 'TreeInvalidated' event by InvalidateRow()
250 var colCount = gTree.columns.count;
251 var column = gTree.columns.getFirstColumn();
252 while (column) {
253 gView.setCellText(1, column, "aloha 1x" + String(column.index));
254 column = column.getNext();
255 }
257 gTreeBox.invalidateRow(1);
258 }
260 this.eventSeq =
261 [
262 new nameChangeChecker("invalidateRow: ", 1, 0),
263 new nameChangeChecker("invalidateRow: ", 1, 1),
264 new rowNameChangeChecker("invalidateRow: ", 1),
265 new treeInvalidatedChecker("invalidateRow", 1, 1, null, null)
266 ];
268 this.getID = function invalidateRow_getID()
269 {
270 return "invalidate row";
271 }
272 }
274 ////////////////////////////////////////////////////////////////////////////
275 // Test
277 var gTree = null;
278 var gTreeBox = null;
279 var gTreeView = null;
280 var gQueue = null;
282 // gA11yEventDumpID = "debug";
283 gA11yEventDumpToConsole = true; // debuggin
285 function doTest()
286 {
287 // Initialize the tree
288 gTree = document.getElementById("tree");
289 gTreeBox = gTree.treeBoxObject;
290 gView = new nsTableTreeView(5);
292 // Perform actions
293 gQueue = new eventQueue();
295 gQueue.push(new setTreeView());
296 gQueue.push(new insertRow());
297 gQueue.push(new invalidateColumn());
298 gQueue.push(new invalidateRow());
300 gQueue.invoke();
301 }
303 SimpleTest.waitForExplicitFinish();
304 addA11yLoadEvent(doTest);
305 ]]>
306 </script>
308 <hbox flex="1" style="overflow: auto;">
309 <body xmlns="http://www.w3.org/1999/xhtml">
310 <a target="_blank"
311 href="https://bugzilla.mozilla.org/show_bug.cgi?id=368835"
312 title="Fire TreeViewChanged/TreeRowCountChanged events.">
313 Mozilla Bug 368835
314 </a><br/>
315 <a target="_blank"
316 href="https://bugzilla.mozilla.org/show_bug.cgi?id=308564"
317 title="No accessibility events when data in a tree row changes.">
318 Mozilla Bug 308564
319 </a><br/>
320 <a target="_blank"
321 href="https://bugzilla.mozilla.org/show_bug.cgi?id=739524"
322 title="replace TreeViewChanged DOM event on direct call from XUL tree.">
323 Mozilla Bug 739524
324 </a><br/>
325 <a target="_blank"
326 href="https://bugzilla.mozilla.org/show_bug.cgi?id=743568"
327 title="Thunderbird message list tree emitting incorrect focus signals after message deleted.">
328 Mozilla Bug 743568
329 </a>
330 <p id="display"></p>
331 <div id="content" style="display: none">
332 </div>
333 <pre id="test">
334 </pre>
335 </body>
337 <vbox id="debug"/>
338 <tree id="tree" flex="1">
339 <treecols>
340 <treecol id="col1" flex="1" primary="true" label="column"/>
341 <treecol id="col2" flex="1" label="column 2"/>
342 </treecols>
343 <treechildren id="treechildren"/>
344 </tree>
345 </hbox>
347 </window>