Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: chrome/browser/resources/settings/languages_page/languages.js

Issue 2261903002: Fix race condition in MD Settings Languages page causing inconsistent settings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update histograms Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview 'settings-languages' handles Chrome's language and input 6 * @fileoverview 'settings-languages' handles Chrome's language and input
7 * method settings. The 'languages' property, which reflects the current 7 * method settings. The 'languages' property, which reflects the current
8 * language settings, must not be changed directly. Instead, changes to 8 * language settings, must not be changed directly. Instead, changes to
9 * language settings should be made using the LanguageHelper APIs provided by 9 * language settings should be made using the LanguageHelper APIs provided by
10 * this class via languageHelper. 10 * this class via languageHelper.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 }, 131 },
132 }, 132 },
133 133
134 observers: [ 134 observers: [
135 'preferredLanguagesPrefChanged_(' + 135 'preferredLanguagesPrefChanged_(' +
136 'prefs.' + preferredLanguagesPrefName + '.value, languages)', 136 'prefs.' + preferredLanguagesPrefName + '.value, languages)',
137 'spellCheckDictionariesPrefChanged_(' + 137 'spellCheckDictionariesPrefChanged_(' +
138 'prefs.spellcheck.dictionaries.value.*, languages)', 138 'prefs.spellcheck.dictionaries.value.*, languages)',
139 'translateLanguagesPrefChanged_(' + 139 'translateLanguagesPrefChanged_(' +
140 'prefs.translate_blocked_languages.value.*, languages)', 140 'prefs.translate_blocked_languages.value.*, languages)',
141 'prospectiveUILanguageChanged_(' + 141 'updateRemovableLanguages_(' +
142 'prefs.intl.app_locale.value, languages)', 142 'prefs.intl.app_locale.value, languages.enabled)',
143 // Observe Chrome OS prefs (ignored for non-Chrome OS). 143 // Observe Chrome OS prefs (ignored for non-Chrome OS).
144 'updateRemovableLanguages_(' + 144 'updateRemovableLanguages_(' +
145 'prefs.settings.language.preload_engines.value, ' + 145 'prefs.settings.language.preload_engines.value, ' +
146 'prefs.settings.language.enabled_extension_imes.value, ' + 146 'prefs.settings.language.enabled_extension_imes.value, ' +
147 'languages)', 147 'languages)',
148 ], 148 ],
149 149
150 /** @override */ 150 /** @override */
151 created: function() { 151 created: function() {
152 this.languageSettingsPrivate = 152 this.languageSettingsPrivate =
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 preferredLanguagesPrefChanged_: function() { 204 preferredLanguagesPrefChanged_: function() {
205 var enabledLanguageStates = 205 var enabledLanguageStates =
206 this.getEnabledLanguageStates_(this.languages.translateTarget); 206 this.getEnabledLanguageStates_(this.languages.translateTarget);
207 207
208 // Recreate the enabled language set before updating languages.enabled. 208 // Recreate the enabled language set before updating languages.enabled.
209 this.enabledLanguageSet_.clear(); 209 this.enabledLanguageSet_.clear();
210 for (var languageState of enabledLanguageStates) 210 for (var languageState of enabledLanguageStates)
211 this.enabledLanguageSet_.add(languageState.language.code); 211 this.enabledLanguageSet_.add(languageState.language.code);
212 212
213 this.set('languages.enabled', enabledLanguageStates); 213 this.set('languages.enabled', enabledLanguageStates);
214 this.updateRemovableLanguages_();
215 }, 214 },
216 215
217 /** 216 /**
218 * Updates the spellCheckEnabled state of each enabled language. 217 * Updates the spellCheckEnabled state of each enabled language.
219 * @private 218 * @private
220 */ 219 */
221 spellCheckDictionariesPrefChanged_: function() { 220 spellCheckDictionariesPrefChanged_: function() {
222 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */( 221 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */(
223 this.getPref('spellcheck.dictionaries').value)); 222 this.getPref('spellcheck.dictionaries').value));
224 for (var i = 0; i < this.languages.enabled.length; i++) { 223 for (var i = 0; i < this.languages.enabled.length; i++) {
(...skipping 11 matching lines...) Expand all
236 235
237 for (var i = 0; i < this.languages.enabled.length; i++) { 236 for (var i = 0; i < this.languages.enabled.length; i++) {
238 var translateCode = this.convertLanguageCodeForTranslate( 237 var translateCode = this.convertLanguageCodeForTranslate(
239 this.languages.enabled[i].language.code); 238 this.languages.enabled[i].language.code);
240 this.set( 239 this.set(
241 'languages.enabled.' + i + '.translateEnabled', 240 'languages.enabled.' + i + '.translateEnabled',
242 !translateBlockedSet.has(translateCode)); 241 !translateBlockedSet.has(translateCode));
243 } 242 }
244 }, 243 },
245 244
246 /** @private */
247 prospectiveUILanguageChanged_: function() {
248 this.updateRemovableLanguages_();
249 },
250
251 /** 245 /**
252 * Constructs the languages model. 246 * Constructs the languages model.
253 * @param {!Array<!chrome.languageSettingsPrivate.Language>} 247 * @param {!Array<!chrome.languageSettingsPrivate.Language>}
254 * supportedLanguages 248 * supportedLanguages
255 * @param {string} translateTarget Language code of the default translate 249 * @param {string} translateTarget Language code of the default translate
256 * target language. 250 * target language.
257 * @param {!Array<!chrome.languageSettingsPrivate.InputMethod>|undefined} 251 * @param {!Array<!chrome.languageSettingsPrivate.InputMethod>|undefined}
258 * supportedInputMethods Input methods (Chrome OS only). 252 * supportedInputMethods Input methods (Chrome OS only).
259 * @param {string|undefined} currentInputMethodId ID of the currently used 253 * @param {string|undefined} currentInputMethodId ID of the currently used
260 * input method (Chrome OS only). 254 * input method (Chrome OS only).
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 }, 462 },
469 463
470 /** 464 /**
471 * Enables the language, making it available for spell check and input. 465 * Enables the language, making it available for spell check and input.
472 * @param {string} languageCode 466 * @param {string} languageCode
473 */ 467 */
474 enableLanguage: function(languageCode) { 468 enableLanguage: function(languageCode) {
475 if (!CrSettingsPrefs.isInitialized) 469 if (!CrSettingsPrefs.isInitialized)
476 return; 470 return;
477 471
478 var languageCodes = 472 this.languageSettingsPrivate.enableLanguage(languageCode);
479 this.getPref(preferredLanguagesPrefName).value.split(',');
480 if (languageCodes.indexOf(languageCode) > -1)
481 return;
482 languageCodes.push(languageCode);
483 this.languageSettingsPrivate.setLanguageList(languageCodes);
484 this.disableTranslateLanguage(languageCode); 473 this.disableTranslateLanguage(languageCode);
485 }, 474 },
486 475
487 /** 476 /**
488 * Disables the language. 477 * Disables the language.
489 * @param {string} languageCode 478 * @param {string} languageCode
490 */ 479 */
491 disableLanguage: function(languageCode) { 480 disableLanguage: function(languageCode) {
492 if (!CrSettingsPrefs.isInitialized) 481 if (!CrSettingsPrefs.isInitialized)
493 return; 482 return;
(...skipping 11 matching lines...) Expand all
505 function(otherLanguageCode) { 494 function(otherLanguageCode) {
506 return otherLanguageCode != languageCode && 495 return otherLanguageCode != languageCode &&
507 this.isLanguageEnabled(otherLanguageCode); 496 this.isLanguageEnabled(otherLanguageCode);
508 }.bind(this)); 497 }.bind(this));
509 if (!supportsOtherEnabledLanguages) 498 if (!supportsOtherEnabledLanguages)
510 this.removeInputMethod(inputMethod.id); 499 this.removeInputMethod(inputMethod.id);
511 } 500 }
512 } 501 }
513 502
514 // Remove the language from preferred languages. 503 // Remove the language from preferred languages.
515 var languageCodes = 504 this.languageSettingsPrivate.disableLanguage(languageCode);
516 this.getPref(preferredLanguagesPrefName).value.split(',');
517 var languageIndex = languageCodes.indexOf(languageCode);
518 if (languageIndex == -1)
519 return;
520 languageCodes.splice(languageIndex, 1);
521 this.languageSettingsPrivate.setLanguageList(languageCodes);
522 this.enableTranslateLanguage(languageCode); 505 this.enableTranslateLanguage(languageCode);
523 }, 506 },
524 507
525 /** 508 /**
526 * @param {string} languageCode Language code for an enabled language. 509 * @param {string} languageCode Language code for an enabled language.
527 * @return {boolean} 510 * @return {boolean}
528 */ 511 */
529 canDisableLanguage: function(languageCode) { 512 canDisableLanguage: function(languageCode) {
530 // Cannot disable the prospective UI language. 513 // Cannot disable the prospective UI language.
531 if ((cr.isChromeOS || cr.isWindows) && 514 if (languageCode == this.getProspectiveUILanguage())
532 languageCode == this.getProspectiveUILanguage()) {
533 return false; 515 return false;
534 }
535 516
536 // Cannot disable the only enabled language. 517 // Cannot disable the only enabled language.
537 if (this.languages.enabled.length == 1) 518 if (this.languages.enabled.length == 1)
538 return false; 519 return false;
539 520
540 if (!cr.isChromeOS) 521 if (!cr.isChromeOS)
541 return true; 522 return true;
542 523
543 // If this is the only enabled language that is supported by all enabled 524 // If this is the only enabled language that is supported by all enabled
544 // component IMEs, it cannot be disabled because we need those IMEs. 525 // component IMEs, it cannot be disabled because we need those IMEs.
(...skipping 18 matching lines...) Expand all
563 * of the list. A Positive one moves the language toward the back. 544 * of the list. A Positive one moves the language toward the back.
564 */ 545 */
565 moveLanguage: function(languageCode, offset) { 546 moveLanguage: function(languageCode, offset) {
566 if (!CrSettingsPrefs.isInitialized) 547 if (!CrSettingsPrefs.isInitialized)
567 return; 548 return;
568 549
569 var languageCodes = 550 var languageCodes =
570 this.getPref(preferredLanguagesPrefName).value.split(','); 551 this.getPref(preferredLanguagesPrefName).value.split(',');
571 552
572 var originalIndex = languageCodes.indexOf(languageCode); 553 var originalIndex = languageCodes.indexOf(languageCode);
573 var newIndex = originalIndex + offset; 554 var newIndex = originalIndex;
574 if (originalIndex == -1 || newIndex < 0 || newIndex >= languageCodes.length) 555 var direction = Math.sign(offset);
575 return; 556 var distance = Math.abs(offset);
576 557
577 languageCodes.splice(originalIndex, 1); 558 // Step over the distance to find the target index.
578 languageCodes.splice(newIndex, 0, languageCode); 559 while (distance > 0) {
579 this.languageSettingsPrivate.setLanguageList(languageCodes); 560 newIndex += direction;
561 if (newIndex < 0 || newIndex >= languageCodes.length)
562 return;
563
564 // Skip over non-enabled languages, since they don't appear in the list
565 // (but we don't want to remove them).
566 if (this.enabledLanguageSet_.has(languageCodes[newIndex]))
567 distance--;
568 }
569
570 languageCodes[originalIndex] = languageCodes[newIndex];
571 languageCodes[newIndex] = languageCode;
572 this.setPrefValue(preferredLanguagesPrefName, languageCodes.join(','));
580 }, 573 },
581 574
582 /** 575 /**
583 * Enables translate for the given language by removing the translate 576 * Enables translate for the given language by removing the translate
584 * language from the blocked languages preference. 577 * language from the blocked languages preference.
585 * @param {string} languageCode 578 * @param {string} languageCode
586 */ 579 */
587 enableTranslateLanguage: function(languageCode) { 580 enableTranslateLanguage: function(languageCode) {
588 languageCode = this.convertLanguageCodeForTranslate(languageCode); 581 languageCode = this.convertLanguageCodeForTranslate(languageCode);
589 this.deletePrefListItem('translate_blocked_languages', languageCode); 582 this.deletePrefListItem('translate_blocked_languages', languageCode);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 this.updateEnabledInputMethods_(); 723 this.updateEnabledInputMethods_();
731 }, 724 },
732 725
733 /** @param {string} id Removed input method ID. */ 726 /** @param {string} id Removed input method ID. */
734 onInputMethodRemoved_: function(id) { 727 onInputMethodRemoved_: function(id) {
735 assert(cr.isChromeOS); 728 assert(cr.isChromeOS);
736 this.updateEnabledInputMethods_(); 729 this.updateEnabledInputMethods_();
737 }, 730 },
738 }); 731 });
739 })(); 732 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698