| 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' 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. |
| 11 */ | 11 */ |
| 12 | 12 |
| 13 (function() { | 13 (function() { |
| 14 'use strict'; | 14 'use strict'; |
| 15 | 15 |
| 16 cr.exportPath('settings'); | 16 cr.exportPath('settings'); |
| 17 | 17 |
| 18 // Translate server treats some language codes the same. | 18 // Translate server treats some language codes the same. |
| 19 // See also: components/translate/core/common/translate_util.cc. | 19 // See also: components/translate/core/common/translate_util.cc. |
| 20 var kLanguageCodeToTranslateCode = { | 20 var kLanguageCodeToTranslateCode = { |
| 21 'nb': 'no', | 21 'nb': 'no', |
| 22 'fil': 'tl', | 22 'fil': 'tl', |
| 23 'zh-HK': 'zh-TW', | 23 'zh-HK': 'zh-TW', |
| 24 'zh-MO': 'zh-TW', | 24 'zh-MO': 'zh-TW', |
| 25 'zh-SG': 'zh-CN', | 25 'zh-SG': 'zh-CN', |
| 26 }; | 26 }; |
| 27 | 27 |
| 28 // Some ISO 639 language codes have been renamed, e.g. "he" to "iw", but | 28 // Some ISO 639 language codes have been renamed, e.g. "he" to "iw", but |
| 29 // Translate still uses the old versions. TODO(michaelpg): Chrome does too. | 29 // Translate still uses the old versions. TODO(michaelpg): Chrome does too. |
| 30 // Follow up with Translate owners to understand the right thing to do. | 30 // Follow up with Translate owners to understand the right thing to do. |
| 31 var kTranslateLanguageSynonyms = { | 31 var kTranslateLanguageSynonyms = { |
| 32 'he': 'iw', | 32 'he': 'iw', |
| 33 'jv': 'jw', | 33 'jv': 'jw', |
| 34 }; | 34 }; |
| 35 | 35 |
| 36 var preferredLanguagesPrefName = cr.isChromeOS ? | 36 var preferredLanguagesPrefName = cr.isChromeOS ? |
| 37 'settings.language.preferred_languages' : 'intl.accept_languages'; | 37 'settings.language.preferred_languages' : |
| 38 | 38 'intl.accept_languages'; |
| 39 /** | 39 |
| 40 * Singleton element that generates the languages model on start-up and | 40 /** |
| 41 * updates it whenever Chrome's pref store and other settings change. | 41 * Singleton element that generates the languages model on start-up and |
| 42 * @implements {LanguageHelper} | 42 * updates it whenever Chrome's pref store and other settings change. |
| 43 */ | 43 * @implements {LanguageHelper} |
| 44 Polymer({ | 44 */ |
| 45 is: 'settings-languages', | 45 Polymer({ |
| 46 | 46 is: 'settings-languages', |
| 47 behaviors: [PrefsBehavior], | 47 |
| 48 | 48 behaviors: [PrefsBehavior], |
| 49 properties: { | 49 |
| 50 /** | 50 properties: { |
| 51 * @type {!LanguagesModel|undefined} | 51 /** |
| 52 */ | 52 * @type {!LanguagesModel|undefined} |
| 53 languages: { | 53 */ |
| 54 type: Object, | 54 languages: { |
| 55 notify: true, | 55 type: Object, |
| 56 readOnly: true, | 56 notify: true, |
| 57 }, | 57 readOnly: true, |
| 58 | 58 }, |
| 59 /** | 59 |
| 60 * This element, as a LanguageHelper instance for API usage. | 60 /** |
| 61 * @type {!LanguageHelper} | 61 * This element, as a LanguageHelper instance for API usage. |
| 62 */ | 62 * @type {!LanguageHelper} |
| 63 languageHelper: { | 63 */ |
| 64 type: Object, | 64 languageHelper: { |
| 65 notify: true, | 65 type: Object, |
| 66 readOnly: true, | 66 notify: true, |
| 67 value: function() { return /** @type {!LanguageHelper} */(this); }, | 67 readOnly: true, |
| 68 }, | 68 value: function() { |
| 69 | 69 return /** @type {!LanguageHelper} */ (this); |
| 70 /** | 70 }, |
| 71 * PromiseResolver to be resolved when the singleton has been initialized. | 71 }, |
| 72 * @private {!PromiseResolver} | 72 |
| 73 */ | 73 /** |
| 74 resolver_: { | 74 * PromiseResolver to be resolved when the singleton has been initialized. |
| 75 type: Object, | 75 * @private {!PromiseResolver} |
| 76 value: function() { | 76 */ |
| 77 return new PromiseResolver(); | 77 resolver_: { |
| 78 }, | 78 type: Object, |
| 79 }, | 79 value: function() { |
| 80 | 80 return new PromiseResolver(); |
| 81 /** @type {!LanguageSettingsPrivate} */ | 81 }, |
| 82 languageSettingsPrivate: Object, | 82 }, |
| 83 | 83 |
| 84 /** @type {!InputMethodPrivate} */ | 84 /** @type {!LanguageSettingsPrivate} */ |
| 85 inputMethodPrivate: Object, | 85 languageSettingsPrivate: Object, |
| 86 | 86 |
| 87 /** | 87 /** @type {!InputMethodPrivate} */ |
| 88 * Hash map of supported languages by language codes for fast lookup. | 88 inputMethodPrivate: Object, |
| 89 * @private {!Map<string, !chrome.languageSettingsPrivate.Language>} | 89 |
| 90 */ | 90 /** |
| 91 supportedLanguageMap_: { | 91 * Hash map of supported languages by language codes for fast lookup. |
| 92 type: Object, | 92 * @private {!Map<string, !chrome.languageSettingsPrivate.Language>} |
| 93 value: function() { return new Map(); }, | 93 */ |
| 94 }, | 94 supportedLanguageMap_: { |
| 95 | 95 type: Object, |
| 96 /** | 96 value: function() { |
| 97 * Hash set of enabled language codes for membership testing. | 97 return new Map(); |
| 98 * @private {!Set<string>} | 98 }, |
| 99 */ | 99 }, |
| 100 enabledLanguageSet_: { | 100 |
| 101 type: Object, | 101 /** |
| 102 value: function() { return new Set(); }, | 102 * Hash set of enabled language codes for membership testing. |
| 103 }, | 103 * @private {!Set<string>} |
| 104 | 104 */ |
| 105 /** | 105 enabledLanguageSet_: { |
| 106 * Hash map of supported input methods by ID for fast lookup. | 106 type: Object, |
| 107 * @private {!Map<string, chrome.languageSettingsPrivate.InputMethod>} | 107 value: function() { |
| 108 */ | 108 return new Set(); |
| 109 supportedInputMethodMap_: { | 109 }, |
| 110 type: Object, | 110 }, |
| 111 value: function() { return new Map(); }, | 111 |
| 112 }, | 112 /** |
| 113 | 113 * Hash map of supported input methods by ID for fast lookup. |
| 114 /** | 114 * @private {!Map<string, chrome.languageSettingsPrivate.InputMethod>} |
| 115 * Hash map of input methods supported for each language. | 115 */ |
| 116 * @type {!Map<string, | 116 supportedInputMethodMap_: { |
| 117 * !Array<!chrome.languageSettingsPrivate.InputMethod>>} | 117 type: Object, |
| 118 value: function() { |
| 119 return new Map(); |
| 120 }, |
| 121 }, |
| 122 |
| 123 /** |
| 124 * Hash map of input methods supported for each language. |
| 125 * @type {!Map<string, |
| 126 * !Array<!chrome.languageSettingsPrivate.InputMethod>>} |
| 127 * @private |
| 128 */ |
| 129 languageInputMethods_: { |
| 130 type: Object, |
| 131 value: function() { |
| 132 return new Map(); |
| 133 }, |
| 134 }, |
| 135 |
| 136 /** @private Prospective UI language when the page was loaded. */ |
| 137 originalProspectiveUILanguage_: String, |
| 138 }, |
| 139 |
| 140 observers: [ |
| 141 // All observers wait for the model to be populated by including the |
| 142 // |languages| property. |
| 143 'prospectiveUILanguageChanged_(prefs.intl.app_locale.value, languages)', |
| 144 'preferredLanguagesPrefChanged_(' + |
| 145 'prefs.' + preferredLanguagesPrefName + '.value, languages)', |
| 146 'spellCheckDictionariesPrefChanged_(' + |
| 147 'prefs.spellcheck.dictionaries.value.*, languages)', |
| 148 'translateLanguagesPrefChanged_(' + |
| 149 'prefs.translate_blocked_languages.value.*, languages)', |
| 150 'updateRemovableLanguages_(' + |
| 151 'prefs.intl.app_locale.value, languages.enabled)', |
| 152 // Observe Chrome OS prefs (ignored for non-Chrome OS). |
| 153 'updateRemovableLanguages_(' + |
| 154 'prefs.settings.language.preload_engines.value, ' + |
| 155 'prefs.settings.language.enabled_extension_imes.value, ' + |
| 156 'languages)', |
| 157 ], |
| 158 |
| 159 /** @override */ |
| 160 created: function() { |
| 161 this.languageSettingsPrivate = |
| 162 settings.languageSettingsPrivateApiForTest || |
| 163 /** @type {!LanguageSettingsPrivate} */ ( |
| 164 chrome.languageSettingsPrivate); |
| 165 |
| 166 this.inputMethodPrivate = settings.inputMethodPrivateApiForTest || |
| 167 /** @type {!InputMethodPrivate} */ (chrome.inputMethodPrivate); |
| 168 |
| 169 var promises = []; |
| 170 |
| 171 // Wait until prefs are initialized before creating the model, so we can |
| 172 // include information about enabled languages. |
| 173 promises[0] = CrSettingsPrefs.initialized; |
| 174 |
| 175 // Get the language list. |
| 176 promises[1] = new Promise(function(resolve) { |
| 177 this.languageSettingsPrivate.getLanguageList(resolve); |
| 178 }.bind(this)); |
| 179 |
| 180 // Get the translate target language. |
| 181 promises[2] = new Promise(function(resolve) { |
| 182 this.languageSettingsPrivate.getTranslateTargetLanguage(resolve); |
| 183 }.bind(this)); |
| 184 |
| 185 if (cr.isChromeOS) { |
| 186 promises[3] = new Promise(function(resolve) { |
| 187 this.languageSettingsPrivate.getInputMethodLists(function(lists) { |
| 188 resolve(lists.componentExtensionImes.concat( |
| 189 lists.thirdPartyExtensionImes)); |
| 190 }); |
| 191 }.bind(this)); |
| 192 |
| 193 promises[4] = new Promise(function(resolve) { |
| 194 this.inputMethodPrivate.getCurrentInputMethod(resolve); |
| 195 }.bind(this)); |
| 196 } |
| 197 |
| 198 if (cr.isWindows || cr.isChromeOS) { |
| 199 // Fetch the starting UI language, which affects which actions should be |
| 200 // enabled. |
| 201 promises.push(cr.sendWithPromise('getProspectiveUILanguage') |
| 202 .then(function(prospectiveUILanguage) { |
| 203 this.originalProspectiveUILanguage_ = |
| 204 prospectiveUILanguage || |
| 205 window.navigator.language; |
| 206 }.bind(this))); |
| 207 } |
| 208 |
| 209 Promise.all(promises).then(function(results) { |
| 210 this.createModel_(results[1], results[2], results[3], results[4]); |
| 211 this.resolver_.resolve(); |
| 212 }.bind(this)); |
| 213 |
| 214 if (cr.isChromeOS) { |
| 215 this.inputMethodPrivate.onChanged.addListener( |
| 216 this.onInputMethodChanged_.bind(this)); |
| 217 } |
| 218 }, |
| 219 |
| 220 /** |
| 221 * Updates the prospective UI language based on the new pref value. |
| 222 * @param {string} prospectiveUILanguage |
| 118 * @private | 223 * @private |
| 119 */ | 224 */ |
| 120 languageInputMethods_: { | 225 prospectiveUILanguageChanged_: function(prospectiveUILanguage) { |
| 121 type: Object, | 226 this.set( |
| 122 value: function() { return new Map(); }, | 227 'languages.prospectiveUILanguage', |
| 123 }, | 228 prospectiveUILanguage || this.originalProspectiveUILanguage_); |
| 124 | 229 }, |
| 125 /** @private Prospective UI language when the page was loaded. */ | 230 |
| 126 originalProspectiveUILanguage_: String, | 231 /** |
| 127 }, | 232 * Updates the list of enabled languages from the preferred languages pref. |
| 128 | 233 * @private |
| 129 observers: [ | 234 */ |
| 130 // All observers wait for the model to be populated by including the | 235 preferredLanguagesPrefChanged_: function() { |
| 131 // |languages| property. | 236 var enabledLanguageStates = this.getEnabledLanguageStates_( |
| 132 'prospectiveUILanguageChanged_(prefs.intl.app_locale.value, languages)', | 237 this.languages.translateTarget, this.languages.prospectiveUILanguage); |
| 133 'preferredLanguagesPrefChanged_(' + | 238 |
| 134 'prefs.' + preferredLanguagesPrefName + '.value, languages)', | 239 // Recreate the enabled language set before updating languages.enabled. |
| 135 'spellCheckDictionariesPrefChanged_(' + | 240 this.enabledLanguageSet_.clear(); |
| 136 'prefs.spellcheck.dictionaries.value.*, languages)', | 241 for (var languageState of enabledLanguageStates) |
| 137 'translateLanguagesPrefChanged_(' + | 242 this.enabledLanguageSet_.add(languageState.language.code); |
| 138 'prefs.translate_blocked_languages.value.*, languages)', | 243 |
| 139 'updateRemovableLanguages_(' + | 244 this.set('languages.enabled', enabledLanguageStates); |
| 140 'prefs.intl.app_locale.value, languages.enabled)', | 245 }, |
| 141 // Observe Chrome OS prefs (ignored for non-Chrome OS). | 246 |
| 142 'updateRemovableLanguages_(' + | 247 /** |
| 143 'prefs.settings.language.preload_engines.value, ' + | 248 * Updates the spellCheckEnabled state of each enabled language. |
| 144 'prefs.settings.language.enabled_extension_imes.value, ' + | 249 * @private |
| 145 'languages)', | 250 */ |
| 146 ], | 251 spellCheckDictionariesPrefChanged_: function() { |
| 147 | 252 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */ ( |
| 148 /** @override */ | 253 this.getPref('spellcheck.dictionaries').value)); |
| 149 created: function() { | 254 for (var i = 0; i < this.languages.enabled.length; i++) { |
| 150 this.languageSettingsPrivate = | 255 var languageState = this.languages.enabled[i]; |
| 151 settings.languageSettingsPrivateApiForTest || | 256 this.set( |
| 152 /** @type {!LanguageSettingsPrivate} */(chrome.languageSettingsPrivate); | 257 'languages.enabled.' + i + '.spellCheckEnabled', |
| 153 | 258 !!spellCheckSet.has(languageState.language.code)); |
| 154 this.inputMethodPrivate = | 259 } |
| 155 settings.inputMethodPrivateApiForTest || | 260 }, |
| 156 /** @type {!InputMethodPrivate} */(chrome.inputMethodPrivate); | 261 |
| 157 | 262 /** @private */ |
| 158 var promises = []; | 263 translateLanguagesPrefChanged_: function() { |
| 159 | 264 var translateBlockedPref = this.getPref('translate_blocked_languages'); |
| 160 // Wait until prefs are initialized before creating the model, so we can | 265 var translateBlockedSet = this.makeSetFromArray_( |
| 161 // include information about enabled languages. | 266 /** @type {!Array<string>} */ (translateBlockedPref.value)); |
| 162 promises[0] = CrSettingsPrefs.initialized; | 267 |
| 163 | 268 for (var i = 0; i < this.languages.enabled.length; i++) { |
| 164 // Get the language list. | 269 if (this.languages.enabled[i].language.code == |
| 165 promises[1] = new Promise(function(resolve) { | 270 this.languages.prospectiveUILanguage) { |
| 166 this.languageSettingsPrivate.getLanguageList(resolve); | 271 continue; |
| 167 }.bind(this)); | 272 } |
| 168 | 273 var translateCode = this.convertLanguageCodeForTranslate( |
| 169 // Get the translate target language. | 274 this.languages.enabled[i].language.code); |
| 170 promises[2] = new Promise(function(resolve) { | 275 this.set( |
| 171 this.languageSettingsPrivate.getTranslateTargetLanguage(resolve); | 276 'languages.enabled.' + i + '.translateEnabled', |
| 172 }.bind(this)); | 277 !translateBlockedSet.has(translateCode)); |
| 173 | 278 } |
| 174 if (cr.isChromeOS) { | 279 }, |
| 175 promises[3] = new Promise(function(resolve) { | 280 |
| 176 this.languageSettingsPrivate.getInputMethodLists(function(lists) { | 281 /** |
| 177 resolve(lists.componentExtensionImes.concat( | 282 * Constructs the languages model. |
| 178 lists.thirdPartyExtensionImes)); | 283 * @param {!Array<!chrome.languageSettingsPrivate.Language>} |
| 284 * supportedLanguages |
| 285 * @param {string} translateTarget Language code of the default translate |
| 286 * target language. |
| 287 * @param {!Array<!chrome.languageSettingsPrivate.InputMethod>|undefined} |
| 288 * supportedInputMethods Input methods (Chrome OS only). |
| 289 * @param {string|undefined} currentInputMethodId ID of the currently used |
| 290 * input method (Chrome OS only). |
| 291 * @private |
| 292 */ |
| 293 createModel_: function( |
| 294 supportedLanguages, translateTarget, supportedInputMethods, |
| 295 currentInputMethodId) { |
| 296 // Populate the hash map of supported languages. |
| 297 for (var language of supportedLanguages) { |
| 298 language.supportsUI = !!language.supportsUI; |
| 299 language.supportsTranslate = !!language.supportsTranslate; |
| 300 language.supportsSpellcheck = !!language.supportsSpellcheck; |
| 301 this.supportedLanguageMap_.set(language.code, language); |
| 302 } |
| 303 |
| 304 if (supportedInputMethods) { |
| 305 // Populate the hash map of supported input methods. |
| 306 for (var inputMethod of supportedInputMethods) { |
| 307 inputMethod.enabled = !!inputMethod.enabled; |
| 308 // Add the input method to the map of IDs. |
| 309 this.supportedInputMethodMap_.set(inputMethod.id, inputMethod); |
| 310 // Add the input method to the list of input methods for each language |
| 311 // it supports. |
| 312 for (var languageCode of inputMethod.languageCodes) { |
| 313 if (!this.supportedLanguageMap_.has(languageCode)) |
| 314 continue; |
| 315 if (!this.languageInputMethods_.has(languageCode)) |
| 316 this.languageInputMethods_.set(languageCode, [inputMethod]); |
| 317 else |
| 318 this.languageInputMethods_.get(languageCode).push(inputMethod); |
| 319 } |
| 320 } |
| 321 } |
| 322 |
| 323 var prospectiveUILanguage; |
| 324 if (cr.isChromeOS || cr.isWindows) { |
| 325 prospectiveUILanguage = |
| 326 /** @type {string} */ (this.getPref('intl.app_locale').value) || |
| 327 this.originalProspectiveUILanguage_; |
| 328 } |
| 329 |
| 330 // Create a list of enabled languages from the supported languages. |
| 331 var enabledLanguageStates = this.getEnabledLanguageStates_( |
| 332 translateTarget, prospectiveUILanguage); |
| 333 // Populate the hash set of enabled languages. |
| 334 for (var languageState of enabledLanguageStates) |
| 335 this.enabledLanguageSet_.add(languageState.language.code); |
| 336 |
| 337 var model = /** @type {!LanguagesModel} */ ({ |
| 338 supported: supportedLanguages, |
| 339 enabled: enabledLanguageStates, |
| 340 translateTarget: translateTarget, |
| 341 }); |
| 342 |
| 343 if (cr.isChromeOS || cr.isWindows) |
| 344 model.prospectiveUILanguage = prospectiveUILanguage; |
| 345 |
| 346 if (cr.isChromeOS) { |
| 347 model.inputMethods = /** @type {!InputMethodsModel} */ ({ |
| 348 supported: supportedInputMethods, |
| 349 enabled: this.getEnabledInputMethods_(), |
| 350 currentId: currentInputMethodId, |
| 179 }); | 351 }); |
| 180 }.bind(this)); | 352 } |
| 181 | 353 |
| 182 promises[4] = new Promise(function(resolve) { | 354 // Initialize the Polymer languages model. |
| 183 this.inputMethodPrivate.getCurrentInputMethod(resolve); | 355 this._setLanguages(model); |
| 184 }.bind(this)); | 356 }, |
| 185 } | 357 |
| 186 | 358 /** |
| 187 if (cr.isWindows || cr.isChromeOS) { | |
| 188 // Fetch the starting UI language, which affects which actions should be | |
| 189 // enabled. | |
| 190 promises.push(cr.sendWithPromise('getProspectiveUILanguage').then( | |
| 191 function(prospectiveUILanguage) { | |
| 192 this.originalProspectiveUILanguage_ = | |
| 193 prospectiveUILanguage || window.navigator.language; | |
| 194 }.bind(this))); | |
| 195 } | |
| 196 | |
| 197 Promise.all(promises).then(function(results) { | |
| 198 this.createModel_(results[1], results[2], results[3], results[4]); | |
| 199 this.resolver_.resolve(); | |
| 200 }.bind(this)); | |
| 201 | |
| 202 if (cr.isChromeOS) { | |
| 203 this.inputMethodPrivate.onChanged.addListener( | |
| 204 this.onInputMethodChanged_.bind(this)); | |
| 205 } | |
| 206 }, | |
| 207 | |
| 208 /** | |
| 209 * Updates the prospective UI language based on the new pref value. | |
| 210 * @param {string} prospectiveUILanguage | |
| 211 * @private | |
| 212 */ | |
| 213 prospectiveUILanguageChanged_: function(prospectiveUILanguage) { | |
| 214 this.set('languages.prospectiveUILanguage', | |
| 215 prospectiveUILanguage || this.originalProspectiveUILanguage_); | |
| 216 }, | |
| 217 | |
| 218 /** | |
| 219 * Updates the list of enabled languages from the preferred languages pref. | |
| 220 * @private | |
| 221 */ | |
| 222 preferredLanguagesPrefChanged_: function() { | |
| 223 var enabledLanguageStates = this.getEnabledLanguageStates_( | |
| 224 this.languages.translateTarget, this.languages.prospectiveUILanguage); | |
| 225 | |
| 226 // Recreate the enabled language set before updating languages.enabled. | |
| 227 this.enabledLanguageSet_.clear(); | |
| 228 for (var languageState of enabledLanguageStates) | |
| 229 this.enabledLanguageSet_.add(languageState.language.code); | |
| 230 | |
| 231 this.set('languages.enabled', enabledLanguageStates); | |
| 232 }, | |
| 233 | |
| 234 /** | |
| 235 * Updates the spellCheckEnabled state of each enabled language. | |
| 236 * @private | |
| 237 */ | |
| 238 spellCheckDictionariesPrefChanged_: function() { | |
| 239 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */( | |
| 240 this.getPref('spellcheck.dictionaries').value)); | |
| 241 for (var i = 0; i < this.languages.enabled.length; i++) { | |
| 242 var languageState = this.languages.enabled[i]; | |
| 243 this.set('languages.enabled.' + i + '.spellCheckEnabled', | |
| 244 !!spellCheckSet.has(languageState.language.code)); | |
| 245 } | |
| 246 }, | |
| 247 | |
| 248 /** @private */ | |
| 249 translateLanguagesPrefChanged_: function() { | |
| 250 var translateBlockedPref = this.getPref('translate_blocked_languages'); | |
| 251 var translateBlockedSet = this.makeSetFromArray_( | |
| 252 /** @type {!Array<string>} */(translateBlockedPref.value)); | |
| 253 | |
| 254 for (var i = 0; i < this.languages.enabled.length; i++) { | |
| 255 if (this.languages.enabled[i].language.code == | |
| 256 this.languages.prospectiveUILanguage) { | |
| 257 continue; | |
| 258 } | |
| 259 var translateCode = this.convertLanguageCodeForTranslate( | |
| 260 this.languages.enabled[i].language.code); | |
| 261 this.set( | |
| 262 'languages.enabled.' + i + '.translateEnabled', | |
| 263 !translateBlockedSet.has(translateCode)); | |
| 264 } | |
| 265 }, | |
| 266 | |
| 267 /** | |
| 268 * Constructs the languages model. | |
| 269 * @param {!Array<!chrome.languageSettingsPrivate.Language>} | |
| 270 * supportedLanguages | |
| 271 * @param {string} translateTarget Language code of the default translate | |
| 272 * target language. | |
| 273 * @param {!Array<!chrome.languageSettingsPrivate.InputMethod>|undefined} | |
| 274 * supportedInputMethods Input methods (Chrome OS only). | |
| 275 * @param {string|undefined} currentInputMethodId ID of the currently used | |
| 276 * input method (Chrome OS only). | |
| 277 * @private | |
| 278 */ | |
| 279 createModel_: function(supportedLanguages, translateTarget, | |
| 280 supportedInputMethods, currentInputMethodId) { | |
| 281 // Populate the hash map of supported languages. | |
| 282 for (var language of supportedLanguages) { | |
| 283 language.supportsUI = !!language.supportsUI; | |
| 284 language.supportsTranslate = !!language.supportsTranslate; | |
| 285 language.supportsSpellcheck = !!language.supportsSpellcheck; | |
| 286 this.supportedLanguageMap_.set(language.code, language); | |
| 287 } | |
| 288 | |
| 289 if (supportedInputMethods) { | |
| 290 // Populate the hash map of supported input methods. | |
| 291 for (var inputMethod of supportedInputMethods) { | |
| 292 inputMethod.enabled = !!inputMethod.enabled; | |
| 293 // Add the input method to the map of IDs. | |
| 294 this.supportedInputMethodMap_.set(inputMethod.id, inputMethod); | |
| 295 // Add the input method to the list of input methods for each language | |
| 296 // it supports. | |
| 297 for (var languageCode of inputMethod.languageCodes) { | |
| 298 if (!this.supportedLanguageMap_.has(languageCode)) | |
| 299 continue; | |
| 300 if (!this.languageInputMethods_.has(languageCode)) | |
| 301 this.languageInputMethods_.set(languageCode, [inputMethod]); | |
| 302 else | |
| 303 this.languageInputMethods_.get(languageCode).push(inputMethod); | |
| 304 } | |
| 305 } | |
| 306 } | |
| 307 | |
| 308 var prospectiveUILanguage; | |
| 309 if (cr.isChromeOS || cr.isWindows) { | |
| 310 prospectiveUILanguage = | |
| 311 /** @type {string} */(this.getPref('intl.app_locale').value) || | |
| 312 this.originalProspectiveUILanguage_; | |
| 313 } | |
| 314 | |
| 315 // Create a list of enabled languages from the supported languages. | |
| 316 var enabledLanguageStates = | |
| 317 this.getEnabledLanguageStates_(translateTarget, prospectiveUILanguage); | |
| 318 // Populate the hash set of enabled languages. | |
| 319 for (var languageState of enabledLanguageStates) | |
| 320 this.enabledLanguageSet_.add(languageState.language.code); | |
| 321 | |
| 322 var model = /** @type {!LanguagesModel} */({ | |
| 323 supported: supportedLanguages, | |
| 324 enabled: enabledLanguageStates, | |
| 325 translateTarget: translateTarget, | |
| 326 }); | |
| 327 | |
| 328 if (cr.isChromeOS || cr.isWindows) | |
| 329 model.prospectiveUILanguage = prospectiveUILanguage; | |
| 330 | |
| 331 if (cr.isChromeOS) { | |
| 332 model.inputMethods = /** @type {!InputMethodsModel} */({ | |
| 333 supported: supportedInputMethods, | |
| 334 enabled: this.getEnabledInputMethods_(), | |
| 335 currentId: currentInputMethodId, | |
| 336 }); | |
| 337 } | |
| 338 | |
| 339 // Initialize the Polymer languages model. | |
| 340 this._setLanguages(model); | |
| 341 }, | |
| 342 | |
| 343 /** | |
| 344 * Returns a list of LanguageStates for each enabled language in the supported | 359 * Returns a list of LanguageStates for each enabled language in the supported |
| 345 * languages list. | 360 * languages list. |
| 346 * @param {string} translateTarget Language code of the default translate | 361 * @param {string} translateTarget Language code of the default translate |
| 347 * target language. | 362 * target language. |
| 348 * @param {(string|undefined)} prospectiveUILanguage Prospective UI display | 363 * @param {(string|undefined)} prospectiveUILanguage Prospective UI display |
| 349 * language. Only defined on Windows and Chrome OS. | 364 * language. Only defined on Windows and Chrome OS. |
| 350 * @return {!Array<!LanguageState>} | 365 * @return {!Array<!LanguageState>} |
| 351 * @private | 366 * @private |
| 352 */ | 367 */ |
| 353 getEnabledLanguageStates_: function(translateTarget, prospectiveUILanguage) { | 368 getEnabledLanguageStates_: function( |
| 354 assert(CrSettingsPrefs.isInitialized); | 369 translateTarget, prospectiveUILanguage) { |
| 355 | 370 assert(CrSettingsPrefs.isInitialized); |
| 356 var pref = this.getPref(preferredLanguagesPrefName); | 371 |
| 357 var enabledLanguageCodes = pref.value.split(','); | 372 var pref = this.getPref(preferredLanguagesPrefName); |
| 358 var spellCheckPref = this.getPref('spellcheck.dictionaries'); | 373 var enabledLanguageCodes = pref.value.split(','); |
| 359 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */( | 374 var spellCheckPref = this.getPref('spellcheck.dictionaries'); |
| 360 spellCheckPref.value)); | 375 var spellCheckSet = this.makeSetFromArray_( |
| 361 | 376 /** @type {!Array<string>} */ (spellCheckPref.value)); |
| 362 var translateBlockedPref = this.getPref('translate_blocked_languages'); | 377 |
| 363 var translateBlockedSet = this.makeSetFromArray_( | 378 var translateBlockedPref = this.getPref('translate_blocked_languages'); |
| 364 /** @type {!Array<string>} */(translateBlockedPref.value)); | 379 var translateBlockedSet = this.makeSetFromArray_( |
| 365 | 380 /** @type {!Array<string>} */ (translateBlockedPref.value)); |
| 366 var enabledLanguageStates = []; | 381 |
| 367 for (var i = 0; i < enabledLanguageCodes.length; i++) { | 382 var enabledLanguageStates = []; |
| 368 var code = enabledLanguageCodes[i]; | 383 for (var i = 0; i < enabledLanguageCodes.length; i++) { |
| 369 var language = this.supportedLanguageMap_.get(code); | 384 var code = enabledLanguageCodes[i]; |
| 370 // Skip unsupported languages. | 385 var language = this.supportedLanguageMap_.get(code); |
| 371 if (!language) | 386 // Skip unsupported languages. |
| 372 continue; | 387 if (!language) |
| 373 var languageState = /** @type {LanguageState} */({}); | 388 continue; |
| 374 languageState.language = language; | 389 var languageState = /** @type {LanguageState} */ ({}); |
| 375 languageState.spellCheckEnabled = !!spellCheckSet.has(code); | 390 languageState.language = language; |
| 376 // Translate is considered disabled if this language maps to any translate | 391 languageState.spellCheckEnabled = !!spellCheckSet.has(code); |
| 377 // language that is blocked. | 392 // Translate is considered disabled if this language maps to any |
| 378 var translateCode = this.convertLanguageCodeForTranslate(code); | 393 // translate |
| 379 languageState.translateEnabled = | 394 // language that is blocked. |
| 380 !!language.supportsTranslate && | 395 var translateCode = this.convertLanguageCodeForTranslate(code); |
| 381 !translateBlockedSet.has(translateCode) && | 396 languageState.translateEnabled = !!language.supportsTranslate && |
| 382 translateCode != translateTarget && | 397 !translateBlockedSet.has(translateCode) && |
| 383 (!prospectiveUILanguage || code != prospectiveUILanguage); | 398 translateCode != translateTarget && |
| 384 enabledLanguageStates.push(languageState); | 399 (!prospectiveUILanguage || code != prospectiveUILanguage); |
| 385 } | 400 enabledLanguageStates.push(languageState); |
| 386 return enabledLanguageStates; | 401 } |
| 387 }, | 402 return enabledLanguageStates; |
| 388 | 403 }, |
| 389 /** | 404 |
| 405 /** |
| 390 * Returns a list of enabled input methods. | 406 * Returns a list of enabled input methods. |
| 391 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} | 407 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} |
| 392 * @private | 408 * @private |
| 393 */ | 409 */ |
| 394 getEnabledInputMethods_: function() { | 410 getEnabledInputMethods_: function() { |
| 395 assert(cr.isChromeOS); | 411 assert(cr.isChromeOS); |
| 396 assert(CrSettingsPrefs.isInitialized); | 412 assert(CrSettingsPrefs.isInitialized); |
| 397 | 413 |
| 398 var enabledInputMethodIds = | 414 var enabledInputMethodIds = |
| 399 this.getPref('settings.language.preload_engines').value.split(','); | 415 this.getPref('settings.language.preload_engines').value.split(','); |
| 400 enabledInputMethodIds = enabledInputMethodIds.concat(this.getPref( | 416 enabledInputMethodIds = enabledInputMethodIds.concat( |
| 401 'settings.language.enabled_extension_imes').value.split(',')); | 417 this.getPref('settings.language.enabled_extension_imes') |
| 402 | 418 .value.split(',')); |
| 403 // Return only supported input methods. | 419 |
| 404 return enabledInputMethodIds.map(function(id) { | 420 // Return only supported input methods. |
| 405 return this.supportedInputMethodMap_.get(id); | 421 return enabledInputMethodIds |
| 406 }.bind(this)).filter(function(inputMethod) { | 422 .map(function(id) { |
| 407 return !!inputMethod; | 423 return this.supportedInputMethodMap_.get(id); |
| 408 }); | 424 }.bind(this)) |
| 409 }, | 425 .filter(function(inputMethod) { |
| 410 | 426 return !!inputMethod; |
| 411 /** @private */ | 427 }); |
| 412 updateEnabledInputMethods_: function() { | 428 }, |
| 413 assert(cr.isChromeOS); | 429 |
| 414 var enabledInputMethods = this.getEnabledInputMethods_(); | 430 /** @private */ |
| 415 var enabledInputMethodSet = this.makeSetFromArray_(enabledInputMethods); | 431 updateEnabledInputMethods_: function() { |
| 416 | 432 assert(cr.isChromeOS); |
| 417 for (var i = 0; i < this.languages.inputMethods.supported.length; i++) { | 433 var enabledInputMethods = this.getEnabledInputMethods_(); |
| 418 this.set('languages.inputMethods.supported.' + i + '.enabled', | 434 var enabledInputMethodSet = this.makeSetFromArray_(enabledInputMethods); |
| 419 enabledInputMethodSet.has(this.languages.inputMethods.supported[i])); | 435 |
| 420 } | 436 for (var i = 0; i < this.languages.inputMethods.supported.length; i++) { |
| 421 this.set('languages.inputMethods.enabled', enabledInputMethods); | 437 this.set( |
| 422 }, | 438 'languages.inputMethods.supported.' + i + '.enabled', |
| 423 | 439 enabledInputMethodSet.has( |
| 424 /** | 440 this.languages.inputMethods.supported[i])); |
| 425 * Updates the |removable| property of the enabled language states based | 441 } |
| 426 * on what other languages and input methods are enabled. | 442 this.set('languages.inputMethods.enabled', enabledInputMethods); |
| 427 * @private | 443 }, |
| 428 */ | 444 |
| 429 updateRemovableLanguages_: function() { | 445 /** |
| 430 assert(this.languages); | 446 * Updates the |removable| property of the enabled language states based |
| 431 // TODO(michaelpg): Enabled input methods can affect which languages are | 447 * on what other languages and input methods are enabled. |
| 432 // removable, so run updateEnabledInputMethods_ first (if it has been | 448 * @private |
| 433 // scheduled). | 449 */ |
| 434 if (cr.isChromeOS) | 450 updateRemovableLanguages_: function() { |
| 435 this.updateEnabledInputMethods_(); | 451 assert(this.languages); |
| 436 | 452 // TODO(michaelpg): Enabled input methods can affect which languages are |
| 437 for (var i = 0; i < this.languages.enabled.length; i++) { | 453 // removable, so run updateEnabledInputMethods_ first (if it has been |
| 438 var languageState = this.languages.enabled[i]; | 454 // scheduled). |
| 439 this.set('languages.enabled.' + i + '.removable', | 455 if (cr.isChromeOS) |
| 440 this.canDisableLanguage(languageState.language.code)); | 456 this.updateEnabledInputMethods_(); |
| 441 } | 457 |
| 442 }, | 458 for (var i = 0; i < this.languages.enabled.length; i++) { |
| 443 | 459 var languageState = this.languages.enabled[i]; |
| 444 /** | 460 this.set( |
| 461 'languages.enabled.' + i + '.removable', |
| 462 this.canDisableLanguage(languageState.language.code)); |
| 463 } |
| 464 }, |
| 465 |
| 466 /** |
| 445 * Creates a Set from the elements of the array. | 467 * Creates a Set from the elements of the array. |
| 446 * @param {!Array<T>} list | 468 * @param {!Array<T>} list |
| 447 * @return {!Set<T>} | 469 * @return {!Set<T>} |
| 448 * @template T | 470 * @template T |
| 449 * @private | 471 * @private |
| 450 */ | 472 */ |
| 451 makeSetFromArray_: function(list) { | 473 makeSetFromArray_: function(list) { |
| 452 var set = new Set(); | 474 var set = new Set(); |
| 453 for (var item of list) | 475 for (var item of list) |
| 454 set.add(item); | 476 set.add(item); |
| 455 return set; | 477 return set; |
| 456 }, | 478 }, |
| 457 | 479 |
| 458 // LanguageHelper implementation. | 480 // LanguageHelper implementation. |
| 459 // TODO(michaelpg): replace duplicate docs with @override once b/24294625 | 481 // TODO(michaelpg): replace duplicate docs with @override once b/24294625 |
| 460 // is fixed. | 482 // is fixed. |
| 461 | 483 |
| 462 /** @return {!Promise} */ | 484 /** @return {!Promise} */ |
| 463 whenReady: function() { | 485 whenReady: function() { |
| 464 return this.resolver_.promise; | 486 return this.resolver_.promise; |
| 465 }, | 487 }, |
| 466 | 488 |
| 467 /** | 489 /** |
| 468 * Sets the prospective UI language to the chosen language. This won't affect | 490 * Sets the prospective UI language to the chosen language. This won't |
| 469 * the actual UI language until a restart. | 491 * affect |
| 470 * @param {string} languageCode | 492 * the actual UI language until a restart. |
| 471 */ | 493 * @param {string} languageCode |
| 472 setProspectiveUILanguage: function(languageCode) { | 494 */ |
| 473 assert(cr.isChromeOS || cr.isWindows); | 495 setProspectiveUILanguage: function(languageCode) { |
| 474 chrome.send('setProspectiveUILanguage', [languageCode]); | 496 assert(cr.isChromeOS || cr.isWindows); |
| 475 }, | 497 chrome.send('setProspectiveUILanguage', [languageCode]); |
| 476 | 498 }, |
| 477 /** | 499 |
| 500 /** |
| 478 * True if the prospective UI language was changed from its starting value. | 501 * True if the prospective UI language was changed from its starting value. |
| 479 * @return {boolean} | 502 * @return {boolean} |
| 480 */ | 503 */ |
| 481 requiresRestart: function() { | 504 requiresRestart: function() { |
| 482 return this.originalProspectiveUILanguage_ != | 505 return this.originalProspectiveUILanguage_ != |
| 483 this.languages.prospectiveUILanguage; | 506 this.languages.prospectiveUILanguage; |
| 484 }, | 507 }, |
| 485 | 508 |
| 486 /** | 509 /** |
| 487 * @param {string} languageCode | 510 * @param {string} languageCode |
| 488 * @return {boolean} True if the language is enabled. | 511 * @return {boolean} True if the language is enabled. |
| 489 */ | 512 */ |
| 490 isLanguageEnabled: function(languageCode) { | 513 isLanguageEnabled: function(languageCode) { |
| 491 return this.enabledLanguageSet_.has(languageCode); | 514 return this.enabledLanguageSet_.has(languageCode); |
| 492 }, | 515 }, |
| 493 | 516 |
| 494 /** | 517 /** |
| 495 * Enables the language, making it available for spell check and input. | 518 * Enables the language, making it available for spell check and input. |
| 496 * @param {string} languageCode | 519 * @param {string} languageCode |
| 497 */ | 520 */ |
| 498 enableLanguage: function(languageCode) { | 521 enableLanguage: function(languageCode) { |
| 499 if (!CrSettingsPrefs.isInitialized) | 522 if (!CrSettingsPrefs.isInitialized) |
| 500 return; | 523 return; |
| 501 | 524 |
| 502 this.languageSettingsPrivate.enableLanguage(languageCode); | 525 this.languageSettingsPrivate.enableLanguage(languageCode); |
| 503 this.disableTranslateLanguage(languageCode); | 526 this.disableTranslateLanguage(languageCode); |
| 504 }, | 527 }, |
| 505 | 528 |
| 506 /** | 529 /** |
| 507 * Disables the language. | 530 * Disables the language. |
| 508 * @param {string} languageCode | 531 * @param {string} languageCode |
| 509 */ | 532 */ |
| 510 disableLanguage: function(languageCode) { | 533 disableLanguage: function(languageCode) { |
| 511 if (!CrSettingsPrefs.isInitialized) | 534 if (!CrSettingsPrefs.isInitialized) |
| 512 return; | 535 return; |
| 513 | 536 |
| 514 assert(this.canDisableLanguage(languageCode)); | 537 assert(this.canDisableLanguage(languageCode)); |
| 515 | 538 |
| 516 // Remove the language from spell check. | 539 // Remove the language from spell check. |
| 517 this.deletePrefListItem('spellcheck.dictionaries', languageCode); | 540 this.deletePrefListItem('spellcheck.dictionaries', languageCode); |
| 518 | 541 |
| 519 if (cr.isChromeOS) { | 542 if (cr.isChromeOS) { |
| 520 // Remove input methods that don't support any other enabled language. | 543 // Remove input methods that don't support any other enabled language. |
| 521 var inputMethods = this.languageInputMethods_.get(languageCode) || []; | 544 var inputMethods = this.languageInputMethods_.get(languageCode) || []; |
| 522 for (var inputMethod of inputMethods) { | 545 for (var inputMethod of inputMethods) { |
| 523 var supportsOtherEnabledLanguages = inputMethod.languageCodes.some( | 546 var supportsOtherEnabledLanguages = |
| 524 function(otherLanguageCode) { | 547 inputMethod.languageCodes.some(function(otherLanguageCode) { |
| 525 return otherLanguageCode != languageCode && | 548 return otherLanguageCode != languageCode && |
| 526 this.isLanguageEnabled(otherLanguageCode); | 549 this.isLanguageEnabled(otherLanguageCode); |
| 527 }.bind(this)); | 550 }.bind(this)); |
| 528 if (!supportsOtherEnabledLanguages) | 551 if (!supportsOtherEnabledLanguages) |
| 529 this.removeInputMethod(inputMethod.id); | 552 this.removeInputMethod(inputMethod.id); |
| 530 } | 553 } |
| 531 } | 554 } |
| 532 | 555 |
| 533 // Remove the language from preferred languages. | 556 // Remove the language from preferred languages. |
| 534 this.languageSettingsPrivate.disableLanguage(languageCode); | 557 this.languageSettingsPrivate.disableLanguage(languageCode); |
| 535 this.enableTranslateLanguage(languageCode); | 558 this.enableTranslateLanguage(languageCode); |
| 536 }, | 559 }, |
| 537 | 560 |
| 538 /** | 561 /** |
| 539 * @param {string} languageCode Language code for an enabled language. | 562 * @param {string} languageCode Language code for an enabled language. |
| 540 * @return {boolean} | 563 * @return {boolean} |
| 541 */ | 564 */ |
| 542 canDisableLanguage: function(languageCode) { | 565 canDisableLanguage: function(languageCode) { |
| 543 // Cannot disable the prospective UI language. | 566 // Cannot disable the prospective UI language. |
| 544 if (languageCode == this.languages.prospectiveUILanguage) | 567 if (languageCode == this.languages.prospectiveUILanguage) |
| 545 return false; | 568 return false; |
| 546 | 569 |
| 547 // Cannot disable the only enabled language. | 570 // Cannot disable the only enabled language. |
| 548 if (this.languages.enabled.length == 1) | 571 if (this.languages.enabled.length == 1) |
| 549 return false; | 572 return false; |
| 550 | 573 |
| 551 if (!cr.isChromeOS) | 574 if (!cr.isChromeOS) |
| 552 return true; | 575 return true; |
| 553 | 576 |
| 554 // If this is the only enabled language that is supported by all enabled | 577 // If this is the only enabled language that is supported by all enabled |
| 555 // component IMEs, it cannot be disabled because we need those IMEs. | 578 // component IMEs, it cannot be disabled because we need those IMEs. |
| 556 var otherInputMethodsEnabled = this.languages.enabled.some( | 579 var otherInputMethodsEnabled = |
| 557 function(languageState) { | 580 this.languages.enabled.some(function(languageState) { |
| 558 var otherLanguageCode = languageState.language.code; | 581 var otherLanguageCode = languageState.language.code; |
| 559 if (otherLanguageCode == languageCode) | 582 if (otherLanguageCode == languageCode) |
| 560 return false; | 583 return false; |
| 561 var inputMethods = this.languageInputMethods_.get(otherLanguageCode); | 584 var inputMethods = |
| 562 return inputMethods && inputMethods.some(function(inputMethod) { | 585 this.languageInputMethods_.get(otherLanguageCode); |
| 563 return this.isComponentIme(inputMethod) && | 586 return inputMethods && inputMethods.some(function(inputMethod) { |
| 564 this.supportedInputMethodMap_.get(inputMethod.id).enabled; | 587 return this.isComponentIme(inputMethod) && |
| 588 this.supportedInputMethodMap_.get(inputMethod.id).enabled; |
| 589 }, this); |
| 565 }, this); | 590 }, this); |
| 566 }, this); | 591 return otherInputMethodsEnabled; |
| 567 return otherInputMethodsEnabled; | 592 }, |
| 568 }, | 593 |
| 569 | 594 /** |
| 570 /** | 595 * Moves the language in the list of enabled languages by the given offset. |
| 571 * Moves the language in the list of enabled languages by the given offset. | 596 * @param {string} languageCode |
| 572 * @param {string} languageCode | 597 * @param {number} offset Negative offset moves the language toward the |
| 573 * @param {number} offset Negative offset moves the language toward the front | 598 * front |
| 574 * of the list. A Positive one moves the language toward the back. | 599 * of the list. A Positive one moves the language toward the back. |
| 575 */ | 600 */ |
| 576 moveLanguage: function(languageCode, offset) { | 601 moveLanguage: function(languageCode, offset) { |
| 577 if (!CrSettingsPrefs.isInitialized) | 602 if (!CrSettingsPrefs.isInitialized) |
| 578 return; | 603 return; |
| 579 | 604 |
| 580 var languageCodes = | 605 var languageCodes = |
| 581 this.getPref(preferredLanguagesPrefName).value.split(','); | 606 this.getPref(preferredLanguagesPrefName).value.split(','); |
| 582 | 607 |
| 583 var originalIndex = languageCodes.indexOf(languageCode); | 608 var originalIndex = languageCodes.indexOf(languageCode); |
| 584 var newIndex = originalIndex; | 609 var newIndex = originalIndex; |
| 585 var direction = Math.sign(offset); | 610 var direction = Math.sign(offset); |
| 586 var distance = Math.abs(offset); | 611 var distance = Math.abs(offset); |
| 587 | 612 |
| 588 // Step over the distance to find the target index. | 613 // Step over the distance to find the target index. |
| 589 while (distance > 0) { | 614 while (distance > 0) { |
| 590 newIndex += direction; | 615 newIndex += direction; |
| 591 if (newIndex < 0 || newIndex >= languageCodes.length) | 616 if (newIndex < 0 || newIndex >= languageCodes.length) |
| 592 return; | 617 return; |
| 593 | 618 |
| 594 // Skip over non-enabled languages, since they don't appear in the list | 619 // Skip over non-enabled languages, since they don't appear in the list |
| 595 // (but we don't want to remove them). | 620 // (but we don't want to remove them). |
| 596 if (this.enabledLanguageSet_.has(languageCodes[newIndex])) | 621 if (this.enabledLanguageSet_.has(languageCodes[newIndex])) |
| 597 distance--; | 622 distance--; |
| 598 } | 623 } |
| 599 | 624 |
| 600 languageCodes[originalIndex] = languageCodes[newIndex]; | 625 languageCodes[originalIndex] = languageCodes[newIndex]; |
| 601 languageCodes[newIndex] = languageCode; | 626 languageCodes[newIndex] = languageCode; |
| 602 this.setPrefValue(preferredLanguagesPrefName, languageCodes.join(',')); | 627 this.setPrefValue(preferredLanguagesPrefName, languageCodes.join(',')); |
| 603 }, | 628 }, |
| 604 | 629 |
| 605 /** | 630 /** |
| 606 * Moves the language directly to the front of the list of enabled languages. | 631 * Moves the language directly to the front of the list of enabled |
| 607 * @param {string} languageCode | 632 * languages. |
| 608 */ | 633 * @param {string} languageCode |
| 609 moveLanguageToFront: function(languageCode) { | 634 */ |
| 610 if (!CrSettingsPrefs.isInitialized) | 635 moveLanguageToFront: function(languageCode) { |
| 611 return; | 636 if (!CrSettingsPrefs.isInitialized) |
| 612 | 637 return; |
| 613 var languageCodes = | 638 |
| 614 this.getPref(preferredLanguagesPrefName).value.split(','); | 639 var languageCodes = |
| 615 var originalIndex = languageCodes.indexOf(languageCode); | 640 this.getPref(preferredLanguagesPrefName).value.split(','); |
| 616 assert(originalIndex != -1); | 641 var originalIndex = languageCodes.indexOf(languageCode); |
| 617 | 642 assert(originalIndex != -1); |
| 618 languageCodes.splice(originalIndex, 1); | 643 |
| 619 languageCodes.unshift(languageCode); | 644 languageCodes.splice(originalIndex, 1); |
| 620 | 645 languageCodes.unshift(languageCode); |
| 621 this.setPrefValue(preferredLanguagesPrefName, languageCodes.join(',')); | 646 |
| 622 }, | 647 this.setPrefValue(preferredLanguagesPrefName, languageCodes.join(',')); |
| 623 | 648 }, |
| 624 /** | 649 |
| 625 * Enables translate for the given language by removing the translate | 650 /** |
| 626 * language from the blocked languages preference. | 651 * Enables translate for the given language by removing the translate |
| 627 * @param {string} languageCode | 652 * language from the blocked languages preference. |
| 628 */ | 653 * @param {string} languageCode |
| 629 enableTranslateLanguage: function(languageCode) { | 654 */ |
| 630 languageCode = this.convertLanguageCodeForTranslate(languageCode); | 655 enableTranslateLanguage: function(languageCode) { |
| 631 this.deletePrefListItem('translate_blocked_languages', languageCode); | 656 languageCode = this.convertLanguageCodeForTranslate(languageCode); |
| 632 }, | 657 this.deletePrefListItem('translate_blocked_languages', languageCode); |
| 633 | 658 }, |
| 634 /** | 659 |
| 635 * Disables translate for the given language by adding the translate | 660 /** |
| 636 * language to the blocked languages preference. | 661 * Disables translate for the given language by adding the translate |
| 637 * @param {string} languageCode | 662 * language to the blocked languages preference. |
| 638 */ | 663 * @param {string} languageCode |
| 639 disableTranslateLanguage: function(languageCode) { | 664 */ |
| 640 this.appendPrefListItem('translate_blocked_languages', | 665 disableTranslateLanguage: function(languageCode) { |
| 641 this.convertLanguageCodeForTranslate(languageCode)); | 666 this.appendPrefListItem( |
| 642 }, | 667 'translate_blocked_languages', |
| 643 | 668 this.convertLanguageCodeForTranslate(languageCode)); |
| 644 /** | 669 }, |
| 645 * Enables or disables spell check for the given language. | 670 |
| 646 * @param {string} languageCode | 671 /** |
| 647 * @param {boolean} enable | 672 * Enables or disables spell check for the given language. |
| 648 */ | 673 * @param {string} languageCode |
| 649 toggleSpellCheck: function(languageCode, enable) { | 674 * @param {boolean} enable |
| 650 if (!this.languages) | 675 */ |
| 651 return; | 676 toggleSpellCheck: function(languageCode, enable) { |
| 652 | 677 if (!this.languages) |
| 653 if (enable) { | 678 return; |
| 654 var spellCheckPref = this.getPref('spellcheck.dictionaries'); | 679 |
| 655 this.appendPrefListItem('spellcheck.dictionaries', languageCode); | 680 if (enable) { |
| 656 } else { | 681 var spellCheckPref = this.getPref('spellcheck.dictionaries'); |
| 657 this.deletePrefListItem('spellcheck.dictionaries', languageCode); | 682 this.appendPrefListItem('spellcheck.dictionaries', languageCode); |
| 658 } | 683 } else { |
| 659 }, | 684 this.deletePrefListItem('spellcheck.dictionaries', languageCode); |
| 660 | 685 } |
| 661 /** | 686 }, |
| 687 |
| 688 /** |
| 662 * Converts the language code for translate. There are some differences | 689 * Converts the language code for translate. There are some differences |
| 663 * between the language set the Translate server uses and that for | 690 * between the language set the Translate server uses and that for |
| 664 * Accept-Language. | 691 * Accept-Language. |
| 665 * @param {string} languageCode | 692 * @param {string} languageCode |
| 666 * @return {string} The converted language code. | 693 * @return {string} The converted language code. |
| 667 */ | 694 */ |
| 668 convertLanguageCodeForTranslate: function(languageCode) { | 695 convertLanguageCodeForTranslate: function(languageCode) { |
| 669 if (languageCode in kLanguageCodeToTranslateCode) | 696 if (languageCode in kLanguageCodeToTranslateCode) |
| 670 return kLanguageCodeToTranslateCode[languageCode]; | 697 return kLanguageCodeToTranslateCode[languageCode]; |
| 671 | 698 |
| 672 var main = languageCode.split('-')[0]; | 699 var main = languageCode.split('-')[0]; |
| 673 if (main == 'zh') { | 700 if (main == 'zh') { |
| 674 // In Translate, general Chinese is not used, and the sub code is | 701 // In Translate, general Chinese is not used, and the sub code is |
| 675 // necessary as a language code for the Translate server. | 702 // necessary as a language code for the Translate server. |
| 676 return languageCode; | 703 return languageCode; |
| 677 } | 704 } |
| 678 if (main in kTranslateLanguageSynonyms) | 705 if (main in kTranslateLanguageSynonyms) |
| 679 return kTranslateLanguageSynonyms[main]; | 706 return kTranslateLanguageSynonyms[main]; |
| 680 | 707 |
| 681 return main; | 708 return main; |
| 682 }, | 709 }, |
| 683 | 710 |
| 684 /** | 711 /** |
| 685 * Given a language code, returns just the base language. E.g., converts | 712 * Given a language code, returns just the base language. E.g., converts |
| 686 * 'en-GB' to 'en'. | 713 * 'en-GB' to 'en'. |
| 687 * @param {string} languageCode | 714 * @param {string} languageCode |
| 688 * @return {string} | 715 * @return {string} |
| 689 */ | 716 */ |
| 690 getLanguageCodeWithoutRegion: function(languageCode) { | 717 getLanguageCodeWithoutRegion: function(languageCode) { |
| 691 // The Norwegian languages fall under the 'no' macrolanguage. | 718 // The Norwegian languages fall under the 'no' macrolanguage. |
| 692 if (languageCode == 'nb' || languageCode == 'nn') | 719 if (languageCode == 'nb' || languageCode == 'nn') |
| 693 return 'no'; | 720 return 'no'; |
| 694 | 721 |
| 695 // Match the characters before the hyphen. | 722 // Match the characters before the hyphen. |
| 696 var result = languageCode.match(/^([^-]+)-?/); | 723 var result = languageCode.match(/^([^-]+)-?/); |
| 697 assert(result.length == 2); | 724 assert(result.length == 2); |
| 698 return result[1]; | 725 return result[1]; |
| 699 }, | 726 }, |
| 700 | 727 |
| 701 /** | 728 /** |
| 702 * @param {string} languageCode | 729 * @param {string} languageCode |
| 703 * @return {!chrome.languageSettingsPrivate.Language|undefined} | 730 * @return {!chrome.languageSettingsPrivate.Language|undefined} |
| 704 */ | 731 */ |
| 705 getLanguage: function(languageCode) { | 732 getLanguage: function(languageCode) { |
| 706 return this.supportedLanguageMap_.get(languageCode); | 733 return this.supportedLanguageMap_.get(languageCode); |
| 707 }, | 734 }, |
| 708 | 735 |
| 709 /** | 736 /** |
| 710 * @param {string} id | 737 * @param {string} id |
| 711 * @return {!chrome.languageSettingsPrivate.InputMethod|undefined} | 738 * @return {!chrome.languageSettingsPrivate.InputMethod|undefined} |
| 712 */ | 739 */ |
| 713 getInputMethod: function(id) { | 740 getInputMethod: function(id) { |
| 714 assert(cr.isChromeOS); | 741 assert(cr.isChromeOS); |
| 715 return this.supportedInputMethodMap_.get(id); | 742 return this.supportedInputMethodMap_.get(id); |
| 716 }, | 743 }, |
| 717 | 744 |
| 718 /** @param {string} id */ | 745 /** @param {string} id */ |
| 719 addInputMethod: function(id) { | 746 addInputMethod: function(id) { |
| 720 assert(cr.isChromeOS); | 747 assert(cr.isChromeOS); |
| 721 if (!this.supportedInputMethodMap_.has(id)) | 748 if (!this.supportedInputMethodMap_.has(id)) |
| 722 return; | 749 return; |
| 723 this.languageSettingsPrivate.addInputMethod(id); | 750 this.languageSettingsPrivate.addInputMethod(id); |
| 724 }, | 751 }, |
| 725 | 752 |
| 726 /** @param {string} id */ | 753 /** @param {string} id */ |
| 727 removeInputMethod: function(id) { | 754 removeInputMethod: function(id) { |
| 728 assert(cr.isChromeOS); | 755 assert(cr.isChromeOS); |
| 729 if (!this.supportedInputMethodMap_.has(id)) | 756 if (!this.supportedInputMethodMap_.has(id)) |
| 730 return; | 757 return; |
| 731 this.languageSettingsPrivate.removeInputMethod(id); | 758 this.languageSettingsPrivate.removeInputMethod(id); |
| 732 }, | 759 }, |
| 733 | 760 |
| 734 /** @param {string} id */ | 761 /** @param {string} id */ |
| 735 setCurrentInputMethod: function(id) { | 762 setCurrentInputMethod: function(id) { |
| 736 assert(cr.isChromeOS); | 763 assert(cr.isChromeOS); |
| 737 this.inputMethodPrivate.setCurrentInputMethod(id); | 764 this.inputMethodPrivate.setCurrentInputMethod(id); |
| 738 }, | 765 }, |
| 739 | 766 |
| 740 /** | 767 /** |
| 741 * @param {string} languageCode | 768 * @param {string} languageCode |
| 742 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} | 769 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} |
| 743 */ | 770 */ |
| 744 getInputMethodsForLanguage: function(languageCode) { | 771 getInputMethodsForLanguage: function(languageCode) { |
| 745 return this.languageInputMethods_.get(languageCode) || []; | 772 return this.languageInputMethods_.get(languageCode) || []; |
| 746 }, | 773 }, |
| 747 | 774 |
| 748 /** | 775 /** |
| 749 * @param {!chrome.languageSettingsPrivate.InputMethod} inputMethod | 776 * @param {!chrome.languageSettingsPrivate.InputMethod} inputMethod |
| 750 * @return {boolean} | 777 * @return {boolean} |
| 751 */ | 778 */ |
| 752 isComponentIme: function(inputMethod) { | 779 isComponentIme: function(inputMethod) { |
| 753 assert(cr.isChromeOS); | 780 assert(cr.isChromeOS); |
| 754 return inputMethod.id.startsWith('_comp_'); | 781 return inputMethod.id.startsWith('_comp_'); |
| 755 }, | 782 }, |
| 756 | 783 |
| 757 /** @param {string} id Input method ID. */ | 784 /** @param {string} id Input method ID. */ |
| 758 openInputMethodOptions: function(id) { | 785 openInputMethodOptions: function(id) { |
| 759 assert(cr.isChromeOS); | 786 assert(cr.isChromeOS); |
| 760 this.inputMethodPrivate.openOptionsPage(id); | 787 this.inputMethodPrivate.openOptionsPage(id); |
| 761 }, | 788 }, |
| 762 | 789 |
| 763 /** @param {string} id New current input method ID. */ | 790 /** @param {string} id New current input method ID. */ |
| 764 onInputMethodChanged_: function(id) { | 791 onInputMethodChanged_: function(id) { |
| 765 assert(cr.isChromeOS); | 792 assert(cr.isChromeOS); |
| 766 this.set('languages.inputMethods.currentId', id); | 793 this.set('languages.inputMethods.currentId', id); |
| 767 }, | 794 }, |
| 768 | 795 |
| 769 /** @param {string} id Added input method ID. */ | 796 /** @param {string} id Added input method ID. */ |
| 770 onInputMethodAdded_: function(id) { | 797 onInputMethodAdded_: function(id) { |
| 771 assert(cr.isChromeOS); | 798 assert(cr.isChromeOS); |
| 772 this.updateEnabledInputMethods_(); | 799 this.updateEnabledInputMethods_(); |
| 773 }, | 800 }, |
| 774 | 801 |
| 775 /** @param {string} id Removed input method ID. */ | 802 /** @param {string} id Removed input method ID. */ |
| 776 onInputMethodRemoved_: function(id) { | 803 onInputMethodRemoved_: function(id) { |
| 777 assert(cr.isChromeOS); | 804 assert(cr.isChromeOS); |
| 778 this.updateEnabledInputMethods_(); | 805 this.updateEnabledInputMethods_(); |
| 779 }, | 806 }, |
| 780 }); | 807 }); |
| 781 })(); | 808 })(); |
| OLD | NEW |