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

Unified Diff: chrome/browser/resources/chromeos/switch_access/tree_walker.js

Issue 2863613003: Implemented scanning by group (Closed)
Patch Set: Responded to comments Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/chromeos/switch_access/tree_walker.js
diff --git a/chrome/browser/resources/chromeos/switch_access/tree_walker.js b/chrome/browser/resources/chromeos/switch_access/tree_walker.js
index 5fc9f1f1d44316a6d0beab9c56a4c1b501bc89fe..5c763b804e9783cf594ec365c5d1db6151b4d5e3 100644
--- a/chrome/browser/resources/chromeos/switch_access/tree_walker.js
+++ b/chrome/browser/resources/chromeos/switch_access/tree_walker.js
@@ -3,50 +3,94 @@
// found in the LICENSE file.
/**
- * Class to move to the appropriate node in the accessibility tree.
+ * Class to move to the appropriate node in the accessibility tree. Stays in a
+ * subtree determined by restrictions passed to it.
*
* @constructor
+ * @param {!chrome.automation.AutomationNode} start
+ * @param {!chrome.automation.AutomationNode} scope
+ * @param {!AutomationTreeWalker.Restriction} restrictions
*/
-function AutomationTreeWalker() {};
+function AutomationTreeWalker(start, scope, restrictions) {
+ /**
+ * Currently highlighted node.
+ *
+ * @private {!chrome.automation.AutomationNode}
+ */
+ this.node_ = start;
+
+ /**
+ * The root of the subtree that the user is navigating through.
+ *
+ * @private {!chrome.automation.AutomationNode}
+ */
+ this.scope_ = scope;
+
+ /**
+ * Function that returns true for a node that is a leaf of the current
+ * subtree.
+ *
+ * @private {!AutomationTreeWalker.Unary}
+ */
+ this.leafPred_ = restrictions.leaf;
+
+ /**
+ * Function that returns true for a node in the current subtree that should
+ * be visited.
+ *
+ * @private {!AutomationTreeWalker.Unary}
+ */
+ this.visitPred_ = restrictions.visit;
+};
+
+/**
+ * @typedef {{leaf: AutomationTreeWalker.Unary,
+ * visit: AutomationTreeWalker.Unary}}
+ */
+AutomationTreeWalker.Restriction;
+
+/**
+ * @typedef {function(!chrome.automation.AutomationNode) : boolean}
+ */
+AutomationTreeWalker.Unary;
AutomationTreeWalker.prototype = {
/**
- * Return the next/previous interesting node from |start|. If no interesting
- * node is found, return the first/last interesting node. If |doNext| is true,
- * will search for next node. Otherwise, will search for previous node.
+ * Set this.node_ to the next/previous interesting node within the current
+ * scope and return it. If no interesting node is found, return the
+ * first/last interesting node. If |doNext| is true, will search for next
+ * node. Otherwise, will search for previous node.
*
- * @param {chrome.automation.AutomationNode} start
- * @param {chrome.automation.AutomationNode} root
* @param {boolean} doNext
* @return {chrome.automation.AutomationNode}
*/
- moveToNode: function(start, root, doNext) {
- let node = start;
+ moveToNode: function(doNext) {
+ let node = this.node_;
+ do {
+ node = doNext ? this.getNextNode_(node) : this.getPreviousNode_(node);
+ } while (node && !this.visitPred_(node));
if (node) {
- do {
- node = doNext ? this.getNextNode_(node) : this.getPreviousNode_(node);
- } while (node && !this.isInteresting_(node));
- if (node)
- return node;
+ this.node_ = node;
+ return node;
}
- if (root) {
- console.log(
- 'Restarting search for node at ' + (doNext ? 'first' : 'last'));
- node = doNext ? root.firstChild : this.getYoungestDescendant_(root);
- while (node && !this.isInteresting_(node))
- node = doNext ? this.getNextNode_(node) : this.getPreviousNode_(node);
- if (node)
- return node;
+ console.log('Restarting search for node at ' + (doNext ? 'first' : 'last'));
+ node = doNext ? this.scope_ : this.getYoungestDescendant_(this.scope_);
+ while (node && !this.visitPred_(node))
+ node = doNext ? this.getNextNode_(node) : this.getPreviousNode_(node);
+ if (node) {
+ this.node_ = node;
+ return node;
}
console.log('Found no interesting nodes to visit.');
return null;
},
+
/**
* Given a flat list of nodes in pre-order, get the node that comes after
- * |node|.
+ * |node| within the current scope.
*
* @param {!chrome.automation.AutomationNode} node
* @return {!chrome.automation.AutomationNode|undefined}
@@ -55,9 +99,14 @@ AutomationTreeWalker.prototype = {
getNextNode_: function(node) {
// Check for child.
let child = node.firstChild;
- if (child)
+ if (child && !this.leafPred_(node))
return child;
+ // Has no children, and if node is root of subtree, don't check siblings
+ // or parent.
+ if (node === this.scope_)
+ return undefined;
+
// No child. Check for right-sibling.
let sibling = node.nextSibling;
if (sibling)
@@ -65,7 +114,7 @@ AutomationTreeWalker.prototype = {
// No right-sibling. Get right-sibling of closest ancestor.
let ancestor = node.parent;
- while (ancestor) {
+ while (ancestor && ancestor !== this.scope_) {
let aunt = ancestor.nextSibling;
if (aunt)
return aunt;
@@ -78,13 +127,17 @@ AutomationTreeWalker.prototype = {
/**
* Given a flat list of nodes in pre-order, get the node that comes before
- * |node|.
+ * |node| within the current scope.
*
* @param {!chrome.automation.AutomationNode} node
* @return {!chrome.automation.AutomationNode|undefined}
* @private
*/
getPreviousNode_: function(node) {
+ // If node is root of subtree, there is no previous node.
+ if (node === this.scope_)
+ return undefined;
+
// Check for left-sibling. If a left-sibling exists, return its youngest
// descendant if it has one, or otherwise return the sibling.
let sibling = node.previousSibling;
@@ -92,59 +145,33 @@ AutomationTreeWalker.prototype = {
return this.getYoungestDescendant_(sibling) || sibling;
// No left-sibling. Return parent if it exists; otherwise return undefined.
- return node.parent;
+ //return node.parent;
+ let parent = node.parent;
+ if (parent)
+ return parent;
+
+ return undefined;
},
/**
- * Get the youngest descendant of |node| if it has one.
+ * Get the youngest descendant of |node|, if it has one, within the current
+ * scope.
*
* @param {!chrome.automation.AutomationNode} node
* @return {!chrome.automation.AutomationNode|undefined}
* @private
*/
getYoungestDescendant_: function(node) {
- if (!node.lastChild)
+ if (!node.lastChild || this.leafPred_(node))
return undefined;
- while (node.lastChild)
+ while (node.lastChild && !this.leafPred_(node))
node = node.lastChild;
return node;
},
/**
- * Returns true if |node| is interesting.
- *
- * @param {!chrome.automation.AutomationNode} node
- * @return {boolean}
- * @private
- */
- isInteresting_: function(node) {
- let loc = node.location;
- let parent = node.parent;
- let root = node.root;
- let role = node.role;
- let state = node.state;
-
- // Skip things that are offscreen
- if (state[chrome.automation.StateType.OFFSCREEN]
- || loc.top < 0 || loc.left < 0)
- return false;
-
- if (parent) {
- // crbug.com/710559
- // Work around for browser tabs
- if (role === chrome.automation.RoleType.TAB
- && parent.role === chrome.automation.RoleType.TAB_LIST
- && root.role === chrome.automation.RoleType.DESKTOP)
- return true;
- }
-
- // The general rule that applies to everything.
- return state[chrome.automation.StateType.FOCUSABLE] === true;
- },
-
- /**
* Return the next sibling of |node| if it has one.
*
* @param {chrome.automation.AutomationNode} node

Powered by Google App Engine
This is Rietveld 408576698