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

Side by Side Diff: chrome/browser/resources/options2/language_options.js

Issue 8930012: Revert 114236 - Options2: Pull the trigger. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 // TODO(kochi): Generalize the notification as a component and put it
6 // in js/cr/ui/notification.js .
7
8 cr.define('options', function() {
9 const OptionsPage = options.OptionsPage;
10 const LanguageList = options.LanguageList;
11
12 // Some input methods like Chinese Pinyin have config pages.
13 // This is the map of the input method names to their config page names.
14 const INPUT_METHOD_ID_TO_CONFIG_PAGE_NAME = {
15 'mozc': 'languageMozc',
16 'mozc-chewing': 'languageChewing',
17 'mozc-dv': 'languageMozc',
18 'mozc-hangul': 'languageHangul',
19 'mozc-jp': 'languageMozc',
20 'pinyin': 'languagePinyin',
21 'pinyin-dv': 'languagePinyin',
22 };
23
24 /////////////////////////////////////////////////////////////////////////////
25 // LanguageOptions class:
26
27 /**
28 * Encapsulated handling of ChromeOS language options page.
29 * @constructor
30 */
31 function LanguageOptions(model) {
32 OptionsPage.call(this, 'languages', templateData.languagePageTabTitle,
33 'languagePage');
34 }
35
36 cr.addSingletonGetter(LanguageOptions);
37
38 // Inherit LanguageOptions from OptionsPage.
39 LanguageOptions.prototype = {
40 __proto__: OptionsPage.prototype,
41
42 /**
43 * Initializes LanguageOptions page.
44 * Calls base class implementation to starts preference initialization.
45 */
46 initializePage: function() {
47 OptionsPage.prototype.initializePage.call(this);
48
49 var languageOptionsList = $('language-options-list');
50 LanguageList.decorate(languageOptionsList);
51
52 languageOptionsList.addEventListener('change',
53 this.handleLanguageOptionsListChange_.bind(this));
54 languageOptionsList.addEventListener('save',
55 this.handleLanguageOptionsListSave_.bind(this));
56
57 this.addEventListener('visibleChange',
58 this.handleVisibleChange_.bind(this));
59
60 if (cr.isChromeOS) {
61 this.initializeInputMethodList_();
62 this.initializeLanguageCodeToInputMethodIdsMap_();
63 }
64 Preferences.getInstance().addEventListener(this.spellCheckDictionaryPref,
65 this.handleSpellCheckDictionaryPrefChange_.bind(this));
66
67 // Set up add button.
68 $('language-options-add-button').onclick = function(e) {
69 // Add the language without showing the overlay if it's specified in
70 // the URL hash (ex. lang_add=ja). Used for automated testing.
71 var match = document.location.hash.match(/\blang_add=([\w-]+)/);
72 if (match) {
73 var addLanguageCode = match[1];
74 $('language-options-list').addLanguage(addLanguageCode);
75 } else {
76 OptionsPage.navigateToPage('addLanguage');
77 }
78 };
79
80 if (cr.isChromeOS) {
81 // Listen to user clicks on the add language list.
82 var addLanguageList = $('add-language-overlay-language-list');
83 addLanguageList.addEventListener('click',
84 this.handleAddLanguageListClick_.bind(this));
85 } else {
86 // Listen to add language dialog ok button.
87 var addLanguageOkButton = $('add-language-overlay-ok-button');
88 addLanguageOkButton.addEventListener('click',
89 this.handleAddLanguageOkButtonClick_.bind(this));
90
91 // Show experimental features if enabled.
92 if (templateData.experimentalSpellCheckFeatures == 'true')
93 $('auto-spell-correction-option').hidden = false;
94
95 // Handle spell check enable/disable.
96 Preferences.getInstance().addEventListener(this.enableSpellCheckPref,
97 this.updateEnableSpellCheck_.bind(this));
98 }
99
100 // Listen to user clicks on the "Change touch keyboard settings..."
101 // button (if it exists).
102 var virtualKeyboardButton = $('language-options-virtual-keyboard');
103 if (virtualKeyboardButton) {
104 // TODO(yusukes): would be better to hide the button if no virtual
105 // keyboard is registered.
106 virtualKeyboardButton.onclick = function(e) {
107 OptionsPage.navigateToPage('virtualKeyboards');
108 };
109 }
110 },
111
112 // The preference is a boolean that enables/disables spell checking.
113 enableSpellCheckPref: 'browser.enable_spellchecking',
114 // The preference is a CSV string that describes preload engines
115 // (i.e. active input methods).
116 preloadEnginesPref: 'settings.language.preload_engines',
117 // The list of preload engines, like ['mozc', 'pinyin'].
118 preloadEngines_: [],
119 // The preference is a string that describes the spell check
120 // dictionary language, like "en-US".
121 spellCheckDictionaryPref: 'spellcheck.dictionary',
122 spellCheckDictionary_: "",
123 // The map of language code to input method IDs, like:
124 // {'ja': ['mozc', 'mozc-jp'], 'zh-CN': ['pinyin'], ...}
125 languageCodeToInputMethodIdsMap_: {},
126
127 /**
128 * Initializes the input method list.
129 */
130 initializeInputMethodList_: function() {
131 var inputMethodList = $('language-options-input-method-list');
132 var inputMethodListData = templateData.inputMethodList;
133
134 // Add all input methods, but make all of them invisible here. We'll
135 // change the visibility in handleLanguageOptionsListChange_() based
136 // on the selected language. Note that we only have less than 100
137 // input methods, so creating DOM nodes at once here should be ok.
138 for (var i = 0; i < inputMethodListData.length; i++) {
139 var inputMethod = inputMethodListData[i];
140 var input = document.createElement('input');
141 input.type = 'checkbox';
142 input.inputMethodId = inputMethod.id;
143 // Listen to user clicks.
144 input.addEventListener('click',
145 this.handleCheckboxClick_.bind(this));
146 var label = document.createElement('label');
147 label.appendChild(input);
148 // Adding a space between the checkbox and the text. This is a bit
149 // dirty, but we rely on a space character for all other checkboxes.
150 label.appendChild(document.createTextNode(
151 ' ' + inputMethod.displayName));
152 label.style.display = 'none';
153 label.languageCodeSet = inputMethod.languageCodeSet;
154 // Add the configure button if the config page is present for this
155 // input method.
156 if (inputMethod.id in INPUT_METHOD_ID_TO_CONFIG_PAGE_NAME) {
157 var pageName = INPUT_METHOD_ID_TO_CONFIG_PAGE_NAME[inputMethod.id];
158 var button = this.createConfigureInputMethodButton_(inputMethod.id,
159 pageName);
160 label.appendChild(button);
161 }
162
163 inputMethodList.appendChild(label);
164 }
165 // Listen to pref change once the input method list is initialized.
166 Preferences.getInstance().addEventListener(this.preloadEnginesPref,
167 this.handlePreloadEnginesPrefChange_.bind(this));
168 },
169
170 /**
171 * Creates a configure button for the given input method ID.
172 * @param {string} inputMethodId Input method ID (ex. "pinyin").
173 * @param {string} pageName Name of the config page (ex. "languagePinyin").
174 * @private
175 */
176 createConfigureInputMethodButton_: function(inputMethodId, pageName) {
177 var button = document.createElement('button');
178 button.textContent = localStrings.getString('configure');
179 button.onclick = function(e) {
180 // Prevent the default action (i.e. changing the checked property
181 // of the checkbox). The button click here should not be handled
182 // as checkbox click.
183 e.preventDefault();
184 chrome.send('inputMethodOptionsOpen', [inputMethodId]);
185 OptionsPage.navigateToPage(pageName);
186 }
187 return button;
188 },
189
190 /**
191 * Handles OptionsPage's visible property change event.
192 * @param {Event} e Property change event.
193 * @private
194 */
195 handleVisibleChange_: function(e) {
196 if (this.visible) {
197 $('language-options-list').redraw();
198 chrome.send('languageOptionsOpen');
199 }
200 },
201
202 /**
203 * Handles languageOptionsList's change event.
204 * @param {Event} e Change event.
205 * @private
206 */
207 handleLanguageOptionsListChange_: function(e) {
208 var languageOptionsList = $('language-options-list');
209 var languageCode = languageOptionsList.getSelectedLanguageCode();
210 // Select the language if it's specified in the URL hash (ex. lang=ja).
211 // Used for automated testing.
212 var match = document.location.hash.match(/\blang=([\w-]+)/);
213 if (match) {
214 var specifiedLanguageCode = match[1];
215 if (languageOptionsList.selectLanguageByCode(specifiedLanguageCode)) {
216 languageCode = specifiedLanguageCode;
217 }
218 }
219 this.updateSelectedLanguageName_(languageCode);
220 if (cr.isWindows || cr.isChromeOS)
221 this.updateUiLanguageButton_(languageCode);
222 this.updateSpellCheckLanguageButton_(languageCode);
223 if (cr.isChromeOS)
224 this.updateInputMethodList_(languageCode);
225 this.updateLanguageListInAddLanguageOverlay_();
226 },
227
228 /**
229 * Handles languageOptionsList's save event.
230 * @param {Event} e Save event.
231 * @private
232 */
233 handleLanguageOptionsListSave_: function(e) {
234 if (cr.isChromeOS) {
235 // Sort the preload engines per the saved languages before save.
236 this.preloadEngines_ = this.sortPreloadEngines_(this.preloadEngines_);
237 this.savePreloadEnginesPref_();
238 }
239 },
240
241 /**
242 * Sorts preloadEngines_ by languageOptionsList's order.
243 * @param {Array} preloadEngines List of preload engines.
244 * @return {Array} Returns sorted preloadEngines.
245 * @private
246 */
247 sortPreloadEngines_: function(preloadEngines) {
248 // For instance, suppose we have two languages and associated input
249 // methods:
250 //
251 // - Korean: hangul
252 // - Chinese: pinyin
253 //
254 // The preloadEngines preference should look like "hangul,pinyin".
255 // If the user reverse the order, the preference should be reorderd
256 // to "pinyin,hangul".
257 var languageOptionsList = $('language-options-list');
258 var languageCodes = languageOptionsList.getLanguageCodes();
259
260 // Convert the list into a dictonary for simpler lookup.
261 var preloadEngineSet = {};
262 for (var i = 0; i < preloadEngines.length; i++) {
263 preloadEngineSet[preloadEngines[i]] = true;
264 }
265
266 // Create the new preload engine list per the language codes.
267 var newPreloadEngines = [];
268 for (var i = 0; i < languageCodes.length; i++) {
269 var languageCode = languageCodes[i];
270 var inputMethodIds = this.languageCodeToInputMethodIdsMap_[
271 languageCode];
272 // Check if we have active input methods associated with the language.
273 for (var j = 0; j < inputMethodIds.length; j++) {
274 var inputMethodId = inputMethodIds[j];
275 if (inputMethodId in preloadEngineSet) {
276 // If we have, add it to the new engine list.
277 newPreloadEngines.push(inputMethodId);
278 // And delete it from the set. This is necessary as one input
279 // method can be associated with more than one language thus
280 // we should avoid having duplicates in the new list.
281 delete preloadEngineSet[inputMethodId];
282 }
283 }
284 }
285
286 return newPreloadEngines;
287 },
288
289 /**
290 * Initializes the map of language code to input method IDs.
291 * @private
292 */
293 initializeLanguageCodeToInputMethodIdsMap_: function() {
294 var inputMethodList = templateData.inputMethodList;
295 for (var i = 0; i < inputMethodList.length; i++) {
296 var inputMethod = inputMethodList[i];
297 for (var languageCode in inputMethod.languageCodeSet) {
298 if (languageCode in this.languageCodeToInputMethodIdsMap_) {
299 this.languageCodeToInputMethodIdsMap_[languageCode].push(
300 inputMethod.id);
301 } else {
302 this.languageCodeToInputMethodIdsMap_[languageCode] =
303 [inputMethod.id];
304 }
305 }
306 }
307 },
308
309 /**
310 * Updates the currently selected language name.
311 * @param {string} languageCode Language code (ex. "fr").
312 * @private
313 */
314 updateSelectedLanguageName_: function(languageCode) {
315 var languageDisplayName = LanguageList.getDisplayNameFromLanguageCode(
316 languageCode);
317 var languageNativeDisplayName =
318 LanguageList.getNativeDisplayNameFromLanguageCode(languageCode);
319 // If the native name is different, add it.
320 if (languageDisplayName != languageNativeDisplayName) {
321 languageDisplayName += ' - ' + languageNativeDisplayName;
322 }
323 // Update the currently selected language name.
324 var languageName = $('language-options-language-name');
325 if (languageDisplayName) {
326 languageName.hidden = false;
327 languageName.textContent = languageDisplayName;
328 } else {
329 languageName.hidden = true;
330 }
331 },
332
333 /**
334 * Updates the UI language button.
335 * @param {string} languageCode Language code (ex. "fr").
336 * @private
337 */
338 updateUiLanguageButton_: function(languageCode) {
339 var uiLanguageButton = $('language-options-ui-language-button');
340 // Check if the language code matches the current UI language.
341 if (languageCode == templateData.currentUiLanguageCode) {
342 // If it matches, the button just says that the UI language is
343 // currently in use.
344 uiLanguageButton.textContent =
345 localStrings.getString('is_displayed_in_this_language');
346 // Make it look like a text label.
347 uiLanguageButton.className = 'text-button';
348 // Remove the event listner.
349 uiLanguageButton.onclick = undefined;
350 } else if (languageCode in templateData.uiLanguageCodeSet) {
351 // If the language is supported as UI language, users can click on
352 // the button to change the UI language.
353 if (cr.commandLine && cr.commandLine.options['--bwsi']) {
354 // In the guest mode for ChromeOS, changing UI language does not make
355 // sense because it does not take effect after browser restart.
356 uiLanguageButton.hidden = true;
357 } else {
358 uiLanguageButton.textContent =
359 localStrings.getString('display_in_this_language');
360 uiLanguageButton.className = '';
361 // Send the change request to Chrome.
362 uiLanguageButton.onclick = function(e) {
363 chrome.send('uiLanguageChange', [languageCode]);
364 }
365 }
366 if (cr.isChromeOS) {
367 $('language-options-ui-restart-button').onclick = function(e) {
368 chrome.send('uiLanguageRestart');
369 }
370 }
371 } else {
372 // If the language is not supported as UI language, the button
373 // just says that Chromium OS cannot be displayed in this language.
374 uiLanguageButton.textContent =
375 localStrings.getString('cannot_be_displayed_in_this_language');
376 uiLanguageButton.className = 'text-button';
377 uiLanguageButton.onclick = undefined;
378 }
379 uiLanguageButton.style.display = 'block';
380 $('language-options-ui-notification-bar').style.display = 'none';
381 },
382
383 /**
384 * Updates the spell check language button.
385 * @param {string} languageCode Language code (ex. "fr").
386 * @private
387 */
388 updateSpellCheckLanguageButton_: function(languageCode) {
389 var display = 'block';
390 var spellCheckLanguageButton = $(
391 'language-options-spell-check-language-button');
392 // Check if the language code matches the current spell check language.
393 if (languageCode == this.spellCheckDictionary_) {
394 // If it matches, the button just says that the spell check language is
395 // currently in use.
396 spellCheckLanguageButton.textContent =
397 localStrings.getString('is_used_for_spell_checking');
398 // Make it look like a text label.
399 spellCheckLanguageButton.className = 'text-button';
400 // Remove the event listner.
401 spellCheckLanguageButton.onclick = undefined;
402 } else if (languageCode in templateData.spellCheckLanguageCodeSet) {
403 // If the language is supported as spell check language, users can
404 // click on the button to change the spell check language.
405 spellCheckLanguageButton.textContent =
406 localStrings.getString('use_this_for_spell_checking');
407 spellCheckLanguageButton.className = '';
408 spellCheckLanguageButton.languageCode = languageCode;
409 // Add an event listner to the click event.
410 spellCheckLanguageButton.addEventListener('click',
411 this.handleSpellCheckLanguageButtonClick_.bind(this));
412 } else if (!languageCode) {
413 display = 'none';
414 } else {
415 // If the language is not supported as spell check language, the
416 // button just says that this language cannot be used for spell
417 // checking.
418 spellCheckLanguageButton.textContent =
419 localStrings.getString('cannot_be_used_for_spell_checking');
420 spellCheckLanguageButton.className = 'text-button';
421 spellCheckLanguageButton.onclick = undefined;
422 }
423 spellCheckLanguageButton.style.display = display;
424 $('language-options-ui-notification-bar').style.display = 'none';
425 },
426
427 /**
428 * Updates the input method list.
429 * @param {string} languageCode Language code (ex. "fr").
430 * @private
431 */
432 updateInputMethodList_: function(languageCode) {
433 // Give one of the checkboxes or buttons focus, if it's specified in the
434 // URL hash (ex. focus=mozc). Used for automated testing.
435 var focusInputMethodId = -1;
436 var match = document.location.hash.match(/\bfocus=([\w:-]+)\b/);
437 if (match) {
438 focusInputMethodId = match[1];
439 }
440 // Change the visibility of the input method list. Input methods that
441 // matches |languageCode| will become visible.
442 var inputMethodList = $('language-options-input-method-list');
443 var labels = inputMethodList.querySelectorAll('label');
444 for (var i = 0; i < labels.length; i++) {
445 var label = labels[i];
446 if (languageCode in label.languageCodeSet) {
447 label.style.display = 'block';
448 var input = label.childNodes[0];
449 // Give it focus if the ID matches.
450 if (input.inputMethodId == focusInputMethodId) {
451 input.focus();
452 }
453 } else {
454 label.style.display = 'none';
455 }
456 }
457
458 if (focusInputMethodId == 'add') {
459 $('language-options-add-button').focus();
460 }
461 },
462
463 /**
464 * Updates the language list in the add language overlay.
465 * @param {string} languageCode Language code (ex. "fr").
466 * @private
467 */
468 updateLanguageListInAddLanguageOverlay_: function(languageCode) {
469 // Change the visibility of the language list in the add language
470 // overlay. Languages that are already active will become invisible,
471 // so that users don't add the same language twice.
472 var languageOptionsList = $('language-options-list');
473 var languageCodes = languageOptionsList.getLanguageCodes();
474 var languageCodeSet = {};
475 for (var i = 0; i < languageCodes.length; i++) {
476 languageCodeSet[languageCodes[i]] = true;
477 }
478 var addLanguageList = $('add-language-overlay-language-list');
479 var lis = addLanguageList.querySelectorAll('li');
480 for (var i = 0; i < lis.length; i++) {
481 // The first child button knows the language code.
482 var button = lis[i].childNodes[0];
483 if (button.languageCode in languageCodeSet) {
484 lis[i].style.display = 'none';
485 } else {
486 lis[i].style.display = 'block';
487 }
488 }
489 },
490
491 /**
492 * Handles preloadEnginesPref change.
493 * @param {Event} e Change event.
494 * @private
495 */
496 handlePreloadEnginesPrefChange_: function(e) {
497 var value = e.value.value;
498 this.preloadEngines_ = this.filterBadPreloadEngines_(value.split(','));
499 this.updateCheckboxesFromPreloadEngines_();
500 $('language-options-list').updateDeletable();
501 },
502
503 /**
504 * Handles input method checkbox's click event.
505 * @param {Event} e Click event.
506 * @private
507 */
508 handleCheckboxClick_ : function(e) {
509 var checkbox = e.target;
510 if (this.preloadEngines_.length == 1 && !checkbox.checked) {
511 // Don't allow disabling the last input method.
512 this.showNotification_(
513 localStrings.getString('please_add_another_input_method'),
514 localStrings.getString('ok_button'));
515 checkbox.checked = true;
516 return;
517 }
518 if (checkbox.checked) {
519 chrome.send('inputMethodEnable', [checkbox.inputMethodId]);
520 } else {
521 chrome.send('inputMethodDisable', [checkbox.inputMethodId]);
522 }
523 this.updatePreloadEnginesFromCheckboxes_();
524 this.preloadEngines_ = this.sortPreloadEngines_(this.preloadEngines_);
525 this.savePreloadEnginesPref_();
526 },
527
528 /**
529 * Handles add language list's click event.
530 * @param {Event} e Click event.
531 */
532 handleAddLanguageListClick_ : function(e) {
533 var languageOptionsList = $('language-options-list');
534 var languageCode = e.target.languageCode;
535 // languageCode can be undefined, if click was made on some random
536 // place in the overlay, rather than a button. Ignore it.
537 if (!languageCode) {
538 return;
539 }
540 languageOptionsList.addLanguage(languageCode);
541 var inputMethodIds = this.languageCodeToInputMethodIdsMap_[languageCode];
542 // Enable the first input method for the language added.
543 if (inputMethodIds && inputMethodIds[0] &&
544 // Don't add the input method it's already present. This can
545 // happen if the same input method is shared among multiple
546 // languages (ex. English US keyboard is used for English US and
547 // Filipino).
548 this.preloadEngines_.indexOf(inputMethodIds[0]) == -1) {
549 this.preloadEngines_.push(inputMethodIds[0]);
550 this.updateCheckboxesFromPreloadEngines_();
551 this.savePreloadEnginesPref_();
552 }
553 OptionsPage.closeOverlay();
554 },
555
556 /**
557 * Handles add language dialog ok button.
558 */
559 handleAddLanguageOkButtonClick_ : function() {
560 var languagesSelect = $('add-language-overlay-language-list');
561 var selectedIndex = languagesSelect.selectedIndex;
562 if (selectedIndex >= 0) {
563 var selection = languagesSelect.options[selectedIndex];
564 $('language-options-list').addLanguage(String(selection.value));
565 OptionsPage.closeOverlay();
566 }
567 },
568
569 /**
570 * Checks if languageCode is deletable or not.
571 * @param {String} languageCode the languageCode to check for deletability.
572 */
573 languageIsDeletable: function(languageCode) {
574 // Don't allow removing the language if it's as UI language.
575 if (languageCode == templateData.currentUiLanguageCode)
576 return false;
577 return (!cr.isChromeOS ||
578 this.canDeleteLanguage_(languageCode));
579 },
580
581 /**
582 * Handles browse.enable_spellchecking change.
583 * @param {Event} e Change event.
584 * @private
585 */
586 updateEnableSpellCheck_: function() {
587 var value = !$('enable-spell-check').checked;
588
589 $('language-options-spell-check-language-button').disabled = value;
590 },
591
592 /**
593 * Handles spellCheckDictionaryPref change.
594 * @param {Event} e Change event.
595 * @private
596 */
597 handleSpellCheckDictionaryPrefChange_: function(e) {
598 var languageCode = e.value.value
599 this.spellCheckDictionary_ = languageCode;
600 var languageOptionsList = $('language-options-list');
601 var selectedLanguageCode = languageOptionsList.getSelectedLanguageCode();
602 this.updateSpellCheckLanguageButton_(selectedLanguageCode);
603 },
604
605 /**
606 * Handles spellCheckLanguageButton click.
607 * @param {Event} e Click event.
608 * @private
609 */
610 handleSpellCheckLanguageButtonClick_: function(e) {
611 var languageCode = e.target.languageCode;
612 // Save the preference.
613 Preferences.setStringPref(this.spellCheckDictionaryPref,
614 languageCode);
615 chrome.send('spellCheckLanguageChange', [languageCode]);
616 },
617
618 /**
619 * Checks whether it's possible to remove the language specified by
620 * languageCode and returns true if possible. This function returns false
621 * if the removal causes the number of preload engines to be zero.
622 *
623 * @param {string} languageCode Language code (ex. "fr").
624 * @return {boolean} Returns true on success.
625 * @private
626 */
627 canDeleteLanguage_: function(languageCode) {
628 // First create the set of engines to be removed from input methods
629 // associated with the language code.
630 var enginesToBeRemovedSet = {};
631 var inputMethodIds = this.languageCodeToInputMethodIdsMap_[languageCode];
632 for (var i = 0; i < inputMethodIds.length; i++) {
633 enginesToBeRemovedSet[inputMethodIds[i]] = true;
634 }
635
636 // Then eliminate engines that are also used for other active languages.
637 // For instance, if "xkb:us::eng" is used for both English and Filipino.
638 var languageCodes = $('language-options-list').getLanguageCodes();
639 for (var i = 0; i < languageCodes.length; i++) {
640 // Skip the target language code.
641 if (languageCodes[i] == languageCode) {
642 continue;
643 }
644 // Check if input methods used in this language are included in
645 // enginesToBeRemovedSet. If so, eliminate these from the set, so
646 // we don't remove this time.
647 var inputMethodIdsForAnotherLanguage =
648 this.languageCodeToInputMethodIdsMap_[languageCodes[i]];
649 for (var j = 0; j < inputMethodIdsForAnotherLanguage.length; j++) {
650 var inputMethodId = inputMethodIdsForAnotherLanguage[j];
651 if (inputMethodId in enginesToBeRemovedSet) {
652 delete enginesToBeRemovedSet[inputMethodId];
653 }
654 }
655 }
656
657 // Update the preload engine list with the to-be-removed set.
658 var newPreloadEngines = [];
659 for (var i = 0; i < this.preloadEngines_.length; i++) {
660 if (!(this.preloadEngines_[i] in enginesToBeRemovedSet)) {
661 newPreloadEngines.push(this.preloadEngines_[i]);
662 }
663 }
664 // Don't allow this operation if it causes the number of preload
665 // engines to be zero.
666 return (newPreloadEngines.length > 0);
667 },
668
669 /**
670 * Saves the preload engines preference.
671 * @private
672 */
673 savePreloadEnginesPref_: function() {
674 Preferences.setStringPref(this.preloadEnginesPref,
675 this.preloadEngines_.join(','));
676 },
677
678 /**
679 * Updates the checkboxes in the input method list from the preload
680 * engines preference.
681 * @private
682 */
683 updateCheckboxesFromPreloadEngines_: function() {
684 // Convert the list into a dictonary for simpler lookup.
685 var dictionary = {};
686 for (var i = 0; i < this.preloadEngines_.length; i++) {
687 dictionary[this.preloadEngines_[i]] = true;
688 }
689
690 var inputMethodList = $('language-options-input-method-list');
691 var checkboxes = inputMethodList.querySelectorAll('input');
692 for (var i = 0; i < checkboxes.length; i++) {
693 checkboxes[i].checked = (checkboxes[i].inputMethodId in dictionary);
694 }
695 },
696
697 /**
698 * Updates the preload engines preference from the checkboxes in the
699 * input method list.
700 * @private
701 */
702 updatePreloadEnginesFromCheckboxes_: function() {
703 this.preloadEngines_ = [];
704 var inputMethodList = $('language-options-input-method-list');
705 var checkboxes = inputMethodList.querySelectorAll('input');
706 for (var i = 0; i < checkboxes.length; i++) {
707 if (checkboxes[i].checked) {
708 this.preloadEngines_.push(checkboxes[i].inputMethodId);
709 }
710 }
711 var languageOptionsList = $('language-options-list');
712 languageOptionsList.updateDeletable();
713 },
714
715 /**
716 * Filters bad preload engines in case bad preload engines are
717 * stored in the preference. Removes duplicates as well.
718 * @param {Array} preloadEngines List of preload engines.
719 * @private
720 */
721 filterBadPreloadEngines_: function(preloadEngines) {
722 // Convert the list into a dictonary for simpler lookup.
723 var dictionary = {};
724 for (var i = 0; i < templateData.inputMethodList.length; i++) {
725 dictionary[templateData.inputMethodList[i].id] = true;
726 }
727
728 var filteredPreloadEngines = [];
729 var seen = {};
730 for (var i = 0; i < preloadEngines.length; i++) {
731 // Check if the preload engine is present in the
732 // dictionary, and not duplicate. Otherwise, skip it.
733 if (preloadEngines[i] in dictionary && !(preloadEngines[i] in seen)) {
734 filteredPreloadEngines.push(preloadEngines[i]);
735 seen[preloadEngines[i]] = true;
736 }
737 }
738 return filteredPreloadEngines;
739 },
740
741 // TODO(kochi): This is an adapted copy from new_tab.js.
742 // If this will go as final UI, refactor this to share the component with
743 // new new tab page.
744 /**
745 * Shows notification
746 * @private
747 */
748 notificationTimeout_: null,
749 showNotification_ : function(text, actionText, opt_delay) {
750 var notificationElement = $('notification');
751 var actionLink = notificationElement.querySelector('.link-color');
752 var delay = opt_delay || 10000;
753
754 function show() {
755 window.clearTimeout(this.notificationTimeout_);
756 notificationElement.classList.add('show');
757 document.body.classList.add('notification-shown');
758 }
759
760 function hide() {
761 window.clearTimeout(this.notificationTimeout_);
762 notificationElement.classList.remove('show');
763 document.body.classList.remove('notification-shown');
764 // Prevent tabbing to the hidden link.
765 actionLink.tabIndex = -1;
766 // Setting tabIndex to -1 only prevents future tabbing to it. If,
767 // however, the user switches window or a tab and then moves back to
768 // this tab the element may gain focus. We therefore make sure that we
769 // blur the element so that the element focus is not restored when
770 // coming back to this window.
771 actionLink.blur();
772 }
773
774 function delayedHide() {
775 this.notificationTimeout_ = window.setTimeout(hide, delay);
776 }
777
778 notificationElement.firstElementChild.textContent = text;
779 actionLink.textContent = actionText;
780
781 actionLink.onclick = hide;
782 actionLink.onkeydown = function(e) {
783 if (e.keyIdentifier == 'Enter') {
784 hide();
785 }
786 };
787 notificationElement.onmouseover = show;
788 notificationElement.onmouseout = delayedHide;
789 actionLink.onfocus = show;
790 actionLink.onblur = delayedHide;
791 // Enable tabbing to the link now that it is shown.
792 actionLink.tabIndex = 0;
793
794 show();
795 delayedHide();
796 }
797 };
798
799 /**
800 * Chrome callback for when the UI language preference is saved.
801 */
802 LanguageOptions.uiLanguageSaved = function() {
803 $('language-options-ui-language-button').style.display = 'none';
804 $('language-options-ui-notification-bar').style.display = 'block';
805 };
806
807 // Export
808 return {
809 LanguageOptions: LanguageOptions
810 };
811 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/options2/language_options.html ('k') | chrome/browser/resources/options2/manage_profile_overlay.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698