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

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

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

Powered by Google App Engine
This is Rietveld 408576698