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..680d5d04fbcabc02277ed6eb12249d3d7fcbf3ff 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.range_ = null; |
|
dmazzoni
2014/10/17 16:46:08
Does this mean the current selected object? Maybe
Peter Lundblad
2014/10/23 13:35:07
Either make the name more self-explanatory or add
|
| /** |
| * Whether ChromeVox Next is active. |
| @@ -129,12 +129,10 @@ Background.prototype = { |
| return; |
| } |
| - if (!this.active_ || !this.current_) |
| + if (!this.active_ || !this.range_) |
| return; |
| - var previous = this.current_; |
| - var current = this.current_; |
| - |
| + var current = this.range_.clone(); |
| 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.move(cursors.Unit.LINE, Dir.FORWARD); |
| break; |
| case 'previousLine': |
| - dir = Dir.BACKWARD; |
| - pred = AutomationPredicate.inlineTextBox; |
| + current.move(cursors.Unit.LINE, Dir.BACKWARD); |
| break; |
| case 'nextLink': |
| dir = Dir.FORWARD; |
| @@ -163,40 +159,40 @@ 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.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.move(cursors.Unit.NODE, Dir.BACKWARD); |
| break; |
| case 'goToBeginning': |
| - current = AutomationUtil.findNodePost(current.root, |
| + var node = AutomationUtil.findNodePost(current.start.node.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.start.node.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.collapse(dir).start.node, dir, pred); |
| + |
| + if (node) |
| + current = cursors.Range.fromNode(node); |
| + } |
| if (current) { |
| - current.focus(); |
| + current.start.node.focus(); |
| - this.onFocus({target: current}); |
| + this.range_ = current; |
| + this.handleOutput(this.range_); |
| } |
| }, |
| @@ -209,20 +205,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.range_ = cursors.Range.fromNode(node); |
| + this.handleOutput(this.range_); |
| }, |
| /** |
| @@ -230,13 +214,17 @@ Background.prototype = { |
| * @param {Object} evt |
| */ |
| onLoadComplete: function(evt) { |
| - if (this.current_) |
| + if (this.range_) |
| 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.range_ = cursors.Range.fromNode(node); |
| + |
| + if (this.range_) |
| + this.handleOutput(this.range_); |
| }, |
| /** |
| @@ -278,7 +266,7 @@ Background.prototype = { |
| } else { |
| if (this.active_) { |
| for (var eventType in this.listeners_) { |
| - this.current_.root.removeEventListener( |
| + this.range_.start.node.root.removeEventListener( |
| eventType, this.listeners_[eventType], true); |
| } |
| } |
| @@ -294,6 +282,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.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; |
| + |
| + return [node.attributes.name, node.attributes.value, role].join(', '); |
| + } |
| + |
| + // Walk the range and collect descriptions. |
| + var output = ''; |
| + var cursor = range.start.clone(); |
| + var nodeLocations = []; |
| + while (cursor.node != range.end.node) { |
| + output += getCursorDesc(cursor); |
| + nodeLocations.push(cursor.node.location); |
| + cursor.move(cursors.Unit.NODE, cursors.Movement.DIRECTIONAL, Dir.FORWARD); |
| + } |
| + output += getCursorDesc(range.end); |
| + nodeLocations.push(range.end.node.location); |
| + |
| + cvox.ChromeVox.tts.speak(output, cvox.QueueMode.FLUSH); |
| + cvox.ChromeVox.braille.write(cvox.NavBraille.fromText(output)); |
| + chrome.accessibilityPrivate.setFocusRing([nodeLocations]); |
| } |
| }; |