| Index: chrome/browser/resources/options2/language_options.js
|
| diff --git a/chrome/browser/resources/options2/language_options.js b/chrome/browser/resources/options2/language_options.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..47674edd0bd1c8135b78c2794e924eeb686cf008
|
| --- /dev/null
|
| +++ b/chrome/browser/resources/options2/language_options.js
|
| @@ -0,0 +1,815 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// TODO(kochi): Generalize the notification as a component and put it
|
| +// in js/cr/ui/notification.js .
|
| +
|
| +cr.define('options', function() {
|
| + const OptionsPage = options.OptionsPage;
|
| + const LanguageList = options.LanguageList;
|
| +
|
| + // Some input methods like Chinese Pinyin have config pages.
|
| + // This is the map of the input method names to their config page names.
|
| + const INPUT_METHOD_ID_TO_CONFIG_PAGE_NAME = {
|
| + 'mozc': 'languageMozc',
|
| + 'mozc-chewing': 'languageChewing',
|
| + 'mozc-dv': 'languageMozc',
|
| + 'mozc-hangul': 'languageHangul',
|
| + 'mozc-jp': 'languageMozc',
|
| + 'pinyin': 'languagePinyin',
|
| + 'pinyin-dv': 'languagePinyin',
|
| + };
|
| +
|
| + /////////////////////////////////////////////////////////////////////////////
|
| + // LanguageOptions class:
|
| +
|
| + /**
|
| + * Encapsulated handling of ChromeOS language options page.
|
| + * @constructor
|
| + */
|
| + function LanguageOptions(model) {
|
| + OptionsPage.call(this, 'languages', templateData.languagePageTabTitle,
|
| + 'languagePage');
|
| + }
|
| +
|
| + cr.addSingletonGetter(LanguageOptions);
|
| +
|
| + // Inherit LanguageOptions from OptionsPage.
|
| + LanguageOptions.prototype = {
|
| + __proto__: OptionsPage.prototype,
|
| +
|
| + /**
|
| + * Initializes LanguageOptions page.
|
| + * Calls base class implementation to starts preference initialization.
|
| + */
|
| + initializePage: function() {
|
| + OptionsPage.prototype.initializePage.call(this);
|
| +
|
| + var languageOptionsList = $('language-options-list');
|
| + LanguageList.decorate(languageOptionsList);
|
| +
|
| + languageOptionsList.addEventListener('change',
|
| + this.handleLanguageOptionsListChange_.bind(this));
|
| + languageOptionsList.addEventListener('save',
|
| + this.handleLanguageOptionsListSave_.bind(this));
|
| +
|
| + this.addEventListener('visibleChange',
|
| + this.handleVisibleChange_.bind(this));
|
| +
|
| + if (cr.isChromeOS) {
|
| + this.initializeInputMethodList_();
|
| + this.initializeLanguageCodeToInputMethodIdsMap_();
|
| + }
|
| + Preferences.getInstance().addEventListener(this.spellCheckDictionaryPref,
|
| + this.handleSpellCheckDictionaryPrefChange_.bind(this));
|
| +
|
| + // Set up add button.
|
| + $('language-options-add-button').onclick = function(e) {
|
| + // Add the language without showing the overlay if it's specified in
|
| + // the URL hash (ex. lang_add=ja). Used for automated testing.
|
| + var match = document.location.hash.match(/\blang_add=([\w-]+)/);
|
| + if (match) {
|
| + var addLanguageCode = match[1];
|
| + $('language-options-list').addLanguage(addLanguageCode);
|
| + } else {
|
| + OptionsPage.navigateToPage('addLanguage');
|
| + }
|
| + };
|
| +
|
| + if (cr.isChromeOS) {
|
| + // Listen to user clicks on the add language list.
|
| + var addLanguageList = $('add-language-overlay-language-list');
|
| + addLanguageList.addEventListener('click',
|
| + this.handleAddLanguageListClick_.bind(this));
|
| + } else {
|
| + // Listen to add language dialog ok button.
|
| + var addLanguageOkButton = $('add-language-overlay-ok-button');
|
| + addLanguageOkButton.addEventListener('click',
|
| + this.handleAddLanguageOkButtonClick_.bind(this));
|
| +
|
| + // Show experimental features if enabled.
|
| + if (templateData.experimentalSpellCheckFeatures == 'true')
|
| + $('auto-spell-correction-option').hidden = false;
|
| +
|
| + // Handle spell check enable/disable.
|
| + if (!cr.isMac) {
|
| + Preferences.getInstance().addEventListener(
|
| + this.enableSpellCheckPref,
|
| + this.updateEnableSpellCheck_.bind(this));
|
| + }
|
| + }
|
| +
|
| + // Listen to user clicks on the "Change touch keyboard settings..."
|
| + // button (if it exists).
|
| + var virtualKeyboardButton = $('language-options-virtual-keyboard');
|
| + if (virtualKeyboardButton) {
|
| + // TODO(yusukes): would be better to hide the button if no virtual
|
| + // keyboard is registered.
|
| + virtualKeyboardButton.onclick = function(e) {
|
| + OptionsPage.navigateToPage('virtualKeyboards');
|
| + };
|
| + }
|
| + },
|
| +
|
| + // The preference is a boolean that enables/disables spell checking.
|
| + enableSpellCheckPref: 'browser.enable_spellchecking',
|
| + // The preference is a CSV string that describes preload engines
|
| + // (i.e. active input methods).
|
| + preloadEnginesPref: 'settings.language.preload_engines',
|
| + // The list of preload engines, like ['mozc', 'pinyin'].
|
| + preloadEngines_: [],
|
| + // The preference is a string that describes the spell check
|
| + // dictionary language, like "en-US".
|
| + spellCheckDictionaryPref: 'spellcheck.dictionary',
|
| + spellCheckDictionary_: "",
|
| + // The map of language code to input method IDs, like:
|
| + // {'ja': ['mozc', 'mozc-jp'], 'zh-CN': ['pinyin'], ...}
|
| + languageCodeToInputMethodIdsMap_: {},
|
| +
|
| + /**
|
| + * Initializes the input method list.
|
| + */
|
| + initializeInputMethodList_: function() {
|
| + var inputMethodList = $('language-options-input-method-list');
|
| + var inputMethodListData = templateData.inputMethodList;
|
| +
|
| + // Add all input methods, but make all of them invisible here. We'll
|
| + // change the visibility in handleLanguageOptionsListChange_() based
|
| + // on the selected language. Note that we only have less than 100
|
| + // input methods, so creating DOM nodes at once here should be ok.
|
| + for (var i = 0; i < inputMethodListData.length; i++) {
|
| + var inputMethod = inputMethodListData[i];
|
| + var input = document.createElement('input');
|
| + input.type = 'checkbox';
|
| + input.inputMethodId = inputMethod.id;
|
| + // Listen to user clicks.
|
| + input.addEventListener('click',
|
| + this.handleCheckboxClick_.bind(this));
|
| + var label = document.createElement('label');
|
| + label.appendChild(input);
|
| + // Adding a space between the checkbox and the text. This is a bit
|
| + // dirty, but we rely on a space character for all other checkboxes.
|
| + label.appendChild(document.createTextNode(
|
| + ' ' + inputMethod.displayName));
|
| + label.style.display = 'none';
|
| + label.languageCodeSet = inputMethod.languageCodeSet;
|
| + // Add the configure button if the config page is present for this
|
| + // input method.
|
| + if (inputMethod.id in INPUT_METHOD_ID_TO_CONFIG_PAGE_NAME) {
|
| + var pageName = INPUT_METHOD_ID_TO_CONFIG_PAGE_NAME[inputMethod.id];
|
| + var button = this.createConfigureInputMethodButton_(inputMethod.id,
|
| + pageName);
|
| + label.appendChild(button);
|
| + }
|
| +
|
| + inputMethodList.appendChild(label);
|
| + }
|
| + // Listen to pref change once the input method list is initialized.
|
| + Preferences.getInstance().addEventListener(this.preloadEnginesPref,
|
| + this.handlePreloadEnginesPrefChange_.bind(this));
|
| + },
|
| +
|
| + /**
|
| + * Creates a configure button for the given input method ID.
|
| + * @param {string} inputMethodId Input method ID (ex. "pinyin").
|
| + * @param {string} pageName Name of the config page (ex. "languagePinyin").
|
| + * @private
|
| + */
|
| + createConfigureInputMethodButton_: function(inputMethodId, pageName) {
|
| + var button = document.createElement('button');
|
| + button.textContent = localStrings.getString('configure');
|
| + button.onclick = function(e) {
|
| + // Prevent the default action (i.e. changing the checked property
|
| + // of the checkbox). The button click here should not be handled
|
| + // as checkbox click.
|
| + e.preventDefault();
|
| + chrome.send('inputMethodOptionsOpen', [inputMethodId]);
|
| + OptionsPage.navigateToPage(pageName);
|
| + }
|
| + return button;
|
| + },
|
| +
|
| + /**
|
| + * Handles OptionsPage's visible property change event.
|
| + * @param {Event} e Property change event.
|
| + * @private
|
| + */
|
| + handleVisibleChange_: function(e) {
|
| + if (this.visible) {
|
| + $('language-options-list').redraw();
|
| + chrome.send('languageOptionsOpen');
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Handles languageOptionsList's change event.
|
| + * @param {Event} e Change event.
|
| + * @private
|
| + */
|
| + handleLanguageOptionsListChange_: function(e) {
|
| + var languageOptionsList = $('language-options-list');
|
| + var languageCode = languageOptionsList.getSelectedLanguageCode();
|
| + // Select the language if it's specified in the URL hash (ex. lang=ja).
|
| + // Used for automated testing.
|
| + var match = document.location.hash.match(/\blang=([\w-]+)/);
|
| + if (match) {
|
| + var specifiedLanguageCode = match[1];
|
| + if (languageOptionsList.selectLanguageByCode(specifiedLanguageCode)) {
|
| + languageCode = specifiedLanguageCode;
|
| + }
|
| + }
|
| + this.updateSelectedLanguageName_(languageCode);
|
| + if (cr.isWindows || cr.isChromeOS)
|
| + this.updateUiLanguageButton_(languageCode);
|
| + if (!cr.isMac)
|
| + this.updateSpellCheckLanguageButton_(languageCode);
|
| + if (cr.isChromeOS)
|
| + this.updateInputMethodList_(languageCode);
|
| + this.updateLanguageListInAddLanguageOverlay_();
|
| + },
|
| +
|
| + /**
|
| + * Handles languageOptionsList's save event.
|
| + * @param {Event} e Save event.
|
| + * @private
|
| + */
|
| + handleLanguageOptionsListSave_: function(e) {
|
| + if (cr.isChromeOS) {
|
| + // Sort the preload engines per the saved languages before save.
|
| + this.preloadEngines_ = this.sortPreloadEngines_(this.preloadEngines_);
|
| + this.savePreloadEnginesPref_();
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Sorts preloadEngines_ by languageOptionsList's order.
|
| + * @param {Array} preloadEngines List of preload engines.
|
| + * @return {Array} Returns sorted preloadEngines.
|
| + * @private
|
| + */
|
| + sortPreloadEngines_: function(preloadEngines) {
|
| + // For instance, suppose we have two languages and associated input
|
| + // methods:
|
| + //
|
| + // - Korean: hangul
|
| + // - Chinese: pinyin
|
| + //
|
| + // The preloadEngines preference should look like "hangul,pinyin".
|
| + // If the user reverse the order, the preference should be reorderd
|
| + // to "pinyin,hangul".
|
| + var languageOptionsList = $('language-options-list');
|
| + var languageCodes = languageOptionsList.getLanguageCodes();
|
| +
|
| + // Convert the list into a dictonary for simpler lookup.
|
| + var preloadEngineSet = {};
|
| + for (var i = 0; i < preloadEngines.length; i++) {
|
| + preloadEngineSet[preloadEngines[i]] = true;
|
| + }
|
| +
|
| + // Create the new preload engine list per the language codes.
|
| + var newPreloadEngines = [];
|
| + for (var i = 0; i < languageCodes.length; i++) {
|
| + var languageCode = languageCodes[i];
|
| + var inputMethodIds = this.languageCodeToInputMethodIdsMap_[
|
| + languageCode];
|
| + // Check if we have active input methods associated with the language.
|
| + for (var j = 0; j < inputMethodIds.length; j++) {
|
| + var inputMethodId = inputMethodIds[j];
|
| + if (inputMethodId in preloadEngineSet) {
|
| + // If we have, add it to the new engine list.
|
| + newPreloadEngines.push(inputMethodId);
|
| + // And delete it from the set. This is necessary as one input
|
| + // method can be associated with more than one language thus
|
| + // we should avoid having duplicates in the new list.
|
| + delete preloadEngineSet[inputMethodId];
|
| + }
|
| + }
|
| + }
|
| +
|
| + return newPreloadEngines;
|
| + },
|
| +
|
| + /**
|
| + * Initializes the map of language code to input method IDs.
|
| + * @private
|
| + */
|
| + initializeLanguageCodeToInputMethodIdsMap_: function() {
|
| + var inputMethodList = templateData.inputMethodList;
|
| + for (var i = 0; i < inputMethodList.length; i++) {
|
| + var inputMethod = inputMethodList[i];
|
| + for (var languageCode in inputMethod.languageCodeSet) {
|
| + if (languageCode in this.languageCodeToInputMethodIdsMap_) {
|
| + this.languageCodeToInputMethodIdsMap_[languageCode].push(
|
| + inputMethod.id);
|
| + } else {
|
| + this.languageCodeToInputMethodIdsMap_[languageCode] =
|
| + [inputMethod.id];
|
| + }
|
| + }
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Updates the currently selected language name.
|
| + * @param {string} languageCode Language code (ex. "fr").
|
| + * @private
|
| + */
|
| + updateSelectedLanguageName_: function(languageCode) {
|
| + var languageDisplayName = LanguageList.getDisplayNameFromLanguageCode(
|
| + languageCode);
|
| + var languageNativeDisplayName =
|
| + LanguageList.getNativeDisplayNameFromLanguageCode(languageCode);
|
| + // If the native name is different, add it.
|
| + if (languageDisplayName != languageNativeDisplayName) {
|
| + languageDisplayName += ' - ' + languageNativeDisplayName;
|
| + }
|
| + // Update the currently selected language name.
|
| + var languageName = $('language-options-language-name');
|
| + if (languageDisplayName) {
|
| + languageName.hidden = false;
|
| + languageName.textContent = languageDisplayName;
|
| + } else {
|
| + languageName.hidden = true;
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Updates the UI language button.
|
| + * @param {string} languageCode Language code (ex. "fr").
|
| + * @private
|
| + */
|
| + updateUiLanguageButton_: function(languageCode) {
|
| + var uiLanguageButton = $('language-options-ui-language-button');
|
| + // Check if the language code matches the current UI language.
|
| + if (languageCode == templateData.currentUiLanguageCode) {
|
| + // If it matches, the button just says that the UI language is
|
| + // currently in use.
|
| + uiLanguageButton.textContent =
|
| + localStrings.getString('is_displayed_in_this_language');
|
| + // Make it look like a text label.
|
| + uiLanguageButton.className = 'text-button';
|
| + // Remove the event listner.
|
| + uiLanguageButton.onclick = undefined;
|
| + } else if (languageCode in templateData.uiLanguageCodeSet) {
|
| + // If the language is supported as UI language, users can click on
|
| + // the button to change the UI language.
|
| + if (cr.commandLine && cr.commandLine.options['--bwsi']) {
|
| + // In the guest mode for ChromeOS, changing UI language does not make
|
| + // sense because it does not take effect after browser restart.
|
| + uiLanguageButton.hidden = true;
|
| + } else {
|
| + uiLanguageButton.textContent =
|
| + localStrings.getString('display_in_this_language');
|
| + uiLanguageButton.className = '';
|
| + // Send the change request to Chrome.
|
| + uiLanguageButton.onclick = function(e) {
|
| + chrome.send('uiLanguageChange', [languageCode]);
|
| + }
|
| + }
|
| + if (cr.isChromeOS) {
|
| + $('language-options-ui-restart-button').onclick = function(e) {
|
| + chrome.send('uiLanguageRestart');
|
| + }
|
| + }
|
| + } else {
|
| + // If the language is not supported as UI language, the button
|
| + // just says that Chromium OS cannot be displayed in this language.
|
| + uiLanguageButton.textContent =
|
| + localStrings.getString('cannot_be_displayed_in_this_language');
|
| + uiLanguageButton.className = 'text-button';
|
| + uiLanguageButton.onclick = undefined;
|
| + }
|
| + uiLanguageButton.style.display = 'block';
|
| + $('language-options-ui-notification-bar').style.display = 'none';
|
| + },
|
| +
|
| + /**
|
| + * Updates the spell check language button.
|
| + * @param {string} languageCode Language code (ex. "fr").
|
| + * @private
|
| + */
|
| + updateSpellCheckLanguageButton_: function(languageCode) {
|
| + var display = 'block';
|
| + var spellCheckLanguageButton = $(
|
| + 'language-options-spell-check-language-button');
|
| + // Check if the language code matches the current spell check language.
|
| + if (languageCode == this.spellCheckDictionary_) {
|
| + // If it matches, the button just says that the spell check language is
|
| + // currently in use.
|
| + spellCheckLanguageButton.textContent =
|
| + localStrings.getString('is_used_for_spell_checking');
|
| + // Make it look like a text label.
|
| + spellCheckLanguageButton.className = 'text-button';
|
| + // Remove the event listner.
|
| + spellCheckLanguageButton.onclick = undefined;
|
| + } else if (languageCode in templateData.spellCheckLanguageCodeSet) {
|
| + // If the language is supported as spell check language, users can
|
| + // click on the button to change the spell check language.
|
| + spellCheckLanguageButton.textContent =
|
| + localStrings.getString('use_this_for_spell_checking');
|
| + spellCheckLanguageButton.className = '';
|
| + spellCheckLanguageButton.languageCode = languageCode;
|
| + // Add an event listner to the click event.
|
| + spellCheckLanguageButton.addEventListener('click',
|
| + this.handleSpellCheckLanguageButtonClick_.bind(this));
|
| + } else if (!languageCode) {
|
| + display = 'none';
|
| + } else {
|
| + // If the language is not supported as spell check language, the
|
| + // button just says that this language cannot be used for spell
|
| + // checking.
|
| + spellCheckLanguageButton.textContent =
|
| + localStrings.getString('cannot_be_used_for_spell_checking');
|
| + spellCheckLanguageButton.className = 'text-button';
|
| + spellCheckLanguageButton.onclick = undefined;
|
| + }
|
| + spellCheckLanguageButton.style.display = display;
|
| + $('language-options-ui-notification-bar').style.display = 'none';
|
| + },
|
| +
|
| + /**
|
| + * Updates the input method list.
|
| + * @param {string} languageCode Language code (ex. "fr").
|
| + * @private
|
| + */
|
| + updateInputMethodList_: function(languageCode) {
|
| + // Give one of the checkboxes or buttons focus, if it's specified in the
|
| + // URL hash (ex. focus=mozc). Used for automated testing.
|
| + var focusInputMethodId = -1;
|
| + var match = document.location.hash.match(/\bfocus=([\w:-]+)\b/);
|
| + if (match) {
|
| + focusInputMethodId = match[1];
|
| + }
|
| + // Change the visibility of the input method list. Input methods that
|
| + // matches |languageCode| will become visible.
|
| + var inputMethodList = $('language-options-input-method-list');
|
| + var labels = inputMethodList.querySelectorAll('label');
|
| + for (var i = 0; i < labels.length; i++) {
|
| + var label = labels[i];
|
| + if (languageCode in label.languageCodeSet) {
|
| + label.style.display = 'block';
|
| + var input = label.childNodes[0];
|
| + // Give it focus if the ID matches.
|
| + if (input.inputMethodId == focusInputMethodId) {
|
| + input.focus();
|
| + }
|
| + } else {
|
| + label.style.display = 'none';
|
| + }
|
| + }
|
| +
|
| + if (focusInputMethodId == 'add') {
|
| + $('language-options-add-button').focus();
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Updates the language list in the add language overlay.
|
| + * @param {string} languageCode Language code (ex. "fr").
|
| + * @private
|
| + */
|
| + updateLanguageListInAddLanguageOverlay_: function(languageCode) {
|
| + // Change the visibility of the language list in the add language
|
| + // overlay. Languages that are already active will become invisible,
|
| + // so that users don't add the same language twice.
|
| + var languageOptionsList = $('language-options-list');
|
| + var languageCodes = languageOptionsList.getLanguageCodes();
|
| + var languageCodeSet = {};
|
| + for (var i = 0; i < languageCodes.length; i++) {
|
| + languageCodeSet[languageCodes[i]] = true;
|
| + }
|
| + var addLanguageList = $('add-language-overlay-language-list');
|
| + var lis = addLanguageList.querySelectorAll('li');
|
| + for (var i = 0; i < lis.length; i++) {
|
| + // The first child button knows the language code.
|
| + var button = lis[i].childNodes[0];
|
| + if (button.languageCode in languageCodeSet) {
|
| + lis[i].style.display = 'none';
|
| + } else {
|
| + lis[i].style.display = 'block';
|
| + }
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Handles preloadEnginesPref change.
|
| + * @param {Event} e Change event.
|
| + * @private
|
| + */
|
| + handlePreloadEnginesPrefChange_: function(e) {
|
| + var value = e.value.value;
|
| + this.preloadEngines_ = this.filterBadPreloadEngines_(value.split(','));
|
| + this.updateCheckboxesFromPreloadEngines_();
|
| + $('language-options-list').updateDeletable();
|
| + },
|
| +
|
| + /**
|
| + * Handles input method checkbox's click event.
|
| + * @param {Event} e Click event.
|
| + * @private
|
| + */
|
| + handleCheckboxClick_ : function(e) {
|
| + var checkbox = e.target;
|
| + if (this.preloadEngines_.length == 1 && !checkbox.checked) {
|
| + // Don't allow disabling the last input method.
|
| + this.showNotification_(
|
| + localStrings.getString('please_add_another_input_method'),
|
| + localStrings.getString('ok_button'));
|
| + checkbox.checked = true;
|
| + return;
|
| + }
|
| + if (checkbox.checked) {
|
| + chrome.send('inputMethodEnable', [checkbox.inputMethodId]);
|
| + } else {
|
| + chrome.send('inputMethodDisable', [checkbox.inputMethodId]);
|
| + }
|
| + this.updatePreloadEnginesFromCheckboxes_();
|
| + this.preloadEngines_ = this.sortPreloadEngines_(this.preloadEngines_);
|
| + this.savePreloadEnginesPref_();
|
| + },
|
| +
|
| + /**
|
| + * Handles add language list's click event.
|
| + * @param {Event} e Click event.
|
| + */
|
| + handleAddLanguageListClick_ : function(e) {
|
| + var languageOptionsList = $('language-options-list');
|
| + var languageCode = e.target.languageCode;
|
| + // languageCode can be undefined, if click was made on some random
|
| + // place in the overlay, rather than a button. Ignore it.
|
| + if (!languageCode) {
|
| + return;
|
| + }
|
| + languageOptionsList.addLanguage(languageCode);
|
| + var inputMethodIds = this.languageCodeToInputMethodIdsMap_[languageCode];
|
| + // Enable the first input method for the language added.
|
| + if (inputMethodIds && inputMethodIds[0] &&
|
| + // Don't add the input method it's already present. This can
|
| + // happen if the same input method is shared among multiple
|
| + // languages (ex. English US keyboard is used for English US and
|
| + // Filipino).
|
| + this.preloadEngines_.indexOf(inputMethodIds[0]) == -1) {
|
| + this.preloadEngines_.push(inputMethodIds[0]);
|
| + this.updateCheckboxesFromPreloadEngines_();
|
| + this.savePreloadEnginesPref_();
|
| + }
|
| + OptionsPage.closeOverlay();
|
| + },
|
| +
|
| + /**
|
| + * Handles add language dialog ok button.
|
| + */
|
| + handleAddLanguageOkButtonClick_ : function() {
|
| + var languagesSelect = $('add-language-overlay-language-list');
|
| + var selectedIndex = languagesSelect.selectedIndex;
|
| + if (selectedIndex >= 0) {
|
| + var selection = languagesSelect.options[selectedIndex];
|
| + $('language-options-list').addLanguage(String(selection.value));
|
| + OptionsPage.closeOverlay();
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Checks if languageCode is deletable or not.
|
| + * @param {String} languageCode the languageCode to check for deletability.
|
| + */
|
| + languageIsDeletable: function(languageCode) {
|
| + // Don't allow removing the language if it's as UI language.
|
| + if (languageCode == templateData.currentUiLanguageCode)
|
| + return false;
|
| + return (!cr.isChromeOS ||
|
| + this.canDeleteLanguage_(languageCode));
|
| + },
|
| +
|
| + /**
|
| + * Handles browse.enable_spellchecking change.
|
| + * @param {Event} e Change event.
|
| + * @private
|
| + */
|
| + updateEnableSpellCheck_: function() {
|
| + var value = !$('enable-spell-check').checked;
|
| +
|
| + $('language-options-spell-check-language-button').disabled = value;
|
| + },
|
| +
|
| + /**
|
| + * Handles spellCheckDictionaryPref change.
|
| + * @param {Event} e Change event.
|
| + * @private
|
| + */
|
| + handleSpellCheckDictionaryPrefChange_: function(e) {
|
| + var languageCode = e.value.value
|
| + this.spellCheckDictionary_ = languageCode;
|
| + var languageOptionsList = $('language-options-list');
|
| + var selectedLanguageCode = languageOptionsList.getSelectedLanguageCode();
|
| + this.updateSpellCheckLanguageButton_(selectedLanguageCode);
|
| + },
|
| +
|
| + /**
|
| + * Handles spellCheckLanguageButton click.
|
| + * @param {Event} e Click event.
|
| + * @private
|
| + */
|
| + handleSpellCheckLanguageButtonClick_: function(e) {
|
| + var languageCode = e.target.languageCode;
|
| + // Save the preference.
|
| + Preferences.setStringPref(this.spellCheckDictionaryPref,
|
| + languageCode);
|
| + chrome.send('spellCheckLanguageChange', [languageCode]);
|
| + },
|
| +
|
| + /**
|
| + * Checks whether it's possible to remove the language specified by
|
| + * languageCode and returns true if possible. This function returns false
|
| + * if the removal causes the number of preload engines to be zero.
|
| + *
|
| + * @param {string} languageCode Language code (ex. "fr").
|
| + * @return {boolean} Returns true on success.
|
| + * @private
|
| + */
|
| + canDeleteLanguage_: function(languageCode) {
|
| + // First create the set of engines to be removed from input methods
|
| + // associated with the language code.
|
| + var enginesToBeRemovedSet = {};
|
| + var inputMethodIds = this.languageCodeToInputMethodIdsMap_[languageCode];
|
| + for (var i = 0; i < inputMethodIds.length; i++) {
|
| + enginesToBeRemovedSet[inputMethodIds[i]] = true;
|
| + }
|
| +
|
| + // Then eliminate engines that are also used for other active languages.
|
| + // For instance, if "xkb:us::eng" is used for both English and Filipino.
|
| + var languageCodes = $('language-options-list').getLanguageCodes();
|
| + for (var i = 0; i < languageCodes.length; i++) {
|
| + // Skip the target language code.
|
| + if (languageCodes[i] == languageCode) {
|
| + continue;
|
| + }
|
| + // Check if input methods used in this language are included in
|
| + // enginesToBeRemovedSet. If so, eliminate these from the set, so
|
| + // we don't remove this time.
|
| + var inputMethodIdsForAnotherLanguage =
|
| + this.languageCodeToInputMethodIdsMap_[languageCodes[i]];
|
| + for (var j = 0; j < inputMethodIdsForAnotherLanguage.length; j++) {
|
| + var inputMethodId = inputMethodIdsForAnotherLanguage[j];
|
| + if (inputMethodId in enginesToBeRemovedSet) {
|
| + delete enginesToBeRemovedSet[inputMethodId];
|
| + }
|
| + }
|
| + }
|
| +
|
| + // Update the preload engine list with the to-be-removed set.
|
| + var newPreloadEngines = [];
|
| + for (var i = 0; i < this.preloadEngines_.length; i++) {
|
| + if (!(this.preloadEngines_[i] in enginesToBeRemovedSet)) {
|
| + newPreloadEngines.push(this.preloadEngines_[i]);
|
| + }
|
| + }
|
| + // Don't allow this operation if it causes the number of preload
|
| + // engines to be zero.
|
| + return (newPreloadEngines.length > 0);
|
| + },
|
| +
|
| + /**
|
| + * Saves the preload engines preference.
|
| + * @private
|
| + */
|
| + savePreloadEnginesPref_: function() {
|
| + Preferences.setStringPref(this.preloadEnginesPref,
|
| + this.preloadEngines_.join(','));
|
| + },
|
| +
|
| + /**
|
| + * Updates the checkboxes in the input method list from the preload
|
| + * engines preference.
|
| + * @private
|
| + */
|
| + updateCheckboxesFromPreloadEngines_: function() {
|
| + // Convert the list into a dictonary for simpler lookup.
|
| + var dictionary = {};
|
| + for (var i = 0; i < this.preloadEngines_.length; i++) {
|
| + dictionary[this.preloadEngines_[i]] = true;
|
| + }
|
| +
|
| + var inputMethodList = $('language-options-input-method-list');
|
| + var checkboxes = inputMethodList.querySelectorAll('input');
|
| + for (var i = 0; i < checkboxes.length; i++) {
|
| + checkboxes[i].checked = (checkboxes[i].inputMethodId in dictionary);
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Updates the preload engines preference from the checkboxes in the
|
| + * input method list.
|
| + * @private
|
| + */
|
| + updatePreloadEnginesFromCheckboxes_: function() {
|
| + this.preloadEngines_ = [];
|
| + var inputMethodList = $('language-options-input-method-list');
|
| + var checkboxes = inputMethodList.querySelectorAll('input');
|
| + for (var i = 0; i < checkboxes.length; i++) {
|
| + if (checkboxes[i].checked) {
|
| + this.preloadEngines_.push(checkboxes[i].inputMethodId);
|
| + }
|
| + }
|
| + var languageOptionsList = $('language-options-list');
|
| + languageOptionsList.updateDeletable();
|
| + },
|
| +
|
| + /**
|
| + * Filters bad preload engines in case bad preload engines are
|
| + * stored in the preference. Removes duplicates as well.
|
| + * @param {Array} preloadEngines List of preload engines.
|
| + * @private
|
| + */
|
| + filterBadPreloadEngines_: function(preloadEngines) {
|
| + // Convert the list into a dictonary for simpler lookup.
|
| + var dictionary = {};
|
| + for (var i = 0; i < templateData.inputMethodList.length; i++) {
|
| + dictionary[templateData.inputMethodList[i].id] = true;
|
| + }
|
| +
|
| + var filteredPreloadEngines = [];
|
| + var seen = {};
|
| + for (var i = 0; i < preloadEngines.length; i++) {
|
| + // Check if the preload engine is present in the
|
| + // dictionary, and not duplicate. Otherwise, skip it.
|
| + if (preloadEngines[i] in dictionary && !(preloadEngines[i] in seen)) {
|
| + filteredPreloadEngines.push(preloadEngines[i]);
|
| + seen[preloadEngines[i]] = true;
|
| + }
|
| + }
|
| + return filteredPreloadEngines;
|
| + },
|
| +
|
| + // TODO(kochi): This is an adapted copy from new_tab.js.
|
| + // If this will go as final UI, refactor this to share the component with
|
| + // new new tab page.
|
| + /**
|
| + * Shows notification
|
| + * @private
|
| + */
|
| + notificationTimeout_: null,
|
| + showNotification_ : function(text, actionText, opt_delay) {
|
| + var notificationElement = $('notification');
|
| + var actionLink = notificationElement.querySelector('.link-color');
|
| + var delay = opt_delay || 10000;
|
| +
|
| + function show() {
|
| + window.clearTimeout(this.notificationTimeout_);
|
| + notificationElement.classList.add('show');
|
| + document.body.classList.add('notification-shown');
|
| + }
|
| +
|
| + function hide() {
|
| + window.clearTimeout(this.notificationTimeout_);
|
| + notificationElement.classList.remove('show');
|
| + document.body.classList.remove('notification-shown');
|
| + // Prevent tabbing to the hidden link.
|
| + actionLink.tabIndex = -1;
|
| + // Setting tabIndex to -1 only prevents future tabbing to it. If,
|
| + // however, the user switches window or a tab and then moves back to
|
| + // this tab the element may gain focus. We therefore make sure that we
|
| + // blur the element so that the element focus is not restored when
|
| + // coming back to this window.
|
| + actionLink.blur();
|
| + }
|
| +
|
| + function delayedHide() {
|
| + this.notificationTimeout_ = window.setTimeout(hide, delay);
|
| + }
|
| +
|
| + notificationElement.firstElementChild.textContent = text;
|
| + actionLink.textContent = actionText;
|
| +
|
| + actionLink.onclick = hide;
|
| + actionLink.onkeydown = function(e) {
|
| + if (e.keyIdentifier == 'Enter') {
|
| + hide();
|
| + }
|
| + };
|
| + notificationElement.onmouseover = show;
|
| + notificationElement.onmouseout = delayedHide;
|
| + actionLink.onfocus = show;
|
| + actionLink.onblur = delayedHide;
|
| + // Enable tabbing to the link now that it is shown.
|
| + actionLink.tabIndex = 0;
|
| +
|
| + show();
|
| + delayedHide();
|
| + }
|
| + };
|
| +
|
| + /**
|
| + * Chrome callback for when the UI language preference is saved.
|
| + */
|
| + LanguageOptions.uiLanguageSaved = function() {
|
| + $('language-options-ui-language-button').style.display = 'none';
|
| + $('language-options-ui-notification-bar').style.display = 'block';
|
| + };
|
| +
|
| + // Export
|
| + return {
|
| + LanguageOptions: LanguageOptions
|
| + };
|
| +});
|
|
|