| 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. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 /** | 114 /** |
| 115 * Hash map of input methods supported for each language. | 115 * Hash map of input methods supported for each language. |
| 116 * @type {!Map<string, | 116 * @type {!Map<string, |
| 117 * !Array<!chrome.languageSettingsPrivate.InputMethod>>} | 117 * !Array<!chrome.languageSettingsPrivate.InputMethod>>} |
| 118 * @private | 118 * @private |
| 119 */ | 119 */ |
| 120 languageInputMethods_: { | 120 languageInputMethods_: { |
| 121 type: Object, | 121 type: Object, |
| 122 value: function() { return new Map(); }, | 122 value: function() { return new Map(); }, |
| 123 }, | 123 }, |
| 124 |
| 125 /** @private Prospective UI language when the page was loaded. */ |
| 126 originalProspectiveUILanguage_: String, |
| 124 }, | 127 }, |
| 125 | 128 |
| 126 observers: [ | 129 observers: [ |
| 130 // All observers wait for the model to be populated by including the |
| 131 // |languages| property. |
| 132 'prospectiveUILanguageChanged_(prefs.intl.app_locale.value, languages)', |
| 127 'preferredLanguagesPrefChanged_(' + | 133 'preferredLanguagesPrefChanged_(' + |
| 128 'prefs.' + preferredLanguagesPrefName + '.value, languages)', | 134 'prefs.' + preferredLanguagesPrefName + '.value, languages)', |
| 129 'spellCheckDictionariesPrefChanged_(' + | 135 'spellCheckDictionariesPrefChanged_(' + |
| 130 'prefs.spellcheck.dictionaries.value.*, languages)', | 136 'prefs.spellcheck.dictionaries.value.*, languages)', |
| 131 'translateLanguagesPrefChanged_(' + | 137 'translateLanguagesPrefChanged_(' + |
| 132 'prefs.translate_blocked_languages.value.*, languages)', | 138 'prefs.translate_blocked_languages.value.*, languages)', |
| 133 'updateRemovableLanguages_(' + | 139 'updateRemovableLanguages_(' + |
| 134 'prefs.intl.app_locale.value, languages.enabled)', | 140 'prefs.intl.app_locale.value, languages.enabled)', |
| 135 // Observe Chrome OS prefs (ignored for non-Chrome OS). | 141 // Observe Chrome OS prefs (ignored for non-Chrome OS). |
| 136 'updateRemovableLanguages_(' + | 142 'updateRemovableLanguages_(' + |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 resolve(lists.componentExtensionImes.concat( | 177 resolve(lists.componentExtensionImes.concat( |
| 172 lists.thirdPartyExtensionImes)); | 178 lists.thirdPartyExtensionImes)); |
| 173 }); | 179 }); |
| 174 }.bind(this)); | 180 }.bind(this)); |
| 175 | 181 |
| 176 promises[4] = new Promise(function(resolve) { | 182 promises[4] = new Promise(function(resolve) { |
| 177 this.inputMethodPrivate.getCurrentInputMethod(resolve); | 183 this.inputMethodPrivate.getCurrentInputMethod(resolve); |
| 178 }.bind(this)); | 184 }.bind(this)); |
| 179 } | 185 } |
| 180 | 186 |
| 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 |
| 181 Promise.all(promises).then(function(results) { | 197 Promise.all(promises).then(function(results) { |
| 182 this.createModel_(results[1], results[2], results[3], results[4]); | 198 this.createModel_(results[1], results[2], results[3], results[4]); |
| 183 this.resolver_.resolve(); | 199 this.resolver_.resolve(); |
| 184 }.bind(this)); | 200 }.bind(this)); |
| 185 | 201 |
| 186 if (cr.isChromeOS) { | 202 if (cr.isChromeOS) { |
| 187 this.inputMethodPrivate.onChanged.addListener( | 203 this.inputMethodPrivate.onChanged.addListener( |
| 188 this.onInputMethodChanged_.bind(this)); | 204 this.onInputMethodChanged_.bind(this)); |
| 189 } | 205 } |
| 190 }, | 206 }, |
| 191 | 207 |
| 192 /** | 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 /** |
| 193 * Updates the list of enabled languages from the preferred languages pref. | 219 * Updates the list of enabled languages from the preferred languages pref. |
| 194 * @private | 220 * @private |
| 195 */ | 221 */ |
| 196 preferredLanguagesPrefChanged_: function() { | 222 preferredLanguagesPrefChanged_: function() { |
| 197 var enabledLanguageStates = | 223 var enabledLanguageStates = this.getEnabledLanguageStates_( |
| 198 this.getEnabledLanguageStates_(this.languages.translateTarget); | 224 this.languages.translateTarget, this.languages.prospectiveUILanguage); |
| 199 | 225 |
| 200 // Recreate the enabled language set before updating languages.enabled. | 226 // Recreate the enabled language set before updating languages.enabled. |
| 201 this.enabledLanguageSet_.clear(); | 227 this.enabledLanguageSet_.clear(); |
| 202 for (var languageState of enabledLanguageStates) | 228 for (var languageState of enabledLanguageStates) |
| 203 this.enabledLanguageSet_.add(languageState.language.code); | 229 this.enabledLanguageSet_.add(languageState.language.code); |
| 204 | 230 |
| 205 this.set('languages.enabled', enabledLanguageStates); | 231 this.set('languages.enabled', enabledLanguageStates); |
| 206 }, | 232 }, |
| 207 | 233 |
| 208 /** | 234 /** |
| (...skipping 10 matching lines...) Expand all Loading... |
| 219 } | 245 } |
| 220 }, | 246 }, |
| 221 | 247 |
| 222 /** @private */ | 248 /** @private */ |
| 223 translateLanguagesPrefChanged_: function() { | 249 translateLanguagesPrefChanged_: function() { |
| 224 var translateBlockedPref = this.getPref('translate_blocked_languages'); | 250 var translateBlockedPref = this.getPref('translate_blocked_languages'); |
| 225 var translateBlockedSet = this.makeSetFromArray_( | 251 var translateBlockedSet = this.makeSetFromArray_( |
| 226 /** @type {!Array<string>} */(translateBlockedPref.value)); | 252 /** @type {!Array<string>} */(translateBlockedPref.value)); |
| 227 | 253 |
| 228 for (var i = 0; i < this.languages.enabled.length; i++) { | 254 for (var i = 0; i < this.languages.enabled.length; i++) { |
| 229 if (this.languages.enabled[i].language.code == navigator.language) | 255 if (this.languages.enabled[i].language.code == |
| 256 this.languages.prospectiveUILanguage) { |
| 230 continue; | 257 continue; |
| 258 } |
| 231 var translateCode = this.convertLanguageCodeForTranslate( | 259 var translateCode = this.convertLanguageCodeForTranslate( |
| 232 this.languages.enabled[i].language.code); | 260 this.languages.enabled[i].language.code); |
| 233 this.set( | 261 this.set( |
| 234 'languages.enabled.' + i + '.translateEnabled', | 262 'languages.enabled.' + i + '.translateEnabled', |
| 235 !translateBlockedSet.has(translateCode)); | 263 !translateBlockedSet.has(translateCode)); |
| 236 } | 264 } |
| 237 }, | 265 }, |
| 238 | 266 |
| 239 /** | 267 /** |
| 240 * Constructs the languages model. | 268 * Constructs the languages model. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 270 if (!this.supportedLanguageMap_.has(languageCode)) | 298 if (!this.supportedLanguageMap_.has(languageCode)) |
| 271 continue; | 299 continue; |
| 272 if (!this.languageInputMethods_.has(languageCode)) | 300 if (!this.languageInputMethods_.has(languageCode)) |
| 273 this.languageInputMethods_.set(languageCode, [inputMethod]); | 301 this.languageInputMethods_.set(languageCode, [inputMethod]); |
| 274 else | 302 else |
| 275 this.languageInputMethods_.get(languageCode).push(inputMethod); | 303 this.languageInputMethods_.get(languageCode).push(inputMethod); |
| 276 } | 304 } |
| 277 } | 305 } |
| 278 } | 306 } |
| 279 | 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 |
| 280 // Create a list of enabled languages from the supported languages. | 315 // Create a list of enabled languages from the supported languages. |
| 281 var enabledLanguageStates = this.getEnabledLanguageStates_(translateTarget); | 316 var enabledLanguageStates = |
| 317 this.getEnabledLanguageStates_(translateTarget, prospectiveUILanguage); |
| 282 // Populate the hash set of enabled languages. | 318 // Populate the hash set of enabled languages. |
| 283 for (var languageState of enabledLanguageStates) | 319 for (var languageState of enabledLanguageStates) |
| 284 this.enabledLanguageSet_.add(languageState.language.code); | 320 this.enabledLanguageSet_.add(languageState.language.code); |
| 285 | 321 |
| 286 var model = /** @type {!LanguagesModel} */({ | 322 var model = /** @type {!LanguagesModel} */({ |
| 287 supported: supportedLanguages, | 323 supported: supportedLanguages, |
| 288 enabled: enabledLanguageStates, | 324 enabled: enabledLanguageStates, |
| 289 translateTarget: translateTarget, | 325 translateTarget: translateTarget, |
| 290 }); | 326 }); |
| 327 |
| 328 if (cr.isChromeOS || cr.isWindows) |
| 329 model.prospectiveUILanguage = prospectiveUILanguage; |
| 330 |
| 291 if (cr.isChromeOS) { | 331 if (cr.isChromeOS) { |
| 292 model.inputMethods = /** @type {!InputMethodsModel} */({ | 332 model.inputMethods = /** @type {!InputMethodsModel} */({ |
| 293 supported: supportedInputMethods, | 333 supported: supportedInputMethods, |
| 294 enabled: this.getEnabledInputMethods_(), | 334 enabled: this.getEnabledInputMethods_(), |
| 295 currentId: currentInputMethodId, | 335 currentId: currentInputMethodId, |
| 296 }); | 336 }); |
| 297 } | 337 } |
| 298 | 338 |
| 299 // Initialize the Polymer languages model. | 339 // Initialize the Polymer languages model. |
| 300 this._setLanguages(model); | 340 this._setLanguages(model); |
| 301 }, | 341 }, |
| 302 | 342 |
| 303 /** | 343 /** |
| 304 * Returns a list of LanguageStates for each enabled language in the supported | 344 * Returns a list of LanguageStates for each enabled language in the supported |
| 305 * languages list. | 345 * languages list. |
| 306 * @param {string} translateTarget Language code of the default translate | 346 * @param {string} translateTarget Language code of the default translate |
| 307 * target language. | 347 * target language. |
| 348 * @param {(string|undefined)} prospectiveUILanguage Prospective UI display |
| 349 * language. Only defined on Windows and Chrome OS. |
| 308 * @return {!Array<!LanguageState>} | 350 * @return {!Array<!LanguageState>} |
| 309 * @private | 351 * @private |
| 310 */ | 352 */ |
| 311 getEnabledLanguageStates_: function(translateTarget) { | 353 getEnabledLanguageStates_: function(translateTarget, prospectiveUILanguage) { |
| 312 assert(CrSettingsPrefs.isInitialized); | 354 assert(CrSettingsPrefs.isInitialized); |
| 313 | 355 |
| 314 var pref = this.getPref(preferredLanguagesPrefName); | 356 var pref = this.getPref(preferredLanguagesPrefName); |
| 315 var enabledLanguageCodes = pref.value.split(','); | 357 var enabledLanguageCodes = pref.value.split(','); |
| 316 var spellCheckPref = this.getPref('spellcheck.dictionaries'); | 358 var spellCheckPref = this.getPref('spellcheck.dictionaries'); |
| 317 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */( | 359 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */( |
| 318 spellCheckPref.value)); | 360 spellCheckPref.value)); |
| 319 | 361 |
| 320 var translateBlockedPref = this.getPref('translate_blocked_languages'); | 362 var translateBlockedPref = this.getPref('translate_blocked_languages'); |
| 321 var translateBlockedSet = this.makeSetFromArray_( | 363 var translateBlockedSet = this.makeSetFromArray_( |
| 322 /** @type {!Array<string>} */(translateBlockedPref.value)); | 364 /** @type {!Array<string>} */(translateBlockedPref.value)); |
| 323 | 365 |
| 324 var enabledLanguageStates = []; | 366 var enabledLanguageStates = []; |
| 325 for (var i = 0; i < enabledLanguageCodes.length; i++) { | 367 for (var i = 0; i < enabledLanguageCodes.length; i++) { |
| 326 var code = enabledLanguageCodes[i]; | 368 var code = enabledLanguageCodes[i]; |
| 327 var language = this.supportedLanguageMap_.get(code); | 369 var language = this.supportedLanguageMap_.get(code); |
| 328 // Skip unsupported languages. | 370 // Skip unsupported languages. |
| 329 if (!language) | 371 if (!language) |
| 330 continue; | 372 continue; |
| 331 var languageState = /** @type {LanguageState} */({}); | 373 var languageState = /** @type {LanguageState} */({}); |
| 332 languageState.language = language; | 374 languageState.language = language; |
| 333 languageState.spellCheckEnabled = !!spellCheckSet.has(code); | 375 languageState.spellCheckEnabled = !!spellCheckSet.has(code); |
| 334 // Translate is considered disabled if this language maps to any translate | 376 // Translate is considered disabled if this language maps to any translate |
| 335 // language that is blocked. | 377 // language that is blocked. |
| 336 var translateCode = this.convertLanguageCodeForTranslate(code); | 378 var translateCode = this.convertLanguageCodeForTranslate(code); |
| 337 languageState.translateEnabled = !!language.supportsTranslate && | 379 languageState.translateEnabled = |
| 338 code != navigator.language && | 380 !!language.supportsTranslate && |
| 339 !translateBlockedSet.has(translateCode) && | 381 !translateBlockedSet.has(translateCode) && |
| 340 translateCode != translateTarget; | 382 translateCode != translateTarget && |
| 383 (!prospectiveUILanguage || code != prospectiveUILanguage); |
| 341 enabledLanguageStates.push(languageState); | 384 enabledLanguageStates.push(languageState); |
| 342 } | 385 } |
| 343 return enabledLanguageStates; | 386 return enabledLanguageStates; |
| 344 }, | 387 }, |
| 345 | 388 |
| 346 /** | 389 /** |
| 347 * Returns a list of enabled input methods. | 390 * Returns a list of enabled input methods. |
| 348 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} | 391 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} |
| 349 * @private | 392 * @private |
| 350 */ | 393 */ |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 /** @return {!Promise} */ | 462 /** @return {!Promise} */ |
| 420 whenReady: function() { | 463 whenReady: function() { |
| 421 return this.resolver_.promise; | 464 return this.resolver_.promise; |
| 422 }, | 465 }, |
| 423 | 466 |
| 424 /** | 467 /** |
| 425 * Sets the prospective UI language to the chosen language. This won't affect | 468 * Sets the prospective UI language to the chosen language. This won't affect |
| 426 * the actual UI language until a restart. | 469 * the actual UI language until a restart. |
| 427 * @param {string} languageCode | 470 * @param {string} languageCode |
| 428 */ | 471 */ |
| 429 setUILanguage: function(languageCode) { | 472 setProspectiveUILanguage: function(languageCode) { |
| 430 assert(cr.isChromeOS || cr.isWindows); | 473 assert(cr.isChromeOS || cr.isWindows); |
| 431 chrome.send('setUILanguage', [languageCode]); | 474 chrome.send('setProspectiveUILanguage', [languageCode]); |
| 432 }, | |
| 433 | |
| 434 /** Resets the prospective UI language back to the actual UI language. */ | |
| 435 resetUILanguage: function() { | |
| 436 assert(cr.isChromeOS || cr.isWindows); | |
| 437 chrome.send('setUILanguage', [navigator.language]); | |
| 438 }, | 475 }, |
| 439 | 476 |
| 440 /** | 477 /** |
| 441 * Returns the "prospective" UI language, i.e. the one to be used on next | 478 * True if the prospective UI language was changed from its starting value. |
| 442 * restart. If the pref is not set, the current UI language is also the | 479 * @return {boolean} |
| 443 * "prospective" language. | |
| 444 * @return {string} Language code of the prospective UI language. | |
| 445 */ | 480 */ |
| 446 getProspectiveUILanguage: function() { | 481 requiresRestart: function() { |
| 447 return /** @type {string} */(this.getPref('intl.app_locale').value) || | 482 return this.originalProspectiveUILanguage_ != |
| 448 navigator.language; | 483 this.languages.prospectiveUILanguage; |
| 449 }, | 484 }, |
| 450 | 485 |
| 451 /** | 486 /** |
| 452 * @param {string} languageCode | 487 * @param {string} languageCode |
| 453 * @return {boolean} True if the language is enabled. | 488 * @return {boolean} True if the language is enabled. |
| 454 */ | 489 */ |
| 455 isLanguageEnabled: function(languageCode) { | 490 isLanguageEnabled: function(languageCode) { |
| 456 return this.enabledLanguageSet_.has(languageCode); | 491 return this.enabledLanguageSet_.has(languageCode); |
| 457 }, | 492 }, |
| 458 | 493 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 this.languageSettingsPrivate.disableLanguage(languageCode); | 534 this.languageSettingsPrivate.disableLanguage(languageCode); |
| 500 this.enableTranslateLanguage(languageCode); | 535 this.enableTranslateLanguage(languageCode); |
| 501 }, | 536 }, |
| 502 | 537 |
| 503 /** | 538 /** |
| 504 * @param {string} languageCode Language code for an enabled language. | 539 * @param {string} languageCode Language code for an enabled language. |
| 505 * @return {boolean} | 540 * @return {boolean} |
| 506 */ | 541 */ |
| 507 canDisableLanguage: function(languageCode) { | 542 canDisableLanguage: function(languageCode) { |
| 508 // Cannot disable the prospective UI language. | 543 // Cannot disable the prospective UI language. |
| 509 if (languageCode == this.getProspectiveUILanguage()) | 544 if (languageCode == this.languages.prospectiveUILanguage) |
| 510 return false; | 545 return false; |
| 511 | 546 |
| 512 // Cannot disable the only enabled language. | 547 // Cannot disable the only enabled language. |
| 513 if (this.languages.enabled.length == 1) | 548 if (this.languages.enabled.length == 1) |
| 514 return false; | 549 return false; |
| 515 | 550 |
| 516 if (!cr.isChromeOS) | 551 if (!cr.isChromeOS) |
| 517 return true; | 552 return true; |
| 518 | 553 |
| 519 // If this is the only enabled language that is supported by all enabled | 554 // If this is the only enabled language that is supported by all enabled |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 this.updateEnabledInputMethods_(); | 772 this.updateEnabledInputMethods_(); |
| 738 }, | 773 }, |
| 739 | 774 |
| 740 /** @param {string} id Removed input method ID. */ | 775 /** @param {string} id Removed input method ID. */ |
| 741 onInputMethodRemoved_: function(id) { | 776 onInputMethodRemoved_: function(id) { |
| 742 assert(cr.isChromeOS); | 777 assert(cr.isChromeOS); |
| 743 this.updateEnabledInputMethods_(); | 778 this.updateEnabledInputMethods_(); |
| 744 }, | 779 }, |
| 745 }); | 780 }); |
| 746 })(); | 781 })(); |
| OLD | NEW |