Commit 9dba103c authored by Katie D's avatar Katie D Committed by Commit Bot

Refactor a PrefsManager from SelectToSpeak.

This manages getting and processing user preferences, and is a pure
refactor with no functional changes.

Change-Id: I6cd82e188420424d37f5122bf571565e7dcdf5ac
Reviewed-on: https://chromium-review.googlesource.com/1143884
Commit-Queue: Katie Dektar <katie@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577040}
parent 4cd2d05b
...@@ -40,6 +40,7 @@ run_jsbundler("select_to_speak_copied_files") { ...@@ -40,6 +40,7 @@ run_jsbundler("select_to_speak_copied_files") {
"options.css", "options.css",
"options.html", "options.html",
"paragraph_utils.js", "paragraph_utils.js",
"prefs_manager.js",
"rect_utils.js", "rect_utils.js",
"select_to_speak.js", "select_to_speak.js",
"select_to_speak_gdocs_script.js", "select_to_speak_gdocs_script.js",
...@@ -175,6 +176,7 @@ js_type_check("closure_compile") { ...@@ -175,6 +176,7 @@ js_type_check("closure_compile") {
":metrics_utils", ":metrics_utils",
":node_utils", ":node_utils",
":paragraph_utils", ":paragraph_utils",
":prefs_manager",
":rect_utils", ":rect_utils",
":select_to_speak", ":select_to_speak",
":select_to_speak_options", ":select_to_speak_options",
...@@ -190,6 +192,7 @@ js_library("select_to_speak") { ...@@ -190,6 +192,7 @@ js_library("select_to_speak") {
":metrics_utils", ":metrics_utils",
":node_utils", ":node_utils",
":paragraph_utils", ":paragraph_utils",
":prefs_manager",
":rect_utils", ":rect_utils",
":word_utils", ":word_utils",
] ]
...@@ -252,7 +255,13 @@ js_library("input_handler") { ...@@ -252,7 +255,13 @@ js_library("input_handler") {
js_library("rect_utils") { js_library("rect_utils") {
} }
js_library("prefs_manager") {
}
js_library("metrics_utils") { js_library("metrics_utils") {
deps = [
":prefs_manager",
]
externs_list = [ "$externs_path/metrics_private.js" ] externs_list = [ "$externs_path/metrics_private.js" ]
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
"metrics_utils.js", "metrics_utils.js",
"node_utils.js", "node_utils.js",
"paragraph_utils.js", "paragraph_utils.js",
"prefs_manager.js",
"word_utils.js", "word_utils.js",
"rect_utils.js", "rect_utils.js",
"select_to_speak.js", "select_to_speak.js",
......
...@@ -135,22 +135,22 @@ MetricsUtils.speechPitchToSparceHistogramInt_ = function(speechPitch) { ...@@ -135,22 +135,22 @@ MetricsUtils.speechPitchToSparceHistogramInt_ = function(speechPitch) {
* Records an event that Select-to-Speak has begun speaking. * Records an event that Select-to-Speak has begun speaking.
* @param {number} method The CrosSelectToSpeakStartSpeechMethod enum * @param {number} method The CrosSelectToSpeakStartSpeechMethod enum
* that reflects how this event was triggered by the user. * that reflects how this event was triggered by the user.
* @param {number} speechRate The current speech rate. * @param {PrefsManager} prefsManager A PrefsManager with the users's current
* @param {number} speechPitch The current speech pitch. * preferences.
* @param {boolean} wordHighlightingEnabled If word highlighting is enabled.
* @public * @public
*/ */
MetricsUtils.recordStartEvent = function( MetricsUtils.recordStartEvent = function(method, prefsManager) {
method, speechRate, speechPitch, wordHighlightingEnabled) {
chrome.metricsPrivate.recordUserAction(MetricsUtils.START_SPEECH_METRIC); chrome.metricsPrivate.recordUserAction(MetricsUtils.START_SPEECH_METRIC);
chrome.metricsPrivate.recordSparseValue( chrome.metricsPrivate.recordSparseValue(
MetricsUtils.SPEECH_RATE_METRIC, MetricsUtils.SPEECH_RATE_METRIC,
MetricsUtils.speechRateToSparceHistogramInt_(speechRate)); MetricsUtils.speechRateToSparceHistogramInt_(prefsManager.speechRate()));
chrome.metricsPrivate.recordSparseValue( chrome.metricsPrivate.recordSparseValue(
MetricsUtils.SPEECH_PITCH_METRIC, MetricsUtils.SPEECH_PITCH_METRIC,
MetricsUtils.speechPitchToSparceHistogramInt_(speechPitch)); MetricsUtils.speechPitchToSparceHistogramInt_(
prefsManager.speechPitch()));
chrome.metricsPrivate.recordBoolean( chrome.metricsPrivate.recordBoolean(
MetricsUtils.WORD_HIGHLIGHTING_METRIC, wordHighlightingEnabled); MetricsUtils.WORD_HIGHLIGHTING_METRIC,
prefsManager.wordHighlightingEnabled());
chrome.metricsPrivate.recordEnumerationValue( chrome.metricsPrivate.recordEnumerationValue(
MetricsUtils.START_SPEECH_METHOD_METRIC.METRIC_NAME, method, MetricsUtils.START_SPEECH_METHOD_METRIC.METRIC_NAME, method,
MetricsUtils.START_SPEECH_METHOD_METRIC.EVENT_COUNT); MetricsUtils.START_SPEECH_METHOD_METRIC.EVENT_COUNT);
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Manages getting and storing user preferences.
* @constructor
*/
let PrefsManager = function() {
/** @private {?string} */
this.voiceNameFromPrefs_ = null;
/** @private {?string} */
this.voiceNameFromLocale_ = null;
/** @private {Set<string>} */
this.validVoiceNames_ = new Set();
/** @private {number} */
this.speechRate_ = 1.0;
/** @private {number} */
this.speechPitch_ = 1.0;
/** @private {boolean} */
this.wordHighlight_ = true;
/** @const {string} */
this.color_ = '#f73a98';
/** @private {string} */
this.highlightColor_ = '#5e9bff';
/**
* Get the list of TTS voices, and set the default voice if not already set.
* @private
*/
this.updateDefaultVoice_ = function() {
var uiLocale = chrome.i18n.getMessage('@@ui_locale');
uiLocale = uiLocale.replace('_', '-').toLowerCase();
chrome.tts.getVoices((voices) => {
this.validVoiceNames_ = new Set();
if (voices.length == 0)
return;
voices.forEach((voice) => {
if (!voice.eventTypes.includes('start') ||
!voice.eventTypes.includes('end') ||
!voice.eventTypes.includes('word') ||
!voice.eventTypes.includes('cancelled')) {
return;
}
this.validVoiceNames_.add(voice.voiceName);
});
voices.sort(function(a, b) {
function score(voice) {
if (voice.lang === undefined)
return -1;
var lang = voice.lang.toLowerCase();
var s = 0;
if (lang == uiLocale)
s += 2;
if (lang.substr(0, 2) == uiLocale.substr(0, 2))
s += 1;
return s;
}
return score(b) - score(a);
});
this.voiceNameFromLocale_ = voices[0].voiceName;
chrome.storage.sync.get(['voice'], (prefs) => {
if (!prefs['voice']) {
chrome.storage.sync.set({'voice': voices[0].voiceName});
}
});
});
};
};
/**
* Loads preferences from chrome.storage, sets default values if
* necessary, and registers a listener to update prefs when they
* change.
* @public
*/
PrefsManager.prototype.initPreferences = function() {
var updatePrefs = () => {
chrome.storage.sync.get(
['voice', 'rate', 'pitch', 'wordHighlight', 'highlightColor'],
(prefs) => {
if (prefs['voice']) {
this.voiceNameFromPrefs_ = prefs['voice'];
}
if (prefs['rate']) {
this.speechRate_ = parseFloat(prefs['rate']);
} else {
chrome.storage.sync.set({'rate': this.speechRate_});
}
if (prefs['pitch']) {
this.speechPitch_ = parseFloat(prefs['pitch']);
} else {
chrome.storage.sync.set({'pitch': this.speechPitch_});
}
if (prefs['wordHighlight'] !== undefined) {
this.wordHighlight_ = prefs['wordHighlight'];
} else {
chrome.storage.sync.set({'wordHighlight': this.wordHighlight_});
}
if (prefs['highlightColor']) {
this.highlightColor_ = prefs['highlightColor'];
} else {
chrome.storage.sync.set({'highlightColor': this.highlightColor_});
}
});
};
updatePrefs();
chrome.storage.onChanged.addListener(updatePrefs);
this.updateDefaultVoice_();
window.speechSynthesis.onvoiceschanged = (function() {
this.updateDefaultVoice_();
}).bind(this);
};
/**
* Generates the basic speech options for Select-to-Speak based on user
* preferences. Call for each chrome.tts.speak.
* @return {Object} options The TTS options.
* @public
*/
PrefsManager.prototype.speechOptions = function() {
let options = {
rate: this.speechRate_,
pitch: this.speechPitch_,
enqueue: true
};
// Pick the voice name from prefs first, or the one that matches
// the locale next, but don't pick a voice that isn't currently
// loaded. If no voices are found, leave the voiceName option
// unset to let the browser try to route the speech request
// anyway if possible.
var valid = '';
this.validVoiceNames_.forEach(function(voiceName) {
if (valid)
valid += ',';
valid += voiceName;
});
if (this.voiceNameFromPrefs_ &&
this.validVoiceNames_.has(this.voiceNameFromPrefs_)) {
options['voiceName'] = this.voiceNameFromPrefs_;
} else if (
this.voiceNameFromLocale_ &&
this.validVoiceNames_.has(this.voiceNameFromLocale_)) {
options['voiceName'] = this.voiceNameFromLocale_;
}
return options;
};
/**
* Gets the user's speech pitch preference.
* @return {number} The user-selected speech pitch.
* @public
*/
PrefsManager.prototype.speechPitch = function() {
return this.speechPitch_;
};
/**
* Gets the user's speech rate preference.
* @return {number} The user-selected speech rate.
* @public
*/
PrefsManager.prototype.speechRate = function() {
return this.speechRate_;
};
/**
* Gets the user's word highlighting enabled preference.
* @return {boolean} True if word highlighting is enabled.
* @public
*/
PrefsManager.prototype.wordHighlightingEnabled = function() {
return this.wordHighlight_;
};
/**
* Gets the user's word highlighting color preference.
* @return {string} Highlight color.
* @public
*/
PrefsManager.prototype.highlightColor = function() {
return this.highlightColor_;
};
/**
* Gets the focus ring color. This is not currently a user preference but it
* could be in the future; stored here for similarity to highlight color.
* @return {string} Highlight color.
* @public
*/
PrefsManager.prototype.focusRingColor = function() {
return this.color_;
};
\ No newline at end of file
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