зеркало из https://github.com/mozilla/gecko-dev.git
1034 строки
26 KiB
JavaScript
1034 строки
26 KiB
JavaScript
/**
|
|
* This file provides set of helper functions to test nsIAccessibleTable
|
|
* interface.
|
|
*
|
|
* Required:
|
|
* common.js
|
|
* role.js
|
|
* states.js
|
|
*/
|
|
/* import-globals-from common.js */
|
|
/* import-globals-from role.js */
|
|
/* import-globals-from states.js */
|
|
|
|
/**
|
|
* Constants used to describe cells array.
|
|
*/
|
|
const kDataCell = 1; // Indicates the cell is origin data cell
|
|
const kRowHeaderCell = 2; // Indicates the cell is row header cell
|
|
const kColHeaderCell = 4; // Indicated the cell is column header cell
|
|
const kOrigin = kDataCell | kRowHeaderCell | kColHeaderCell;
|
|
|
|
const kRowSpanned = 8; // Indicates the cell is not origin and row spanned
|
|
const kColSpanned = 16; // Indicates the cell is not origin and column spanned
|
|
const kSpanned = kRowSpanned | kColSpanned;
|
|
|
|
/**
|
|
* Constants to define column header type.
|
|
*/
|
|
const kNoColumnHeader = 0;
|
|
const kListboxColumnHeader = 1;
|
|
const kTreeColumnHeader = 2;
|
|
|
|
/**
|
|
* Constants to define table type.
|
|
*/
|
|
const kTable = 0;
|
|
const kTreeTable = 1;
|
|
const kMathTable = 2;
|
|
|
|
/**
|
|
* Test table structure and related methods.
|
|
*
|
|
* @param aIdentifier [in] table accessible identifier
|
|
* @param aCellsArray [in] two dimensional array (row X columns) of
|
|
* cell types (see constants defined above).
|
|
* @param aColHeaderType [in] specifies wether column header cells are
|
|
* arranged into the list.
|
|
* @param aCaption [in] caption text if any
|
|
* @param aSummary [in] summary text if any
|
|
* @param aTableType [in] specifies the table type.
|
|
* @param aRowRoles [in] array of row roles.
|
|
*/
|
|
function testTableStruct(
|
|
aIdentifier,
|
|
aCellsArray,
|
|
aColHeaderType,
|
|
aCaption,
|
|
aSummary,
|
|
aTableType,
|
|
aRowRoles
|
|
) {
|
|
var tableNode = getNode(aIdentifier);
|
|
var isGrid =
|
|
tableNode.getAttribute("role") == "grid" ||
|
|
tableNode.getAttribute("role") == "treegrid" ||
|
|
tableNode.localName == "tree";
|
|
|
|
var rowCount = aCellsArray.length;
|
|
var colsCount = aCellsArray[0] ? aCellsArray[0].length : 0;
|
|
|
|
// Test table accessible tree.
|
|
var tableObj = {
|
|
children: [],
|
|
};
|
|
switch (aTableType) {
|
|
case kTable:
|
|
tableObj.role = ROLE_TABLE;
|
|
break;
|
|
case kTreeTable:
|
|
tableObj.role = ROLE_TREE_TABLE;
|
|
break;
|
|
case kMathTable:
|
|
tableObj.role = ROLE_MATHML_TABLE;
|
|
break;
|
|
}
|
|
|
|
// caption accessible handling
|
|
if (aCaption) {
|
|
var captionObj = {
|
|
role: ROLE_CAPTION,
|
|
children: [
|
|
{
|
|
role: ROLE_TEXT_LEAF,
|
|
name: aCaption,
|
|
},
|
|
],
|
|
};
|
|
|
|
tableObj.children.push(captionObj);
|
|
}
|
|
|
|
// special types of column headers handling
|
|
if (aColHeaderType) {
|
|
var headersObj = {
|
|
role: ROLE_LIST,
|
|
children: [],
|
|
};
|
|
|
|
for (let idx = 0; idx < colsCount; idx++) {
|
|
var headerCellObj = {
|
|
role: ROLE_COLUMNHEADER,
|
|
};
|
|
headersObj.children.push(headerCellObj);
|
|
}
|
|
|
|
if (aColHeaderType == kTreeColumnHeader) {
|
|
var columnPickerObj = {
|
|
role: ROLE_PUSHBUTTON,
|
|
};
|
|
|
|
headersObj.children.push(columnPickerObj);
|
|
}
|
|
|
|
tableObj.children.push(headersObj);
|
|
}
|
|
|
|
// rows and cells accessibles
|
|
for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
let rowObj = {
|
|
role: aRowRoles ? aRowRoles[rowIdx] : ROLE_ROW,
|
|
children: [],
|
|
};
|
|
|
|
for (let colIdx = 0; colIdx < colsCount; colIdx++) {
|
|
let celltype = aCellsArray[rowIdx][colIdx];
|
|
|
|
var role = ROLE_NOTHING;
|
|
switch (celltype) {
|
|
case kDataCell:
|
|
role =
|
|
aTableType == kMathTable
|
|
? ROLE_MATHML_CELL
|
|
: isGrid
|
|
? ROLE_GRID_CELL
|
|
: ROLE_CELL;
|
|
break;
|
|
case kRowHeaderCell:
|
|
role = ROLE_ROWHEADER;
|
|
break;
|
|
case kColHeaderCell:
|
|
role = ROLE_COLUMNHEADER;
|
|
break;
|
|
}
|
|
|
|
if (role != ROLE_NOTHING) {
|
|
var cellObj = { role };
|
|
rowObj.children.push(cellObj);
|
|
}
|
|
}
|
|
|
|
tableObj.children.push(rowObj);
|
|
}
|
|
|
|
testAccessibleTree(aIdentifier, tableObj);
|
|
|
|
// Test table table interface.
|
|
var table = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
|
|
|
// summary
|
|
if (aSummary) {
|
|
is(
|
|
table.summary,
|
|
aSummary,
|
|
"Wrong summary of the table " + prettyName(aIdentifier)
|
|
);
|
|
}
|
|
|
|
// rowCount and columnCount
|
|
is(
|
|
table.rowCount,
|
|
rowCount,
|
|
"Wrong rows count of " + prettyName(aIdentifier)
|
|
);
|
|
is(
|
|
table.columnCount,
|
|
colsCount,
|
|
"Wrong columns count of " + prettyName(aIdentifier)
|
|
);
|
|
|
|
// rows and columns extents
|
|
for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
for (let colIdx = 0; colIdx < colsCount; colIdx++) {
|
|
let celltype = aCellsArray[rowIdx][colIdx];
|
|
if (celltype & kOrigin) {
|
|
// table getRowExtentAt
|
|
var rowExtent = table.getRowExtentAt(rowIdx, colIdx);
|
|
let idx;
|
|
/* eslint-disable no-empty */
|
|
for (
|
|
idx = rowIdx + 1;
|
|
idx < rowCount && aCellsArray[idx][colIdx] & kRowSpanned;
|
|
idx++
|
|
) {}
|
|
/* eslint-enable no-empty */
|
|
|
|
var expectedRowExtent = idx - rowIdx;
|
|
is(
|
|
rowExtent,
|
|
expectedRowExtent,
|
|
"getRowExtentAt: Wrong number of spanned rows at (" +
|
|
rowIdx +
|
|
", " +
|
|
colIdx +
|
|
") for " +
|
|
prettyName(aIdentifier)
|
|
);
|
|
|
|
// table getColumnExtentAt
|
|
var colExtent = table.getColumnExtentAt(rowIdx, colIdx);
|
|
/* eslint-disable no-empty */
|
|
for (
|
|
idx = colIdx + 1;
|
|
idx < colsCount && aCellsArray[rowIdx][idx] & kColSpanned;
|
|
idx++
|
|
) {}
|
|
/* eslint-enable no-empty */
|
|
|
|
var expectedColExtent = idx - colIdx;
|
|
is(
|
|
colExtent,
|
|
expectedColExtent,
|
|
"getColumnExtentAt: Wrong number of spanned columns at (" +
|
|
rowIdx +
|
|
", " +
|
|
colIdx +
|
|
") for " +
|
|
prettyName(aIdentifier)
|
|
);
|
|
|
|
// cell rowExtent and columnExtent
|
|
var cell = getAccessible(table.getCellAt(rowIdx, colIdx), [
|
|
nsIAccessibleTableCell,
|
|
]);
|
|
|
|
is(
|
|
cell.rowExtent,
|
|
expectedRowExtent,
|
|
"rowExtent: Wrong number of spanned rows at (" +
|
|
rowIdx +
|
|
", " +
|
|
colIdx +
|
|
") for " +
|
|
prettyName(aIdentifier)
|
|
);
|
|
|
|
is(
|
|
cell.columnExtent,
|
|
expectedColExtent,
|
|
"columnExtent: Wrong number of spanned column at (" +
|
|
rowIdx +
|
|
", " +
|
|
colIdx +
|
|
") for " +
|
|
prettyName(aIdentifier)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test table indexes.
|
|
*
|
|
* @param aIdentifier [in] table accessible identifier
|
|
* @param aIdxes [in] two dimensional array of cell indexes
|
|
*/
|
|
function testTableIndexes(aIdentifier, aIdxes) {
|
|
var tableAcc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
|
if (!tableAcc) {
|
|
return;
|
|
}
|
|
|
|
var obtainedRowIdx, obtainedColIdx, obtainedIdx;
|
|
var cellAcc;
|
|
|
|
var id = prettyName(aIdentifier);
|
|
|
|
var rowCount = aIdxes.length;
|
|
for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
var colCount = aIdxes[rowIdx].length;
|
|
for (var colIdx = 0; colIdx < colCount; colIdx++) {
|
|
var idx = aIdxes[rowIdx][colIdx];
|
|
|
|
// getCellAt
|
|
try {
|
|
cellAcc = null;
|
|
cellAcc = tableAcc.getCellAt(rowIdx, colIdx);
|
|
} catch (e) {}
|
|
|
|
ok(
|
|
(idx != -1 && cellAcc) || (idx == -1 && !cellAcc),
|
|
id +
|
|
": Can't get cell accessible at row = " +
|
|
rowIdx +
|
|
", column = " +
|
|
colIdx
|
|
);
|
|
|
|
if (idx != -1) {
|
|
// getRowIndexAt
|
|
var origRowIdx = rowIdx;
|
|
while (
|
|
origRowIdx > 0 &&
|
|
aIdxes[rowIdx][colIdx] == aIdxes[origRowIdx - 1][colIdx]
|
|
) {
|
|
origRowIdx--;
|
|
}
|
|
|
|
try {
|
|
obtainedRowIdx = tableAcc.getRowIndexAt(idx);
|
|
} catch (e) {
|
|
ok(
|
|
false,
|
|
id + ": can't get row index for cell index " + idx + "," + e
|
|
);
|
|
}
|
|
|
|
is(
|
|
obtainedRowIdx,
|
|
origRowIdx,
|
|
id + ": row for index " + idx + " is not correct (getRowIndexAt)"
|
|
);
|
|
|
|
// getColumnIndexAt
|
|
var origColIdx = colIdx;
|
|
while (
|
|
origColIdx > 0 &&
|
|
aIdxes[rowIdx][colIdx] == aIdxes[rowIdx][origColIdx - 1]
|
|
) {
|
|
origColIdx--;
|
|
}
|
|
|
|
try {
|
|
obtainedColIdx = tableAcc.getColumnIndexAt(idx);
|
|
} catch (e) {
|
|
ok(
|
|
false,
|
|
id + ": can't get column index for cell index " + idx + "," + e
|
|
);
|
|
}
|
|
|
|
is(
|
|
obtainedColIdx,
|
|
origColIdx,
|
|
id +
|
|
": column for index " +
|
|
idx +
|
|
" is not correct (getColumnIndexAt)"
|
|
);
|
|
|
|
// getRowAndColumnIndicesAt
|
|
var obtainedRowIdxObj = {},
|
|
obtainedColIdxObj = {};
|
|
try {
|
|
tableAcc.getRowAndColumnIndicesAt(
|
|
idx,
|
|
obtainedRowIdxObj,
|
|
obtainedColIdxObj
|
|
);
|
|
} catch (e) {
|
|
ok(
|
|
false,
|
|
id +
|
|
": can't get row and column indices for cell index " +
|
|
idx +
|
|
"," +
|
|
e
|
|
);
|
|
}
|
|
|
|
is(
|
|
obtainedRowIdxObj.value,
|
|
origRowIdx,
|
|
id +
|
|
": row for index " +
|
|
idx +
|
|
" is not correct (getRowAndColumnIndicesAt)"
|
|
);
|
|
is(
|
|
obtainedColIdxObj.value,
|
|
origColIdx,
|
|
id +
|
|
": column for index " +
|
|
idx +
|
|
" is not correct (getRowAndColumnIndicesAt)"
|
|
);
|
|
|
|
if (cellAcc) {
|
|
var cellId = prettyName(cellAcc);
|
|
cellAcc = getAccessible(cellAcc, [nsIAccessibleTableCell]);
|
|
|
|
// cell: 'table-cell-index' attribute
|
|
var attrs = cellAcc.attributes;
|
|
var strIdx = "";
|
|
try {
|
|
strIdx = attrs.getStringProperty("table-cell-index");
|
|
} catch (e) {
|
|
ok(
|
|
false,
|
|
cellId +
|
|
": no cell index from object attributes on the cell accessible at index " +
|
|
idx +
|
|
"."
|
|
);
|
|
}
|
|
|
|
if (strIdx) {
|
|
is(
|
|
parseInt(strIdx),
|
|
idx,
|
|
cellId +
|
|
": cell index from object attributes of cell accessible isn't corrent."
|
|
);
|
|
}
|
|
|
|
// cell: table
|
|
try {
|
|
is(
|
|
cellAcc.table,
|
|
tableAcc,
|
|
cellId + ": wrong table accessible for the cell."
|
|
);
|
|
} catch (e) {
|
|
ok(false, cellId + ": can't get table accessible from the cell.");
|
|
}
|
|
|
|
// cell: getRowIndex
|
|
try {
|
|
obtainedRowIdx = cellAcc.rowIndex;
|
|
} catch (e) {
|
|
ok(
|
|
false,
|
|
cellId +
|
|
": can't get row index of the cell at index " +
|
|
idx +
|
|
"," +
|
|
e
|
|
);
|
|
}
|
|
|
|
is(
|
|
obtainedRowIdx,
|
|
origRowIdx,
|
|
cellId + ": row for the cell at index " + idx + " is not correct"
|
|
);
|
|
|
|
// cell: getColumnIndex
|
|
try {
|
|
obtainedColIdx = cellAcc.columnIndex;
|
|
} catch (e) {
|
|
ok(
|
|
false,
|
|
cellId +
|
|
": can't get column index of the cell at index " +
|
|
idx +
|
|
"," +
|
|
e
|
|
);
|
|
}
|
|
|
|
is(
|
|
obtainedColIdx,
|
|
origColIdx,
|
|
id + ": column for the cell at index " + idx + " is not correct"
|
|
);
|
|
}
|
|
}
|
|
|
|
// getCellIndexAt
|
|
try {
|
|
obtainedIdx = tableAcc.getCellIndexAt(rowIdx, colIdx);
|
|
} catch (e) {
|
|
obtainedIdx = -1;
|
|
}
|
|
|
|
is(
|
|
obtainedIdx,
|
|
idx,
|
|
id +
|
|
": row " +
|
|
rowIdx +
|
|
" /column " +
|
|
colIdx +
|
|
" and index " +
|
|
obtainedIdx +
|
|
" aren't inconsistent."
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test table getters selection methods.
|
|
*
|
|
* @param aIdentifier [in] table accessible identifier
|
|
* @param aCellsArray [in] two dimensional array (row X columns) of cells
|
|
* states (either boolean (selected/unselected) if cell is
|
|
* origin, otherwise kRowSpanned or kColSpanned constant).
|
|
* @param aMsg [in] text appended before every message
|
|
*/
|
|
function testTableSelection(aIdentifier, aCellsArray, aMsg) {
|
|
var msg = aMsg ? aMsg : "";
|
|
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
|
if (!acc) {
|
|
return;
|
|
}
|
|
|
|
var rowCount = aCellsArray.length;
|
|
var colsCount = aCellsArray[0].length;
|
|
|
|
// Columns selection tests.
|
|
var selCols = [];
|
|
|
|
// isColumnSelected test
|
|
for (let colIdx = 0; colIdx < colsCount; colIdx++) {
|
|
var isColSelected = true;
|
|
for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
if (
|
|
!aCellsArray[rowIdx][colIdx] ||
|
|
aCellsArray[rowIdx][colIdx] == undefined
|
|
) {
|
|
isColSelected = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
is(
|
|
acc.isColumnSelected(colIdx),
|
|
isColSelected,
|
|
msg +
|
|
"Wrong selection state of " +
|
|
colIdx +
|
|
" column for " +
|
|
prettyName(aIdentifier)
|
|
);
|
|
|
|
if (isColSelected) {
|
|
selCols.push(colIdx);
|
|
}
|
|
}
|
|
|
|
// selectedColsCount test
|
|
is(
|
|
acc.selectedColumnCount,
|
|
selCols.length,
|
|
msg + "Wrong count of selected columns for " + prettyName(aIdentifier)
|
|
);
|
|
|
|
// getSelectedColumns test
|
|
var actualSelCols = acc.getSelectedColumnIndices();
|
|
|
|
var actualSelColsCount = actualSelCols.length;
|
|
is(
|
|
actualSelColsCount,
|
|
selCols.length,
|
|
msg +
|
|
"Wrong count of selected columns for " +
|
|
prettyName(aIdentifier) +
|
|
"from getSelectedColumns."
|
|
);
|
|
|
|
for (let i = 0; i < actualSelColsCount; i++) {
|
|
is(
|
|
actualSelCols[i],
|
|
selCols[i],
|
|
msg + "Column at index " + selCols[i] + " should be selected."
|
|
);
|
|
}
|
|
|
|
// Rows selection tests.
|
|
var selRows = [];
|
|
|
|
// isRowSelected test
|
|
for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
var isRowSelected = true;
|
|
for (let colIdx = 0; colIdx < colsCount; colIdx++) {
|
|
if (
|
|
!aCellsArray[rowIdx][colIdx] ||
|
|
aCellsArray[rowIdx][colIdx] == undefined
|
|
) {
|
|
isRowSelected = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
is(
|
|
acc.isRowSelected(rowIdx),
|
|
isRowSelected,
|
|
msg +
|
|
"Wrong selection state of " +
|
|
rowIdx +
|
|
" row for " +
|
|
prettyName(aIdentifier)
|
|
);
|
|
|
|
if (isRowSelected) {
|
|
selRows.push(rowIdx);
|
|
}
|
|
}
|
|
|
|
// selectedRowCount test
|
|
is(
|
|
acc.selectedRowCount,
|
|
selRows.length,
|
|
msg + "Wrong count of selected rows for " + prettyName(aIdentifier)
|
|
);
|
|
|
|
// getSelectedRows test
|
|
var actualSelRows = acc.getSelectedRowIndices();
|
|
|
|
var actualSelrowCount = actualSelRows.length;
|
|
is(
|
|
actualSelrowCount,
|
|
selRows.length,
|
|
msg +
|
|
"Wrong count of selected rows for " +
|
|
prettyName(aIdentifier) +
|
|
"from getSelectedRows."
|
|
);
|
|
|
|
for (let i = 0; i < actualSelrowCount; i++) {
|
|
is(
|
|
actualSelRows[i],
|
|
selRows[i],
|
|
msg + "Row at index " + selRows[i] + " should be selected."
|
|
);
|
|
}
|
|
|
|
// Cells selection tests.
|
|
var selCells = [];
|
|
|
|
// isCellSelected test
|
|
for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
for (let colIdx = 0; colIdx < colsCount; colIdx++) {
|
|
if (aCellsArray[rowIdx][colIdx] & kSpanned) {
|
|
continue;
|
|
}
|
|
|
|
var isSelected = !!aCellsArray[rowIdx][colIdx];
|
|
is(
|
|
acc.isCellSelected(rowIdx, colIdx),
|
|
isSelected,
|
|
msg +
|
|
"Wrong selection state of cell at " +
|
|
rowIdx +
|
|
" row and " +
|
|
colIdx +
|
|
" column for " +
|
|
prettyName(aIdentifier)
|
|
);
|
|
|
|
if (aCellsArray[rowIdx][colIdx]) {
|
|
selCells.push(acc.getCellIndexAt(rowIdx, colIdx));
|
|
}
|
|
}
|
|
}
|
|
|
|
// selectedCellCount tests
|
|
is(
|
|
acc.selectedCellCount,
|
|
selCells.length,
|
|
msg + "Wrong count of selected cells for " + prettyName(aIdentifier)
|
|
);
|
|
|
|
// getSelectedCellIndices test
|
|
var actualSelCells = acc.getSelectedCellIndices();
|
|
|
|
var actualSelCellsCount = actualSelCells.length;
|
|
is(
|
|
actualSelCellsCount,
|
|
selCells.length,
|
|
msg +
|
|
"Wrong count of selected cells for " +
|
|
prettyName(aIdentifier) +
|
|
"from getSelectedCells."
|
|
);
|
|
|
|
for (let i = 0; i < actualSelCellsCount; i++) {
|
|
is(
|
|
actualSelCells[i],
|
|
selCells[i],
|
|
msg +
|
|
"getSelectedCellIndices: Cell at index " +
|
|
selCells[i] +
|
|
" should be selected."
|
|
);
|
|
}
|
|
|
|
// selectedCells and isSelected tests
|
|
var actualSelCellsArray = acc.selectedCells;
|
|
for (let i = 0; i < actualSelCellsCount; i++) {
|
|
var actualSelCellAccessible = actualSelCellsArray.queryElementAt(
|
|
i,
|
|
nsIAccessibleTableCell
|
|
);
|
|
|
|
let colIdx = acc.getColumnIndexAt(selCells[i]);
|
|
let rowIdx = acc.getRowIndexAt(selCells[i]);
|
|
var expectedSelCellAccessible = acc.getCellAt(rowIdx, colIdx);
|
|
|
|
is(
|
|
actualSelCellAccessible,
|
|
expectedSelCellAccessible,
|
|
msg +
|
|
"getSelectedCells: Cell at index " +
|
|
selCells[i] +
|
|
" should be selected."
|
|
);
|
|
|
|
ok(
|
|
actualSelCellAccessible.isSelected(),
|
|
"isSelected: Cell at index " + selCells[i] + " should be selected."
|
|
);
|
|
}
|
|
|
|
// selected states tests
|
|
for (let rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
for (let colIdx = 0; colIdx < colsCount; colIdx++) {
|
|
if (aCellsArray[rowIdx][colIdx] & kSpanned) {
|
|
continue;
|
|
}
|
|
|
|
var cell = acc.getCellAt(rowIdx, colIdx);
|
|
var isSel = aCellsArray[rowIdx][colIdx];
|
|
if (isSel == undefined) {
|
|
testStates(cell, 0, 0, STATE_SELECTABLE | STATE_SELECTED);
|
|
} else if (isSel) {
|
|
testStates(cell, STATE_SELECTED);
|
|
} else {
|
|
testStates(cell, STATE_SELECTABLE, 0, STATE_SELECTED);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test unselectColumn method of accessible table.
|
|
*/
|
|
function testUnselectTableColumn(aIdentifier, aColIdx, aCellsArray) {
|
|
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
|
if (!acc) {
|
|
return;
|
|
}
|
|
|
|
var rowCount = aCellsArray.length;
|
|
for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
// Unselect origin cell.
|
|
var [origRowIdx, origColIdx] = getOrigRowAndColumn(
|
|
aCellsArray,
|
|
rowIdx,
|
|
aColIdx
|
|
);
|
|
aCellsArray[origRowIdx][origColIdx] = false;
|
|
}
|
|
|
|
acc.unselectColumn(aColIdx);
|
|
testTableSelection(
|
|
aIdentifier,
|
|
aCellsArray,
|
|
"Unselect " + aColIdx + " column: "
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Test selectColumn method of accessible table.
|
|
*/
|
|
function testSelectTableColumn(aIdentifier, aColIdx, aCellsArray) {
|
|
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
|
if (!acc) {
|
|
return;
|
|
}
|
|
|
|
var rowCount = aCellsArray.length;
|
|
var colsCount = aCellsArray[0].length;
|
|
|
|
for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
for (var colIdx = 0; colIdx < colsCount; colIdx++) {
|
|
var cellState = aCellsArray[rowIdx][colIdx];
|
|
|
|
if (colIdx == aColIdx) {
|
|
// select target column
|
|
if (!(cellState & kSpanned)) {
|
|
// Select the cell if it is origin.
|
|
aCellsArray[rowIdx][colIdx] = true;
|
|
} else {
|
|
// If the cell is spanned then search origin cell and select it.
|
|
var [origRowIdx, origColIdx] = getOrigRowAndColumn(
|
|
aCellsArray,
|
|
rowIdx,
|
|
colIdx
|
|
);
|
|
aCellsArray[origRowIdx][origColIdx] = true;
|
|
}
|
|
} else if (!(cellState & kSpanned)) {
|
|
// unselect other columns
|
|
if (colIdx > aColIdx) {
|
|
// Unselect the cell if traversed column index is greater than column
|
|
// index of target cell.
|
|
aCellsArray[rowIdx][colIdx] = false;
|
|
} else if (!(aCellsArray[rowIdx][aColIdx] & kColSpanned)) {
|
|
// Unselect the cell if the target cell is not row spanned.
|
|
aCellsArray[rowIdx][colIdx] = false;
|
|
} else {
|
|
// Unselect the cell if it is not spanned to the target cell.
|
|
for (
|
|
var spannedColIdx = colIdx + 1;
|
|
spannedColIdx < aColIdx;
|
|
spannedColIdx++
|
|
) {
|
|
var spannedCellState = aCellsArray[rowIdx][spannedColIdx];
|
|
if (!(spannedCellState & kRowSpanned)) {
|
|
aCellsArray[rowIdx][colIdx] = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
acc.selectColumn(aColIdx);
|
|
testTableSelection(
|
|
aIdentifier,
|
|
aCellsArray,
|
|
"Select " + aColIdx + " column: "
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Test unselectRow method of accessible table.
|
|
*/
|
|
function testUnselectTableRow(aIdentifier, aRowIdx, aCellsArray) {
|
|
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
|
if (!acc) {
|
|
return;
|
|
}
|
|
|
|
var colsCount = aCellsArray[0].length;
|
|
for (var colIdx = 0; colIdx < colsCount; colIdx++) {
|
|
// Unselect origin cell.
|
|
var [origRowIdx, origColIdx] = getOrigRowAndColumn(
|
|
aCellsArray,
|
|
aRowIdx,
|
|
colIdx
|
|
);
|
|
aCellsArray[origRowIdx][origColIdx] = false;
|
|
}
|
|
|
|
acc.unselectRow(aRowIdx);
|
|
testTableSelection(
|
|
aIdentifier,
|
|
aCellsArray,
|
|
"Unselect " + aRowIdx + " row: "
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Test selectRow method of accessible table.
|
|
*/
|
|
function testSelectTableRow(aIdentifier, aRowIdx, aCellsArray) {
|
|
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
|
if (!acc) {
|
|
return;
|
|
}
|
|
|
|
var rowCount = aCellsArray.length;
|
|
var colsCount = aCellsArray[0].length;
|
|
|
|
for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
|
|
for (var colIdx = 0; colIdx < colsCount; colIdx++) {
|
|
var cellState = aCellsArray[rowIdx][colIdx];
|
|
|
|
if (rowIdx == aRowIdx) {
|
|
// select the given row
|
|
if (!(cellState & kSpanned)) {
|
|
// Select the cell if it is origin.
|
|
aCellsArray[rowIdx][colIdx] = true;
|
|
} else {
|
|
// If the cell is spanned then search origin cell and select it.
|
|
var [origRowIdx, origColIdx] = getOrigRowAndColumn(
|
|
aCellsArray,
|
|
rowIdx,
|
|
colIdx
|
|
);
|
|
|
|
aCellsArray[origRowIdx][origColIdx] = true;
|
|
}
|
|
} else if (!(cellState & kSpanned)) {
|
|
// unselect other rows
|
|
if (rowIdx > aRowIdx) {
|
|
// Unselect the cell if traversed row index is greater than row
|
|
// index of target cell.
|
|
aCellsArray[rowIdx][colIdx] = false;
|
|
} else if (!(aCellsArray[aRowIdx][colIdx] & kRowSpanned)) {
|
|
// Unselect the cell if the target cell is not row spanned.
|
|
aCellsArray[rowIdx][colIdx] = false;
|
|
} else {
|
|
// Unselect the cell if it is not spanned to the target cell.
|
|
for (
|
|
var spannedRowIdx = rowIdx + 1;
|
|
spannedRowIdx < aRowIdx;
|
|
spannedRowIdx++
|
|
) {
|
|
var spannedCellState = aCellsArray[spannedRowIdx][colIdx];
|
|
if (!(spannedCellState & kRowSpanned)) {
|
|
aCellsArray[rowIdx][colIdx] = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
acc.selectRow(aRowIdx);
|
|
testTableSelection(aIdentifier, aCellsArray, "Select " + aRowIdx + " row: ");
|
|
}
|
|
|
|
/**
|
|
* Test columnHeaderCells and rowHeaderCells of accessible table.
|
|
*/
|
|
function testHeaderCells(aHeaderInfoMap) {
|
|
for (var testIdx = 0; testIdx < aHeaderInfoMap.length; testIdx++) {
|
|
var dataCellIdentifier = aHeaderInfoMap[testIdx].cell;
|
|
var dataCell = getAccessible(dataCellIdentifier, [nsIAccessibleTableCell]);
|
|
|
|
// row header cells
|
|
var rowHeaderCells = aHeaderInfoMap[testIdx].rowHeaderCells;
|
|
var rowHeaderCellsCount = rowHeaderCells.length;
|
|
var actualRowHeaderCells = dataCell.rowHeaderCells;
|
|
var actualRowHeaderCellsCount = actualRowHeaderCells.length;
|
|
|
|
is(
|
|
actualRowHeaderCellsCount,
|
|
rowHeaderCellsCount,
|
|
"Wrong number of row header cells for the cell " +
|
|
prettyName(dataCellIdentifier)
|
|
);
|
|
|
|
if (actualRowHeaderCellsCount == rowHeaderCellsCount) {
|
|
for (let idx = 0; idx < rowHeaderCellsCount; idx++) {
|
|
var rowHeaderCell = getAccessible(rowHeaderCells[idx]);
|
|
var actualRowHeaderCell = actualRowHeaderCells.queryElementAt(
|
|
idx,
|
|
nsIAccessible
|
|
);
|
|
isObject(
|
|
actualRowHeaderCell,
|
|
rowHeaderCell,
|
|
"Wrong row header cell at index " +
|
|
idx +
|
|
" for the cell " +
|
|
dataCellIdentifier
|
|
);
|
|
}
|
|
}
|
|
|
|
// column header cells
|
|
var colHeaderCells = aHeaderInfoMap[testIdx].columnHeaderCells;
|
|
var colHeaderCellsCount = colHeaderCells.length;
|
|
var actualColHeaderCells = dataCell.columnHeaderCells;
|
|
var actualColHeaderCellsCount = actualColHeaderCells.length;
|
|
|
|
is(
|
|
actualColHeaderCellsCount,
|
|
colHeaderCellsCount,
|
|
"Wrong number of column header cells for the cell " +
|
|
prettyName(dataCellIdentifier)
|
|
);
|
|
|
|
if (actualColHeaderCellsCount == colHeaderCellsCount) {
|
|
for (let idx = 0; idx < colHeaderCellsCount; idx++) {
|
|
var colHeaderCell = getAccessible(colHeaderCells[idx]);
|
|
var actualColHeaderCell = actualColHeaderCells.queryElementAt(
|
|
idx,
|
|
nsIAccessible
|
|
);
|
|
isObject(
|
|
actualColHeaderCell,
|
|
colHeaderCell,
|
|
"Wrong column header cell at index " +
|
|
idx +
|
|
" for the cell " +
|
|
dataCellIdentifier
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// private implementation
|
|
|
|
/**
|
|
* Return row and column of orig cell for the given spanned cell.
|
|
*/
|
|
function getOrigRowAndColumn(aCellsArray, aRowIdx, aColIdx) {
|
|
var cellState = aCellsArray[aRowIdx][aColIdx];
|
|
|
|
var origRowIdx = aRowIdx,
|
|
origColIdx = aColIdx;
|
|
if (cellState & kRowSpanned) {
|
|
for (var prevRowIdx = aRowIdx - 1; prevRowIdx >= 0; prevRowIdx--) {
|
|
let prevCellState = aCellsArray[prevRowIdx][aColIdx];
|
|
if (!(prevCellState & kRowSpanned)) {
|
|
origRowIdx = prevRowIdx;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cellState & kColSpanned) {
|
|
for (var prevColIdx = aColIdx - 1; prevColIdx >= 0; prevColIdx--) {
|
|
let prevCellState = aCellsArray[aRowIdx][prevColIdx];
|
|
if (!(prevCellState & kColSpanned)) {
|
|
origColIdx = prevColIdx;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return [origRowIdx, origColIdx];
|
|
}
|