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' 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 'prospectiveUILanguageChanged_(prefs.intl.app_locale.value)', | |
| 127 'preferredLanguagesPrefChanged_(' + | 131 'preferredLanguagesPrefChanged_(' + |
| 128 'prefs.' + preferredLanguagesPrefName + '.value, languages)', | 132 'prefs.' + preferredLanguagesPrefName + '.value, languages)', |
| 129 'spellCheckDictionariesPrefChanged_(' + | 133 'spellCheckDictionariesPrefChanged_(' + |
| 130 'prefs.spellcheck.dictionaries.value.*, languages)', | 134 'prefs.spellcheck.dictionaries.value.*, languages)', |
| 131 'translateLanguagesPrefChanged_(' + | 135 'translateLanguagesPrefChanged_(' + |
| 132 'prefs.translate_blocked_languages.value.*, languages)', | 136 'prefs.translate_blocked_languages.value.*, languages)', |
| 133 'updateRemovableLanguages_(' + | 137 'updateRemovableLanguages_(' + |
| 134 'prefs.intl.app_locale.value, languages.enabled)', | 138 'prefs.intl.app_locale.value, languages.enabled)', |
| 135 // Observe Chrome OS prefs (ignored for non-Chrome OS). | 139 // Observe Chrome OS prefs (ignored for non-Chrome OS). |
| 136 'updateRemovableLanguages_(' + | 140 'updateRemovableLanguages_(' + |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 resolve(lists.componentExtensionImes.concat( | 175 resolve(lists.componentExtensionImes.concat( |
| 172 lists.thirdPartyExtensionImes)); | 176 lists.thirdPartyExtensionImes)); |
| 173 }); | 177 }); |
| 174 }.bind(this)); | 178 }.bind(this)); |
| 175 | 179 |
| 176 promises[4] = new Promise(function(resolve) { | 180 promises[4] = new Promise(function(resolve) { |
| 177 this.inputMethodPrivate.getCurrentInputMethod(resolve); | 181 this.inputMethodPrivate.getCurrentInputMethod(resolve); |
| 178 }.bind(this)); | 182 }.bind(this)); |
| 179 } | 183 } |
| 180 | 184 |
| 185 if (cr.isWindows || cr.isChromeOS) { | |
| 186 // Fetch the starting UI language, which affects which actions should be | |
| 187 // enabled. | |
| 188 promises.push(cr.sendWithPromise('getProspectiveUILanguage').then( | |
| 189 function(prospectiveUILanguage) { | |
| 190 this.originalProspectiveUILanguage_ = | |
| 191 prospectiveUILanguage || navigator.language; | |
|
stevenjb
2016/12/13 18:53:09
nit: I had to look up 'navigator.language', maybe
michaelpg
2016/12/14 01:13:27
Done.
| |
| 192 }.bind(this))); | |
| 193 } | |
| 194 | |
| 181 Promise.all(promises).then(function(results) { | 195 Promise.all(promises).then(function(results) { |
| 182 this.createModel_(results[1], results[2], results[3], results[4]); | 196 this.createModel_(results[1], results[2], results[3], results[4]); |
| 183 this.resolver_.resolve(); | 197 this.resolver_.resolve(); |
| 184 }.bind(this)); | 198 }.bind(this)); |
| 185 | 199 |
| 186 if (cr.isChromeOS) { | 200 if (cr.isChromeOS) { |
| 187 this.inputMethodPrivate.onChanged.addListener( | 201 this.inputMethodPrivate.onChanged.addListener( |
| 188 this.onInputMethodChanged_.bind(this)); | 202 this.onInputMethodChanged_.bind(this)); |
| 189 } | 203 } |
| 190 }, | 204 }, |
| 191 | 205 |
| 192 /** | 206 /** |
| 207 * Updates the prospective UI language based on the new pref value. | |
| 208 * @param {string} prospectiveUILanguage | |
| 209 * @private | |
| 210 */ | |
| 211 prospectiveUILanguageChanged_: function(prospectiveUILanguage) { | |
| 212 if (!this.languages) | |
| 213 return; | |
|
stevenjb
2016/12/13 18:53:09
Maybe make 'languages' an argument to this observe
michaelpg
2016/12/14 01:13:27
Done.
| |
| 214 | |
| 215 this.set('languages.prospectiveUILanguage', | |
| 216 prospectiveUILanguage || this.originalProspectiveUILanguage_); | |
| 217 }, | |
| 218 | |
| 219 /** | |
| 193 * Updates the list of enabled languages from the preferred languages pref. | 220 * Updates the list of enabled languages from the preferred languages pref. |
| 194 * @private | 221 * @private |
| 195 */ | 222 */ |
| 196 preferredLanguagesPrefChanged_: function() { | 223 preferredLanguagesPrefChanged_: function() { |
| 197 var enabledLanguageStates = | 224 var enabledLanguageStates = this.getEnabledLanguageStates_( |
| 198 this.getEnabledLanguageStates_(this.languages.translateTarget); | 225 this.languages.translateTarget, this.languages.prospectiveUILanguage); |
| 199 | 226 |
| 200 // Recreate the enabled language set before updating languages.enabled. | 227 // Recreate the enabled language set before updating languages.enabled. |
| 201 this.enabledLanguageSet_.clear(); | 228 this.enabledLanguageSet_.clear(); |
| 202 for (var languageState of enabledLanguageStates) | 229 for (var languageState of enabledLanguageStates) |
| 203 this.enabledLanguageSet_.add(languageState.language.code); | 230 this.enabledLanguageSet_.add(languageState.language.code); |
| 204 | 231 |
| 205 this.set('languages.enabled', enabledLanguageStates); | 232 this.set('languages.enabled', enabledLanguageStates); |
| 206 }, | 233 }, |
| 207 | 234 |
| 208 /** | 235 /** |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 219 } | 246 } |
| 220 }, | 247 }, |
| 221 | 248 |
| 222 /** @private */ | 249 /** @private */ |
| 223 translateLanguagesPrefChanged_: function() { | 250 translateLanguagesPrefChanged_: function() { |
| 224 var translateBlockedPref = this.getPref('translate_blocked_languages'); | 251 var translateBlockedPref = this.getPref('translate_blocked_languages'); |
| 225 var translateBlockedSet = this.makeSetFromArray_( | 252 var translateBlockedSet = this.makeSetFromArray_( |
| 226 /** @type {!Array<string>} */(translateBlockedPref.value)); | 253 /** @type {!Array<string>} */(translateBlockedPref.value)); |
| 227 | 254 |
| 228 for (var i = 0; i < this.languages.enabled.length; i++) { | 255 for (var i = 0; i < this.languages.enabled.length; i++) { |
| 229 if (this.languages.enabled[i].language.code == navigator.language) | 256 if (this.languages.enabled[i].language.code == |
| 257 this.languages.prospectiveUILanguage) { | |
| 230 continue; | 258 continue; |
| 259 } | |
| 231 var translateCode = this.convertLanguageCodeForTranslate( | 260 var translateCode = this.convertLanguageCodeForTranslate( |
| 232 this.languages.enabled[i].language.code); | 261 this.languages.enabled[i].language.code); |
| 233 this.set( | 262 this.set( |
| 234 'languages.enabled.' + i + '.translateEnabled', | 263 'languages.enabled.' + i + '.translateEnabled', |
| 235 !translateBlockedSet.has(translateCode)); | 264 !translateBlockedSet.has(translateCode)); |
| 236 } | 265 } |
| 237 }, | 266 }, |
| 238 | 267 |
| 239 /** | 268 /** |
| 240 * Constructs the languages model. | 269 * Constructs the languages model. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 270 if (!this.supportedLanguageMap_.has(languageCode)) | 299 if (!this.supportedLanguageMap_.has(languageCode)) |
| 271 continue; | 300 continue; |
| 272 if (!this.languageInputMethods_.has(languageCode)) | 301 if (!this.languageInputMethods_.has(languageCode)) |
| 273 this.languageInputMethods_.set(languageCode, [inputMethod]); | 302 this.languageInputMethods_.set(languageCode, [inputMethod]); |
| 274 else | 303 else |
| 275 this.languageInputMethods_.get(languageCode).push(inputMethod); | 304 this.languageInputMethods_.get(languageCode).push(inputMethod); |
| 276 } | 305 } |
| 277 } | 306 } |
| 278 } | 307 } |
| 279 | 308 |
| 309 var prospectiveUILanguage; | |
| 310 if (cr.isChromeOS || cr.isWindows) { | |
| 311 prospectiveUILanguage = | |
| 312 /** @type {string} */(this.getPref('intl.app_locale').value) || | |
| 313 this.originalProspectiveUILanguage_; | |
| 314 } | |
| 315 | |
| 280 // Create a list of enabled languages from the supported languages. | 316 // Create a list of enabled languages from the supported languages. |
| 281 var enabledLanguageStates = this.getEnabledLanguageStates_(translateTarget); | 317 var enabledLanguageStates = |
| 318 this.getEnabledLanguageStates_(translateTarget, prospectiveUILanguage); | |
| 282 // Populate the hash set of enabled languages. | 319 // Populate the hash set of enabled languages. |
| 283 for (var languageState of enabledLanguageStates) | 320 for (var languageState of enabledLanguageStates) |
| 284 this.enabledLanguageSet_.add(languageState.language.code); | 321 this.enabledLanguageSet_.add(languageState.language.code); |
| 285 | 322 |
| 286 var model = /** @type {!LanguagesModel} */({ | 323 var model = /** @type {!LanguagesModel} */({ |
| 287 supported: supportedLanguages, | 324 supported: supportedLanguages, |
| 288 enabled: enabledLanguageStates, | 325 enabled: enabledLanguageStates, |
| 289 translateTarget: translateTarget, | 326 translateTarget: translateTarget, |
| 290 }); | 327 }); |
| 328 | |
| 329 if (cr.isChromeOS || cr.isWindows) | |
| 330 model.prospectiveUILanguage = prospectiveUILanguage; | |
| 331 | |
| 291 if (cr.isChromeOS) { | 332 if (cr.isChromeOS) { |
| 292 model.inputMethods = /** @type {!InputMethodsModel} */({ | 333 model.inputMethods = /** @type {!InputMethodsModel} */({ |
| 293 supported: supportedInputMethods, | 334 supported: supportedInputMethods, |
| 294 enabled: this.getEnabledInputMethods_(), | 335 enabled: this.getEnabledInputMethods_(), |
| 295 currentId: currentInputMethodId, | 336 currentId: currentInputMethodId, |
| 296 }); | 337 }); |
| 297 } | 338 } |
| 298 | 339 |
| 299 // Initialize the Polymer languages model. | 340 // Initialize the Polymer languages model. |
| 300 this._setLanguages(model); | 341 this._setLanguages(model); |
| 301 }, | 342 }, |
| 302 | 343 |
| 303 /** | 344 /** |
| 304 * Returns a list of LanguageStates for each enabled language in the supported | 345 * Returns a list of LanguageStates for each enabled language in the supported |
| 305 * languages list. | 346 * languages list. |
| 306 * @param {string} translateTarget Language code of the default translate | 347 * @param {string} translateTarget Language code of the default translate |
| 307 * target language. | 348 * target language. |
| 349 * @param {(string|undefined)} prospectiveUILanguage Prospective UI display | |
| 350 * language. Only defined on Windows and Chrome OS. | |
| 308 * @return {!Array<!LanguageState>} | 351 * @return {!Array<!LanguageState>} |
| 309 * @private | 352 * @private |
| 310 */ | 353 */ |
| 311 getEnabledLanguageStates_: function(translateTarget) { | 354 getEnabledLanguageStates_: function(translateTarget, prospectiveUILanguage) { |
| 312 assert(CrSettingsPrefs.isInitialized); | 355 assert(CrSettingsPrefs.isInitialized); |
| 313 | 356 |
| 314 var pref = this.getPref(preferredLanguagesPrefName); | 357 var pref = this.getPref(preferredLanguagesPrefName); |
| 315 var enabledLanguageCodes = pref.value.split(','); | 358 var enabledLanguageCodes = pref.value.split(','); |
| 316 var spellCheckPref = this.getPref('spellcheck.dictionaries'); | 359 var spellCheckPref = this.getPref('spellcheck.dictionaries'); |
| 317 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */( | 360 var spellCheckSet = this.makeSetFromArray_(/** @type {!Array<string>} */( |
| 318 spellCheckPref.value)); | 361 spellCheckPref.value)); |
| 319 | 362 |
| 320 var translateBlockedPref = this.getPref('translate_blocked_languages'); | 363 var translateBlockedPref = this.getPref('translate_blocked_languages'); |
| 321 var translateBlockedSet = this.makeSetFromArray_( | 364 var translateBlockedSet = this.makeSetFromArray_( |
| 322 /** @type {!Array<string>} */(translateBlockedPref.value)); | 365 /** @type {!Array<string>} */(translateBlockedPref.value)); |
| 323 | 366 |
| 324 var enabledLanguageStates = []; | 367 var enabledLanguageStates = []; |
| 325 for (var i = 0; i < enabledLanguageCodes.length; i++) { | 368 for (var i = 0; i < enabledLanguageCodes.length; i++) { |
| 326 var code = enabledLanguageCodes[i]; | 369 var code = enabledLanguageCodes[i]; |
| 327 var language = this.supportedLanguageMap_.get(code); | 370 var language = this.supportedLanguageMap_.get(code); |
| 328 // Skip unsupported languages. | 371 // Skip unsupported languages. |
| 329 if (!language) | 372 if (!language) |
| 330 continue; | 373 continue; |
| 331 var languageState = /** @type {LanguageState} */({}); | 374 var languageState = /** @type {LanguageState} */({}); |
| 332 languageState.language = language; | 375 languageState.language = language; |
| 333 languageState.spellCheckEnabled = !!spellCheckSet.has(code); | 376 languageState.spellCheckEnabled = !!spellCheckSet.has(code); |
| 334 // Translate is considered disabled if this language maps to any translate | 377 // Translate is considered disabled if this language maps to any translate |
| 335 // language that is blocked. | 378 // language that is blocked. |
| 336 var translateCode = this.convertLanguageCodeForTranslate(code); | 379 var translateCode = this.convertLanguageCodeForTranslate(code); |
| 337 languageState.translateEnabled = !!language.supportsTranslate && | 380 languageState.translateEnabled = !!language.supportsTranslate && |
| 338 code != navigator.language && | 381 code != prospectiveUILanguage && |
|
stevenjb
2016/12/13 18:53:09
This will be undefined on osx, right? Won't this a
michaelpg
2016/12/14 01:13:27
Added !prospectiveUILanguage. There's already more
stevenjb
2016/12/14 01:19:50
Understood. It just wasn't clear that on platforms
| |
| 339 !translateBlockedSet.has(translateCode) && | 382 !translateBlockedSet.has(translateCode) && |
| 340 translateCode != translateTarget; | 383 translateCode != translateTarget; |
| 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>} |
| (...skipping 70 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 |