1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/tests/mochitest/table.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,759 @@ 1.4 +/** 1.5 + * This file provides set of helper functions to test nsIAccessibleTable 1.6 + * interface. 1.7 + * 1.8 + * Required: 1.9 + * common.js 1.10 + * role.js 1.11 + * states.js 1.12 + */ 1.13 + 1.14 +/** 1.15 + * Constants used to describe cells array. 1.16 + */ 1.17 +const kDataCell = 1; // Indicates the cell is origin data cell 1.18 +const kRowHeaderCell = 2; // Indicates the cell is row header cell 1.19 +const kColHeaderCell = 4; // Indicated the cell is column header cell 1.20 +const kOrigin = kDataCell | kRowHeaderCell | kColHeaderCell; 1.21 + 1.22 +const kRowSpanned = 8; // Indicates the cell is not origin and row spanned 1.23 +const kColSpanned = 16; // Indicates the cell is not origin and column spanned 1.24 +const kSpanned = kRowSpanned | kColSpanned; 1.25 + 1.26 +/** 1.27 + * Constants to define column header type. 1.28 + */ 1.29 +const kNoColumnHeader = 0; 1.30 +const kListboxColumnHeader = 1; 1.31 +const kTreeColumnHeader = 2; 1.32 + 1.33 +/** 1.34 + * Test table structure and related methods. 1.35 + * 1.36 + * @param aIdentifier [in] table accessible identifier 1.37 + * @param aCellsArray [in] two dimensional array (row X columns) of 1.38 + * cell types (see constants defined above). 1.39 + * @param aColHeaderType [in] specifies wether column header cells are 1.40 + * arranged into the list. 1.41 + * @param aCaption [in] caption text if any 1.42 + * @param aSummary [in] summary text if any 1.43 + * @param aIsTreeTable [in] specifies whether given table is tree table 1.44 + */ 1.45 +function testTableStruct(aIdentifier, aCellsArray, aColHeaderType, 1.46 + aCaption, aSummary, aIsTreeTable) 1.47 +{ 1.48 + var tableNode = getNode(aIdentifier); 1.49 + var isGrid = tableNode.getAttribute("role") == "grid" || 1.50 + tableNode.getAttribute("role") == "treegrid" || 1.51 + tableNode.localName == "tree"; 1.52 + 1.53 + var rowCount = aCellsArray.length; 1.54 + var colsCount = aCellsArray[0] ? aCellsArray[0].length : 0; 1.55 + 1.56 + // Test table accessible tree. 1.57 + var tableObj = { 1.58 + role: aIsTreeTable ? ROLE_TREE_TABLE : ROLE_TABLE, 1.59 + children: [] 1.60 + }; 1.61 + 1.62 + // caption accessible handling 1.63 + if (aCaption) { 1.64 + var captionObj = { 1.65 + role: ROLE_CAPTION, 1.66 + children: [ 1.67 + { 1.68 + role: ROLE_TEXT_LEAF, 1.69 + name: aCaption 1.70 + } 1.71 + ] 1.72 + }; 1.73 + 1.74 + tableObj.children.push(captionObj); 1.75 + } 1.76 + 1.77 + // special types of column headers handling 1.78 + if (aColHeaderType) { 1.79 + var headersObj = { 1.80 + role: ROLE_LIST, 1.81 + children: [] 1.82 + }; 1.83 + 1.84 + for (var idx = 0; idx < colsCount; idx++) { 1.85 + var headerCellObj = { 1.86 + role: ROLE_COLUMNHEADER 1.87 + }; 1.88 + headersObj.children.push(headerCellObj); 1.89 + } 1.90 + 1.91 + if (aColHeaderType == kTreeColumnHeader) { 1.92 + var columnPickerObj = { 1.93 + role: ROLE_PUSHBUTTON 1.94 + }; 1.95 + 1.96 + headersObj.children.push(columnPickerObj); 1.97 + } 1.98 + 1.99 + tableObj.children.push(headersObj); 1.100 + } 1.101 + 1.102 + // rows and cells accessibles 1.103 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.104 + var rowObj = { 1.105 + role: ROLE_ROW, 1.106 + children: [] 1.107 + }; 1.108 + 1.109 + for (var colIdx = 0; colIdx < colsCount; colIdx++) { 1.110 + var celltype = aCellsArray[rowIdx][colIdx]; 1.111 + 1.112 + var role = ROLE_NOTHING; 1.113 + switch (celltype) { 1.114 + case kDataCell: 1.115 + role = (isGrid ? ROLE_GRID_CELL : ROLE_CELL); 1.116 + break; 1.117 + case kRowHeaderCell: 1.118 + role = ROLE_ROWHEADER; 1.119 + break; 1.120 + case kColHeaderCell: 1.121 + role = ROLE_COLUMNHEADER; 1.122 + break; 1.123 + } 1.124 + 1.125 + if (role != ROLE_NOTHING) { 1.126 + var cellObj = { 1.127 + role: role 1.128 + }; 1.129 + rowObj.children.push(cellObj); 1.130 + } 1.131 + } 1.132 + 1.133 + tableObj.children.push(rowObj); 1.134 + } 1.135 + 1.136 + testAccessibleTree(aIdentifier, tableObj); 1.137 + 1.138 + // Test table table interface. 1.139 + var table = getAccessible(aIdentifier, [nsIAccessibleTable]); 1.140 + 1.141 + // summary 1.142 + if (aSummary) 1.143 + is(table.summary, aSummary, 1.144 + "Wrong summary of the table " + prettyName(aIdentifier)); 1.145 + 1.146 + // rowCount and columnCount 1.147 + is(table.rowCount, rowCount, 1.148 + "Wrong rows count of " + prettyName(aIdentifier)); 1.149 + is(table.columnCount, colsCount, 1.150 + "Wrong columns count of " + prettyName(aIdentifier)); 1.151 + 1.152 + // rows and columns extents 1.153 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.154 + for (var colIdx = 0; colIdx < colsCount; colIdx++) { 1.155 + var celltype = aCellsArray[rowIdx][colIdx]; 1.156 + if (celltype & kOrigin) { 1.157 + 1.158 + // table getRowExtentAt 1.159 + var rowExtent = table.getRowExtentAt(rowIdx, colIdx); 1.160 + for (var idx = rowIdx + 1; 1.161 + idx < rowCount && (aCellsArray[idx][colIdx] & kRowSpanned); 1.162 + idx++); 1.163 + 1.164 + var expectedRowExtent = idx - rowIdx; 1.165 + is(rowExtent, expectedRowExtent, 1.166 + "getRowExtentAt: Wrong number of spanned rows at (" + rowIdx + ", " + 1.167 + colIdx + ") for " + prettyName(aIdentifier)); 1.168 + 1.169 + // table getColumnExtentAt 1.170 + var colExtent = table.getColumnExtentAt(rowIdx, colIdx); 1.171 + for (var idx = colIdx + 1; 1.172 + idx < colsCount && (aCellsArray[rowIdx][idx] & kColSpanned); 1.173 + idx++); 1.174 + 1.175 + var expectedColExtent = idx - colIdx; 1.176 + is(colExtent, expectedColExtent, 1.177 + "getColumnExtentAt: Wrong number of spanned columns at (" + rowIdx + 1.178 + ", " + colIdx + ") for " + prettyName(aIdentifier)); 1.179 + 1.180 + // cell rowExtent and columnExtent 1.181 + var cell = getAccessible(table.getCellAt(rowIdx, colIdx), 1.182 + [nsIAccessibleTableCell]); 1.183 + 1.184 + is(cell.rowExtent, expectedRowExtent, 1.185 + "rowExtent: Wrong number of spanned rows at (" + rowIdx + ", " + 1.186 + colIdx + ") for " + prettyName(aIdentifier)); 1.187 + 1.188 + is(cell.columnExtent, expectedColExtent, 1.189 + "columnExtent: Wrong number of spanned column at (" + rowIdx + ", " + 1.190 + colIdx + ") for " + prettyName(aIdentifier)); 1.191 + } 1.192 + } 1.193 + } 1.194 +} 1.195 + 1.196 +/** 1.197 + * Test table indexes. 1.198 + * 1.199 + * @param aIdentifier [in] table accessible identifier 1.200 + * @param aIdxes [in] two dimensional array of cell indexes 1.201 + */ 1.202 +function testTableIndexes(aIdentifier, aIdxes) 1.203 +{ 1.204 + var tableAcc = getAccessible(aIdentifier, [nsIAccessibleTable]); 1.205 + if (!tableAcc) 1.206 + return; 1.207 + 1.208 + var obtainedRowIdx, obtainedColIdx, obtainedIdx; 1.209 + var cellAcc; 1.210 + 1.211 + var id = prettyName(aIdentifier); 1.212 + 1.213 + var rowCount = aIdxes.length; 1.214 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.215 + var colCount = aIdxes[rowIdx].length; 1.216 + for (var colIdx = 0; colIdx < colCount; colIdx++) { 1.217 + var idx = aIdxes[rowIdx][colIdx]; 1.218 + 1.219 + // getCellAt 1.220 + try { 1.221 + cellAcc = null; 1.222 + cellAcc = tableAcc.getCellAt(rowIdx, colIdx); 1.223 + } catch (e) { } 1.224 + 1.225 + ok(idx != -1 && cellAcc || idx == -1 && !cellAcc, 1.226 + id + ": Can't get cell accessible at row = " + rowIdx + ", column = " + colIdx); 1.227 + 1.228 + if (idx != - 1) { 1.229 + 1.230 + // getRowIndexAt 1.231 + var origRowIdx = rowIdx; 1.232 + while (origRowIdx > 0 && 1.233 + aIdxes[rowIdx][colIdx] == aIdxes[origRowIdx - 1][colIdx]) 1.234 + origRowIdx--; 1.235 + 1.236 + try { 1.237 + obtainedRowIdx = tableAcc.getRowIndexAt(idx); 1.238 + } catch (e) { 1.239 + ok(false, id + ": can't get row index for cell index " + idx + "," + e); 1.240 + } 1.241 + 1.242 + is(obtainedRowIdx, origRowIdx, 1.243 + id + ": row for index " + idx + " is not correct (getRowIndexAt)"); 1.244 + 1.245 + // getColumnIndexAt 1.246 + var origColIdx = colIdx; 1.247 + while (origColIdx > 0 && 1.248 + aIdxes[rowIdx][colIdx] == aIdxes[rowIdx][origColIdx - 1]) 1.249 + origColIdx--; 1.250 + 1.251 + try { 1.252 + obtainedColIdx = tableAcc.getColumnIndexAt(idx); 1.253 + } catch (e) { 1.254 + ok(false, id + ": can't get column index for cell index " + idx + "," + e); 1.255 + } 1.256 + 1.257 + is(obtainedColIdx, origColIdx, 1.258 + id + ": column for index " + idx + " is not correct (getColumnIndexAt)"); 1.259 + 1.260 + // getRowAndColumnIndicesAt 1.261 + var obtainedRowIdxObj = { }, obtainedColIdxObj = { }; 1.262 + try { 1.263 + tableAcc.getRowAndColumnIndicesAt(idx, obtainedRowIdxObj, 1.264 + obtainedColIdxObj); 1.265 + } catch (e) { 1.266 + ok(false, id + ": can't get row and column indices for cell index " + idx + "," + e); 1.267 + } 1.268 + 1.269 + is(obtainedRowIdxObj.value, origRowIdx, 1.270 + id + ": row for index " + idx + " is not correct (getRowAndColumnIndicesAt)"); 1.271 + is(obtainedColIdxObj.value, origColIdx, 1.272 + id + ": column for index " + idx + " is not correct (getRowAndColumnIndicesAt)"); 1.273 + 1.274 + if (cellAcc) { 1.275 + 1.276 + var cellId = prettyName(cellAcc); 1.277 + cellAcc = getAccessible(cellAcc, [nsIAccessibleTableCell]); 1.278 + 1.279 + // cell: 'table-cell-index' attribute 1.280 + var attrs = cellAcc.attributes; 1.281 + var strIdx = ""; 1.282 + try { 1.283 + strIdx = attrs.getStringProperty("table-cell-index"); 1.284 + } catch (e) { 1.285 + ok(false, 1.286 + cellId + ": no cell index from object attributes on the cell accessible at index " + idx + "."); 1.287 + } 1.288 + 1.289 + if (strIdx) { 1.290 + is (parseInt(strIdx), idx, 1.291 + cellId + ": cell index from object attributes of cell accessible isn't corrent."); 1.292 + } 1.293 + 1.294 + // cell: table 1.295 + try { 1.296 + is(cellAcc.table, tableAcc, 1.297 + cellId + ": wrong table accessible for the cell."); 1.298 + 1.299 + } catch (e) { 1.300 + ok(false, 1.301 + cellId + ": can't get table accessible from the cell."); 1.302 + } 1.303 + 1.304 + // cell: getRowIndex 1.305 + try { 1.306 + obtainedRowIdx = cellAcc.rowIndex; 1.307 + } catch (e) { 1.308 + ok(false, 1.309 + cellId + ": can't get row index of the cell at index " + idx + "," + e); 1.310 + } 1.311 + 1.312 + is(obtainedRowIdx, origRowIdx, 1.313 + cellId + ": row for the cell at index " + idx +" is not correct"); 1.314 + 1.315 + // cell: getColumnIndex 1.316 + try { 1.317 + obtainedColIdx = cellAcc.columnIndex; 1.318 + } catch (e) { 1.319 + ok(false, 1.320 + cellId + ": can't get column index of the cell at index " + idx + "," + e); 1.321 + } 1.322 + 1.323 + is(obtainedColIdx, origColIdx, 1.324 + id + ": column for the cell at index " + idx +" is not correct"); 1.325 + } 1.326 + } 1.327 + 1.328 + // getCellIndexAt 1.329 + try { 1.330 + obtainedIdx = tableAcc.getCellIndexAt(rowIdx, colIdx); 1.331 + } catch (e) { 1.332 + obtainedIdx = -1; 1.333 + } 1.334 + 1.335 + is(obtainedIdx, idx, 1.336 + id + ": row " + rowIdx + " /column " + colIdx + " and index " + obtainedIdx + " aren't inconsistent."); 1.337 + } 1.338 + } 1.339 +} 1.340 + 1.341 +/** 1.342 + * Test table getters selection methods. 1.343 + * 1.344 + * @param aIdentifier [in] table accessible identifier 1.345 + * @param aCellsArray [in] two dimensional array (row X columns) of cells 1.346 + * states (either boolean (selected/unselected) if cell is 1.347 + * origin, otherwise kRowSpanned or kColSpanned constant). 1.348 + * @param aMsg [in] text appended before every message 1.349 + */ 1.350 +function testTableSelection(aIdentifier, aCellsArray, aMsg) 1.351 +{ 1.352 + var msg = aMsg ? aMsg : ""; 1.353 + var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); 1.354 + if (!acc) 1.355 + return; 1.356 + 1.357 + var rowCount = aCellsArray.length; 1.358 + var colsCount = aCellsArray[0].length; 1.359 + 1.360 + // Columns selection tests. 1.361 + var selCols = new Array(); 1.362 + 1.363 + // isColumnSelected test 1.364 + for (var colIdx = 0; colIdx < colsCount; colIdx++) { 1.365 + var isColSelected = true; 1.366 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.367 + if (aCellsArray[rowIdx][colIdx] == false || 1.368 + aCellsArray[rowIdx][colIdx] == undefined) { 1.369 + isColSelected = false; 1.370 + break; 1.371 + } 1.372 + } 1.373 + 1.374 + is(acc.isColumnSelected(colIdx), isColSelected, 1.375 + msg + "Wrong selection state of " + colIdx + " column for " + 1.376 + prettyName(aIdentifier)); 1.377 + 1.378 + if (isColSelected) 1.379 + selCols.push(colIdx); 1.380 + } 1.381 + 1.382 + // selectedColsCount test 1.383 + is(acc.selectedColumnCount, selCols.length, 1.384 + msg + "Wrong count of selected columns for " + prettyName(aIdentifier)); 1.385 + 1.386 + // getSelectedColumns test 1.387 + var actualSelColsCountObj = { value: null }; 1.388 + var actualSelCols = acc.getSelectedColumnIndices(actualSelColsCountObj); 1.389 + 1.390 + var actualSelColsCount = actualSelColsCountObj.value; 1.391 + is (actualSelColsCount, selCols.length, 1.392 + msg + "Wrong count of selected columns for " + prettyName(aIdentifier) + 1.393 + "from getSelectedColumns."); 1.394 + 1.395 + for (var i = 0; i < actualSelColsCount; i++) { 1.396 + is (actualSelCols[i], selCols[i], 1.397 + msg + "Column at index " + selCols[i] + " should be selected."); 1.398 + } 1.399 + 1.400 + // Rows selection tests. 1.401 + var selRows = new Array(); 1.402 + 1.403 + // isRowSelected test 1.404 + var selrowCount = 0; 1.405 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.406 + var isRowSelected = true; 1.407 + for (var colIdx = 0; colIdx < colsCount; colIdx++) { 1.408 + if (aCellsArray[rowIdx][colIdx] == false || 1.409 + aCellsArray[rowIdx][colIdx] == undefined) { 1.410 + isRowSelected = false; 1.411 + break; 1.412 + } 1.413 + } 1.414 + 1.415 + is(acc.isRowSelected(rowIdx), isRowSelected, 1.416 + msg + "Wrong selection state of " + rowIdx + " row for " + 1.417 + prettyName(aIdentifier)); 1.418 + 1.419 + if (isRowSelected) 1.420 + selRows.push(rowIdx); 1.421 + } 1.422 + 1.423 + // selectedRowCount test 1.424 + is(acc.selectedRowCount, selRows.length, 1.425 + msg + "Wrong count of selected rows for " + prettyName(aIdentifier)); 1.426 + 1.427 + // getSelectedRows test 1.428 + var actualSelrowCountObj = { value: null }; 1.429 + var actualSelRows = acc.getSelectedRowIndices(actualSelrowCountObj); 1.430 + 1.431 + var actualSelrowCount = actualSelrowCountObj.value; 1.432 + is (actualSelrowCount, selRows.length, 1.433 + msg + "Wrong count of selected rows for " + prettyName(aIdentifier) + 1.434 + "from getSelectedRows."); 1.435 + 1.436 + for (var i = 0; i < actualSelrowCount; i++) { 1.437 + is (actualSelRows[i], selRows[i], 1.438 + msg + "Row at index " + selRows[i] + " should be selected."); 1.439 + } 1.440 + 1.441 + // Cells selection tests. 1.442 + var selCells = new Array(); 1.443 + 1.444 + // isCellSelected test 1.445 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.446 + for (var colIdx = 0; colIdx < colsCount; colIdx++) { 1.447 + if (aCellsArray[rowIdx][colIdx] & kSpanned) 1.448 + continue; 1.449 + 1.450 + var isSelected = aCellsArray[rowIdx][colIdx] == true; 1.451 + is(acc.isCellSelected(rowIdx, colIdx), isSelected, 1.452 + msg + "Wrong selection state of cell at " + rowIdx + " row and " + 1.453 + colIdx + " column for " + prettyName(aIdentifier)); 1.454 + 1.455 + if (aCellsArray[rowIdx][colIdx]) 1.456 + selCells.push(acc.getCellIndexAt(rowIdx, colIdx)); 1.457 + } 1.458 + } 1.459 + 1.460 + // selectedCellCount tests 1.461 + is(acc.selectedCellCount, selCells.length, 1.462 + msg + "Wrong count of selected cells for " + prettyName(aIdentifier)); 1.463 + 1.464 + // getSelectedCellIndices test 1.465 + var actualSelCellsCountObj = { value: null }; 1.466 + var actualSelCells = acc.getSelectedCellIndices(actualSelCellsCountObj); 1.467 + 1.468 + var actualSelCellsCount = actualSelCellsCountObj.value; 1.469 + is(actualSelCellsCount, selCells.length, 1.470 + msg + "Wrong count of selected cells for " + prettyName(aIdentifier) + 1.471 + "from getSelectedCells."); 1.472 + 1.473 + for (var i = 0; i < actualSelCellsCount; i++) { 1.474 + is(actualSelCells[i], selCells[i], 1.475 + msg + "getSelectedCellIndices: Cell at index " + selCells[i] + 1.476 + " should be selected."); 1.477 + } 1.478 + 1.479 + // selectedCells and isSelected tests 1.480 + var actualSelCellsArray = acc.selectedCells; 1.481 + for (var i = 0; i < actualSelCellsCount; i++) { 1.482 + var actualSelCellAccessible = 1.483 + actualSelCellsArray.queryElementAt(i, nsIAccessibleTableCell); 1.484 + 1.485 + var colIdx = acc.getColumnIndexAt(selCells[i]); 1.486 + var rowIdx = acc.getRowIndexAt(selCells[i]); 1.487 + var expectedSelCellAccessible = acc.getCellAt(rowIdx, colIdx); 1.488 + 1.489 + ok(actualSelCellAccessible, expectedSelCellAccessible, 1.490 + msg + "getSelectedCells: Cell at index " + selCells[i] + 1.491 + " should be selected."); 1.492 + 1.493 + ok(actualSelCellAccessible.isSelected(), 1.494 + "isSelected: Cell at index " + selCells[i] + " should be selected."); 1.495 + } 1.496 + 1.497 + // selected states tests 1.498 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.499 + for (var colIdx = 0; colIdx < colsCount; colIdx++) { 1.500 + if (aCellsArray[rowIdx][colIdx] & kSpanned) 1.501 + continue; 1.502 + 1.503 + var cell = acc.getCellAt(rowIdx, colIdx); 1.504 + var isSel = aCellsArray[rowIdx][colIdx]; 1.505 + if (isSel == undefined) 1.506 + testStates(cell, 0, 0, STATE_SELECTABLE | STATE_SELECTED); 1.507 + else if (isSel == true) 1.508 + testStates(cell, STATE_SELECTED); 1.509 + else 1.510 + testStates(cell, STATE_SELECTABLE, 0, STATE_SELECTED); 1.511 + } 1.512 + } 1.513 +} 1.514 + 1.515 +/** 1.516 + * Test unselectColumn method of accessible table. 1.517 + */ 1.518 +function testUnselectTableColumn(aIdentifier, aColIdx, aCellsArray) 1.519 +{ 1.520 + var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); 1.521 + if (!acc) 1.522 + return; 1.523 + 1.524 + var rowCount = aCellsArray.length; 1.525 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.526 + var cellState = aCellsArray[rowIdx][aColIdx]; 1.527 + // Unselect origin cell. 1.528 + var [origRowIdx, origColIdx] = 1.529 + getOrigRowAndColumn(aCellsArray, rowIdx, aColIdx); 1.530 + aCellsArray[origRowIdx][origColIdx] = false; 1.531 + } 1.532 + 1.533 + acc.unselectColumn(aColIdx); 1.534 + testTableSelection(aIdentifier, aCellsArray, 1.535 + "Unselect " + aColIdx + " column: "); 1.536 +} 1.537 + 1.538 +/** 1.539 + * Test selectColumn method of accessible table. 1.540 + */ 1.541 +function testSelectTableColumn(aIdentifier, aColIdx, aCellsArray) 1.542 +{ 1.543 + var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); 1.544 + if (!acc) 1.545 + return; 1.546 + 1.547 + var rowCount = aCellsArray.length; 1.548 + var colsCount = aCellsArray[0].length; 1.549 + 1.550 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.551 + for (var colIdx = 0; colIdx < colsCount; colIdx++) { 1.552 + var cellState = aCellsArray[rowIdx][colIdx]; 1.553 + 1.554 + if (colIdx == aColIdx) { // select target column 1.555 + if (!(cellState & kSpanned)) { 1.556 + // Select the cell if it is origin. 1.557 + aCellsArray[rowIdx][colIdx] = true; 1.558 + 1.559 + } else { 1.560 + // If the cell is spanned then search origin cell and select it. 1.561 + var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray, 1.562 + rowIdx, colIdx); 1.563 + aCellsArray[origRowIdx][origColIdx] = true; 1.564 + } 1.565 + 1.566 + } else if (!(cellState & kSpanned)) { // unselect other columns 1.567 + if (colIdx > aColIdx) { 1.568 + // Unselect the cell if traversed column index is greater than column 1.569 + // index of target cell. 1.570 + aCellsArray[rowIdx][colIdx] = false; 1.571 + 1.572 + } else if (!(aCellsArray[rowIdx][aColIdx] & kColSpanned)) { 1.573 + // Unselect the cell if the target cell is not row spanned. 1.574 + aCellsArray[rowIdx][colIdx] = false; 1.575 + 1.576 + } else { 1.577 + // Unselect the cell if it is not spanned to the target cell. 1.578 + for (var spannedColIdx = colIdx + 1; spannedColIdx < aColIdx; 1.579 + spannedColIdx++) { 1.580 + var spannedCellState = aCellsArray[rowIdx][spannedColIdx]; 1.581 + if (!(spannedCellState & kRowSpanned)) { 1.582 + aCellsArray[rowIdx][colIdx] = false; 1.583 + break; 1.584 + } 1.585 + } 1.586 + } 1.587 + } 1.588 + } 1.589 + } 1.590 + 1.591 + acc.selectColumn(aColIdx); 1.592 + testTableSelection(aIdentifier, aCellsArray, 1.593 + "Select " + aColIdx + " column: "); 1.594 +} 1.595 + 1.596 +/** 1.597 + * Test unselectRow method of accessible table. 1.598 + */ 1.599 +function testUnselectTableRow(aIdentifier, aRowIdx, aCellsArray) 1.600 +{ 1.601 + var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); 1.602 + if (!acc) 1.603 + return; 1.604 + 1.605 + var colsCount = aCellsArray[0].length; 1.606 + for (var colIdx = 0; colIdx < colsCount; colIdx++) { 1.607 + // Unselect origin cell. 1.608 + var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray, 1.609 + aRowIdx, colIdx); 1.610 + aCellsArray[origRowIdx][origColIdx] = false; 1.611 + } 1.612 + 1.613 + acc.unselectRow(aRowIdx); 1.614 + testTableSelection(aIdentifier, aCellsArray, 1.615 + "Unselect " + aRowIdx + " row: "); 1.616 +} 1.617 + 1.618 +/** 1.619 + * Test selectRow method of accessible table. 1.620 + */ 1.621 +function testSelectTableRow(aIdentifier, aRowIdx, aCellsArray) 1.622 +{ 1.623 + var acc = getAccessible(aIdentifier, [nsIAccessibleTable]); 1.624 + if (!acc) 1.625 + return; 1.626 + 1.627 + var rowCount = aCellsArray.length; 1.628 + var colsCount = aCellsArray[0].length; 1.629 + 1.630 + for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) { 1.631 + for (var colIdx = 0; colIdx < colsCount; colIdx++) { 1.632 + var cellState = aCellsArray[rowIdx][colIdx]; 1.633 + 1.634 + if (rowIdx == aRowIdx) { // select the given row 1.635 + if (!(cellState & kSpanned)) { 1.636 + // Select the cell if it is origin. 1.637 + aCellsArray[rowIdx][colIdx] = true; 1.638 + 1.639 + } else { 1.640 + // If the cell is spanned then search origin cell and select it. 1.641 + var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray, 1.642 + rowIdx, colIdx); 1.643 + 1.644 + aCellsArray[origRowIdx][origColIdx] = true; 1.645 + } 1.646 + 1.647 + } else if (!(cellState & kSpanned)) { // unselect other rows 1.648 + if (rowIdx > aRowIdx) { 1.649 + // Unselect the cell if traversed row index is greater than row 1.650 + // index of target cell. 1.651 + aCellsArray[rowIdx][colIdx] = false; 1.652 + 1.653 + } else if (!(aCellsArray[aRowIdx][colIdx] & kRowSpanned)) { 1.654 + // Unselect the cell if the target cell is not row spanned. 1.655 + aCellsArray[rowIdx][colIdx] = false; 1.656 + 1.657 + } else { 1.658 + // Unselect the cell if it is not spanned to the target cell. 1.659 + for (var spannedRowIdx = rowIdx + 1; spannedRowIdx < aRowIdx; 1.660 + spannedRowIdx++) { 1.661 + var spannedCellState = aCellsArray[spannedRowIdx][colIdx]; 1.662 + if (!(spannedCellState & kRowSpanned)) { 1.663 + aCellsArray[rowIdx][colIdx] = false; 1.664 + break; 1.665 + } 1.666 + } 1.667 + } 1.668 + } 1.669 + } 1.670 + } 1.671 + 1.672 + acc.selectRow(aRowIdx); 1.673 + testTableSelection(aIdentifier, aCellsArray, 1.674 + "Select " + aRowIdx + " row: "); 1.675 +} 1.676 + 1.677 +/** 1.678 + * Test columnHeaderCells and rowHeaderCells of accessible table. 1.679 + */ 1.680 +function testHeaderCells(aHeaderInfoMap) 1.681 +{ 1.682 + for (var testIdx = 0; testIdx < aHeaderInfoMap.length; testIdx++) { 1.683 + var dataCellIdentifier = aHeaderInfoMap[testIdx].cell; 1.684 + var dataCell = getAccessible(dataCellIdentifier, [nsIAccessibleTableCell]); 1.685 + 1.686 + // row header cells 1.687 + var rowHeaderCells = aHeaderInfoMap[testIdx].rowHeaderCells; 1.688 + var rowHeaderCellsCount = rowHeaderCells.length; 1.689 + var actualRowHeaderCells = dataCell.rowHeaderCells; 1.690 + var actualRowHeaderCellsCount = actualRowHeaderCells.length; 1.691 + 1.692 + is(actualRowHeaderCellsCount, rowHeaderCellsCount, 1.693 + "Wrong number of row header cells for the cell " + 1.694 + prettyName(dataCellIdentifier)); 1.695 + 1.696 + if (actualRowHeaderCellsCount == rowHeaderCellsCount) { 1.697 + for (var idx = 0; idx < rowHeaderCellsCount; idx++) { 1.698 + var rowHeaderCell = getAccessible(rowHeaderCells[idx]); 1.699 + var actualRowHeaderCell = 1.700 + actualRowHeaderCells.queryElementAt(idx, nsIAccessible); 1.701 + ok(actualRowHeaderCell, rowHeaderCell, 1.702 + "Wrong row header cell at index " + idx + " for the cell " + 1.703 + prettyName(rowHeaderCells[idx])); 1.704 + } 1.705 + } 1.706 + 1.707 + // column header cells 1.708 + var colHeaderCells = aHeaderInfoMap[testIdx].columnHeaderCells; 1.709 + var colHeaderCellsCount = colHeaderCells.length; 1.710 + var actualColHeaderCells = dataCell.columnHeaderCells; 1.711 + var actualColHeaderCellsCount = actualColHeaderCells.length; 1.712 + 1.713 + is(actualColHeaderCellsCount, colHeaderCellsCount, 1.714 + "Wrong number of column header cells for the cell " + 1.715 + prettyName(dataCellIdentifier)); 1.716 + 1.717 + if (actualColHeaderCellsCount == colHeaderCellsCount) { 1.718 + for (var idx = 0; idx < colHeaderCellsCount; idx++) { 1.719 + var colHeaderCell = getAccessible(colHeaderCells[idx]); 1.720 + var actualColHeaderCell = 1.721 + actualColHeaderCells.queryElementAt(idx, nsIAccessible); 1.722 + ok(actualColHeaderCell, colHeaderCell, 1.723 + "Wrong column header cell at index " + idx + " for the cell " + 1.724 + prettyName(colHeaderCells[idx])); 1.725 + } 1.726 + } 1.727 + } 1.728 +} 1.729 + 1.730 +//////////////////////////////////////////////////////////////////////////////// 1.731 +// private implementation 1.732 + 1.733 +/** 1.734 + * Return row and column of orig cell for the given spanned cell. 1.735 + */ 1.736 +function getOrigRowAndColumn(aCellsArray, aRowIdx, aColIdx) 1.737 +{ 1.738 + var cellState = aCellsArray[aRowIdx][aColIdx]; 1.739 + 1.740 + var origRowIdx = aRowIdx, origColIdx = aColIdx; 1.741 + if (cellState & kRowSpanned) { 1.742 + for (var prevRowIdx = aRowIdx - 1; prevRowIdx >= 0; prevRowIdx--) { 1.743 + var prevCellState = aCellsArray[prevRowIdx][aColIdx]; 1.744 + if (!(prevCellState & kRowSpanned)) { 1.745 + origRowIdx = prevRowIdx; 1.746 + break; 1.747 + } 1.748 + } 1.749 + } 1.750 + 1.751 + if (cellState & kColSpanned) { 1.752 + for (var prevColIdx = aColIdx - 1; prevColIdx >= 0; prevColIdx--) { 1.753 + var prevCellState = aCellsArray[aRowIdx][prevColIdx]; 1.754 + if (!(prevCellState & kColSpanned)) { 1.755 + origColIdx = prevColIdx; 1.756 + break; 1.757 + } 1.758 + } 1.759 + } 1.760 + 1.761 + return [origRowIdx, origColIdx]; 1.762 +}