Commit f007456b authored by Josiah K's avatar Josiah K Committed by Commit Bot

Add Punctuation Echo Setting to ChromeVox Options Page - with fewer flakes


Same as original CL below, but with a less flaky test.
https://chromium-review.googlesource.com/c/chromium/src/+/2388402

Change-Id: Ie689601521e88affd7569ab1adfaad840660bc21
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2402579
Commit-Queue: Josiah Krutz <josiahk@google.com>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Reviewed-by: default avatarAkihiro Ota <akihiroota@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805860}
parent 230ce50a
......@@ -298,6 +298,39 @@ AbstractTts.FONT_WEIGHT = 'fontWeight';
/** TTS punctuation-echo property. @type {string} */
AbstractTts.PUNCTUATION_ECHO = 'punctuationEcho';
/**
* List of punctuation echoes that the user can cycle through.
* @type {!Array<{name:(string),
* msg:(string),
* regexp:(RegExp),
* clear:(boolean)}>}
*/
AbstractTts.PUNCTUATION_ECHOES = [
// Punctuation echoed for the 'none' option.
{
name: 'none',
msg: 'no_punctuation',
regexp: /[-$#"()*;:<>\n\\\/+='~`@_]/g,
clear: true
},
// Punctuation echoed for the 'some' option.
{
name: 'some',
msg: 'some_punctuation',
regexp: /[$#"*<>\\\/\{\}+=~`%\u2022]/g,
clear: false
},
// Punctuation echoed for the 'all' option.
{
name: 'all',
msg: 'all_punctuation',
regexp: /[-$#"()*;:<>\n\\\/\{\}\[\]+='~`!@_.,?%\u2022]/g,
clear: false
}
];
/** TTS pause property. @type {string} */
AbstractTts.PAUSE = 'pause';
......
......@@ -49,45 +49,6 @@ TtsBackground = class extends ChromeTtsBase {
this.currentPunctuationEcho_ =
parseInt(localStorage[AbstractTts.PUNCTUATION_ECHO] || 1, 10);
/**
* @type {!Array<{name:(string),
* msg:(string),
* regexp:(RegExp),
* clear:(boolean)}>}
* @private
*/
this.punctuationEchoes_ = [
/**
* Punctuation echoed for the 'none' option.
*/
{
name: 'none',
msg: 'no_punctuation',
regexp: /[-$#"()*;:<>\n\\\/+='~`@_]/g,
clear: true
},
/**
* Punctuation echoed for the 'some' option.
*/
{
name: 'some',
msg: 'some_punctuation',
regexp: /[$#"*<>\\\/\{\}+=~`%\u2022]/g,
clear: false
},
/**
* Punctuation echoed for the 'all' option.
*/
{
name: 'all',
msg: 'all_punctuation',
regexp: /[-$#"()*;:<>\n\\\/\{\}\[\]+='~`!@_.,?%\u2022]/g,
clear: false
}
];
/**
* A list of punctuation characters that should always be spliced into
* output even with literal word substitutions. This is important for tts
......@@ -653,17 +614,18 @@ TtsBackground = class extends ChromeTtsBase {
text = super.preprocess(text, properties);
// Perform any remaining processing such as punctuation expansion.
let pE = null;
let punctEcho = null;
if (properties[AbstractTts.PUNCTUATION_ECHO]) {
for (let i = 0; pE = this.punctuationEchoes_[i]; i++) {
if (properties[AbstractTts.PUNCTUATION_ECHO] == pE.name) {
for (let i = 0; punctEcho = AbstractTts.PUNCTUATION_ECHOES[i]; i++) {
if (properties[AbstractTts.PUNCTUATION_ECHO] == punctEcho.name) {
break;
}
}
} else {
pE = this.punctuationEchoes_[this.currentPunctuationEcho_];
punctEcho = AbstractTts.PUNCTUATION_ECHOES[this.currentPunctuationEcho_];
}
text = text.replace(pE.regexp, this.createPunctuationReplace_(pE.clear));
text = text.replace(
punctEcho.regexp, this.createPunctuationReplace_(punctEcho.clear));
// Remove all whitespace from the beginning and end, and collapse all
// inner strings of whitespace to a single space.
......@@ -706,15 +668,26 @@ TtsBackground = class extends ChromeTtsBase {
return previousValue == 0;
}
/**
* Method that updates the punctuation echo level, and also persists setting
* to local storage.
* @param {number} punctuationEcho The index of the desired punctuation echo
* level in AbstractTts.PUNCTUATION_ECHOES.
*/
updatePunctuationEcho(punctuationEcho) {
this.currentPunctuationEcho_ = punctuationEcho;
localStorage[AbstractTts.PUNCTUATION_ECHO] = punctuationEcho;
}
/**
* Method that cycles among the available punctuation echo levels.
* @return {string} The resulting punctuation level message id.
*/
cyclePunctuationEcho() {
this.currentPunctuationEcho_ =
(this.currentPunctuationEcho_ + 1) % this.punctuationEchoes_.length;
localStorage[AbstractTts.PUNCTUATION_ECHO] = this.currentPunctuationEcho_;
return this.punctuationEchoes_[this.currentPunctuationEcho_].msg;
this.updatePunctuationEcho(
(this.currentPunctuationEcho_ + 1) %
AbstractTts.PUNCTUATION_ECHOES.length);
return AbstractTts.PUNCTUATION_ECHOES[this.currentPunctuationEcho_].msg;
}
/**
......
......@@ -173,6 +173,56 @@ SYNC_TEST_F('ChromeVoxTtsBackgroundTest', 'AnnounceCapitalLetters', function() {
assertEquals('A.', preprocess('A.'));
});
SYNC_TEST_F('ChromeVoxTtsBackgroundTest', 'PunctuationMode', function() {
const PUNCTUATION_ECHO_NONE = '0';
const PUNCTUATION_ECHO_SOME = '1';
const PUNCTUATION_ECHO_ALL = '2';
const updatePunctuationEcho = tts.updatePunctuationEcho.bind(tts);
let lastSpokenTextString = '';
tts.speakUsingQueue_ = function(utterance, _) {
lastSpokenTextString = utterance.textString;
};
// No punctuation.
updatePunctuationEcho(PUNCTUATION_ECHO_NONE);
tts.speak(`"That's all, folks!"`);
assertEquals(`That's all, folks!`, lastSpokenTextString);
tts.speak('"$1,234.56 (plus tax) for 78% of your #2 pencils?", they mused');
assertEquals(
'1,234.56 plus tax for 78% of your 2 pencils? , they mused',
lastSpokenTextString);
// Some punctuation.
updatePunctuationEcho(PUNCTUATION_ECHO_SOME);
tts.speak(`"That's all, folks!"`);
assertEquals(`quote That's all, folks! quote`, lastSpokenTextString);
tts.speak('"$1,234.56 (plus tax) for 78% of your #2 pencils?", they mused');
assertEquals(
'quote dollar 1,234.56 (plus tax) for 78 percent of your pound 2 ' +
'pencils? quote , they mused',
lastSpokenTextString);
// All punctuation.
updatePunctuationEcho(PUNCTUATION_ECHO_ALL);
tts.speak(`"That's all, folks!"`);
assertEquals(
`quote That apostrophe' s all comma folks exclamation! quote`,
lastSpokenTextString);
tts.speak('"$1,234.56 (plus tax) for 78% of your #2 pencils?", they mused');
assertEquals(
'quote dollar 1 comma 234 dot 56 open paren plus tax close paren for ' +
'78 percent of your pound 2 pencils question mark? quote comma ' +
'they mused',
lastSpokenTextString);
});
SYNC_TEST_F('ChromeVoxTtsBackgroundTest', 'NumberReadingStyle', function() {
let lastSpokenTextString = '';
tts.speakUsingQueue_ = function(utterance, _) {
......
......@@ -102,6 +102,28 @@
</select>
</div>
<div class="option" id="punctuationEchoOption">
<label id="punctuationEchoLabel" class="i18n"
msgid="options_punctuation_echo_select_label">
Punctuation echo:
</label>
<select id="punctuationEcho" class="pref"
aria-labelledby="punctuationEchoLabel">
<option id="none" class="i18n"
msgid="options_punctuation_echo_none">
None
</option>
<option id="some" class="i18n"
msgid="options_punctuation_echo_some">
Some
</option>
<option id="all" class="i18n"
msgid="options_punctuation_echo_all">
All
</option>
</select>
</div>
<div class="option">
<label id="announceDownloadsLabel" class="i18n"
msgid="options_announce_download">
......
......@@ -9,10 +9,12 @@
goog.provide('OptionsPage');
goog.require('AbstractTts');
goog.require('BluetoothBrailleDisplayUI');
goog.require('ConsoleTts');
goog.require('Msgs');
goog.require('PanelCommand');
goog.require('TtsBackground');
goog.require('BrailleTable');
goog.require('BrailleTranslatorManager');
goog.require('ChromeVox');
......@@ -36,6 +38,8 @@ OptionsPage = class {
OptionsPage.prefs = chrome.extension.getBackgroundPage().prefs;
OptionsPage.consoleTts =
chrome.extension.getBackgroundPage().ConsoleTts.getInstance();
OptionsPage.backgroundTts =
chrome.extension.getBackgroundPage().ChromeVoxState.backgroundTts;
OptionsPage.populateVoicesSelect();
BrailleTable.getAll(function(tables) {
/** @type {!Array<BrailleTable.Table>} */
......@@ -101,6 +105,17 @@ OptionsPage = class {
}
}
if (localStorage[AbstractTts.PUNCTUATION_ECHO]) {
const currentPunctuationEcho =
AbstractTts
.PUNCTUATION_ECHOES[localStorage[AbstractTts.PUNCTUATION_ECHO]];
for (let i = 0, opt; opt = $('punctuationEcho').options[i]; ++i) {
if (opt.id == currentPunctuationEcho.name) {
opt.setAttribute('selected', '');
}
}
}
chrome.commandLinePrivate.hasSwitch(
'disable-experimental-accessibility-chromevox-language-switching',
(enabled) => {
......@@ -445,6 +460,11 @@ OptionsPage = class {
}
} else if (target.className.indexOf('eventstream') != -1) {
OptionsPage.setEventStreamFilter(target.name, target.checked);
} else if (target.id == 'punctuationEcho') {
const selectedPunctuationEcho = target.options[target.selectedIndex].id;
const punctuationEcho = AbstractTts.PUNCTUATION_ECHOES.findIndex(
echo => echo.name === selectedPunctuationEcho);
OptionsPage.backgroundTts.updatePunctuationEcho(punctuationEcho);
} else if (target.classList.contains('pref')) {
if (target.tagName == 'INPUT' && target.type == 'checkbox') {
OptionsPage.prefs.setPref(target.name, target.checked);
......@@ -487,11 +507,16 @@ OptionsPage = class {
OptionsPage.prefs;
/**
* The ChromeVoxConsoleTts object.
* The ConsoleTts object.
* @type {ConsoleTts}
*/
OptionsPage.consoleTts;
/**
* The TtsBackground object.
* @type {TtsBackground}
*/
OptionsPage.backgroundTts;
/**
* Adds event listeners to input boxes to update local storage values and
......
......@@ -84,6 +84,53 @@ TEST_F('ChromeVoxOptionsTest', 'NumberReadingStyleSelect', function() {
});
});
TEST_F('ChromeVoxOptionsTest', 'punctuationEchoSelect', function() {
this.runOnOptionsPage((mockFeedback, evt) => {
const PUNCTUATION_ECHO_NONE = '0';
const PUNCTUATION_ECHO_SOME = '1';
const PUNCTUATION_ECHO_ALL = '2';
const punctuationEchoSelect = evt.target.find({
role: chrome.automation.RoleType.POP_UP_BUTTON,
attributes: {name: 'Punctuation echo:'}
});
assertNotNullNorUndefined(punctuationEchoSelect);
mockFeedback.call(punctuationEchoSelect.focus.bind(punctuationEchoSelect))
.expectSpeech('Punctuation echo:', 'None', 'Collapsed')
.call(punctuationEchoSelect.doDefault.bind(punctuationEchoSelect))
.expectSpeech('Expanded')
// Before selecting the menu option.
.call(() => {
assertEquals(
PUNCTUATION_ECHO_NONE,
localStorage[AbstractTts.PUNCTUATION_ECHO]);
})
.call(press(40 /* ArrowDown */))
.expectSpeech('Some', 'List item', ' 2 of 3 ')
.call(press(13 /* enter */))
// TODO(josiahk): The underlying select behavior here is unexpected
// because we never get a new focus event for the select (moving us
// away from the menu item). We simply repeat the menu item.
.expectSpeech('Some', ' 2 of 3 ')
.call(() => {
assertEquals(
PUNCTUATION_ECHO_SOME,
localStorage[AbstractTts.PUNCTUATION_ECHO]);
})
.call(press(40 /* ArrowDown */))
.expectSpeech('All', ' 3 of 3 ')
.call(() => {
assertEquals(
PUNCTUATION_ECHO_ALL, localStorage[AbstractTts.PUNCTUATION_ECHO]);
})
.replay();
});
});
TEST_F('ChromeVoxOptionsTest', 'SmartStickyMode', function() {
this.runOnOptionsPage((mockFeedback, evt) => {
const smartStickyModeCheckbox = evt.target.find({
......
......@@ -2918,6 +2918,18 @@
<message desc="Describes an option for ChromeVox to read numbers as digits." name="IDS_CHROMEVOX_OPTIONS_NUMBER_READING_STYLE_DIGITS">
Digits
</message>
<message desc="Labels the select for choosing how ChromeVox reads punctuation." name="IDS_CHROMEVOX_OPTIONS_PUNCTUATION_ECHO_SELECT_LABEL">
Punctuation echo:
</message>
<message desc="Describes an option for ChromeVox to echo (speak) no punctuation." name="IDS_CHROMEVOX_OPTIONS_PUNCTUATION_ECHO_NONE">
None
</message>
<message desc="Describes an option for ChromeVox to echo (speak) some punctuation." name="IDS_CHROMEVOX_OPTIONS_PUNCTUATION_ECHO_SOME">
Some
</message>
<message desc="Describes an option for ChromeVox to echo (speak) all punctuation." name="IDS_CHROMEVOX_OPTIONS_PUNCTUATION_ECHO_ALL">
All
</message>
<message desc="Labels the checkbox on the options page that enables displaying Perkins Brailler commands in the ChromeVox menus." name="IDS_CHROMEVOX_OPTIONS_MENU_BRAILLE_COMMANDS">
Show braille commands in the ChromeVox menus
</message>
......
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