Commit 8d8f897c authored by Akihiro Ota's avatar Akihiro Ota Committed by Commit Bot

ChromeVox locale switching: perform exact comparison on locales.

Before this change, ChromeVox compared locales using the language
component. It treated zh-hant and zh-hans as the same, even though
they are completely different. This change fixes this behavior; we
now perform a strict comparison and alert the user if the locale
has changed in any way.

Bug: 1061222
Relnotes: N/A
Change-Id: I1b1fe89c43d9fa9cec0a7b35a21798e937263754
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2101717Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Commit-Queue: Akihiro Ota <akihiroota@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756426}
parent f3e896b4
...@@ -76,10 +76,10 @@ LocaleOutputHelper = class { ...@@ -76,10 +76,10 @@ LocaleOutputHelper = class {
contextNode.detectedLanguage || contextNode.language || ''; contextNode.detectedLanguage || contextNode.language || '';
const newLocale = this.computeNewLocale_(nodeLocale); const newLocale = this.computeNewLocale_(nodeLocale);
let outputString = text; let outputString = text;
const shouldUpdate = this.shouldUpdateLocale_(newLocale); const shouldAlert = newLocale !== this.currentLocale_;
if (this.hasVoiceForLocale_(newLocale)) { if (this.hasVoiceForLocale_(newLocale)) {
this.setCurrentLocale_(newLocale); this.setCurrentLocale_(newLocale);
if (shouldUpdate) { if (shouldAlert) {
// Prepend the human-readable locale to |outputString|. // Prepend the human-readable locale to |outputString|.
const displayLanguage = const displayLanguage =
chrome.accessibilityPrivate.getDisplayNameForLocale( chrome.accessibilityPrivate.getDisplayNameForLocale(
...@@ -116,24 +116,6 @@ LocaleOutputHelper = class { ...@@ -116,24 +116,6 @@ LocaleOutputHelper = class {
return LocaleOutputHelper.BROWSER_UI_LOCALE_; return LocaleOutputHelper.BROWSER_UI_LOCALE_;
} }
// TODO(akihiroota): http://crbug.com/1061222
/**
* Only compares the language components of each locale.
* Note: Locale validation is the responsibility of the caller.
* Ex: 'fr-fr' and 'fr-ca' have the same language component, but different
* country components. We would return false in the above case. Ex: 'fr-ca'
* and 'en-ca' have different language components, but the same country
* components. We would return true in the above case.
* @param {string} newLocale
* @return {boolean}
* @private
*/
shouldUpdateLocale_(newLocale) {
const newComponents = newLocale.split('-');
const currentComponents = this.currentLocale_.split('-');
return newComponents[0] !== currentComponents[0];
}
/** /**
* @param {string} targetLocale * @param {string} targetLocale
* @return {boolean} * @return {boolean}
......
...@@ -56,7 +56,7 @@ ChromeVoxLocaleOutputHelperTest = class extends ChromeVoxNextE2ETest { ...@@ -56,7 +56,7 @@ ChromeVoxLocaleOutputHelperTest = class extends ChromeVoxNextE2ETest {
callback([ callback([
{'lang': 'en-US'}, {'lang': 'fr-CA'}, {'lang': 'es-ES'}, {'lang': 'en-US'}, {'lang': 'fr-CA'}, {'lang': 'es-ES'},
{'lang': 'it-IT'}, {'lang': 'ja-JP'}, {'lang': 'ko-KR'}, {'lang': 'it-IT'}, {'lang': 'ja-JP'}, {'lang': 'ko-KR'},
{'lang': 'zh-TW'}, {'lang': 'ast'} {'lang': 'zh-TW'}, {'lang': 'ast'}, {'lang': 'pt'}
]); ]);
}; };
} }
...@@ -197,6 +197,26 @@ ChromeVoxLocaleOutputHelperTest = class extends ChromeVoxNextE2ETest { ...@@ -197,6 +197,26 @@ ChromeVoxLocaleOutputHelperTest = class extends ChromeVoxNextE2ETest {
<p lang="ur">Urdu text.</p> <p lang="ur">Urdu text.</p>
`; `;
} }
get chineseDoc() {
return `
<p lang="en-us">United States</p>
<p lang="zh">Chinese</p>
<p lang="zh-hans">Simplified Chinese</p>
<p lang="zh-hant">Traditional Chinese</p>
<p lang="zh">Chinese</p>
`;
}
get portugueseDoc() {
return `
<p lang="en-us">United States</p>
<p lang="pt">Portuguese</p>
<p lang="pt-br">Brazil</p>
<p lang="pt-pt">Portugal</p>
<p lang="pt">Portuguese</p>
`;
}
}; };
TEST_F( TEST_F(
...@@ -227,7 +247,7 @@ TEST_F( ...@@ -227,7 +247,7 @@ TEST_F(
this.setAvailableVoices(); this.setAvailableVoices();
mockFeedback.call(doCmd('jumpToTop')) mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLocale( .expectSpeechWithLocale(
'en', 'In the morning, I sometimes eat breakfast.'); 'en', 'English: In the morning, I sometimes eat breakfast.');
mockFeedback.call(doCmd('nextLine')) mockFeedback.call(doCmd('nextLine'))
.expectSpeechWithLocale( .expectSpeechWithLocale(
'fr', 'français: Dans l\'apres-midi, je dejeune.'); 'fr', 'français: Dans l\'apres-midi, je dejeune.');
...@@ -322,8 +342,9 @@ TEST_F( ...@@ -322,8 +342,9 @@ TEST_F(
mockFeedback.call(doCmd('jumpToTop')) mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLocale( .expectSpeechWithLocale(
'en', 'en',
'This entire object should be read in English, even' + 'English: This entire object should be read in English, even' +
' the following French passage: salut mon ami! Ca va? Bien, et toi? It\'s hard to' + ' the following French passage: ' +
'salut mon ami! Ca va? Bien, et toi? It\'s hard to' +
' differentiate between latin-based languages.'); ' differentiate between latin-based languages.');
mockFeedback.replay(); mockFeedback.replay();
}); });
...@@ -475,7 +496,7 @@ TEST_F('ChromeVoxLocaleOutputHelperTest', 'WordNavigationTest', function() { ...@@ -475,7 +496,7 @@ TEST_F('ChromeVoxLocaleOutputHelperTest', 'WordNavigationTest', function() {
this.setAvailableVoices(); this.setAvailableVoices();
mockFeedback.call(doCmd('jumpToTop')) mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLocale( .expectSpeechWithLocale(
'en', 'In the morning, I sometimes eat breakfast.') 'en', 'English: In the morning, I sometimes eat breakfast.')
.call(doCmd('nextLine')) .call(doCmd('nextLine'))
.expectSpeechWithLocale( .expectSpeechWithLocale(
'fr', 'français: Dans l\'apres-midi, je dejeune.') 'fr', 'français: Dans l\'apres-midi, je dejeune.')
...@@ -517,7 +538,7 @@ TEST_F( ...@@ -517,7 +538,7 @@ TEST_F(
this.setAvailableVoices(); this.setAvailableVoices();
mockFeedback.call(doCmd('jumpToTop')) mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLocale( .expectSpeechWithLocale(
'en', 'In the morning, I sometimes eat breakfast.') 'en', 'English: In the morning, I sometimes eat breakfast.')
.call(doCmd('nextLine')) .call(doCmd('nextLine'))
.expectSpeechWithLocale( .expectSpeechWithLocale(
'fr', 'français: Dans l\'apres-midi, je dejeune.') 'fr', 'français: Dans l\'apres-midi, je dejeune.')
...@@ -553,3 +574,47 @@ TEST_F( ...@@ -553,3 +574,47 @@ TEST_F(
.replay(); .replay();
}); });
}); });
TEST_F(
'ChromeVoxLocaleOutputHelperTest', 'SwitchBetweenChineseDialectsTest',
function() {
const mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.chineseDoc, function() {
localStorage['languageSwitching'] = 'true';
this.setAvailableVoices();
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLocale('en-us', 'United States')
.call(doCmd('nextLine'))
.expectSpeechWithLocale('zh', '中文: Chinese')
.call(doCmd('nextLine'))
.expectSpeechWithLocale(
'zh-hans', '中文(简体): Simplified Chinese')
.call(doCmd('nextLine'))
.expectSpeechWithLocale(
'zh-hant', '中文(繁體): Traditional Chinese')
.call(doCmd('nextLine'))
.expectSpeechWithLocale('zh', '中文: Chinese');
mockFeedback.replay();
});
});
TEST_F(
'ChromeVoxLocaleOutputHelperTest', 'SwitchBetweenPortugueseDialectsTest',
function() {
const mockFeedback = this.createMockFeedback();
this.runWithLoadedTree(this.portugueseDoc, function() {
localStorage['languageSwitching'] = 'true';
this.setAvailableVoices();
mockFeedback.call(doCmd('jumpToTop'))
.expectSpeechWithLocale('en-us', 'United States')
.call(doCmd('nextLine'))
.expectSpeechWithLocale('pt', 'português: Portuguese')
.call(doCmd('nextLine'))
.expectSpeechWithLocale('pt-br', 'português (Brasil): Brazil')
.call(doCmd('nextLine'))
.expectSpeechWithLocale('pt-pt', 'português (Portugal): Portugal')
.call(doCmd('nextLine'))
.expectSpeechWithLocale('pt', 'português: Portuguese');
mockFeedback.replay();
});
});
\ 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