Chromium Code Reviews| Index: chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js |
| diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js |
| index 4d117e02ed7cdf4c6c1c1a022ac4f084fa079562..7589cf5dc5c24b2c3e662458583c44bcc6941f3e 100644 |
| --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js |
| +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js |
| @@ -93,6 +93,9 @@ Output.ROLE_INFO_ = { |
| checkbox: { |
| msgId: 'input_type_checkbox' |
| }, |
| + dialog: { |
| + msgId: 'dialog' |
| + }, |
| heading: { |
| msgId: 'aria_role_heading', |
| }, |
| @@ -210,7 +213,7 @@ Output.RULES = { |
| }, |
| menuStart: { |
| 'default': { |
| - speak: '@chrome_menu_opened($name) $role $earcon(OBJECT_OPEN)' |
| + speak: '@chrome_menu_opened($name) $earcon(OBJECT_OPEN)' |
| } |
| }, |
| menuEnd: { |
| @@ -258,6 +261,12 @@ Output.Action.prototype = { |
| }; |
| /** |
| + * Annotation for string splitting. |
| + * @constructor |
| + */ |
| +Output.StringSplit = function() {}; |
| + |
| +/** |
| * Annotation for selection. |
| * @param {number} startIndex |
| * @param {number} endIndex |
| @@ -350,14 +359,42 @@ Output.prototype = { |
| // Speech. |
| var buff = this.buffer_; |
| if (buff.toString()) { |
| - if (this.speechStartCallback_) |
| - this.speechProperties_['startCallback'] = this.speechStartCallback_; |
| - if (this.speechEndCallback_) { |
| - this.speechProperties_['endCallback'] = this.speechEndCallback_; |
| - } |
| + var splits = |
| + buff.getSpansInstanceOf(Output.StringSplit).map(function(split) { |
| + return buff.getSpanStart(split); |
| + }); |
| - cvox.ChromeVox.tts.speak( |
| - buff.toString(), cvox.QueueMode.FLUSH, this.speechProperties_); |
| + if (splits.length == 0) { |
| + cvox.ChromeVox.tts.speak(buff.toString(), |
| + cvox.QueueMode.FLUSH, this.speechProperties_); |
| + } else { |
| + var start = -1; |
| + var seen = {}; |
| + splits = splits.filter(function(i) { |
|
Peter Lundblad
2015/03/30 15:27:46
When are we going to have duplicates here?
|
| + if (seen[i]) |
| + return false; |
| + seen[i] = true; |
| + return true; |
| + }); |
| + var queueMode = cvox.QueueMode.FLUSH; |
| + do { |
| + start++; |
| + if (this.speechStartCallback_ && start == 0) |
| + this.speechProperties_['startCallback'] = this.speechStartCallback_; |
| + else |
| + this.speechProperties_['startCallback'] = null; |
| + if (this.speechEndCallback_ && start == splits.length - 1) |
| + this.speechProperties_['endCallback'] = this.speechEndCallback_; |
| + else |
| + this.speechProperties_['endCallback'] = null; |
| + var startIndex = splits[start]; |
| + var endIndex = splits[start + 1] || buff.getLength(); |
| + |
| + cvox.ChromeVox.tts.speak(buff.substring(startIndex, |
| + endIndex).toString(), queueMode, this.speechProperties_); |
| + queueMode = cvox.QueueMode.QUEUE; |
| + } while (start < splits.length - 1); |
| + } |
| } |
| var actions = buff.getSpansInstanceOf(Output.Action); |
| @@ -436,6 +473,11 @@ Output.prototype = { |
| } |
| tokens.forEach(function(token) { |
| + // Always split at the beginning of each token for speech. |
| + var splitOptions = {}; |
| + splitOptions.annotation = new Output.StringSplit(); |
| + this.addToSpannable_(buff, new cvox.Spannable(), splitOptions); |
| + |
| // Ignore empty tokens. |
| if (!token) |
| return; |
| @@ -622,6 +664,9 @@ Output.prototype = { |
| cursor = cursor.move(cursors.Unit.NODE, |
| cursors.Movement.DIRECTIONAL, |
| Dir.FORWARD); |
| + var options = {}; |
| + options.annotation = new Output.StringSplit(); |
| + this.addToSpannable_(rangeBuff, new cvox.Spannable(), options); |
| } |
| var lastNode = range.getEnd().getNode(); |
| this.addToSpannable_(rangeBuff, formatNodeAndAncestors(lastNode, prevNode)); |
| @@ -727,8 +772,8 @@ Output.prototype = { |
| * Adds to the given buffer with proper delimiters added. |
| * @param {!cvox.Spannable} spannable |
| * @param {string|!cvox.Spannable} value |
| - * @param {{ifEmpty: boolean, |
| - * annotation: (string|Output.Action|undefined)}=} opt_options |
| + * @param {{ifEmpty: (boolean|undefined), |
| + * annotation: *}=} opt_options |
| */ |
| addToSpannable_: function(spannable, value, opt_options) { |
| opt_options = opt_options || {ifEmpty: false, annotation: undefined}; |
| @@ -748,7 +793,13 @@ Output.prototype = { |
| Output.ATTRIBUTE_ALIAS[opt_options.annotation]) != undefined)) |
| return; |
| - var prefixed = new cvox.Spannable(Output.SPACE); |
| + // Figure out if we need to add the spacing prefix. |
| + var needsPrefix = this.formatOptions_.braille; |
| + if (needsPrefix) { |
|
Peter Lundblad
2015/03/30 15:27:46
Indentation.
|
| + needsPrefix = value instanceof cvox.Spannable ? |
| + value.getLength() > 0 : value.length > 0; |
| + } |
| + var prefixed = new cvox.Spannable(needsPrefix ? Output.SPACE : ''); |
| prefixed.append(spannableToAdd); |
| spannable.append(prefixed); |
| }, |