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

Unified Diff: chrome/browser/resources/chromeos/switch_access/automation_manager.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/automation_manager.js
diff --git a/chrome/browser/resources/chromeos/switch_access/automation_manager.js b/chrome/browser/resources/chromeos/switch_access/automation_manager.js
index 855539dae6706fb34f3e20fc1de1df08d3610dfe..a26ec16bc8c40f0001f4778a8c583d47590dc890 100644
--- a/chrome/browser/resources/chromeos/switch_access/automation_manager.js
+++ b/chrome/browser/resources/chromeos/switch_access/automation_manager.js
@@ -10,18 +10,34 @@
*/
function AutomationManager() {
/**
- * Currently selected node.
+ * Currently highlighted node.
*
* @private {chrome.automation.AutomationNode}
*/
this.node_ = null;
/**
- * Root node (i.e., the desktop).
+ * The root of the subtree that the user is navigating through.
*
* @private {chrome.automation.AutomationNode}
*/
- this.root_ = null;
+ this.scope_ = null;
+
+ /**
+ * The desktop node.
+ *
+ * @private {chrome.automation.AutomationNode}
+ */
+ this.desktop_ = null;
+
+ /**
+ * A stack of past scopes. Allows user to traverse back to previous groups
+ * after selecting one or more groups. The most recent group is at the end
+ * of the array.
+ *
+ * @private {Array<chrome.automation.AutomationNode>}
+ */
+ this.scopeStack_ = [];
/**
* Moves to the appropriate node in the accessibility tree.
@@ -35,17 +51,17 @@ function AutomationManager() {
AutomationManager.prototype = {
/**
- * Set this.node_ and this.root_ to the desktop node, and initialize the
- * tree walker.
+ * Set this.node_, this.root_, and this.desktop_ to the desktop node, and
+ * creates an initial tree walker.
*
* @private
*/
init_: function() {
- this.treeWalker_ = new AutomationTreeWalker();
-
chrome.automation.getDesktop(function(desktop) {
this.node_ = desktop;
- this.root_ = desktop;
+ this.scope_ = desktop;
+ this.desktop_ = desktop;
+ this.treeWalker_ = this.createTreeWalker_(desktop);
console.log('AutomationNode for desktop is loaded');
this.printNode_(this.node_);
}.bind(this));
@@ -60,7 +76,10 @@ AutomationManager.prototype = {
* @param {boolean} doNext
*/
moveToNode: function(doNext) {
- let node = this.treeWalker_.moveToNode(this.node_, this.root_, doNext);
+ if (!this.treeWalker_)
+ return;
+
+ let node = this.treeWalker_.moveToNode(doNext);
if (node) {
this.node_ = node;
this.printNode_(this.node_);
@@ -69,15 +88,77 @@ AutomationManager.prototype = {
},
/**
- * Perform the default action on the currently selected node.
+ * Select the currently highlighted node. If the node is the current scope,
+ * go back to the previous scope (i.e., create a new tree walker rooted at
+ * the previous scope). If the node is a group other than the current scope,
+ * create a new tree walker for the new subtree the user is scanning through.
+ * Otherwise, meaning the node is interesting, perform the default action on
+ * it.
*/
- doDefault: function() {
- if (!this.node_)
+ selectCurrentNode: function() {
+ if (!this.node_ || !this.scope_ || !this.treeWalker_)
+ return;
+
+ if (this.node_ === this.scope_) {
+ // Don't let user select the top-level root node (i.e., the desktop node).
+ if (this.scopeStack_.length === 0)
+ return;
+
+ // Find a previous scope that is still valid.
+ let oldScope;
+ do {
+ oldScope = this.scopeStack_.pop();
+ } while (oldScope && !oldScope.role);
+
+ // oldScope will always be valid here, so this will always be true.
+ if (oldScope) {
+ this.scope_ = oldScope;
+ this.treeWalker_ = this.createTreeWalker_(this.scope_, this.node_);
+ }
return;
+ }
+
+ if (AutomationPredicate.isGroup(this.node_, this.scope_)) {
+ this.scopeStack_.push(this.scope_);
+ this.scope_ = this.node_;
+ this.treeWalker_ = this.createTreeWalker_(this.scope_);
+ this.moveToNode(true);
+ return;
+ }
this.node_.doDefault();
},
+ /**
+ * Create an AutomationTreeWalker for the subtree with |scope| as its root.
+ * If |opt_start| is defined, the tree walker will start walking the tree
+ * from |opt_start|; otherwise, it will start from |scope|.
+ *
+ * @param {!chrome.automation.AutomationNode} scope
+ * @param {!chrome.automation.AutomationNode=} opt_start
+ * @return {!AutomationTreeWalker}
+ */
+ createTreeWalker_: function(scope, opt_start) {
+ // If no explicit start node, start walking the tree from |scope|.
+ let start = opt_start || scope;
+
+ let leafPred = function(node) {
+ return (node !== scope && AutomationPredicate.isSubtreeLeaf(node, scope))
+ || !AutomationPredicate.isInterestingSubtree(node);
+ };
+ let visitPred = function(node) {
+ // Avoid visiting the top-level root node (i.e., the desktop node).
+ return node !== this.desktop_
+ && AutomationPredicate.isSubtreeLeaf(node, scope);
+ }.bind(this);
+
+ let restrictions = {
+ leaf: leafPred,
+ visit: visitPred
+ };
+ return new AutomationTreeWalker(start, scope, restrictions);
+ },
+
// TODO(elichtenberg): Move print functions to a custom logger class. Only
// log when debuggingEnabled is true.
/**

Powered by Google App Engine
This is Rietveld 408576698