Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js

Issue 2132123002: Complete table support in ChromeVox Next. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview ChromeVox predicates for the automation extension API. 6 * @fileoverview ChromeVox predicates for the automation extension API.
7 */ 7 */
8 8
9 goog.provide('AutomationPredicate'); 9 goog.provide('AutomationPredicate');
10 goog.provide('AutomationPredicate.Binary'); 10 goog.provide('AutomationPredicate.Binary');
11 goog.provide('AutomationPredicate.Unary'); 11 goog.provide('AutomationPredicate.Unary');
12 12
13 goog.require('constants');
14
13 goog.scope(function() { 15 goog.scope(function() {
14 var AutomationNode = chrome.automation.AutomationNode; 16 var AutomationNode = chrome.automation.AutomationNode;
17 var Dir = constants.Dir;
15 var RoleType = chrome.automation.RoleType; 18 var RoleType = chrome.automation.RoleType;
16 19
17 /** 20 /**
18 * @constructor 21 * @constructor
19 */ 22 */
20 AutomationPredicate = function() {}; 23 AutomationPredicate = function() {};
21 24
22 /** 25 /**
23 * @typedef {function(!AutomationNode) : boolean} 26 * @typedef {function(!AutomationNode) : boolean}
24 */ 27 */
(...skipping 20 matching lines...) Expand all
45 /** @type {AutomationPredicate.Unary} */ 48 /** @type {AutomationPredicate.Unary} */
46 AutomationPredicate.comboBox = AutomationPredicate.withRole(RoleType.comboBox); 49 AutomationPredicate.comboBox = AutomationPredicate.withRole(RoleType.comboBox);
47 /** @type {AutomationPredicate.Unary} */ 50 /** @type {AutomationPredicate.Unary} */
48 AutomationPredicate.heading = AutomationPredicate.withRole(RoleType.heading); 51 AutomationPredicate.heading = AutomationPredicate.withRole(RoleType.heading);
49 /** @type {AutomationPredicate.Unary} */ 52 /** @type {AutomationPredicate.Unary} */
50 AutomationPredicate.inlineTextBox = 53 AutomationPredicate.inlineTextBox =
51 AutomationPredicate.withRole(RoleType.inlineTextBox); 54 AutomationPredicate.withRole(RoleType.inlineTextBox);
52 /** @type {AutomationPredicate.Unary} */ 55 /** @type {AutomationPredicate.Unary} */
53 AutomationPredicate.link = AutomationPredicate.withRole(RoleType.link); 56 AutomationPredicate.link = AutomationPredicate.withRole(RoleType.link);
54 /** @type {AutomationPredicate.Unary} */ 57 /** @type {AutomationPredicate.Unary} */
58 AutomationPredicate.row = AutomationPredicate.withRole(RoleType.row);
59 /** @type {AutomationPredicate.Unary} */
55 AutomationPredicate.table = AutomationPredicate.withRole(RoleType.table); 60 AutomationPredicate.table = AutomationPredicate.withRole(RoleType.table);
56 61
57 /** 62 /**
58 * @param {!AutomationNode} node 63 * @param {!AutomationNode} node
59 * @return {boolean} 64 * @return {boolean}
60 */ 65 */
61 AutomationPredicate.button = function(node) { 66 AutomationPredicate.button = function(node) {
62 return /button/i.test(node.role); 67 return /button/i.test(node.role);
63 }; 68 };
64 69
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 if (node.role == RoleType.listMarker) 281 if (node.role == RoleType.listMarker)
277 return true; 282 return true;
278 283
279 // Don't ignore nodes with names. 284 // Don't ignore nodes with names.
280 if (node.name || node.value || node.description) 285 if (node.name || node.value || node.description)
281 return false; 286 return false;
282 287
283 // Ignore some roles. 288 // Ignore some roles.
284 return AutomationPredicate.leaf(node) && 289 return AutomationPredicate.leaf(node) &&
285 (node.role == RoleType.client || 290 (node.role == RoleType.client ||
291 node.role == RoleType.column ||
286 node.role == RoleType.div || 292 node.role == RoleType.div ||
287 node.role == RoleType.group || 293 node.role == RoleType.group ||
288 node.role == RoleType.image || 294 node.role == RoleType.image ||
289 node.role == RoleType.staticText); 295 node.role == RoleType.staticText ||
296 node.role == RoleType.tableHeaderContainer);
290 }; 297 };
291 298
292 299
293 /** 300 /**
294 * Returns if the node has a meaningful checked state. 301 * Returns if the node has a meaningful checked state.
295 * @param {!AutomationNode} node 302 * @param {!AutomationNode} node
296 * @return {boolean} 303 * @return {boolean}
297 */ 304 */
298 AutomationPredicate.checkable = function(node) { 305 AutomationPredicate.checkable = function(node) {
299 return node.role == RoleType.checkBox || 306 return node.role == RoleType.checkBox ||
300 node.role == RoleType.radioButton || 307 node.role == RoleType.radioButton ||
301 node.role == RoleType.menuItemCheckBox || 308 node.role == RoleType.menuItemCheckBox ||
302 node.role == RoleType.menuItemRadio; 309 node.role == RoleType.menuItemRadio;
303 }; 310 };
304 311
312 // Table related predicates.
313 /**
314 * Returns if the node has a cell like role.
315 * @param {!AutomationNode} node
316 * @return {boolean}
317 */
318 AutomationPredicate.cellLike = function(node) {
319 return node.role == RoleType.cell ||
320 node.role == RoleType.rowHeader ||
321 node.role == RoleType.columnHeader;
322 };
323
324 /**
325 * Returns a predicate that will match against the directed next cell taking
326 * into account the current ancestor cell's position in the table.
327 * @param {AutomationNode} start
328 * @param {{dir: (Dir|undefined),
329 * row: (boolean|undefined),
330 * col: (boolean|undefined)}} opts
331 * |dir|, specifies direction for |row or/and |col| movement by one cell.
332 * |dir| defaults to forward.
333 * |row| and |col| are both false by default.
334 * |end| defaults to false. If set to true, |col| must also be set to true.
335 * It will then return the first or last cell in the current column.
336 * @return {?AutomationPredicate.Unary} Returns null if not in a table.
337 */
338 AutomationPredicate.makeTableCellPredicate = function(start, opts) {
339 if (!opts.row && !opts.col)
340 throw new Error('You must set either row or col to true');
341
342 var dir = opts.dir || Dir.FORWARD;
343
344 // Compute the row/col index defaulting to 0.
345 var rowIndex = 0, colIndex = 0;
346 var tableNode = start;
347 while (tableNode) {
348 if (AutomationPredicate.table(tableNode))
349 break;
350
351 if (AutomationPredicate.cellLike(tableNode)) {
352 rowIndex = tableNode.tableCellRowIndex;
353 colIndex = tableNode.tableCellColumnIndex;
354 }
355
356 tableNode = tableNode.parent;
357 }
358 if (!tableNode)
359 return null;
360
361 // Only support making a predicate for column ends.
362 if (opts.end) {
363 if (!opts.col)
364 throw 'Unsupported option.';
365
366 if (dir == Dir.FORWARD) {
367 return function(node) {
368 return AutomationPredicate.cellLike(node) &&
369 node.tableCellColumnIndex == colIndex &&
370 node.tableCellRowIndex >= 0;
371 };
372 } else {
373 return function(node) {
374 return AutomationPredicate.cellLike(node) &&
375 node.tableCellColumnIndex == colIndex &&
376 node.tableCellRowIndex < tableNode.tableRowCount;
377 };
378 }
379 }
380
381 // Adjust for the next/previous row/col.
382 if (opts.row)
383 rowIndex = dir == Dir.FORWARD ? rowIndex + 1 : rowIndex - 1;
384 if (opts.col)
385 colIndex = dir == Dir.FORWARD ? colIndex + 1 : colIndex - 1;
386
387 return function(node) {
388 return AutomationPredicate.cellLike(node) &&
389 node.tableCellColumnIndex == colIndex &&
390 node.tableCellRowIndex == rowIndex;
391 };
392 };
393
305 }); // goog.scope 394 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698