|
1 /** |
|
2 * This file provides set of helper functions to test nsIAccessibleTable |
|
3 * interface. |
|
4 * |
|
5 * Required: |
|
6 * common.js |
|
7 * role.js |
|
8 * states.js |
|
9 */ |
|
10 |
|
11 /** |
|
12 * Constants used to describe cells array. |
|
13 */ |
|
14 const kDataCell = 1; // Indicates the cell is origin data cell |
|
15 const kRowHeaderCell = 2; // Indicates the cell is row header cell |
|
16 const kColHeaderCell = 4; // Indicated the cell is column header cell |
|
17 const kOrigin = kDataCell | kRowHeaderCell | kColHeaderCell; |
|
18 |
|
19 const kRowSpanned = 8; // Indicates the cell is not origin and row spanned |
|
20 const kColSpanned = 16; // Indicates the cell is not origin and column spanned |
|
21 const kSpanned = kRowSpanned | kColSpanned; |
|
22 |
|
23 /** |
|
24 * Constants to define column header type. |
|
25 */ |
|
26 const kNoColumnHeader = 0; |
|
27 const kListboxColumnHeader = 1; |
|
28 const kTreeColumnHeader = 2; |
|
29 |
|
30 /** |
|
31 * Test table structure and related methods. |
|
32 * |
|
33 * @param aIdentifier [in] table accessible identifier |
|
34 * @param aCellsArray [in] two dimensional array (row X columns) of |
|
35 * cell types (see constants defined above). |
|
36 * @param aColHeaderType [in] specifies wether column header cells are |
|
37 * arranged into the list. |
|
38 * @param aCaption [in] caption text if any |
|
39 * @param aSummary [in] summary text if any |
|
40 * @param aIsTreeTable [in] specifies whether given table is tree table |
|
41 */ |
|
42 function testTableStruct(aIdentifier, aCellsArray, aColHeaderType, |
|
43 aCaption, aSummary, aIsTreeTable) |
|
44 { |
|
45 var tableNode = getNode(aIdentifier); |
|
46 var isGrid = tableNode.getAttribute("role") == "grid" || |
|
47 tableNode.getAttribute("role") == "treegrid" || |
|
48 tableNode.localName == "tree"; |
|
49 |
|
50 var rowCount = aCellsArray.length; |
|
51 var colsCount = aCellsArray[0] ? aCellsArray[0].length : 0; |
|
52 |
|
53 // Test table accessible tree. |
|
54 var tableObj = { |
|
55 role: aIsTreeTable ? ROLE_TREE_TABLE : ROLE_TABLE, |
|
56 children: [] |
|
57 }; |
|
58 |
|
59 // caption accessible handling |
|
60 if (aCaption) { |
|
61 var captionObj = { |
|
62 role: ROLE_CAPTION, |
|
63 children: [ |
|
64 { |
|
65 role: ROLE_TEXT_LEAF, |
|
66 name: aCaption |
|
67 } |
|
68 ] |
|
69 }; |
|
70 |
|
71 tableObj.children.push(captionObj); |
|
72 } |
|
73 |
|
74 // special types of column headers handling |
|
75 if (aColHeaderType) { |
|
76 var headersObj = { |
|
77 role: ROLE_LIST, |
|
78 children: [] |
|
79 }; |
|
80 |
|
81 for (var idx = 0; idx < colsCount; idx++) { |
|
82 var headerCellObj = { |
|
83 role: ROLE_COLUMNHEADER |
|
84 }; |
|
85 headersObj.children.push(headerCellObj); |
|
86 } |
|
87 |
|
88 if (aColHeaderType == kTreeColumnHeader) { |
|
89 var columnPickerObj = { |
|
90 role: ROLE_PUSHBUTTON |
|
91 }; |
|
92 |
|
93 headersObj.children.push(columnPickerObj); |
|
94 } |
|
95 |
|
96 tableObj.children.push(headersObj); |
|
97 } |
|
98 |
|
99 // rows and cells accessibles |
|
100 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
101 var rowObj = { |
|
102 role: ROLE_ROW, |
|
103 children: [] |
|
104 }; |
|
105 |
|
106 for (var colIdx = 0; colIdx < colsCount; colIdx++) { |
|
107 var celltype = aCellsArray[rowIdx][colIdx]; |
|
108 |
|
109 var role = ROLE_NOTHING; |
|
110 switch (celltype) { |
|
111 case kDataCell: |
|
112 role = (isGrid ? ROLE_GRID_CELL : ROLE_CELL); |
|
113 break; |
|
114 case kRowHeaderCell: |
|
115 role = ROLE_ROWHEADER; |
|
116 break; |
|
117 case kColHeaderCell: |
|
118 role = ROLE_COLUMNHEADER; |
|
119 break; |
|
120 } |
|
121 |
|
122 if (role != ROLE_NOTHING) { |
|
123 var cellObj = { |
|
124 role: role |
|
125 }; |
|
126 rowObj.children.push(cellObj); |
|
127 } |
|
128 } |
|
129 |
|
130 tableObj.children.push(rowObj); |
|
131 } |
|
132 |
|
133 testAccessibleTree(aIdentifier, tableObj); |
|
134 |
|
135 // Test table table interface. |
|
136 var table = getAccessible(aIdentifier, [nsIAccessibleTable]); |
|
137 |
|
138 // summary |
|
139 if (aSummary) |
|
140 is(table.summary, aSummary, |
|
141 "Wrong summary of the table " + prettyName(aIdentifier)); |
|
142 |
|
143 // rowCount and columnCount |
|
144 is(table.rowCount, rowCount, |
|
145 "Wrong rows count of " + prettyName(aIdentifier)); |
|
146 is(table.columnCount, colsCount, |
|
147 "Wrong columns count of " + prettyName(aIdentifier)); |
|
148 |
|
149 // rows and columns extents |
|
150 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
151 for (var colIdx = 0; colIdx < colsCount; colIdx++) { |
|
152 var celltype = aCellsArray[rowIdx][colIdx]; |
|
153 if (celltype & kOrigin) { |
|
154 |
|
155 // table getRowExtentAt |
|
156 var rowExtent = table.getRowExtentAt(rowIdx, colIdx); |
|
157 for (var idx = rowIdx + 1; |
|
158 idx < rowCount && (aCellsArray[idx][colIdx] & kRowSpanned); |
|
159 idx++); |
|
160 |
|
161 var expectedRowExtent = idx - rowIdx; |
|
162 is(rowExtent, expectedRowExtent, |
|
163 "getRowExtentAt: Wrong number of spanned rows at (" + rowIdx + ", " + |
|
164 colIdx + ") for " + prettyName(aIdentifier)); |
|
165 |
|
166 // table getColumnExtentAt |
|
167 var colExtent = table.getColumnExtentAt(rowIdx, colIdx); |
|
168 for (var idx = colIdx + 1; |
|
169 idx < colsCount && (aCellsArray[rowIdx][idx] & kColSpanned); |
|
170 idx++); |
|
171 |
|
172 var expectedColExtent = idx - colIdx; |
|
173 is(colExtent, expectedColExtent, |
|
174 "getColumnExtentAt: Wrong number of spanned columns at (" + rowIdx + |
|
175 ", " + colIdx + ") for " + prettyName(aIdentifier)); |
|
176 |
|
177 // cell rowExtent and columnExtent |
|
178 var cell = getAccessible(table.getCellAt(rowIdx, colIdx), |
|
179 [nsIAccessibleTableCell]); |
|
180 |
|
181 is(cell.rowExtent, expectedRowExtent, |
|
182 "rowExtent: Wrong number of spanned rows at (" + rowIdx + ", " + |
|
183 colIdx + ") for " + prettyName(aIdentifier)); |
|
184 |
|
185 is(cell.columnExtent, expectedColExtent, |
|
186 "columnExtent: Wrong number of spanned column at (" + rowIdx + ", " + |
|
187 colIdx + ") for " + prettyName(aIdentifier)); |
|
188 } |
|
189 } |
|
190 } |
|
191 } |
|
192 |
|
193 /** |
|
194 * Test table indexes. |
|
195 * |
|
196 * @param aIdentifier [in] table accessible identifier |
|
197 * @param aIdxes [in] two dimensional array of cell indexes |
|
198 */ |
|
199 function testTableIndexes(aIdentifier, aIdxes) |
|
200 { |
|
201 var tableAcc = getAccessible(aIdentifier, [nsIAccessibleTable]); |
|
202 if (!tableAcc) |
|
203 return; |
|
204 |
|
205 var obtainedRowIdx, obtainedColIdx, obtainedIdx; |
|
206 var cellAcc; |
|
207 |
|
208 var id = prettyName(aIdentifier); |
|
209 |
|
210 var rowCount = aIdxes.length; |
|
211 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
212 var colCount = aIdxes[rowIdx].length; |
|
213 for (var colIdx = 0; colIdx < colCount; colIdx++) { |
|
214 var idx = aIdxes[rowIdx][colIdx]; |
|
215 |
|
216 // getCellAt |
|
217 try { |
|
218 cellAcc = null; |
|
219 cellAcc = tableAcc.getCellAt(rowIdx, colIdx); |
|
220 } catch (e) { } |
|
221 |
|
222 ok(idx != -1 && cellAcc || idx == -1 && !cellAcc, |
|
223 id + ": Can't get cell accessible at row = " + rowIdx + ", column = " + colIdx); |
|
224 |
|
225 if (idx != - 1) { |
|
226 |
|
227 // getRowIndexAt |
|
228 var origRowIdx = rowIdx; |
|
229 while (origRowIdx > 0 && |
|
230 aIdxes[rowIdx][colIdx] == aIdxes[origRowIdx - 1][colIdx]) |
|
231 origRowIdx--; |
|
232 |
|
233 try { |
|
234 obtainedRowIdx = tableAcc.getRowIndexAt(idx); |
|
235 } catch (e) { |
|
236 ok(false, id + ": can't get row index for cell index " + idx + "," + e); |
|
237 } |
|
238 |
|
239 is(obtainedRowIdx, origRowIdx, |
|
240 id + ": row for index " + idx + " is not correct (getRowIndexAt)"); |
|
241 |
|
242 // getColumnIndexAt |
|
243 var origColIdx = colIdx; |
|
244 while (origColIdx > 0 && |
|
245 aIdxes[rowIdx][colIdx] == aIdxes[rowIdx][origColIdx - 1]) |
|
246 origColIdx--; |
|
247 |
|
248 try { |
|
249 obtainedColIdx = tableAcc.getColumnIndexAt(idx); |
|
250 } catch (e) { |
|
251 ok(false, id + ": can't get column index for cell index " + idx + "," + e); |
|
252 } |
|
253 |
|
254 is(obtainedColIdx, origColIdx, |
|
255 id + ": column for index " + idx + " is not correct (getColumnIndexAt)"); |
|
256 |
|
257 // getRowAndColumnIndicesAt |
|
258 var obtainedRowIdxObj = { }, obtainedColIdxObj = { }; |
|
259 try { |
|
260 tableAcc.getRowAndColumnIndicesAt(idx, obtainedRowIdxObj, |
|
261 obtainedColIdxObj); |
|
262 } catch (e) { |
|
263 ok(false, id + ": can't get row and column indices for cell index " + idx + "," + e); |
|
264 } |
|
265 |
|
266 is(obtainedRowIdxObj.value, origRowIdx, |
|
267 id + ": row for index " + idx + " is not correct (getRowAndColumnIndicesAt)"); |
|
268 is(obtainedColIdxObj.value, origColIdx, |
|
269 id + ": column for index " + idx + " is not correct (getRowAndColumnIndicesAt)"); |
|
270 |
|
271 if (cellAcc) { |
|
272 |
|
273 var cellId = prettyName(cellAcc); |
|
274 cellAcc = getAccessible(cellAcc, [nsIAccessibleTableCell]); |
|
275 |
|
276 // cell: 'table-cell-index' attribute |
|
277 var attrs = cellAcc.attributes; |
|
278 var strIdx = ""; |
|
279 try { |
|
280 strIdx = attrs.getStringProperty("table-cell-index"); |
|
281 } catch (e) { |
|
282 ok(false, |
|
283 cellId + ": no cell index from object attributes on the cell accessible at index " + idx + "."); |
|
284 } |
|
285 |
|
286 if (strIdx) { |
|
287 is (parseInt(strIdx), idx, |
|
288 cellId + ": cell index from object attributes of cell accessible isn't corrent."); |
|
289 } |
|
290 |
|
291 // cell: table |
|
292 try { |
|
293 is(cellAcc.table, tableAcc, |
|
294 cellId + ": wrong table accessible for the cell."); |
|
295 |
|
296 } catch (e) { |
|
297 ok(false, |
|
298 cellId + ": can't get table accessible from the cell."); |
|
299 } |
|
300 |
|
301 // cell: getRowIndex |
|
302 try { |
|
303 obtainedRowIdx = cellAcc.rowIndex; |
|
304 } catch (e) { |
|
305 ok(false, |
|
306 cellId + ": can't get row index of the cell at index " + idx + "," + e); |
|
307 } |
|
308 |
|
309 is(obtainedRowIdx, origRowIdx, |
|
310 cellId + ": row for the cell at index " + idx +" is not correct"); |
|
311 |
|
312 // cell: getColumnIndex |
|
313 try { |
|
314 obtainedColIdx = cellAcc.columnIndex; |
|
315 } catch (e) { |
|
316 ok(false, |
|
317 cellId + ": can't get column index of the cell at index " + idx + "," + e); |
|
318 } |
|
319 |
|
320 is(obtainedColIdx, origColIdx, |
|
321 id + ": column for the cell at index " + idx +" is not correct"); |
|
322 } |
|
323 } |
|
324 |
|
325 // getCellIndexAt |
|
326 try { |
|
327 obtainedIdx = tableAcc.getCellIndexAt(rowIdx, colIdx); |
|
328 } catch (e) { |
|
329 obtainedIdx = -1; |
|
330 } |
|
331 |
|
332 is(obtainedIdx, idx, |
|
333 id + ": row " + rowIdx + " /column " + colIdx + " and index " + obtainedIdx + " aren't inconsistent."); |
|
334 } |
|
335 } |
|
336 } |
|
337 |
|
338 /** |
|
339 * Test table getters selection methods. |
|
340 * |
|
341 * @param aIdentifier [in] table accessible identifier |
|
342 * @param aCellsArray [in] two dimensional array (row X columns) of cells |
|
343 * states (either boolean (selected/unselected) if cell is |
|
344 * origin, otherwise kRowSpanned or kColSpanned constant). |
|
345 * @param aMsg [in] text appended before every message |
|
346 */ |
|
347 function testTableSelection(aIdentifier, aCellsArray, aMsg) |
|
348 { |
|
349 var msg = aMsg ? aMsg : ""; |
|
350 var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); |
|
351 if (!acc) |
|
352 return; |
|
353 |
|
354 var rowCount = aCellsArray.length; |
|
355 var colsCount = aCellsArray[0].length; |
|
356 |
|
357 // Columns selection tests. |
|
358 var selCols = new Array(); |
|
359 |
|
360 // isColumnSelected test |
|
361 for (var colIdx = 0; colIdx < colsCount; colIdx++) { |
|
362 var isColSelected = true; |
|
363 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
364 if (aCellsArray[rowIdx][colIdx] == false || |
|
365 aCellsArray[rowIdx][colIdx] == undefined) { |
|
366 isColSelected = false; |
|
367 break; |
|
368 } |
|
369 } |
|
370 |
|
371 is(acc.isColumnSelected(colIdx), isColSelected, |
|
372 msg + "Wrong selection state of " + colIdx + " column for " + |
|
373 prettyName(aIdentifier)); |
|
374 |
|
375 if (isColSelected) |
|
376 selCols.push(colIdx); |
|
377 } |
|
378 |
|
379 // selectedColsCount test |
|
380 is(acc.selectedColumnCount, selCols.length, |
|
381 msg + "Wrong count of selected columns for " + prettyName(aIdentifier)); |
|
382 |
|
383 // getSelectedColumns test |
|
384 var actualSelColsCountObj = { value: null }; |
|
385 var actualSelCols = acc.getSelectedColumnIndices(actualSelColsCountObj); |
|
386 |
|
387 var actualSelColsCount = actualSelColsCountObj.value; |
|
388 is (actualSelColsCount, selCols.length, |
|
389 msg + "Wrong count of selected columns for " + prettyName(aIdentifier) + |
|
390 "from getSelectedColumns."); |
|
391 |
|
392 for (var i = 0; i < actualSelColsCount; i++) { |
|
393 is (actualSelCols[i], selCols[i], |
|
394 msg + "Column at index " + selCols[i] + " should be selected."); |
|
395 } |
|
396 |
|
397 // Rows selection tests. |
|
398 var selRows = new Array(); |
|
399 |
|
400 // isRowSelected test |
|
401 var selrowCount = 0; |
|
402 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
403 var isRowSelected = true; |
|
404 for (var colIdx = 0; colIdx < colsCount; colIdx++) { |
|
405 if (aCellsArray[rowIdx][colIdx] == false || |
|
406 aCellsArray[rowIdx][colIdx] == undefined) { |
|
407 isRowSelected = false; |
|
408 break; |
|
409 } |
|
410 } |
|
411 |
|
412 is(acc.isRowSelected(rowIdx), isRowSelected, |
|
413 msg + "Wrong selection state of " + rowIdx + " row for " + |
|
414 prettyName(aIdentifier)); |
|
415 |
|
416 if (isRowSelected) |
|
417 selRows.push(rowIdx); |
|
418 } |
|
419 |
|
420 // selectedRowCount test |
|
421 is(acc.selectedRowCount, selRows.length, |
|
422 msg + "Wrong count of selected rows for " + prettyName(aIdentifier)); |
|
423 |
|
424 // getSelectedRows test |
|
425 var actualSelrowCountObj = { value: null }; |
|
426 var actualSelRows = acc.getSelectedRowIndices(actualSelrowCountObj); |
|
427 |
|
428 var actualSelrowCount = actualSelrowCountObj.value; |
|
429 is (actualSelrowCount, selRows.length, |
|
430 msg + "Wrong count of selected rows for " + prettyName(aIdentifier) + |
|
431 "from getSelectedRows."); |
|
432 |
|
433 for (var i = 0; i < actualSelrowCount; i++) { |
|
434 is (actualSelRows[i], selRows[i], |
|
435 msg + "Row at index " + selRows[i] + " should be selected."); |
|
436 } |
|
437 |
|
438 // Cells selection tests. |
|
439 var selCells = new Array(); |
|
440 |
|
441 // isCellSelected test |
|
442 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
443 for (var colIdx = 0; colIdx < colsCount; colIdx++) { |
|
444 if (aCellsArray[rowIdx][colIdx] & kSpanned) |
|
445 continue; |
|
446 |
|
447 var isSelected = aCellsArray[rowIdx][colIdx] == true; |
|
448 is(acc.isCellSelected(rowIdx, colIdx), isSelected, |
|
449 msg + "Wrong selection state of cell at " + rowIdx + " row and " + |
|
450 colIdx + " column for " + prettyName(aIdentifier)); |
|
451 |
|
452 if (aCellsArray[rowIdx][colIdx]) |
|
453 selCells.push(acc.getCellIndexAt(rowIdx, colIdx)); |
|
454 } |
|
455 } |
|
456 |
|
457 // selectedCellCount tests |
|
458 is(acc.selectedCellCount, selCells.length, |
|
459 msg + "Wrong count of selected cells for " + prettyName(aIdentifier)); |
|
460 |
|
461 // getSelectedCellIndices test |
|
462 var actualSelCellsCountObj = { value: null }; |
|
463 var actualSelCells = acc.getSelectedCellIndices(actualSelCellsCountObj); |
|
464 |
|
465 var actualSelCellsCount = actualSelCellsCountObj.value; |
|
466 is(actualSelCellsCount, selCells.length, |
|
467 msg + "Wrong count of selected cells for " + prettyName(aIdentifier) + |
|
468 "from getSelectedCells."); |
|
469 |
|
470 for (var i = 0; i < actualSelCellsCount; i++) { |
|
471 is(actualSelCells[i], selCells[i], |
|
472 msg + "getSelectedCellIndices: Cell at index " + selCells[i] + |
|
473 " should be selected."); |
|
474 } |
|
475 |
|
476 // selectedCells and isSelected tests |
|
477 var actualSelCellsArray = acc.selectedCells; |
|
478 for (var i = 0; i < actualSelCellsCount; i++) { |
|
479 var actualSelCellAccessible = |
|
480 actualSelCellsArray.queryElementAt(i, nsIAccessibleTableCell); |
|
481 |
|
482 var colIdx = acc.getColumnIndexAt(selCells[i]); |
|
483 var rowIdx = acc.getRowIndexAt(selCells[i]); |
|
484 var expectedSelCellAccessible = acc.getCellAt(rowIdx, colIdx); |
|
485 |
|
486 ok(actualSelCellAccessible, expectedSelCellAccessible, |
|
487 msg + "getSelectedCells: Cell at index " + selCells[i] + |
|
488 " should be selected."); |
|
489 |
|
490 ok(actualSelCellAccessible.isSelected(), |
|
491 "isSelected: Cell at index " + selCells[i] + " should be selected."); |
|
492 } |
|
493 |
|
494 // selected states tests |
|
495 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
496 for (var colIdx = 0; colIdx < colsCount; colIdx++) { |
|
497 if (aCellsArray[rowIdx][colIdx] & kSpanned) |
|
498 continue; |
|
499 |
|
500 var cell = acc.getCellAt(rowIdx, colIdx); |
|
501 var isSel = aCellsArray[rowIdx][colIdx]; |
|
502 if (isSel == undefined) |
|
503 testStates(cell, 0, 0, STATE_SELECTABLE | STATE_SELECTED); |
|
504 else if (isSel == true) |
|
505 testStates(cell, STATE_SELECTED); |
|
506 else |
|
507 testStates(cell, STATE_SELECTABLE, 0, STATE_SELECTED); |
|
508 } |
|
509 } |
|
510 } |
|
511 |
|
512 /** |
|
513 * Test unselectColumn method of accessible table. |
|
514 */ |
|
515 function testUnselectTableColumn(aIdentifier, aColIdx, aCellsArray) |
|
516 { |
|
517 var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); |
|
518 if (!acc) |
|
519 return; |
|
520 |
|
521 var rowCount = aCellsArray.length; |
|
522 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
523 var cellState = aCellsArray[rowIdx][aColIdx]; |
|
524 // Unselect origin cell. |
|
525 var [origRowIdx, origColIdx] = |
|
526 getOrigRowAndColumn(aCellsArray, rowIdx, aColIdx); |
|
527 aCellsArray[origRowIdx][origColIdx] = false; |
|
528 } |
|
529 |
|
530 acc.unselectColumn(aColIdx); |
|
531 testTableSelection(aIdentifier, aCellsArray, |
|
532 "Unselect " + aColIdx + " column: "); |
|
533 } |
|
534 |
|
535 /** |
|
536 * Test selectColumn method of accessible table. |
|
537 */ |
|
538 function testSelectTableColumn(aIdentifier, aColIdx, aCellsArray) |
|
539 { |
|
540 var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); |
|
541 if (!acc) |
|
542 return; |
|
543 |
|
544 var rowCount = aCellsArray.length; |
|
545 var colsCount = aCellsArray[0].length; |
|
546 |
|
547 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
548 for (var colIdx = 0; colIdx < colsCount; colIdx++) { |
|
549 var cellState = aCellsArray[rowIdx][colIdx]; |
|
550 |
|
551 if (colIdx == aColIdx) { // select target column |
|
552 if (!(cellState & kSpanned)) { |
|
553 // Select the cell if it is origin. |
|
554 aCellsArray[rowIdx][colIdx] = true; |
|
555 |
|
556 } else { |
|
557 // If the cell is spanned then search origin cell and select it. |
|
558 var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray, |
|
559 rowIdx, colIdx); |
|
560 aCellsArray[origRowIdx][origColIdx] = true; |
|
561 } |
|
562 |
|
563 } else if (!(cellState & kSpanned)) { // unselect other columns |
|
564 if (colIdx > aColIdx) { |
|
565 // Unselect the cell if traversed column index is greater than column |
|
566 // index of target cell. |
|
567 aCellsArray[rowIdx][colIdx] = false; |
|
568 |
|
569 } else if (!(aCellsArray[rowIdx][aColIdx] & kColSpanned)) { |
|
570 // Unselect the cell if the target cell is not row spanned. |
|
571 aCellsArray[rowIdx][colIdx] = false; |
|
572 |
|
573 } else { |
|
574 // Unselect the cell if it is not spanned to the target cell. |
|
575 for (var spannedColIdx = colIdx + 1; spannedColIdx < aColIdx; |
|
576 spannedColIdx++) { |
|
577 var spannedCellState = aCellsArray[rowIdx][spannedColIdx]; |
|
578 if (!(spannedCellState & kRowSpanned)) { |
|
579 aCellsArray[rowIdx][colIdx] = false; |
|
580 break; |
|
581 } |
|
582 } |
|
583 } |
|
584 } |
|
585 } |
|
586 } |
|
587 |
|
588 acc.selectColumn(aColIdx); |
|
589 testTableSelection(aIdentifier, aCellsArray, |
|
590 "Select " + aColIdx + " column: "); |
|
591 } |
|
592 |
|
593 /** |
|
594 * Test unselectRow method of accessible table. |
|
595 */ |
|
596 function testUnselectTableRow(aIdentifier, aRowIdx, aCellsArray) |
|
597 { |
|
598 var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); |
|
599 if (!acc) |
|
600 return; |
|
601 |
|
602 var colsCount = aCellsArray[0].length; |
|
603 for (var colIdx = 0; colIdx < colsCount; colIdx++) { |
|
604 // Unselect origin cell. |
|
605 var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray, |
|
606 aRowIdx, colIdx); |
|
607 aCellsArray[origRowIdx][origColIdx] = false; |
|
608 } |
|
609 |
|
610 acc.unselectRow(aRowIdx); |
|
611 testTableSelection(aIdentifier, aCellsArray, |
|
612 "Unselect " + aRowIdx + " row: "); |
|
613 } |
|
614 |
|
615 /** |
|
616 * Test selectRow method of accessible table. |
|
617 */ |
|
618 function testSelectTableRow(aIdentifier, aRowIdx, aCellsArray) |
|
619 { |
|
620 var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); |
|
621 if (!acc) |
|
622 return; |
|
623 |
|
624 var rowCount = aCellsArray.length; |
|
625 var colsCount = aCellsArray[0].length; |
|
626 |
|
627 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { |
|
628 for (var colIdx = 0; colIdx < colsCount; colIdx++) { |
|
629 var cellState = aCellsArray[rowIdx][colIdx]; |
|
630 |
|
631 if (rowIdx == aRowIdx) { // select the given row |
|
632 if (!(cellState & kSpanned)) { |
|
633 // Select the cell if it is origin. |
|
634 aCellsArray[rowIdx][colIdx] = true; |
|
635 |
|
636 } else { |
|
637 // If the cell is spanned then search origin cell and select it. |
|
638 var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray, |
|
639 rowIdx, colIdx); |
|
640 |
|
641 aCellsArray[origRowIdx][origColIdx] = true; |
|
642 } |
|
643 |
|
644 } else if (!(cellState & kSpanned)) { // unselect other rows |
|
645 if (rowIdx > aRowIdx) { |
|
646 // Unselect the cell if traversed row index is greater than row |
|
647 // index of target cell. |
|
648 aCellsArray[rowIdx][colIdx] = false; |
|
649 |
|
650 } else if (!(aCellsArray[aRowIdx][colIdx] & kRowSpanned)) { |
|
651 // Unselect the cell if the target cell is not row spanned. |
|
652 aCellsArray[rowIdx][colIdx] = false; |
|
653 |
|
654 } else { |
|
655 // Unselect the cell if it is not spanned to the target cell. |
|
656 for (var spannedRowIdx = rowIdx + 1; spannedRowIdx < aRowIdx; |
|
657 spannedRowIdx++) { |
|
658 var spannedCellState = aCellsArray[spannedRowIdx][colIdx]; |
|
659 if (!(spannedCellState & kRowSpanned)) { |
|
660 aCellsArray[rowIdx][colIdx] = false; |
|
661 break; |
|
662 } |
|
663 } |
|
664 } |
|
665 } |
|
666 } |
|
667 } |
|
668 |
|
669 acc.selectRow(aRowIdx); |
|
670 testTableSelection(aIdentifier, aCellsArray, |
|
671 "Select " + aRowIdx + " row: "); |
|
672 } |
|
673 |
|
674 /** |
|
675 * Test columnHeaderCells and rowHeaderCells of accessible table. |
|
676 */ |
|
677 function testHeaderCells(aHeaderInfoMap) |
|
678 { |
|
679 for (var testIdx = 0; testIdx < aHeaderInfoMap.length; testIdx++) { |
|
680 var dataCellIdentifier = aHeaderInfoMap[testIdx].cell; |
|
681 var dataCell = getAccessible(dataCellIdentifier, [nsIAccessibleTableCell]); |
|
682 |
|
683 // row header cells |
|
684 var rowHeaderCells = aHeaderInfoMap[testIdx].rowHeaderCells; |
|
685 var rowHeaderCellsCount = rowHeaderCells.length; |
|
686 var actualRowHeaderCells = dataCell.rowHeaderCells; |
|
687 var actualRowHeaderCellsCount = actualRowHeaderCells.length; |
|
688 |
|
689 is(actualRowHeaderCellsCount, rowHeaderCellsCount, |
|
690 "Wrong number of row header cells for the cell " + |
|
691 prettyName(dataCellIdentifier)); |
|
692 |
|
693 if (actualRowHeaderCellsCount == rowHeaderCellsCount) { |
|
694 for (var idx = 0; idx < rowHeaderCellsCount; idx++) { |
|
695 var rowHeaderCell = getAccessible(rowHeaderCells[idx]); |
|
696 var actualRowHeaderCell = |
|
697 actualRowHeaderCells.queryElementAt(idx, nsIAccessible); |
|
698 ok(actualRowHeaderCell, rowHeaderCell, |
|
699 "Wrong row header cell at index " + idx + " for the cell " + |
|
700 prettyName(rowHeaderCells[idx])); |
|
701 } |
|
702 } |
|
703 |
|
704 // column header cells |
|
705 var colHeaderCells = aHeaderInfoMap[testIdx].columnHeaderCells; |
|
706 var colHeaderCellsCount = colHeaderCells.length; |
|
707 var actualColHeaderCells = dataCell.columnHeaderCells; |
|
708 var actualColHeaderCellsCount = actualColHeaderCells.length; |
|
709 |
|
710 is(actualColHeaderCellsCount, colHeaderCellsCount, |
|
711 "Wrong number of column header cells for the cell " + |
|
712 prettyName(dataCellIdentifier)); |
|
713 |
|
714 if (actualColHeaderCellsCount == colHeaderCellsCount) { |
|
715 for (var idx = 0; idx < colHeaderCellsCount; idx++) { |
|
716 var colHeaderCell = getAccessible(colHeaderCells[idx]); |
|
717 var actualColHeaderCell = |
|
718 actualColHeaderCells.queryElementAt(idx, nsIAccessible); |
|
719 ok(actualColHeaderCell, colHeaderCell, |
|
720 "Wrong column header cell at index " + idx + " for the cell " + |
|
721 prettyName(colHeaderCells[idx])); |
|
722 } |
|
723 } |
|
724 } |
|
725 } |
|
726 |
|
727 //////////////////////////////////////////////////////////////////////////////// |
|
728 // private implementation |
|
729 |
|
730 /** |
|
731 * Return row and column of orig cell for the given spanned cell. |
|
732 */ |
|
733 function getOrigRowAndColumn(aCellsArray, aRowIdx, aColIdx) |
|
734 { |
|
735 var cellState = aCellsArray[aRowIdx][aColIdx]; |
|
736 |
|
737 var origRowIdx = aRowIdx, origColIdx = aColIdx; |
|
738 if (cellState & kRowSpanned) { |
|
739 for (var prevRowIdx = aRowIdx - 1; prevRowIdx >= 0; prevRowIdx--) { |
|
740 var prevCellState = aCellsArray[prevRowIdx][aColIdx]; |
|
741 if (!(prevCellState & kRowSpanned)) { |
|
742 origRowIdx = prevRowIdx; |
|
743 break; |
|
744 } |
|
745 } |
|
746 } |
|
747 |
|
748 if (cellState & kColSpanned) { |
|
749 for (var prevColIdx = aColIdx - 1; prevColIdx >= 0; prevColIdx--) { |
|
750 var prevCellState = aCellsArray[aRowIdx][prevColIdx]; |
|
751 if (!(prevCellState & kColSpanned)) { |
|
752 origColIdx = prevColIdx; |
|
753 break; |
|
754 } |
|
755 } |
|
756 } |
|
757 |
|
758 return [origRowIdx, origColIdx]; |
|
759 } |