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

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: Ignore some roles. 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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 if (node.role == RoleType.listMarker) 279 if (node.role == RoleType.listMarker)
277 return true; 280 return true;
278 281
279 // Don't ignore nodes with names. 282 // Don't ignore nodes with names.
280 if (node.name || node.value || node.description) 283 if (node.name || node.value || node.description)
281 return false; 284 return false;
282 285
283 // Ignore some roles. 286 // Ignore some roles.
284 return AutomationPredicate.leaf(node) && 287 return AutomationPredicate.leaf(node) &&
285 (node.role == RoleType.client || 288 (node.role == RoleType.client ||
289 node.role == RoleType.column ||
286 node.role == RoleType.div || 290 node.role == RoleType.div ||
287 node.role == RoleType.group || 291 node.role == RoleType.group ||
288 node.role == RoleType.image || 292 node.role == RoleType.image ||
289 node.role == RoleType.staticText); 293 node.role == RoleType.staticText ||
294 node.role == RoleType.tableHeaderContainer);
290 }; 295 };
291 296
292 297
293 /** 298 /**
294 * Returns if the node has a meaningful checked state. 299 * Returns if the node has a meaningful checked state.
295 * @param {!AutomationNode} node 300 * @param {!AutomationNode} node
296 * @return {boolean} 301 * @return {boolean}
297 */ 302 */
298 AutomationPredicate.checkable = function(node) { 303 AutomationPredicate.checkable = function(node) {
299 return node.role == RoleType.checkBox || 304 return node.role == RoleType.checkBox ||
300 node.role == RoleType.radioButton || 305 node.role == RoleType.radioButton ||
301 node.role == RoleType.menuItemCheckBox || 306 node.role == RoleType.menuItemCheckBox ||
302 node.role == RoleType.menuItemRadio; 307 node.role == RoleType.menuItemRadio;
303 }; 308 };
304 309
310 // Table related predicates.
311 /**
312 * Returns if the node has a cell like role.
313 * @param {!AutomationNode} node
314 * @return {boolean}
315 */
316 AutomationPredicate.cellLike = function(node) {
317 return node.role == RoleType.cell ||
318 node.role == RoleType.rowHeader ||
319 node.role == RoleType.columnHeader;
320 };
321
322 /**
323 * Returns a predicate that will match against the directed next vertical cell
324 * taking into account the current ancestor cell's position in the table.
325 * @param {AutomationNode} start
326 * @param {{dir: (Dir|undefined),
327 * end: (boolean|undefined),
328 * row: (boolean|undefined),
329 * col: (boolean|undefined)}} opts
330 * |dir|, specifies direction for |row or/and |col| movement by one cell.
331 * |dir| defaults to forward.
332 * |row| and |col| are both false by default.
333 * |end| defaults to false. If set to true, the first row or co will be
334 * returned.
335 * @return {?AutomationPredicate.Unary} Returns null if not in a table.
336 */
337 AutomationPredicate.rowCol = function(start, opts) {
dmazzoni 2016/07/13 23:38:28 I'd maybe call the predicate tableNavigation or mo
David Tseng 2016/07/14 20:24:41 Probably part of the confusion...it makes a predic
338 if (!opts.row && !opts.col)
339 throw new Error('You must set either row or col to true');
dmazzoni 2016/07/13 23:38:28 indent
David Tseng 2016/07/14 20:24:41 Done.
340
341 var dir = opts.dir || Dir.FORWARD;
342
343 // Compute the row/col index defaulting to 0.
344 var rowIndex = 0, colIndex = 0;
345 var tableNode = start;
346 while (tableNode) {
347 if (AutomationPredicate.table(tableNode))
348 break;
349
350 if (AutomationPredicate.cellLike(tableNode)) {
351 rowIndex = tableNode.tableCellRowIndex;
352 colIndex = tableNode.tableCellColumnIndex;
353 }
354
355 tableNode = tableNode.parent;
356 }
357 if (!tableNode)
358 return null;
359
360 if (!opts.end) {
361 // Adjust for the next/previous row/col.
362 if (opts.row)
363 rowIndex = dir == Dir.FORWARD ? rowIndex + 1 : rowIndex - 1;
364 if (opts.col)
365 colIndex = dir == Dir.FORWARD ? colIndex + 1 : colIndex - 1;
366 } else {
367 var rowEnd = dir == Dir.FORWARD ? (tableNode.tableRowCount - 1) : 0;
368 var colEnd = dir == Dir.FORWARD ? (tableNode.tableColumnCount - 1) : 0;
369
370 if (opts.row && opts.col) {
371 // Do nothing if we're already there.
372 if (rowEnd === rowIndex && colEnd === colIndex)
373 return null;
374
375 rowIndex = rowEnd;
376 colIndex = colEnd;
377 } else if (opts.row) {
378 // This looks counter-intuitive, but moving to the end of a row, means
379 // moving horizontally (by col).
380
381 // Do nothing if we're already there.
382 if (colEnd == colIndex)
383 return null;
384
385 colIndex = colEnd;
386 } else if (opts.col) {
387 // Do nothing if we're already there.
388 if (rowEnd == rowIndex)
389 return null;
390
391 rowIndex = rowEnd;
392 }
393 }
394
395 return function(node) {
dmazzoni 2016/07/13 23:38:28 Why is this a predicate that returns a function ra
David Tseng 2016/07/14 20:24:41 How did you conclude that? This method makes a pre
396 return AutomationPredicate.cellLike(node) &&
397 node.tableCellColumnIndex == colIndex &&
398 node.tableCellRowIndex == rowIndex;
399 };
400 };
401
305 }); // goog.scope 402 }); // goog.scope
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698