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); |
}, |