Chromium Code Reviews| OLD | NEW |
|---|---|
| 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' provides convenient access to | 6 * @fileoverview 'settings-languages' handles Chrome's language and input |
| 7 * Chrome's language and input method settings. | 7 * method settings. The 'languages' property, which reflects the current |
| 8 * | 8 * language settings, must not be changed directly. Instead, changes to |
| 9 * Instances of this element have a 'languages' property, which reflects the | 9 * language settings should be made using settings.LanguageHelperImpl. |
| 10 * current language settings. The 'languages' property is read-only, meaning | |
| 11 * hosts using this element cannot change it directly. Instead, changes to | |
| 12 * language settings should be made using the LanguageHelperImpl singleton. | |
| 13 * | |
| 14 * Use upward binding syntax to propagate changes from child to host, so that | |
| 15 * changes made internally to 'languages' propagate to your host element: | |
| 16 * | |
| 17 * <template> | |
| 18 * <settings-languages languages="{{languages}}"> | |
| 19 * </settings-languages> | |
| 20 * <div>[[languages.someProperty]]</div> | |
| 21 * </template> | |
| 22 */ | 10 */ |
| 23 | 11 |
| 24 var SettingsLanguagesSingletonElement; | 12 cr.define('settings', function() { |
| 25 | |
| 26 cr.exportPath('languageSettings'); | |
| 27 | |
| 28 (function() { | |
| 29 'use strict'; | 13 'use strict'; |
|
michaelpg
2016/08/18 03:05:28
Everything inside this function will be indented (
stevenjb
2016/08/18 16:22:03
Thank you!
michaelpg
2016/08/18 22:32:27
I've further decided to leave it this way -- the h
| |
| 30 | 14 |
| 31 // Translate server treats some language codes the same. | 15 // Translate server treats some language codes the same. |
| 32 // See also: components/translate/core/common/translate_util.cc. | 16 // See also: components/translate/core/common/translate_util.cc. |
| 33 var kLanguageCodeToTranslateCode = { | 17 var kLanguageCodeToTranslateCode = { |
| 34 'nb': 'no', | 18 'nb': 'no', |
| 35 'fil': 'tl', | 19 'fil': 'tl', |
| 36 'zh-HK': 'zh-TW', | 20 'zh-HK': 'zh-TW', |
| 37 'zh-MO': 'zh-TW', | 21 'zh-MO': 'zh-TW', |
| 38 'zh-SG': 'zh-CN', | 22 'zh-SG': 'zh-CN', |
| 39 }; | 23 }; |
| 40 | 24 |
| 41 // Some ISO 639 language codes have been renamed, e.g. "he" to "iw", but | 25 // Some ISO 639 language codes have been renamed, e.g. "he" to "iw", but |
| 42 // Translate still uses the old versions. TODO(michaelpg): Chrome does too. | 26 // Translate still uses the old versions. TODO(michaelpg): Chrome does too. |
| 43 // Follow up with Translate owners to understand the right thing to do. | 27 // Follow up with Translate owners to understand the right thing to do. |
| 44 var kTranslateLanguageSynonyms = { | 28 var kTranslateLanguageSynonyms = { |
| 45 'he': 'iw', | 29 'he': 'iw', |
| 46 'jv': 'jw', | 30 'jv': 'jw', |
| 47 }; | 31 }; |
| 48 | 32 |
| 49 var preferredLanguagesPrefName = cr.isChromeOS ? | 33 var preferredLanguagesPrefName = cr.isChromeOS ? |
| 50 'settings.language.preferred_languages' : 'intl.accept_languages'; | 34 'settings.language.preferred_languages' : 'intl.accept_languages'; |
| 51 | 35 |
| 52 /** | 36 /** |
| 53 * Singleton element that generates the languages model on start-up and | 37 * Singleton element that generates the languages model on start-up and |
| 54 * updates it whenever Chrome's pref store and other settings change. These | 38 * updates it whenever Chrome's pref store and other settings change. |
| 55 * updates propagate to each <settings-language> instance so that their | |
| 56 * 'languages' property updates like any other Polymer property. | |
| 57 * @implements {LanguageHelper} | 39 * @implements {LanguageHelper} |
| 58 */ | 40 */ |
| 59 SettingsLanguagesSingletonElement = Polymer({ | 41 var SettingsLanguagesElement = Polymer({ |
| 60 is: 'settings-languages-singleton', | 42 is: 'settings-languages', |
| 61 | 43 |
| 62 behaviors: [PrefsBehavior], | 44 behaviors: [PrefsBehavior], |
| 63 | 45 |
| 64 properties: { | 46 properties: { |
| 65 /** | 47 /** |
| 66 * @type {!LanguagesModel|undefined} | 48 * @type {!LanguagesModel|undefined} |
| 67 */ | 49 */ |
| 68 languages: { | 50 languages: { |
| 69 type: Object, | 51 type: Object, |
| 70 notify: true, | 52 notify: true, |
| 53 readOnly: true, | |
| 71 }, | 54 }, |
| 72 | 55 |
| 73 /** | 56 /** |
| 74 * Object containing all preferences. | 57 * Object containing all preferences. |
| 75 */ | 58 */ |
| 76 prefs: { | 59 prefs: { |
| 77 type: Object, | 60 type: Object, |
| 78 notify: true, | 61 notify: true, |
| 79 }, | 62 }, |
| 80 | 63 |
| 81 /** | 64 /** |
| 82 * PromiseResolver to be resolved when the singleton has been initialized. | 65 * PromiseResolver to be resolved when the singleton has been initialized. |
| 83 * @private {!PromiseResolver} | 66 * @private {!PromiseResolver} |
| 84 */ | 67 */ |
| 85 resolver_: { | 68 resolver_: { |
| 86 type: Object, | 69 type: Object, |
| 87 value: function() { | 70 value: function() { |
| 88 return new PromiseResolver(); | 71 return new PromiseResolver(); |
| 89 }, | 72 }, |
| 90 }, | 73 }, |
| 91 | 74 |
| 92 /** @type {!LanguageSettingsPrivate} */ | 75 /** @type {!LanguageSettingsPrivate} */ |
| 93 languageSettingsPrivate: Object, | 76 languageSettingsPrivate: Object, |
| 94 | 77 |
| 95 /** @type {!InputMethodPrivate} */ | 78 /** @type {!InputMethodPrivate} */ |
| 96 inputMethodPrivate: Object, | 79 inputMethodPrivate: Object, |
| 80 | |
| 81 /** | |
| 82 * Hash map of supported languages by language codes for fast lookup. | |
| 83 * @private {!Map<string, !chrome.languageSettingsPrivate.Language>} | |
| 84 */ | |
| 85 supportedLanguageMap_: { | |
| 86 type: Object, | |
| 87 value: function() { return new Map(); }, | |
| 88 }, | |
| 89 | |
| 90 /** | |
| 91 * Hash set of enabled language codes for membership testing. | |
| 92 * @private {!Set<string>} | |
| 93 */ | |
| 94 enabledLanguageSet_: { | |
| 95 type: Object, | |
| 96 value: function() { return new Set(); }, | |
| 97 }, | |
| 98 | |
| 99 /** | |
| 100 * Hash map of supported input methods by ID for fast lookup. | |
| 101 * @private {!Map<string, chrome.languageSettingsPrivate.InputMethod>} | |
| 102 */ | |
| 103 supportedInputMethodMap_: { | |
| 104 type: Object, | |
| 105 value: function() { return new Map(); }, | |
| 106 }, | |
| 107 | |
| 108 /** | |
| 109 * Hash map of input methods supported for each language. | |
| 110 * @type {!Map<string, | |
| 111 * !Array<!chrome.languageSettingsPrivate.InputMethod>>} | |
| 112 * @private | |
| 113 */ | |
| 114 languageInputMethods_: { | |
| 115 type: Object, | |
| 116 value: function() { return new Map(); }, | |
| 117 }, | |
| 97 }, | 118 }, |
| 98 | 119 |
| 99 /** | |
| 100 * Hash map of supported languages by language codes for fast lookup. | |
| 101 * @private {!Map<string, !chrome.languageSettingsPrivate.Language>} | |
| 102 */ | |
| 103 supportedLanguageMap_: new Map(), | |
| 104 | |
| 105 /** | |
| 106 * Hash set of enabled language codes for membership testing. | |
| 107 * @private {!Set<string>} | |
| 108 */ | |
| 109 enabledLanguageSet_: new Set(), | |
| 110 | |
| 111 /** | |
| 112 * Hash map of supported input methods by ID for fast lookup. | |
| 113 * @private {!Map<string, chrome.languageSettingsPrivate.InputMethod>} | |
| 114 */ | |
| 115 supportedInputMethodMap_: new Map(), | |
| 116 | |
| 117 /** | |
| 118 * Hash map of input methods supported for each language. | |
| 119 * @type {!Map<string, !Array<!chrome.languageSettingsPrivate.InputMethod>>} | |
| 120 * @private | |
| 121 */ | |
| 122 languageInputMethods_: new Map(), | |
| 123 | |
| 124 observers: [ | 120 observers: [ |
| 125 'preferredLanguagesPrefChanged_(' + | 121 'preferredLanguagesPrefChanged_(' + |
| 126 'prefs.' + preferredLanguagesPrefName + '.value, languages)', | 122 'prefs.' + preferredLanguagesPrefName + '.value, languages)', |
| 127 'spellCheckDictionariesPrefChanged_(' + | 123 'spellCheckDictionariesPrefChanged_(' + |
| 128 'prefs.spellcheck.dictionaries.value.*, languages)', | 124 'prefs.spellcheck.dictionaries.value.*, languages)', |
| 129 'translateLanguagesPrefChanged_(' + | 125 'translateLanguagesPrefChanged_(' + |
| 130 'prefs.translate_blocked_languages.value.*, languages)', | 126 'prefs.translate_blocked_languages.value.*, languages)', |
| 131 'prospectiveUILanguageChanged_(' + | 127 'prospectiveUILanguageChanged_(' + |
| 132 'prefs.intl.app_locale.value, languages)', | 128 'prefs.intl.app_locale.value, languages)', |
| 133 // Observe Chrome OS prefs (ignored for non-Chrome OS). | 129 // Observe Chrome OS prefs (ignored for non-Chrome OS). |
| 134 'updateRemovableLanguages_(' + | 130 'updateRemovableLanguages_(' + |
| 135 'prefs.settings.language.preload_engines.value, ' + | 131 'prefs.settings.language.preload_engines.value, ' + |
| 136 'prefs.settings.language.enabled_extension_imes.value, ' + | 132 'prefs.settings.language.enabled_extension_imes.value, ' + |
| 137 'languages)', | 133 'languages)', |
| 138 ], | 134 ], |
| 139 | 135 |
| 140 /** @override */ | 136 /** @override */ |
| 141 created: function() { | 137 created: function() { |
| 138 // This element can now be used through the LanguageHelper API. | |
| 139 SettingsLanguagesElement.instance_ = /** @type {!LanguageHelper} */(this); | |
| 140 | |
| 142 this.languageSettingsPrivate = | 141 this.languageSettingsPrivate = |
| 143 languageSettings.languageSettingsPrivateApiForTest || | 142 settings.languageSettingsPrivateApiForTest || |
| 144 /** @type {!LanguageSettingsPrivate} */(chrome.languageSettingsPrivate); | 143 /** @type {!LanguageSettingsPrivate} */( |
| 144 chrome.languageSettingsPrivate); | |
| 145 | 145 |
| 146 this.inputMethodPrivate = | 146 this.inputMethodPrivate = |
| 147 languageSettings.inputMethodPrivateApiForTest || | 147 settings.inputMethodPrivateApiForTest || |
| 148 /** @type {!InputMethodPrivate} */(chrome.inputMethodPrivate); | 148 /** @type {!InputMethodPrivate} */(chrome.inputMethodPrivate); |
| 149 | 149 |
| 150 var promises = []; | 150 var promises = []; |
| 151 | 151 |
| 152 // Wait until prefs are initialized before creating the model, so we can | 152 // Wait until prefs are initialized before creating the model, so we can |
| 153 // include information about enabled languages. | 153 // include information about enabled languages. |
| 154 promises[0] = CrSettingsPrefs.initialized; | 154 promises[0] = CrSettingsPrefs.initialized; |
| 155 | 155 |
| 156 // Get the language list. | 156 // Get the language list. |
| 157 promises[1] = new Promise(function(resolve) { | 157 promises[1] = new Promise(function(resolve) { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 language.supportsSpellcheck = !!language.supportsSpellcheck; | 259 language.supportsSpellcheck = !!language.supportsSpellcheck; |
| 260 this.supportedLanguageMap_.set(language.code, language); | 260 this.supportedLanguageMap_.set(language.code, language); |
| 261 } | 261 } |
| 262 | 262 |
| 263 if (supportedInputMethods) { | 263 if (supportedInputMethods) { |
| 264 // Populate the hash map of supported input methods. | 264 // Populate the hash map of supported input methods. |
| 265 for (var inputMethod of supportedInputMethods) { | 265 for (var inputMethod of supportedInputMethods) { |
| 266 inputMethod.enabled = !!inputMethod.enabled; | 266 inputMethod.enabled = !!inputMethod.enabled; |
| 267 // Add the input method to the map of IDs. | 267 // Add the input method to the map of IDs. |
| 268 this.supportedInputMethodMap_.set(inputMethod.id, inputMethod); | 268 this.supportedInputMethodMap_.set(inputMethod.id, inputMethod); |
| 269 // Add the input method to the list of input methods for each language | 269 // Add the input method to the list of input methods for each |
| 270 // it supports. | 270 // language it supports. |
| 271 for (var languageCode of inputMethod.languageCodes) { | 271 for (var languageCode of inputMethod.languageCodes) { |
| 272 if (!this.supportedLanguageMap_.has(languageCode)) | 272 if (!this.supportedLanguageMap_.has(languageCode)) |
| 273 continue; | 273 continue; |
| 274 if (!this.languageInputMethods_.has(languageCode)) | 274 if (!this.languageInputMethods_.has(languageCode)) |
| 275 this.languageInputMethods_.set(languageCode, [inputMethod]); | 275 this.languageInputMethods_.set(languageCode, [inputMethod]); |
| 276 else | 276 else |
| 277 this.languageInputMethods_.get(languageCode).push(inputMethod); | 277 this.languageInputMethods_.get(languageCode).push(inputMethod); |
| 278 } | 278 } |
| 279 } | 279 } |
| 280 } | 280 } |
| 281 | 281 |
| 282 // Create a list of enabled languages from the supported languages. | 282 // Create a list of enabled languages from the supported languages. |
| 283 var enabledLanguageStates = this.getEnabledLanguageStates_(translateTarget); | 283 var enabledLanguageStates = |
| 284 this.getEnabledLanguageStates_(translateTarget); | |
| 285 | |
| 284 // Populate the hash set of enabled languages. | 286 // Populate the hash set of enabled languages. |
| 285 for (var languageState of enabledLanguageStates) | 287 for (var languageState of enabledLanguageStates) |
| 286 this.enabledLanguageSet_.add(languageState.language.code); | 288 this.enabledLanguageSet_.add(languageState.language.code); |
| 287 | 289 |
| 288 var model = /** @type {!LanguagesModel} */({ | 290 var model = /** @type {!LanguagesModel} */({ |
| 289 supported: supportedLanguages, | 291 supported: supportedLanguages, |
| 290 enabled: enabledLanguageStates, | 292 enabled: enabledLanguageStates, |
| 291 translateTarget: translateTarget, | 293 translateTarget: translateTarget, |
| 292 }); | 294 }); |
| 293 if (cr.isChromeOS) { | 295 if (cr.isChromeOS) { |
| 294 model.inputMethods = /** @type {!InputMethodsModel} */({ | 296 model.inputMethods = /** @type {!InputMethodsModel} */({ |
| 295 supported: supportedInputMethods, | 297 supported: supportedInputMethods, |
| 296 enabled: this.getEnabledInputMethods_(), | 298 enabled: this.getEnabledInputMethods_(), |
| 297 currentId: currentInputMethodId, | 299 currentId: currentInputMethodId, |
| 298 }); | 300 }); |
| 299 } | 301 } |
| 300 | 302 |
| 301 // Initialize the Polymer languages model. | 303 // Initialize the Polymer languages model. |
| 302 this.languages = model; | 304 this._setLanguages(model); |
| 303 }, | 305 }, |
| 304 | 306 |
| 305 /** | 307 /** |
| 306 * Returns a list of LanguageStates for each enabled language in the supported | 308 * Returns a list of LanguageStates for each enabled language in the |
| 307 * languages list. | 309 * supported languages list. |
| 308 * @param {string} translateTarget Language code of the default translate | 310 * @param {string} translateTarget Language code of the default translate |
| 309 * target language. | 311 * target language. |
| 310 * @return {!Array<!LanguageState>} | 312 * @return {!Array<!LanguageState>} |
| 311 * @private | 313 * @private |
| 312 */ | 314 */ |
| 313 getEnabledLanguageStates_: function(translateTarget) { | 315 getEnabledLanguageStates_: function(translateTarget) { |
| 314 assert(CrSettingsPrefs.isInitialized); | 316 assert(CrSettingsPrefs.isInitialized); |
| 315 | 317 |
| 316 var pref = this.getPref(preferredLanguagesPrefName); | 318 var pref = this.getPref(preferredLanguagesPrefName); |
| 317 var enabledLanguageCodes = pref.value.split(','); | 319 var enabledLanguageCodes = pref.value.split(','); |
| 318 var spellCheckPref = this.getPref('spellcheck.dictionaries'); | 320 var spellCheckPref = this.getPref('spellcheck.dictionaries'); |
| 319 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */( | 321 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */( |
| 320 spellCheckPref.value)); | 322 spellCheckPref.value)); |
| 321 | 323 |
| 322 var translateBlockedPref = this.getPref('translate_blocked_languages'); | 324 var translateBlockedPref = this.getPref('translate_blocked_languages'); |
| 323 var translateBlockedSet = this.makeSetFromArray_( | 325 var translateBlockedSet = this.makeSetFromArray_( |
| 324 /** @type {!Array<string>} */(translateBlockedPref.value)); | 326 /** @type {!Array<string>} */(translateBlockedPref.value)); |
| 325 | 327 |
| 326 var enabledLanguageStates = []; | 328 var enabledLanguageStates = []; |
| 327 for (var i = 0; i < enabledLanguageCodes.length; i++) { | 329 for (var i = 0; i < enabledLanguageCodes.length; i++) { |
| 328 var code = enabledLanguageCodes[i]; | 330 var code = enabledLanguageCodes[i]; |
| 329 var language = this.supportedLanguageMap_.get(code); | 331 var language = this.supportedLanguageMap_.get(code); |
| 330 // Skip unsupported languages. | 332 // Skip unsupported languages. |
| 331 if (!language) | 333 if (!language) |
| 332 continue; | 334 continue; |
| 333 var languageState = /** @type {LanguageState} */({}); | 335 var languageState = /** @type {LanguageState} */({}); |
| 334 languageState.language = language; | 336 languageState.language = language; |
| 335 languageState.spellCheckEnabled = !!spellCheckSet.has(code); | 337 languageState.spellCheckEnabled = !!spellCheckSet.has(code); |
| 336 // Translate is considered disabled if this language maps to any translate | 338 // Translate is considered disabled if this language maps to any |
| 337 // language that is blocked. | 339 // translate language that is blocked. |
| 338 var translateCode = this.convertLanguageCodeForTranslate(code); | 340 var translateCode = this.convertLanguageCodeForTranslate(code); |
| 339 languageState.translateEnabled = !!language.supportsTranslate && | 341 languageState.translateEnabled = !!language.supportsTranslate && |
| 340 !translateBlockedSet.has(translateCode) && | 342 !translateBlockedSet.has(translateCode) && |
| 341 translateCode != translateTarget; | 343 translateCode != translateTarget; |
| 342 enabledLanguageStates.push(languageState); | 344 enabledLanguageStates.push(languageState); |
| 343 } | 345 } |
| 344 return enabledLanguageStates; | 346 return enabledLanguageStates; |
| 345 }, | 347 }, |
| 346 | 348 |
| 347 /** | 349 /** |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 367 }, | 369 }, |
| 368 | 370 |
| 369 /** @private */ | 371 /** @private */ |
| 370 updateEnabledInputMethods_: function() { | 372 updateEnabledInputMethods_: function() { |
| 371 assert(cr.isChromeOS); | 373 assert(cr.isChromeOS); |
| 372 var enabledInputMethods = this.getEnabledInputMethods_(); | 374 var enabledInputMethods = this.getEnabledInputMethods_(); |
| 373 var enabledInputMethodSet = this.makeSetFromArray_(enabledInputMethods); | 375 var enabledInputMethodSet = this.makeSetFromArray_(enabledInputMethods); |
| 374 | 376 |
| 375 for (var i = 0; i < this.languages.inputMethods.supported.length; i++) { | 377 for (var i = 0; i < this.languages.inputMethods.supported.length; i++) { |
| 376 this.set('languages.inputMethods.supported.' + i + '.enabled', | 378 this.set('languages.inputMethods.supported.' + i + '.enabled', |
| 377 enabledInputMethodSet.has(this.languages.inputMethods.supported[i])); | 379 enabledInputMethodSet.has( |
| 380 this.languages.inputMethods.supported[i])); | |
| 378 } | 381 } |
| 379 this.set('languages.inputMethods.enabled', enabledInputMethods); | 382 this.set('languages.inputMethods.enabled', enabledInputMethods); |
| 380 }, | 383 }, |
| 381 | 384 |
| 382 /** | 385 /** |
| 383 * Updates the |removable| property of the enabled language states based | 386 * Updates the |removable| property of the enabled language states based |
| 384 * on what other languages and input methods are enabled. | 387 * on what other languages and input methods are enabled. |
| 385 * @private | 388 * @private |
| 386 */ | 389 */ |
| 387 updateRemovableLanguages_: function() { | 390 updateRemovableLanguages_: function() { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 416 // LanguageHelper implementation. | 419 // LanguageHelper implementation. |
| 417 // TODO(michaelpg): replace duplicate docs with @override once b/24294625 | 420 // TODO(michaelpg): replace duplicate docs with @override once b/24294625 |
| 418 // is fixed. | 421 // is fixed. |
| 419 | 422 |
| 420 /** @return {!Promise} */ | 423 /** @return {!Promise} */ |
| 421 whenReady: function() { | 424 whenReady: function() { |
| 422 return this.resolver_.promise; | 425 return this.resolver_.promise; |
| 423 }, | 426 }, |
| 424 | 427 |
| 425 /** | 428 /** |
| 426 * Sets the prospective UI language to the chosen language. This won't affect | 429 * Sets the prospective UI language to the chosen language. This won't |
| 427 * the actual UI language until a restart. | 430 * affect the actual UI language until a restart. |
| 428 * @param {string} languageCode | 431 * @param {string} languageCode |
| 429 */ | 432 */ |
| 430 setUILanguage: function(languageCode) { | 433 setUILanguage: function(languageCode) { |
| 431 assert(cr.isChromeOS || cr.isWindows); | 434 assert(cr.isChromeOS || cr.isWindows); |
| 432 chrome.send('setUILanguage', [languageCode]); | 435 chrome.send('setUILanguage', [languageCode]); |
| 433 }, | 436 }, |
| 434 | 437 |
| 435 /** Resets the prospective UI language back to the actual UI language. */ | 438 /** Resets the prospective UI language back to the actual UI language. */ |
| 436 resetUILanguage: function() { | 439 resetUILanguage: function() { |
| 437 assert(cr.isChromeOS || cr.isWindows); | 440 assert(cr.isChromeOS || cr.isWindows); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 480 */ | 483 */ |
| 481 disableLanguage: function(languageCode) { | 484 disableLanguage: function(languageCode) { |
| 482 if (!CrSettingsPrefs.isInitialized) | 485 if (!CrSettingsPrefs.isInitialized) |
| 483 return; | 486 return; |
| 484 | 487 |
| 485 assert(this.canDisableLanguage(languageCode)); | 488 assert(this.canDisableLanguage(languageCode)); |
| 486 | 489 |
| 487 // Remove the language from spell check. | 490 // Remove the language from spell check. |
| 488 this.deletePrefListItem('spellcheck.dictionaries', languageCode); | 491 this.deletePrefListItem('spellcheck.dictionaries', languageCode); |
| 489 | 492 |
| 493 // Remove input methods that don't support any other enabled language. | |
| 490 if (cr.isChromeOS) { | 494 if (cr.isChromeOS) { |
| 491 // Remove input methods that don't support any other enabled language. | |
| 492 var inputMethods = this.languageInputMethods_.get(languageCode) || []; | 495 var inputMethods = this.languageInputMethods_.get(languageCode) || []; |
| 493 for (var inputMethod of inputMethods) { | 496 for (var inputMethod of inputMethods) { |
| 494 var supportsOtherEnabledLanguages = inputMethod.languageCodes.some( | 497 var supportsOtherEnabledLanguages = inputMethod.languageCodes.some( |
| 495 function(otherLanguageCode) { | 498 function(otherLanguageCode) { |
| 496 return otherLanguageCode != languageCode && | 499 return otherLanguageCode != languageCode && |
| 497 this.isLanguageEnabled(otherLanguageCode); | 500 this.isLanguageEnabled(otherLanguageCode); |
| 498 }.bind(this)); | 501 }.bind(this)); |
| 499 if (!supportsOtherEnabledLanguages) | 502 if (!supportsOtherEnabledLanguages) |
| 500 this.removeInputMethod(inputMethod.id); | 503 this.removeInputMethod(inputMethod.id); |
| 501 } | 504 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 530 if (!cr.isChromeOS) | 533 if (!cr.isChromeOS) |
| 531 return true; | 534 return true; |
| 532 | 535 |
| 533 // If this is the only enabled language that is supported by all enabled | 536 // If this is the only enabled language that is supported by all enabled |
| 534 // component IMEs, it cannot be disabled because we need those IMEs. | 537 // component IMEs, it cannot be disabled because we need those IMEs. |
| 535 var otherInputMethodsEnabled = this.languages.enabled.some( | 538 var otherInputMethodsEnabled = this.languages.enabled.some( |
| 536 function(languageState) { | 539 function(languageState) { |
| 537 var otherLanguageCode = languageState.language.code; | 540 var otherLanguageCode = languageState.language.code; |
| 538 if (otherLanguageCode == languageCode) | 541 if (otherLanguageCode == languageCode) |
| 539 return false; | 542 return false; |
| 540 var inputMethods = this.languageInputMethods_.get(otherLanguageCode); | 543 var inputMethods = |
| 544 this.languageInputMethods_.get(otherLanguageCode); | |
| 541 return inputMethods && inputMethods.some(function(inputMethod) { | 545 return inputMethods && inputMethods.some(function(inputMethod) { |
| 542 return this.isComponentIme(inputMethod) && | 546 return this.isComponentIme(inputMethod) && |
| 543 this.supportedInputMethodMap_.get(inputMethod.id).enabled; | 547 this.supportedInputMethodMap_.get(inputMethod.id).enabled; |
| 544 }, this); | 548 }, this); |
| 545 }, this); | 549 }, this); |
| 546 return otherInputMethodsEnabled; | 550 return otherInputMethodsEnabled; |
| 547 }, | 551 }, |
| 548 | 552 |
| 549 /** | 553 /** |
| 550 * Moves the language in the list of enabled languages by the given offset. | 554 * Moves the language in the list of enabled languages by the given offset. |
| 551 * @param {string} languageCode | 555 * @param {string} languageCode |
| 552 * @param {number} offset Negative offset moves the language toward the front | 556 * @param {number} offset Negative offset moves the language toward the |
| 553 * of the list. A Positive one moves the language toward the back. | 557 * front of the list. A Positive one moves the language toward the back. |
| 554 */ | 558 */ |
| 555 moveLanguage: function(languageCode, offset) { | 559 moveLanguage: function(languageCode, offset) { |
| 556 if (!CrSettingsPrefs.isInitialized) | 560 if (!CrSettingsPrefs.isInitialized) |
| 557 return; | 561 return; |
| 558 | 562 |
| 559 var languageCodes = | 563 var languageCodes = |
| 560 this.getPref(preferredLanguagesPrefName).value.split(','); | 564 this.getPref(preferredLanguagesPrefName).value.split(','); |
| 561 | 565 |
| 562 var originalIndex = languageCodes.indexOf(languageCode); | 566 var originalIndex = languageCodes.indexOf(languageCode); |
| 563 var newIndex = originalIndex + offset; | 567 var newIndex = originalIndex + offset; |
| 564 if (originalIndex == -1 || newIndex < 0 || newIndex >= languageCodes.length) | 568 if (originalIndex == -1 || newIndex < 0 || |
| 569 newIndex >= languageCodes.length) { | |
| 565 return; | 570 return; |
| 571 } | |
| 566 | 572 |
| 567 languageCodes.splice(originalIndex, 1); | 573 languageCodes.splice(originalIndex, 1); |
| 568 languageCodes.splice(newIndex, 0, languageCode); | 574 languageCodes.splice(newIndex, 0, languageCode); |
| 569 this.languageSettingsPrivate.setLanguageList(languageCodes); | 575 this.languageSettingsPrivate.setLanguageList(languageCodes); |
| 570 }, | 576 }, |
| 571 | 577 |
| 572 /** | 578 /** |
| 573 * Enables translate for the given language by removing the translate | 579 * Enables translate for the given language by removing the translate |
| 574 * language from the blocked languages preference. | 580 * language from the blocked languages preference. |
| 575 * @param {string} languageCode | 581 * @param {string} languageCode |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 this.languageSettingsPrivate.removeInputMethod(id); | 685 this.languageSettingsPrivate.removeInputMethod(id); |
| 680 }, | 686 }, |
| 681 | 687 |
| 682 /** @param {string} id */ | 688 /** @param {string} id */ |
| 683 setCurrentInputMethod: function(id) { | 689 setCurrentInputMethod: function(id) { |
| 684 assert(cr.isChromeOS); | 690 assert(cr.isChromeOS); |
| 685 this.inputMethodPrivate.setCurrentInputMethod(id); | 691 this.inputMethodPrivate.setCurrentInputMethod(id); |
| 686 }, | 692 }, |
| 687 | 693 |
| 688 /** | 694 /** |
| 689 * param {string} languageCode | 695 * @param {string} languageCode |
| 690 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} | 696 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} |
| 691 */ | 697 */ |
| 692 getInputMethodsForLanguage: function(languageCode) { | 698 getInputMethodsForLanguage: function(languageCode) { |
| 693 return this.languageInputMethods_.get(languageCode) || []; | 699 return this.languageInputMethods_.get(languageCode) || []; |
| 694 }, | 700 }, |
| 695 | 701 |
| 696 /** | 702 /** |
| 697 * @param {!chrome.languageSettingsPrivate.InputMethod} inputMethod | 703 * @param {!chrome.languageSettingsPrivate.InputMethod} inputMethod |
| 698 * @return {boolean} | 704 * @return {boolean} |
| 699 */ | 705 */ |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 719 assert(cr.isChromeOS); | 725 assert(cr.isChromeOS); |
| 720 this.updateEnabledInputMethods_(); | 726 this.updateEnabledInputMethods_(); |
| 721 }, | 727 }, |
| 722 | 728 |
| 723 /** @param {string} id Removed input method ID. */ | 729 /** @param {string} id Removed input method ID. */ |
| 724 onInputMethodRemoved_: function(id) { | 730 onInputMethodRemoved_: function(id) { |
| 725 assert(cr.isChromeOS); | 731 assert(cr.isChromeOS); |
| 726 this.updateEnabledInputMethods_(); | 732 this.updateEnabledInputMethods_(); |
| 727 }, | 733 }, |
| 728 }); | 734 }); |
| 729 })(); | |
| 730 | 735 |
| 731 /** | 736 return { |
| 732 * A reference to the singleton under the guise of a LanguageHelper | 737 LanguageHelperImpl: SettingsLanguagesElement, |
| 733 * implementation. This provides a limited API but implies the singleton | 738 }; |
| 734 * should not be used directly for data binding. | 739 }); |
| 735 */ | |
| 736 var LanguageHelperImpl = SettingsLanguagesSingletonElement; | |
| 737 cr.addSingletonGetter(LanguageHelperImpl); | |
| 738 | 740 |
| 739 /** | 741 /** @return {!LanguageHelper} */ |
| 740 * This element has a reference to the singleton, exposing the singleton's | 742 settings.LanguageHelperImpl.getInstance = function() { |
| 741 * |languages| model to the host of this element. | 743 // <settings-languages> must have been created before this is called, so it |
| 742 */ | 744 // can set itself as the LanguageHelperImpl instance. |
| 743 Polymer({ | 745 return assert(settings.LanguageHelperImpl.instance_); |
| 744 is: 'settings-languages', | 746 }; |
| 745 | |
| 746 properties: { | |
| 747 /** | |
| 748 * A reference to the languages model from the singleton, exposed as a | |
| 749 * read-only property so hosts can bind to it, but not change it. | |
| 750 * @type {LanguagesModel|undefined} | |
| 751 */ | |
| 752 languages: { | |
| 753 type: Object, | |
| 754 notify: true, | |
| 755 readOnly: true, | |
| 756 }, | |
| 757 }, | |
| 758 | |
| 759 ready: function() { | |
| 760 var singleton = /** @type {!SettingsLanguagesSingletonElement} */ | |
| 761 (LanguageHelperImpl.getInstance()); | |
| 762 singleton.whenReady().then(function() { | |
| 763 // Set the 'languages' property to reference the singleton's model. | |
| 764 this._setLanguages(singleton.languages); | |
| 765 // Listen for changes to the singleton's languages property, so we know | |
| 766 // when to notify hosts of changes to (our reference to) the property. | |
| 767 this.listen(singleton, 'languages-changed', 'singletonLanguagesChanged_'); | |
| 768 }.bind(this)); | |
| 769 }, | |
| 770 | |
| 771 /** | |
| 772 * Takes changes reported by the singleton and forwards them to the host, | |
| 773 * manually sending a change notification for our 'languages' property (since | |
| 774 * it's the same object as the singleton's property, but isn't bound by | |
| 775 * Polymer). | |
| 776 * @private | |
| 777 */ | |
| 778 singletonLanguagesChanged_: function(e) { | |
| 779 // Forward the change notification to the host. | |
| 780 this.fire(e.type, e.detail, {bubbles: false}); | |
| 781 }, | |
| 782 }); | |
| OLD | NEW |