Chromium Code Reviews| 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..f47d399f2c0baa3dd23e62a0b308e1688a18ca7d 100644 |
| --- a/chrome/browser/resources/chromeos/switch_access/automation_manager.js |
| +++ b/chrome/browser/resources/chromeos/switch_access/automation_manager.js |
| @@ -10,18 +10,33 @@ |
| */ |
| 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 list of past subtree roots. Allows user to traverse back to previous |
|
dmazzoni
2017/05/05 18:23:19
Would it be more clear to say this is a list of pa
elichtenberg
2017/05/06 00:13:53
Done.
|
| + * groups after selecting one or more groups. |
| + * |
| + * @private {Array<chrome.automation.AutomationNode>} |
| + */ |
| + this.oldScopes_ = []; |
| /** |
| * Moves to the appropriate node in the accessibility tree. |
| @@ -35,17 +50,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 +75,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 +87,67 @@ AutomationManager.prototype = { |
| }, |
| /** |
| - * Perform the default action on the currently selected node. |
| + * Select the currently highlighted node. If the node is a group, create a |
|
dmazzoni
2017/05/05 18:23:19
Also document what happens if you're on the curren
elichtenberg
2017/05/06 00:13:53
Done.
|
| + * 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_) { |
| + let oldScope = this.oldScopes_.pop(); |
| + |
| + // Don't let user select the top-level root node (i.e., the desktop node). |
| + if (!oldScope) |
|
dmazzoni
2017/05/05 18:25:52
One possible bug - it's possible that the old scop
elichtenberg
2017/05/06 00:13:53
Done.
|
| + return; |
| + |
| + this.scope_ = oldScope; |
| + this.treeWalker_ = this.createTreeWalker_(this.scope_, this.node_); |
| + return; |
| + } |
| + |
| + if (AutomationPredicate.isGroup(this.node_, this.scope_)) { |
| + this.oldScopes_.push(this.scope_); |
| + this.scope_ = this.node_; |
| + this.treeWalker_ = this.createTreeWalker_(this.scope_); |
| + 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|. |
|
dmazzoni
2017/05/05 18:23:19
Does it start at |scope|, or at the first child?
elichtenberg
2017/05/06 00:13:53
I agree. I changed selectCurrentNode so that when
|
| + 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. |
| /** |