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

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

Issue 1351623008: MD Settings: Languages model for language pages (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@SingletonPrefs
Patch Set: Created 5 years, 3 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
(Empty)
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
3 // found in the LICENSE file.
4
5 /**
6 * @fileoverview 'cr-settings-languages-model' provides convenient access to
7 * Chrome's language and input method settings.
8 *
9 * @group Chrome Settings Elements
10 * @element cr-settings-languages-model
11 */
12
13 /**
14 * @typedef {{spellCheckEnabled: boolean}}
15 */
16 var LanguageState;
17
18 /**
19 * @typedef {{language: !chrome.languageSettingsPrivate.Language,
20 * state: !LanguageState}}
21 */
22 var LanguageInfo;
23
24 /**
25 * The model includes:
26 * supportedLanguages: an array of languages, ordered alphabetically.
27 * enabledLanguages: an array of enabled language info and state, ordered by
28 * preference.
29 * As well as hash map equivalents: supportedLanguageMap, enabledLanguageMap.
30 * @typedef {{
31 * supportedLanguages: !Array<!chrome.languageSettingsPrivate.Language>,
32 * supportedLanguageMap: !Object<!chrome.languageSettingsPrivate.Language>,
33 * enabledLanguages: !Array<!LanguageInfo>,
34 * enabledLanguageMap: !Object<!LanguageInfo>
35 * }}
36 */
37 var LanguagesModel;
38
39 (function() {
40 'use strict';
41
42 /** Exposes the singleton model to hosts. */
43 Polymer({
44 is: 'cr-settings-languages-model',
45
46 properties: {
47 /**
48 * Shared languages model.
49 * @type {(LanguagesModel|undefined)}
50 */
51 model: {
52 type: Object,
53 notify: true,
54 readOnly: true,
55 },
56
57 /**
58 * Shared private state.
59 * @type {!Element}
60 */
61 privateModel_: {
62 type: Object,
63 value: document.createElement('cr-settings-languages-model-private'),
64 },
65 },
66
67 ready: function() {
68 this.squelching_(function() {
69 // This notifies the host via Polymer.
70 this._setModel(this.privateModel_.model);
71 });
72 this.listen(this.privateModel_, 'model-changed', 'privateModelChanged_');
73 },
74
75 /**
76 * On supported systems, sets the prospective UI language to the chosen
77 * language. This dosen't affect the actual UI language until a restart.
78 * @param {string} languageCode
79 */
80 setUILanguage: function(languageCode) {
81 this.privateModel_.setUILanguage(languageCode);
82 },
83
84 /**
85 * Enables the language, making it available for spell check and input.
86 * @param {string} languageCode
87 * */
88 enableLanguage: function(languageCode) {
89 this.privateModel_.enableLanguage(languageCode);
90 },
91
92 /**
93 * Disables the language.
94 * @param {string} languageCode
95 */
96 disableLanguage: function(languageCode) {
97 this.privateModel_.disableLanguage(languageCode);
98 },
99
100 /**
101 * Enables or disables spell check for the given language.
102 * @param {string} languageCode
103 * @param {boolean} enable
104 */
105 toggleSpellCheck: function(languageCode, enable) {
106 this.privateModel_.toggleSpellCheck(languageCode, enable);
107 },
108
109 /**
110 * Forwards changes reported by privateModel_ to the host.
111 * @private
112 */
113 privateModelChanged_: function(e) {
114 // Squelch because we've defeated Polymer's internal dirty-checking.
115 this.squelching_(function() {
116 // Forward notification to host.
117 this.fire(e.type, e.detail, {bubbles: false});
118 });
119 },
120
121 /**
122 * Sets a "squelch" switch before calling the function, so functions can
123 * return early when the switch is active.
124 * @param {!function()} fn
125 * @private
126 */
127 squelching_: function(fn) {
128 this.squelch_ = true;
129 fn.call(this);
130 // We can unset squelch_ now because change notifications are synchronous.
131 this.squelch_ = false;
132 },
133 });
134
135 var preferredLanguagesPath;
136 if (cr.isChromeOS)
137 preferredLanguagesPath = 'prefs.settings.language.preferred_languages.value';
138 else
139 preferredLanguagesPath = 'prefs.intl.accept_languages.value';
140
141 /**
142 * Privately used element that contains, listens to and updates the shared
143 * languages model.
144 */
145 Polymer({
146 is: 'cr-settings-languages-model-private',
147
148 properties: {
149 /**
150 * @type {(LanguagesModel|undefined)}
151 */
152 model: {
153 type: Object,
154 notify: true,
155 },
156
157 /**
158 * Object containing all preferences, for use by Polymer controls.
159 */
160 prefs: {
161 type: Object,
162 notify: true,
163 },
164 },
165
166 observers: [
167 'preferredLanguagesPrefChanged_(' + preferredLanguagesPath + ')',
168 'spellCheckDictionariesPrefChanged_(prefs.spellcheck.dictionaries.value.*)',
169 ],
170
171 /** @override */
172 created: function() {
173 chrome.languageSettingsPrivate.getLanguageList(function(languageList) {
174 // Wait until prefs are initialized before creating the model, so we can
175 // include information about enabled languages.
176 CrSettingsPrefs.initialized.then(function() {
177 this.createModel_(languageList);
178 this.initialized_ = true;
179 }.bind(this));
180 }.bind(this));
181 },
182
183 /**
184 * Constructs the model with the given language list.
185 * @param {!Array<!chrome.languageSettingsPrivate.Language>}
186 * supportedLanguages
187 */
188 createModel_: function(supportedLanguages) {
189 // Create a hash table of supported languages.
190 var supportedLanguageMap = {};
191 for (var i = 0; i < supportedLanguages.length; i++)
192 supportedLanguageMap[supportedLanguages[i].code] = supportedLanguages[i];
193
194 // Create a list and map of enabled language info.
195 var enabledLanguages = this.getEnabledLanguages_(supportedLanguageMap);
196 var enabledLanguageMap = {};
197 for (var i = 0; i < enabledLanguages.length; i++) {
198 var languageInfo = enabledLanguages[i];
199 enabledLanguageMap[languageInfo.language.code] = languageInfo;
200 }
201
202 // Initialize the Polymer model.
203 this.model = {
204 supportedLanguages: supportedLanguages,
205 supportedLanguageMap: supportedLanguageMap,
206 enabledLanguages: enabledLanguages,
207 enabledLanguageMap: enabledLanguageMap,
208 };
209 },
210
211 /**
212 * Returns a list of LanguageInfos for each enabled language in the supported
213 * languages list.
214 * @private
215 * @param {!Object<!chrome.languageSettingsPrivate.Language>}
216 * supportedLanguageMap
217 * @return {!Array<!LanguageInfo>}
218 */
219 getEnabledLanguages_: function(supportedLanguageMap) {
220 var languageCodes = this.get(preferredLanguagesPath).split(',');
221 var enabledLanguages = [];
222 var spellCheckMap = this.getSpellCheckMap_();
223 for (var i = 0; i < languageCodes.length; i++) {
224 var code = languageCodes[i];
225 var language = supportedLanguageMap[code];
226 if (!language)
227 continue;
228 var state = {spellCheckEnabled: !!spellCheckMap[code]};
229 enabledLanguages.push({language: language, state: state});
230 }
231 return enabledLanguages;
232 },
233
234 /**
235 * Creates a map whose keys are languages enabled for spell check.
236 * @return {!Object<boolean>}
237 */
238 getSpellCheckMap_: function() {
239 var spellCheckPref = /** @type {chrome.settingsPrivate.PrefObject} */(
240 this.get('prefs.spellcheck.dictionaries'));
241 var spellCheckCodes = spellCheckPref.value;
242 var spellCheckMap = {};
243 for (var i = 0; i < spellCheckCodes.length; i++)
244 spellCheckMap[spellCheckCodes[i]] = true;
245 return spellCheckMap;
246 },
247
248 /** @private */
249 preferredLanguagesPrefChanged_: function() {
250 if (!this.initialized_)
251 return;
252
253 var enabledLanguages =
254 this.getEnabledLanguages_(this.model.supportedLanguageMap);
255 this.set('model.enabledLanguages', enabledLanguages);
256 var enabledLanguageMap = {};
257 for (var i = 0; i < enabledLanguages.length; i++) {
258 var languageInfo = enabledLanguages[i];
259 enabledLanguageMap[languageInfo.language.code] = languageInfo;
260 }
261 this.set('model.enabledLanguageMap', enabledLanguageMap);
262 },
263
264 /**
265 * Updates the spellCheckEnabled state of each enabled language.
266 * @private
267 */
268 spellCheckDictionariesPrefChanged_: function() {
269 if (!this.initialized_)
270 return;
271
272 var spellCheckMap = this.getSpellCheckMap_();
273 for (var i = 0; i < this.model.enabledLanguages.length; i++) {
274 this.set('model.enabledLanguages.' + i + '.state.spellCheckEnabled',
275 !!spellCheckMap[this.model.enabledLanguages[i].language.code]);
276 }
277 },
278
279 /**
280 * On supported systems, sets the prospective UI language to the chosen
281 * language. This dosen't affect the actual UI language until a restart.
282 * @param {string} languageCode
283 */
284 setUILanguage: function(languageCode) {
285 // Set the prospective UI language. This won't take effect until a restart.
286 if (cr.isWindows)
287 this.set('prefs.intl.app_locale.value', languageCode);
288 else if (cr.isChromeOS)
289 chrome.send('setUILanguage', [languageCode]);
290 },
291
292 /**
293 * Enables the language, making it available for spell check and input.
294 * @param {string} languageCode
295 */
296 enableLanguage: function(languageCode) {
297 var languageCodes = this.get(preferredLanguagesPath);
298 var index = languageCodes.split(',').indexOf(languageCode);
299 if (index > -1)
300 return;
301 this.set(preferredLanguagesPath, languageCodes + ',' + languageCode);
302 },
303
304 /**
305 * Disables the language.
306 * @param {string} languageCode
307 */
308 disableLanguage: function(languageCode) {
309 // Don't disable the UI language.
310 var appLocale = this.get('prefs.intl.app_locale.value') ||
311 navigator.language;
312 if (languageCode == appLocale)
313 return;
314
315 var languageCodes = this.get(preferredLanguagesPath).split(',');
316 // Don't disable the only enabled language.
317 if (languageCodes.length == 1)
318 return;
319
320 // Remove the language from spell check.
321 var spellCheckIndex =
322 this.get('prefs.spellcheck.dictionaries.value').indexOf(languageCode);
323 if (spellCheckIndex != -1)
324 this.splice('prefs.spellcheck.dictionaries.value', spellCheckIndex, 1);
325
326 var languageIndex = languageCodes.indexOf(languageCode);
327 if (languageIndex == -1)
328 return;
329 languageCodes.splice(languageIndex, 1);
330 this.set(preferredLanguagesPath, languageCodes.join(','));
331 },
332
333 /**
334 * Enables or disables spell check for the given language.
335 * @param {string} languageCode
336 * @param {boolean} enable
337 */
338 toggleSpellCheck: function(languageCode, enable) {
339 var spellCheckPref = /** @type {chrome.settingsPrivate.PrefObject} */(
340 this.get('prefs.spellcheck.dictionaries'));
341 if (enable) {
342 if (spellCheckPref.value.indexOf(languageCode) == -1)
343 this.push('prefs.spellcheck.dictionaries.value', languageCode);
344 } else {
345 // TODO: need update externs before committing
346 this.arrayDelete('prefs.spellcheck.dictionaries.value', languageCode);
347 }
348 },
349 });
350 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698