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

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

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

Powered by Google App Engine
This is Rietveld 408576698