| Index: chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
|
| diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
|
| index f054868b831967ccd7c8826b5d814b9260790741..8fe99e95d521f6b538726d3c75688ca5c7cc6c8f 100644
|
| --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
|
| +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
|
| @@ -10,8 +10,11 @@ goog.provide('AutomationPredicate');
|
| goog.provide('AutomationPredicate.Binary');
|
| goog.provide('AutomationPredicate.Unary');
|
|
|
| +goog.require('constants');
|
| +
|
| goog.scope(function() {
|
| var AutomationNode = chrome.automation.AutomationNode;
|
| +var Dir = constants.Dir;
|
| var RoleType = chrome.automation.RoleType;
|
|
|
| /**
|
| @@ -52,6 +55,8 @@ AutomationPredicate.inlineTextBox =
|
| /** @type {AutomationPredicate.Unary} */
|
| AutomationPredicate.link = AutomationPredicate.withRole(RoleType.link);
|
| /** @type {AutomationPredicate.Unary} */
|
| +AutomationPredicate.row = AutomationPredicate.withRole(RoleType.row);
|
| +/** @type {AutomationPredicate.Unary} */
|
| AutomationPredicate.table = AutomationPredicate.withRole(RoleType.table);
|
|
|
| /**
|
| @@ -283,10 +288,12 @@ AutomationPredicate.shouldIgnoreNode = function(node) {
|
| // Ignore some roles.
|
| return AutomationPredicate.leaf(node) &&
|
| (node.role == RoleType.client ||
|
| + node.role == RoleType.column ||
|
| node.role == RoleType.div ||
|
| node.role == RoleType.group ||
|
| node.role == RoleType.image ||
|
| - node.role == RoleType.staticText);
|
| + node.role == RoleType.staticText ||
|
| + node.role == RoleType.tableHeaderContainer);
|
| };
|
|
|
|
|
| @@ -302,4 +309,86 @@ AutomationPredicate.checkable = function(node) {
|
| node.role == RoleType.menuItemRadio;
|
| };
|
|
|
| +// Table related predicates.
|
| +/**
|
| + * Returns if the node has a cell like role.
|
| + * @param {!AutomationNode} node
|
| + * @return {boolean}
|
| + */
|
| +AutomationPredicate.cellLike = function(node) {
|
| + return node.role == RoleType.cell ||
|
| + node.role == RoleType.rowHeader ||
|
| + node.role == RoleType.columnHeader;
|
| +};
|
| +
|
| +/**
|
| + * Returns a predicate that will match against the directed next cell taking
|
| + * into account the current ancestor cell's position in the table.
|
| + * @param {AutomationNode} start
|
| + * @param {{dir: (Dir|undefined),
|
| +* row: (boolean|undefined),
|
| + * col: (boolean|undefined)}} opts
|
| + * |dir|, specifies direction for |row or/and |col| movement by one cell.
|
| + * |dir| defaults to forward.
|
| + * |row| and |col| are both false by default.
|
| + * |end| defaults to false. If set to true, |col| must also be set to true.
|
| + * It will then return the first or last cell in the current column.
|
| + * @return {?AutomationPredicate.Unary} Returns null if not in a table.
|
| + */
|
| +AutomationPredicate.makeTableCellPredicate = function(start, opts) {
|
| + if (!opts.row && !opts.col)
|
| + throw new Error('You must set either row or col to true');
|
| +
|
| + var dir = opts.dir || Dir.FORWARD;
|
| +
|
| + // Compute the row/col index defaulting to 0.
|
| + var rowIndex = 0, colIndex = 0;
|
| + var tableNode = start;
|
| + while (tableNode) {
|
| + if (AutomationPredicate.table(tableNode))
|
| + break;
|
| +
|
| + if (AutomationPredicate.cellLike(tableNode)) {
|
| + rowIndex = tableNode.tableCellRowIndex;
|
| + colIndex = tableNode.tableCellColumnIndex;
|
| + }
|
| +
|
| + tableNode = tableNode.parent;
|
| + }
|
| + if (!tableNode)
|
| + return null;
|
| +
|
| + // Only support making a predicate for column ends.
|
| + if (opts.end) {
|
| + if (!opts.col)
|
| + throw 'Unsupported option.';
|
| +
|
| + if (dir == Dir.FORWARD) {
|
| + return function(node) {
|
| + return AutomationPredicate.cellLike(node) &&
|
| + node.tableCellColumnIndex == colIndex &&
|
| + node.tableCellRowIndex >= 0;
|
| + };
|
| + } else {
|
| + return function(node) {
|
| + return AutomationPredicate.cellLike(node) &&
|
| + node.tableCellColumnIndex == colIndex &&
|
| + node.tableCellRowIndex < tableNode.tableRowCount;
|
| + };
|
| + }
|
| + }
|
| +
|
| + // Adjust for the next/previous row/col.
|
| + if (opts.row)
|
| + rowIndex = dir == Dir.FORWARD ? rowIndex + 1 : rowIndex - 1;
|
| + if (opts.col)
|
| + colIndex = dir == Dir.FORWARD ? colIndex + 1 : colIndex - 1;
|
| +
|
| + return function(node) {
|
| + return AutomationPredicate.cellLike(node) &&
|
| + node.tableCellColumnIndex == colIndex &&
|
| + node.tableCellRowIndex == rowIndex;
|
| + };
|
| +};
|
| +
|
| }); // goog.scope
|
|
|