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

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: Reduce 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 the LanguageHelper APIs provided by
10 * current language settings. The 'languages' property is read-only, meaning 10 * this class via languageHelper.
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 */ 11 */
23 12
24 var SettingsLanguagesSingletonElement;
25
26 cr.exportPath('languageSettings');
27
28 (function() { 13 (function() {
29 'use strict'; 14 'use strict';
30 15
16 cr.exportPath('settings');
17
31 // Translate server treats some language codes the same. 18 // Translate server treats some language codes the same.
32 // See also: components/translate/core/common/translate_util.cc. 19 // See also: components/translate/core/common/translate_util.cc.
33 var kLanguageCodeToTranslateCode = { 20 var kLanguageCodeToTranslateCode = {
34 'nb': 'no', 21 'nb': 'no',
35 'fil': 'tl', 22 'fil': 'tl',
36 'zh-HK': 'zh-TW', 23 'zh-HK': 'zh-TW',
37 'zh-MO': 'zh-TW', 24 'zh-MO': 'zh-TW',
38 'zh-SG': 'zh-CN', 25 'zh-SG': 'zh-CN',
39 }; 26 };
40 27
41 // 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
42 // Translate still uses the old versions. TODO(michaelpg): Chrome does too. 29 // Translate still uses the old versions. TODO(michaelpg): Chrome does too.
43 // 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.
44 var kTranslateLanguageSynonyms = { 31 var kTranslateLanguageSynonyms = {
45 'he': 'iw', 32 'he': 'iw',
46 'jv': 'jw', 33 'jv': 'jw',
47 }; 34 };
48 35
49 var preferredLanguagesPrefName = cr.isChromeOS ? 36 var preferredLanguagesPrefName = cr.isChromeOS ?
50 'settings.language.preferred_languages' : 'intl.accept_languages'; 37 'settings.language.preferred_languages' : 'intl.accept_languages';
51 38
52 /** 39 /**
53 * Singleton element that generates the languages model on start-up and 40 * Singleton element that generates the languages model on start-up and
54 * updates it whenever Chrome's pref store and other settings change. These 41 * 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} 42 * @implements {LanguageHelper}
58 */ 43 */
59 SettingsLanguagesSingletonElement = Polymer({ 44 Polymer({
60 is: 'settings-languages-singleton', 45 is: 'settings-languages',
61 46
62 behaviors: [PrefsBehavior], 47 behaviors: [PrefsBehavior],
63 48
64 properties: { 49 properties: {
65 /** 50 /**
66 * @type {!LanguagesModel|undefined} 51 * @type {!LanguagesModel|undefined}
67 */ 52 */
68 languages: { 53 languages: {
69 type: Object, 54 type: Object,
70 notify: true, 55 notify: true,
56 readOnly: true,
71 }, 57 },
72 58
73 /** 59 /**
74 * Object containing all preferences. 60 * Object containing all preferences.
75 */ 61 */
76 prefs: { 62 prefs: {
77 type: Object, 63 type: Object,
78 notify: true, 64 notify: true,
79 }, 65 },
80 66
81 /** 67 /**
68 * This element, as a LanguageHelper instance for API usage.
69 * @type {!LanguageHelper}
70 */
71 languageHelper: {
72 type: Object,
73 notify: true,
74 readOnly: true,
75 value: function() { return /** @type {!LanguageHelper} */(this); },
76 },
77
78 /**
82 * PromiseResolver to be resolved when the singleton has been initialized. 79 * PromiseResolver to be resolved when the singleton has been initialized.
83 * @private {!PromiseResolver} 80 * @private {!PromiseResolver}
84 */ 81 */
85 resolver_: { 82 resolver_: {
86 type: Object, 83 type: Object,
87 value: function() { 84 value: function() {
88 return new PromiseResolver(); 85 return new PromiseResolver();
89 }, 86 },
90 }, 87 },
91 88
92 /** @type {!LanguageSettingsPrivate} */ 89 /** @type {!LanguageSettingsPrivate} */
93 languageSettingsPrivate: Object, 90 languageSettingsPrivate: Object,
94 91
95 /** @type {!InputMethodPrivate} */ 92 /** @type {!InputMethodPrivate} */
96 inputMethodPrivate: Object, 93 inputMethodPrivate: Object,
94
95 /**
96 * Hash map of supported languages by language codes for fast lookup.
97 * @private {!Map<string, !chrome.languageSettingsPrivate.Language>}
98 */
99 supportedLanguageMap_: {
100 type: Object,
101 value: function() { return new Map(); },
102 },
103
104 /**
105 * Hash set of enabled language codes for membership testing.
106 * @private {!Set<string>}
107 */
108 enabledLanguageSet_: {
109 type: Object,
110 value: function() { return new Set(); },
111 },
112
113 /**
114 * Hash map of supported input methods by ID for fast lookup.
115 * @private {!Map<string, chrome.languageSettingsPrivate.InputMethod>}
116 */
117 supportedInputMethodMap_: {
118 type: Object,
119 value: function() { return new Map(); },
120 },
121
122 /**
123 * Hash map of input methods supported for each language.
124 * @type {!Map<string,
125 * !Array<!chrome.languageSettingsPrivate.InputMethod>>}
126 * @private
127 */
128 languageInputMethods_: {
129 type: Object,
130 value: function() { return new Map(); },
131 },
97 }, 132 },
98 133
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: [ 134 observers: [
125 'preferredLanguagesPrefChanged_(' + 135 'preferredLanguagesPrefChanged_(' +
126 'prefs.' + preferredLanguagesPrefName + '.value, languages)', 136 'prefs.' + preferredLanguagesPrefName + '.value, languages)',
127 'spellCheckDictionariesPrefChanged_(' + 137 'spellCheckDictionariesPrefChanged_(' +
128 'prefs.spellcheck.dictionaries.value.*, languages)', 138 'prefs.spellcheck.dictionaries.value.*, languages)',
129 'translateLanguagesPrefChanged_(' + 139 'translateLanguagesPrefChanged_(' +
130 'prefs.translate_blocked_languages.value.*, languages)', 140 'prefs.translate_blocked_languages.value.*, languages)',
131 'prospectiveUILanguageChanged_(' + 141 'prospectiveUILanguageChanged_(' +
132 'prefs.intl.app_locale.value, languages)', 142 'prefs.intl.app_locale.value, languages)',
133 // Observe Chrome OS prefs (ignored for non-Chrome OS). 143 // Observe Chrome OS prefs (ignored for non-Chrome OS).
134 'updateRemovableLanguages_(' + 144 'updateRemovableLanguages_(' +
135 'prefs.settings.language.preload_engines.value, ' + 145 'prefs.settings.language.preload_engines.value, ' +
136 'prefs.settings.language.enabled_extension_imes.value, ' + 146 'prefs.settings.language.enabled_extension_imes.value, ' +
137 'languages)', 147 'languages)',
138 ], 148 ],
139 149
140 /** @override */ 150 /** @override */
141 created: function() { 151 created: function() {
142 this.languageSettingsPrivate = 152 this.languageSettingsPrivate =
143 languageSettings.languageSettingsPrivateApiForTest || 153 settings.languageSettingsPrivateApiForTest ||
144 /** @type {!LanguageSettingsPrivate} */(chrome.languageSettingsPrivate); 154 /** @type {!LanguageSettingsPrivate} */(chrome.languageSettingsPrivate);
145 155
146 this.inputMethodPrivate = 156 this.inputMethodPrivate =
147 languageSettings.inputMethodPrivateApiForTest || 157 settings.inputMethodPrivateApiForTest ||
148 /** @type {!InputMethodPrivate} */(chrome.inputMethodPrivate); 158 /** @type {!InputMethodPrivate} */(chrome.inputMethodPrivate);
149 159
150 var promises = []; 160 var promises = [];
151 161
152 // Wait until prefs are initialized before creating the model, so we can 162 // Wait until prefs are initialized before creating the model, so we can
153 // include information about enabled languages. 163 // include information about enabled languages.
154 promises[0] = CrSettingsPrefs.initialized; 164 promises[0] = CrSettingsPrefs.initialized;
155 165
156 // Get the language list. 166 // Get the language list.
157 promises[1] = new Promise(function(resolve) { 167 promises[1] = new Promise(function(resolve) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 }); 302 });
293 if (cr.isChromeOS) { 303 if (cr.isChromeOS) {
294 model.inputMethods = /** @type {!InputMethodsModel} */({ 304 model.inputMethods = /** @type {!InputMethodsModel} */({
295 supported: supportedInputMethods, 305 supported: supportedInputMethods,
296 enabled: this.getEnabledInputMethods_(), 306 enabled: this.getEnabledInputMethods_(),
297 currentId: currentInputMethodId, 307 currentId: currentInputMethodId,
298 }); 308 });
299 } 309 }
300 310
301 // Initialize the Polymer languages model. 311 // Initialize the Polymer languages model.
302 this.languages = model; 312 this._setLanguages(model);
303 }, 313 },
304 314
305 /** 315 /**
306 * Returns a list of LanguageStates for each enabled language in the supported 316 * Returns a list of LanguageStates for each enabled language in the supported
307 * languages list. 317 * languages list.
308 * @param {string} translateTarget Language code of the default translate 318 * @param {string} translateTarget Language code of the default translate
309 * target language. 319 * target language.
310 * @return {!Array<!LanguageState>} 320 * @return {!Array<!LanguageState>}
311 * @private 321 * @private
312 */ 322 */
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 this.languageSettingsPrivate.removeInputMethod(id); 689 this.languageSettingsPrivate.removeInputMethod(id);
680 }, 690 },
681 691
682 /** @param {string} id */ 692 /** @param {string} id */
683 setCurrentInputMethod: function(id) { 693 setCurrentInputMethod: function(id) {
684 assert(cr.isChromeOS); 694 assert(cr.isChromeOS);
685 this.inputMethodPrivate.setCurrentInputMethod(id); 695 this.inputMethodPrivate.setCurrentInputMethod(id);
686 }, 696 },
687 697
688 /** 698 /**
689 * param {string} languageCode 699 * @param {string} languageCode
690 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} 700 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>}
691 */ 701 */
692 getInputMethodsForLanguage: function(languageCode) { 702 getInputMethodsForLanguage: function(languageCode) {
693 return this.languageInputMethods_.get(languageCode) || []; 703 return this.languageInputMethods_.get(languageCode) || [];
694 }, 704 },
695 705
696 /** 706 /**
697 * @param {!chrome.languageSettingsPrivate.InputMethod} inputMethod 707 * @param {!chrome.languageSettingsPrivate.InputMethod} inputMethod
698 * @return {boolean} 708 * @return {boolean}
699 */ 709 */
(...skipping 20 matching lines...) Expand all
720 this.updateEnabledInputMethods_(); 730 this.updateEnabledInputMethods_();
721 }, 731 },
722 732
723 /** @param {string} id Removed input method ID. */ 733 /** @param {string} id Removed input method ID. */
724 onInputMethodRemoved_: function(id) { 734 onInputMethodRemoved_: function(id) {
725 assert(cr.isChromeOS); 735 assert(cr.isChromeOS);
726 this.updateEnabledInputMethods_(); 736 this.updateEnabledInputMethods_();
727 }, 737 },
728 }); 738 });
729 })(); 739 })();
730
731 /**
732 * A reference to the singleton under the guise of a LanguageHelper
733 * implementation. This provides a limited API but implies the singleton
734 * should not be used directly for data binding.
735 */
736 var LanguageHelperImpl = SettingsLanguagesSingletonElement;
737 cr.addSingletonGetter(LanguageHelperImpl);
738
739 /**
740 * This element has a reference to the singleton, exposing the singleton's
741 * |languages| model to the host of this element.
742 */
743 Polymer({
744 is: 'settings-languages',
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