Commit 80d1057b authored by Katie D's avatar Katie D Committed by Commit Bot

Adds user setting to allow speech to continue after text goes away.

If the Accessibility node becomes undefined during reading, the
default behavior is to stop reading immediately. This allows STS
to continue reading hen nodes are undefined.

Advanced users may want more control over text, while novice users
may be surprised when text continues after windows are closed (and
there's no visual indicator that speech is still in prgoress).

An open question is whether this should also apply to nodes that
disappear from the screen after their window is closed or minimized,
or if they are scrolled off screen. Right now, that behavior is
read and is unchanged by this patch.

Adds this behind the --enable-experimental-accessibility-features
flag in Chrome OS.

Bug: 818835
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: Ib063d6ac5071f35a5d4e0a90cd472bb0ffc165f9
Reviewed-on: https://chromium-review.googlesource.com/949776
Commit-Queue: Katie Dektar <katie@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541617}
parent 355e2167
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
'<(EXTERNS_GYP):accessibility_private', '<(EXTERNS_GYP):accessibility_private',
'<(EXTERNS_GYP):automation', '<(EXTERNS_GYP):automation',
'<(EXTERNS_GYP):chrome_extensions', '<(EXTERNS_GYP):chrome_extensions',
'<(EXTERNS_GYP):command_line_private',
'<(EXTERNS_GYP):metrics_private', '<(EXTERNS_GYP):metrics_private',
], ],
'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
......
...@@ -103,6 +103,17 @@ ...@@ -103,6 +103,17 @@
</div> </div>
</div> </div>
</div> </div>
<div id="behavior">
<h2 class="i18n" msgid="options_behavior"></h2>
<div class="option">
<input id="readAfterClose" type="checkbox" class="checkbox pref"
name="readAfterClose" aria-labeledby="readAfterCloseLabel">
<label id="readAfterCloseLabel" class="i18n"
msgid="options_read_after_close">
</label>
</div>
</div>
</div> </div>
<script src="select_to_speak_options.js"></script> <script src="select_to_speak_options.js"></script>
......
...@@ -115,6 +115,9 @@ var SelectToSpeak = function() { ...@@ -115,6 +115,9 @@ var SelectToSpeak = function() {
/** @private {string} */ /** @private {string} */
this.highlightColor_ = '#5e9bff'; this.highlightColor_ = '#5e9bff';
/** @private {boolean} */
this.readAfterClose_ = false;
/** @private {?NodeGroupItem} */ /** @private {?NodeGroupItem} */
this.currentNode_ = null; this.currentNode_ = null;
...@@ -861,7 +864,10 @@ SelectToSpeak.prototype = { ...@@ -861,7 +864,10 @@ SelectToSpeak.prototype = {
var updatePrefs = var updatePrefs =
(function() { (function() {
chrome.storage.sync.get( chrome.storage.sync.get(
['voice', 'rate', 'pitch', 'wordHighlight', 'highlightColor'], [
'voice', 'rate', 'pitch', 'wordHighlight', 'highlightColor',
'readAfterClose'
],
(function(prefs) { (function(prefs) {
if (prefs['voice']) { if (prefs['voice']) {
this.voiceNameFromPrefs_ = prefs['voice']; this.voiceNameFromPrefs_ = prefs['voice'];
...@@ -888,6 +894,12 @@ SelectToSpeak.prototype = { ...@@ -888,6 +894,12 @@ SelectToSpeak.prototype = {
chrome.storage.sync.set( chrome.storage.sync.set(
{'highlightColor': this.highlightColor_}); {'highlightColor': this.highlightColor_});
} }
if (prefs['readAfterClose'] !== undefined) {
this.readAfterClose_ = prefs['readAfterClose'];
} else {
chrome.storage.sync.set(
{'readAfterClose': this.readAfterClose_});
}
}).bind(this)); }).bind(this));
}).bind(this); }).bind(this);
...@@ -953,8 +965,14 @@ SelectToSpeak.prototype = { ...@@ -953,8 +965,14 @@ SelectToSpeak.prototype = {
updateFromNodeState_: function(nodeGroupItem, inForeground) { updateFromNodeState_: function(nodeGroupItem, inForeground) {
switch (getNodeState(nodeGroupItem.node)) { switch (getNodeState(nodeGroupItem.node)) {
case NodeState.NODE_STATE_INVALID: case NodeState.NODE_STATE_INVALID:
// If the node is invalid, stop speaking entirely. // If the node is invalid, stop speaking entirely if the user setting
this.stopAll_(); // is not to continue reading.
if (this.readAfterClose_) {
this.clearFocusRing_();
this.visible_ = false;
} else {
this.stopAll_();
}
break; break;
case NodeState.NODE_STATE_INVISIBLE: case NodeState.NODE_STATE_INVISIBLE:
// If it is invisible but still valid, just clear the focus ring. // If it is invisible but still valid, just clear the focus ring.
......
...@@ -37,6 +37,13 @@ SelectToSpeakOptionsPage.prototype = { ...@@ -37,6 +37,13 @@ SelectToSpeakOptionsPage.prototype = {
select.disabled = true; select.disabled = true;
} }
}); });
this.syncCheckboxControlToPref_('readAfterClose', 'readAfterClose');
chrome.commandLinePrivate.hasSwitch(
'enable-experimental-accessibility-features',
(experimentalFeaturesEnabled) => {
let behaviorSection = document.getElementById('behavior');
behaviorSection.hidden = !experimentalFeaturesEnabled;
});
this.setUpHighlightListener_(); this.setUpHighlightListener_();
chrome.metricsPrivate.recordUserAction( chrome.metricsPrivate.recordUserAction(
'Accessibility.CrosSelectToSpeak.LoadSettings'); 'Accessibility.CrosSelectToSpeak.LoadSettings');
......
...@@ -204,6 +204,12 @@ ...@@ -204,6 +204,12 @@
<message desc="Label for highest synthesized speech pitch in the Select-to-speak options dialog." name="IDS_SELECT_TO_SPEAK_OPTIONS_PITCH_HIGHEST"> <message desc="Label for highest synthesized speech pitch in the Select-to-speak options dialog." name="IDS_SELECT_TO_SPEAK_OPTIONS_PITCH_HIGHEST">
Highest Highest
</message> </message>
<message desc="Group of options for controlling behavior" name="IDS_SELECT_TO_SPEAK_OPTIONS_BEHAVIOR">
Behavior
</message>
<message desc="Label for option to continue reading after text goes away, or stop when text goes away" name="IDS_SELECT_TO_SPEAK_OPTIONS_READ_AFTER_CLOSE">
Continue reading if text being spoken goes away
</message>
</messages> </messages>
</release> </release>
</grit> </grit>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment