|
1 /** |
|
2 * Helper method to start a single XUL tree test. |
|
3 */ |
|
4 function loadXULTreeAndDoTest(aDoTestFunc, aTreeID, aTreeView) |
|
5 { |
|
6 var doTestFunc = aDoTestFunc ? aDoTestFunc : gXULTreeLoadContext.doTestFunc; |
|
7 var treeID = aTreeID ? aTreeID : gXULTreeLoadContext.treeID; |
|
8 var treeView = aTreeView ? aTreeView : gXULTreeLoadContext.treeView; |
|
9 |
|
10 function loadXULTree(aTreeID, aTreeView) |
|
11 { |
|
12 this.treeNode = getNode(aTreeID); |
|
13 |
|
14 this.eventSeq = [ |
|
15 new invokerChecker(EVENT_REORDER, this.treeNode) |
|
16 ]; |
|
17 |
|
18 this.invoke = function loadXULTree_invoke() |
|
19 { |
|
20 this.treeNode.treeBoxObject.view = aTreeView; |
|
21 } |
|
22 |
|
23 this.getID = function loadXULTree_getID() |
|
24 { |
|
25 return "Load XUL tree " + prettyName(aTreeID); |
|
26 } |
|
27 } |
|
28 |
|
29 gXULTreeLoadContext.queue = new eventQueue(); |
|
30 gXULTreeLoadContext.queue.push(new loadXULTree(treeID, treeView)); |
|
31 gXULTreeLoadContext.queue.onFinish = function() |
|
32 { |
|
33 SimpleTest.executeSoon(doTestFunc); |
|
34 return DO_NOT_FINISH_TEST; |
|
35 } |
|
36 gXULTreeLoadContext.queue.invoke(); |
|
37 } |
|
38 |
|
39 /** |
|
40 * Analogy of addA11yLoadEvent, nice helper to load XUL tree and start the test. |
|
41 */ |
|
42 function addA11yXULTreeLoadEvent(aDoTestFunc, aTreeID, aTreeView) |
|
43 { |
|
44 gXULTreeLoadContext.doTestFunc = aDoTestFunc; |
|
45 gXULTreeLoadContext.treeID = aTreeID; |
|
46 gXULTreeLoadContext.treeView = aTreeView; |
|
47 |
|
48 addA11yLoadEvent(loadXULTreeAndDoTest); |
|
49 } |
|
50 |
|
51 |
|
52 function nsTableTreeView(aRowCount) |
|
53 { |
|
54 this.__proto__ = new nsTreeView(); |
|
55 |
|
56 for (var idx = 0; idx < aRowCount; idx++) |
|
57 this.mData.push(new treeItem("row" + String(idx) + "_")); |
|
58 } |
|
59 |
|
60 function nsTreeTreeView() |
|
61 { |
|
62 this.__proto__ = new nsTreeView(); |
|
63 |
|
64 this.mData = [ |
|
65 new treeItem("row1"), |
|
66 new treeItem("row2_", true, [new treeItem("row2.1_"), new treeItem("row2.2_")]), |
|
67 new treeItem("row3_", false, [new treeItem("row3.1_"), new treeItem("row3.2_")]), |
|
68 new treeItem("row4") |
|
69 ]; |
|
70 } |
|
71 |
|
72 function nsTreeView() |
|
73 { |
|
74 this.mTree = null; |
|
75 this.mData = []; |
|
76 } |
|
77 |
|
78 nsTreeView.prototype = |
|
79 { |
|
80 ////////////////////////////////////////////////////////////////////////////// |
|
81 // nsITreeView implementation |
|
82 |
|
83 get rowCount() |
|
84 { |
|
85 return this.getRowCountIntl(this.mData); |
|
86 }, |
|
87 setTree: function setTree(aTree) |
|
88 { |
|
89 this.mTree = aTree; |
|
90 }, |
|
91 getCellText: function getCellText(aRow, aCol) |
|
92 { |
|
93 var data = this.getDataForIndex(aRow); |
|
94 if (aCol.id in data.colsText) |
|
95 return data.colsText[aCol.id]; |
|
96 |
|
97 return data.text + aCol.id; |
|
98 }, |
|
99 getCellValue: function getCellValue(aRow, aCol) |
|
100 { |
|
101 var data = this.getDataForIndex(aRow); |
|
102 return data.value; |
|
103 }, |
|
104 getRowProperties: function getRowProperties(aIndex) { return ""; }, |
|
105 getCellProperties: function getCellProperties(aIndex, aCol) |
|
106 { |
|
107 if (!aCol.cycler) |
|
108 return ""; |
|
109 |
|
110 var data = this.getDataForIndex(aIndex); |
|
111 return this.mCyclerStates[data.cyclerState]; |
|
112 }, |
|
113 getColumnProperties: function getColumnProperties(aCol) { return ""; }, |
|
114 getParentIndex: function getParentIndex(aRowIndex) |
|
115 { |
|
116 var info = this.getInfoByIndex(aRowIndex); |
|
117 return info.parentIndex; |
|
118 }, |
|
119 hasNextSibling: function hasNextSibling(aRowIndex, aAfterIndex) { }, |
|
120 getLevel: function getLevel(aIndex) |
|
121 { |
|
122 var info = this.getInfoByIndex(aIndex); |
|
123 return info.level; |
|
124 }, |
|
125 getImageSrc: function getImageSrc(aRow, aCol) {}, |
|
126 getProgressMode: function getProgressMode(aRow, aCol) {}, |
|
127 isContainer: function isContainer(aIndex) |
|
128 { |
|
129 var data = this.getDataForIndex(aIndex); |
|
130 return data.open != undefined; |
|
131 }, |
|
132 isContainerOpen: function isContainerOpen(aIndex) |
|
133 { |
|
134 var data = this.getDataForIndex(aIndex); |
|
135 return data.open; |
|
136 }, |
|
137 isContainerEmpty: function isContainerEmpty(aIndex) |
|
138 { |
|
139 var data = this.getDataForIndex(aIndex); |
|
140 return data.open == undefined; |
|
141 }, |
|
142 isSeparator: function isSeparator(aIndex) {}, |
|
143 isSorted: function isSorted() {}, |
|
144 toggleOpenState: function toggleOpenState(aIndex) |
|
145 { |
|
146 var data = this.getDataForIndex(aIndex); |
|
147 |
|
148 data.open = !data.open; |
|
149 var rowCount = this.getRowCountIntl(data.children); |
|
150 |
|
151 if (data.open) |
|
152 this.mTree.rowCountChanged(aIndex + 1, rowCount); |
|
153 else |
|
154 this.mTree.rowCountChanged(aIndex + 1, -rowCount); |
|
155 }, |
|
156 selectionChanged: function selectionChanged() {}, |
|
157 cycleHeader: function cycleHeader(aCol) {}, |
|
158 cycleCell: function cycleCell(aRow, aCol) |
|
159 { |
|
160 var data = this.getDataForIndex(aRow); |
|
161 data.cyclerState = (data.cyclerState + 1) % 3; |
|
162 |
|
163 this.mTree.invalidateCell(aRow, aCol); |
|
164 }, |
|
165 isEditable: function isEditable(aRow, aCol) |
|
166 { |
|
167 return true; |
|
168 }, |
|
169 isSelectable: function isSelectable(aRow, aCol) {}, |
|
170 setCellText: function setCellText(aRow, aCol, aValue) |
|
171 { |
|
172 var data = this.getDataForIndex(aRow); |
|
173 data.colsText[aCol.id] = aValue; |
|
174 }, |
|
175 setCellValue: function setCellValue(aRow, aCol, aValue) |
|
176 { |
|
177 var data = this.getDataForIndex(aRow); |
|
178 data.value = aValue; |
|
179 |
|
180 this.mTree.invalidateCell(aRow, aCol); |
|
181 }, |
|
182 performAction: function performAction(aAction) {}, |
|
183 performActionOnRow: function performActionOnRow(aAction, aRow) {}, |
|
184 performActionOnCell: function performActionOnCell(aAction, aRow, aCol) {}, |
|
185 |
|
186 ////////////////////////////////////////////////////////////////////////////// |
|
187 // public implementation |
|
188 |
|
189 appendItem: function appendItem(aText) |
|
190 { |
|
191 this.mData.push(new treeItem(aText)); |
|
192 }, |
|
193 |
|
194 ////////////////////////////////////////////////////////////////////////////// |
|
195 // private implementation |
|
196 |
|
197 getDataForIndex: function getDataForIndex(aRowIndex) |
|
198 { |
|
199 return this.getInfoByIndex(aRowIndex).data; |
|
200 }, |
|
201 |
|
202 getInfoByIndex: function getInfoByIndex(aRowIndex) |
|
203 { |
|
204 var info = { |
|
205 data: null, |
|
206 parentIndex: -1, |
|
207 level: 0, |
|
208 index: -1 |
|
209 }; |
|
210 |
|
211 this.getInfoByIndexIntl(aRowIndex, info, this.mData, 0); |
|
212 return info; |
|
213 }, |
|
214 |
|
215 getRowCountIntl: function getRowCountIntl(aChildren) |
|
216 { |
|
217 var rowCount = 0; |
|
218 for (var childIdx = 0; childIdx < aChildren.length; childIdx++) { |
|
219 rowCount++; |
|
220 |
|
221 var data = aChildren[childIdx]; |
|
222 if (data.open) |
|
223 rowCount += this.getRowCountIntl(data.children); |
|
224 } |
|
225 |
|
226 return rowCount; |
|
227 }, |
|
228 |
|
229 getInfoByIndexIntl: function getInfoByIndexIntl(aRowIdx, aInfo, |
|
230 aChildren, aLevel) |
|
231 { |
|
232 var rowIdx = aRowIdx; |
|
233 for (var childIdx = 0; childIdx < aChildren.length; childIdx++) { |
|
234 var data = aChildren[childIdx]; |
|
235 |
|
236 aInfo.index++; |
|
237 |
|
238 if (rowIdx == 0) { |
|
239 aInfo.data = data; |
|
240 aInfo.level = aLevel; |
|
241 return -1; |
|
242 } |
|
243 |
|
244 if (data.open) { |
|
245 var parentIdx = aInfo.index; |
|
246 rowIdx = this.getInfoByIndexIntl(rowIdx - 1, aInfo, data.children, |
|
247 aLevel + 1); |
|
248 |
|
249 if (rowIdx == -1) { |
|
250 if (aInfo.parentIndex == -1) |
|
251 aInfo.parentIndex = parentIdx; |
|
252 return 0; |
|
253 } |
|
254 } else { |
|
255 rowIdx--; |
|
256 } |
|
257 } |
|
258 |
|
259 return rowIdx; |
|
260 }, |
|
261 |
|
262 mCyclerStates: [ |
|
263 "cyclerState1", |
|
264 "cyclerState2", |
|
265 "cyclerState3" |
|
266 ] |
|
267 }; |
|
268 |
|
269 function treeItem(aText, aOpen, aChildren) |
|
270 { |
|
271 this.text = aText; |
|
272 this.colsText = {}; |
|
273 this.open = aOpen; |
|
274 this.value = "true"; |
|
275 this.cyclerState = 0; |
|
276 if (aChildren) |
|
277 this.children = aChildren; |
|
278 } |
|
279 |
|
280 function createAtom(aName) |
|
281 { |
|
282 return Components.classes["@mozilla.org/atom-service;1"] |
|
283 .getService(Components.interfaces.nsIAtomService).getAtom(aName); |
|
284 } |
|
285 |
|
286 /** |
|
287 * Used in conjunction with loadXULTreeAndDoTest and addA11yXULTreeLoadEvent. |
|
288 */ |
|
289 var gXULTreeLoadContext = |
|
290 { |
|
291 doTestFunc: null, |
|
292 treeID: null, |
|
293 treeView: null, |
|
294 queue: null |
|
295 }; |