Chromium Code Reviews| Index: chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js |
| diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js |
| index 989adde5b82d5d71802bc216b9a0bd801762a9d1..d09a1de2e57e08fb825e4c13f586e7e150b215af 100644 |
| --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js |
| +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background.js |
| @@ -16,9 +16,9 @@ goog.require('cursors.Cursor'); |
| goog.require('cvox.TabsApiHandler'); |
| goog.scope(function() { |
| +var AutomationNode = chrome.automation.AutomationNode; |
| var Dir = AutomationUtil.Dir; |
| var EventType = chrome.automation.EventType; |
| -var AutomationNode = chrome.automation.AutomationNode; |
| /** Classic Chrome accessibility API. */ |
| global.accessibility = |
| @@ -46,10 +46,10 @@ Background = function() { |
| cvox.ChromeVox.earcons); |
| /** |
| - * @type {chrome.automation.AutomationNode} |
| + * @type {cursors.Range} |
| * @private |
| */ |
| - this.currentNode_ = null; |
| + this.activeRange_ = null; |
|
dmazzoni
2014/10/24 16:13:30
Since we use "active" to mean whether ChromeVox is
|
| /** |
| * Whether ChromeVox Next is active. |
| @@ -129,12 +129,10 @@ Background.prototype = { |
| return; |
| } |
| - if (!this.active_ || !this.current_) |
| + if (!this.active_ || !this.activeRange_) |
| return; |
| - var previous = this.current_; |
| - var current = this.current_; |
| - |
| + var current = this.activeRange_; |
| var dir = Dir.FORWARD; |
| var pred = null; |
| switch (command) { |
| @@ -147,12 +145,10 @@ Background.prototype = { |
| pred = AutomationPredicate.heading; |
| break; |
| case 'nextLine': |
| - dir = Dir.FORWARD; |
| - pred = AutomationPredicate.inlineTextBox; |
| + current = current.move(cursors.Unit.LINE, Dir.FORWARD); |
| break; |
| case 'previousLine': |
| - dir = Dir.BACKWARD; |
| - pred = AutomationPredicate.inlineTextBox; |
| + current = current.move(cursors.Unit.LINE, Dir.BACKWARD); |
| break; |
| case 'nextLink': |
| dir = Dir.FORWARD; |
| @@ -163,40 +159,41 @@ Background.prototype = { |
| pred = AutomationPredicate.link; |
| break; |
| case 'nextElement': |
| - current = current.role == chrome.automation.RoleType.inlineTextBox ? |
| - current.parent() : current; |
| - current = AutomationUtil.findNextNode(current, |
| - Dir.FORWARD, |
| - AutomationPredicate.inlineTextBox); |
| - current = current ? current.parent() : current; |
| + current = current.move(cursors.Unit.NODE, Dir.FORWARD); |
| break; |
| case 'previousElement': |
| - current = current.role == chrome.automation.RoleType.inlineTextBox ? |
| - current.parent() : current; |
| - current = AutomationUtil.findNextNode(current, |
| - Dir.BACKWARD, |
| - AutomationPredicate.inlineTextBox); |
| - current = current ? current.parent() : current; |
| + current = current.move(cursors.Unit.NODE, Dir.BACKWARD); |
| break; |
| case 'goToBeginning': |
| - current = AutomationUtil.findNodePost(current.root, |
| + var node = AutomationUtil.findNodePost(current.getStart().getNode().root, |
| Dir.FORWARD, |
| - AutomationPredicate.inlineTextBox); |
| + AutomationPredicate.leaf); |
| + if (node) |
| + current = cursors.Range.fromNode(node); |
| break; |
| case 'goToEnd': |
| - current = AutomationUtil.findNodePost(current.root, |
| + var node = |
| + AutomationUtil.findNodePost(current.getStart().getNode().root, |
| Dir.BACKWARD, |
| - AutomationPredicate.inlineTextBox); |
| + AutomationPredicate.leaf); |
| + if (node) |
| + current = cursors.Range.fromNode(node); |
| break; |
| } |
| - if (pred) |
| - current = AutomationUtil.findNextNode(current, dir, pred); |
| + if (pred) { |
| + var node = AutomationUtil.findNextNode( |
| + current.getBound(dir).getNode(), dir, pred); |
| + |
| + if (node) |
| + current = cursors.Range.fromNode(node); |
| + } |
| if (current) { |
| - current.focus(); |
| + current.getStart().getNode().focus(); |
|
dmazzoni
2014/10/24 16:13:29
Perhaps this should call a method on current that
|
| - this.onFocus({target: current}); |
| + this.activeRange_ = current; |
| + this.handleOutput(this.activeRange_); |
| } |
| }, |
| @@ -209,20 +206,8 @@ Background.prototype = { |
| if (!node) |
| return; |
| - this.current_ = node; |
| - var container = node; |
| - while (container && |
| - (container.role == chrome.automation.RoleType.inlineTextBox || |
| - container.role == chrome.automation.RoleType.staticText)) |
| - container = container.parent(); |
| - |
| - var role = container ? container.role : node.role; |
| - |
| - var output = |
| - [node.attributes.name, node.attributes.value, role].join(', '); |
| - cvox.ChromeVox.tts.speak(output, cvox.QueueMode.FLUSH); |
| - cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(output)); |
| - chrome.accessibilityPrivate.setFocusRing([evt.target.location]); |
| + this.activeRange_ = cursors.Range.fromNode(node); |
| + this.handleOutput(this.activeRange_); |
| }, |
| /** |
| @@ -230,13 +215,17 @@ Background.prototype = { |
| * @param {Object} evt |
| */ |
| onLoadComplete: function(evt) { |
| - if (this.current_) |
| + if (this.activeRange_) |
| return; |
| - this.current_ = AutomationUtil.findNodePost(evt.target, |
| + var node = AutomationUtil.findNodePost(evt.target, |
| Dir.FORWARD, |
| - AutomationPredicate.inlineTextBox); |
| - this.onFocus({target: this.current_}); |
| + AutomationPredicate.leaf); |
| + if (node) |
| + this.activeRange_ = cursors.Range.fromNode(node); |
| + |
| + if (this.activeRange_) |
| + this.handleOutput(this.activeRange_); |
| }, |
| /** |
| @@ -278,7 +267,7 @@ Background.prototype = { |
| } else { |
| if (this.active_) { |
| for (var eventType in this.listeners_) { |
| - this.current_.root.removeEventListener( |
| + this.activeRange_.getStart().getNode().root.removeEventListener( |
| eventType, this.listeners_[eventType], true); |
| } |
| } |
| @@ -294,6 +283,43 @@ Background.prototype = { |
| }.bind(this)); |
| } |
| }.bind(this)); |
| + }, |
| + |
| + /** |
| + * Handles output of a Range. |
| + * @param {!cursors.Range} range Current location. |
| + */ |
| + handleOutput: function(range) { |
| + // TODO(dtseng): This is just placeholder logic for generating descriptions |
| + // pending further design discussion. |
| + function getCursorDesc(cursor) { |
| + var node = cursor.getNode(); |
| + var container = node; |
| + while (container && |
| + (container.role == chrome.automation.RoleType.inlineTextBox || |
| + container.role == chrome.automation.RoleType.staticText)) |
| + container = container.parent(); |
| + |
| + var role = container ? container.role : node.role; |
| + return [node.attributes.name, node.attributes.value, role].join(', '); |
| + } |
| + |
| + // Walk the range and collect descriptions. |
| + var output = ''; |
| + var cursor = range.getStart(); |
| + var nodeLocations = []; |
| + while (cursor.getNode() != range.getEnd().getNode()) { |
| + output += getCursorDesc(cursor); |
| + nodeLocations.push(cursor.getNode().location); |
| + cursor = cursor.move( |
| + cursors.Unit.NODE, cursors.Movement.DIRECTIONAL, Dir.FORWARD); |
| + } |
| + output += getCursorDesc(range.getEnd()); |
| + nodeLocations.push(range.getEnd().getNode().location); |
| + |
| + cvox.ChromeVox.tts.speak(output, cvox.QueueMode.FLUSH); |
| + cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(output)); |
| + chrome.accessibilityPrivate.setFocusRing(nodeLocations); |
| } |
| }; |