172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// TODO(kochi): Generalize the notification as a component and put it
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// in js/cr/ui/notification.js .
7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsencr.define('options', function() {
9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  const OptionsPage = options.OptionsPage;
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const LanguageList = options.LanguageList;
11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Some input methods like Chinese Pinyin have config pages.
13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // This is the map of the input method names to their config page names.
14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  const INPUT_METHOD_ID_TO_CONFIG_PAGE_NAME = {
15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    'hangul': 'languageHangul',
16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    'mozc': 'languageMozc',
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    'mozc-chewing': 'languageChewing',
18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    'mozc-dv': 'languageMozc',
19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    'mozc-jp': 'languageMozc',
20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    'pinyin': 'languagePinyin',
21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  };
22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  /////////////////////////////////////////////////////////////////////////////
24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // LanguageOptions class:
25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  /**
27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen   * Encapsulated handling of ChromeOS language options page.
28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen   * @constructor
29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen   */
30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  function LanguageOptions(model) {
31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    OptionsPage.call(this, 'languages', templateData.languagePageTabTitle,
32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                     'languagePage');
33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cr.addSingletonGetter(LanguageOptions);
36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Inherit LanguageOptions from OptionsPage.
38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  LanguageOptions.prototype = {
39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    __proto__: OptionsPage.prototype,
40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Initializes LanguageOptions page.
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Calls base class implementation to starts preference initialization.
44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    initializePage: function() {
46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      OptionsPage.prototype.initializePage.call(this);
47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageOptionsList = $('language-options-list');
49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      LanguageList.decorate(languageOptionsList);
50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      languageOptionsList.addEventListener('change',
52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          this.handleLanguageOptionsListChange_.bind(this));
53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      languageOptionsList.addEventListener('save',
54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          this.handleLanguageOptionsListSave_.bind(this));
55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      this.addEventListener('visibleChange',
57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                            this.handleVisibleChange_.bind(this));
58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (cr.isChromeOS) {
6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        this.initializeInputMethodList_();
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.initializeLanguageCodeToInputMethodIdsMap_();
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Preferences.getInstance().addEventListener(this.spellCheckDictionaryPref,
6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          this.handleSpellCheckDictionaryPrefChange_.bind(this));
65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Set up add button.
67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      $('language-options-add-button').onclick = function(e) {
684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        // Add the language without showing the overlay if it's specified in
694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        // the URL hash (ex. lang_add=ja).  Used for automated testing.
704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        var match = document.location.hash.match(/\blang_add=([\w-]+)/);
714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        if (match) {
724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          var addLanguageCode = match[1];
734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          $('language-options-list').addLanguage(addLanguageCode);
744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        } else {
75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          OptionsPage.navigateToPage('addLanguage');
764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        }
77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      };
78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (cr.isChromeOS) {
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // Listen to user clicks on the add language list.
8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        var addLanguageList = $('add-language-overlay-language-list');
8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        addLanguageList.addEventListener('click',
8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            this.handleAddLanguageListClick_.bind(this));
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      } else {
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // Listen to add language dialog ok button.
8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        var addLanguageOkButton = $('add-language-overlay-ok-button');
8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        addLanguageOkButton.addEventListener('click',
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            this.handleAddLanguageOkButtonClick_.bind(this));
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // Show experimental features if enabled.
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        if (templateData.experimentalSpellCheckFeatures == 'true') {
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          $('auto-spell-correction-option').classList.remove('hidden');
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        }
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // The preference is a CSV string that describes preload engines
98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // (i.e. active input methods).
99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    preloadEnginesPref: 'settings.language.preload_engines',
100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // The list of preload engines, like ['mozc', 'pinyin'].
101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    preloadEngines_: [],
102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // The preference is a string that describes the spell check
103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // dictionary language, like "en-US".
104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spellCheckDictionaryPref: 'spellcheck.dictionary',
105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spellCheckDictionary_: "",
106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // The map of language code to input method IDs, like:
107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // {'ja': ['mozc', 'mozc-jp'], 'zh-CN': ['pinyin'], ...}
108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    languageCodeToInputMethodIdsMap_: {},
109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Initializes the input method list.
112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    initializeInputMethodList_: function() {
114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var inputMethodList = $('language-options-input-method-list');
115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var inputMethodListData = templateData.inputMethodList;
116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Add all input methods, but make all of them invisible here. We'll
118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // change the visibility in handleLanguageOptionsListChange_() based
119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // on the selected language. Note that we only have less than 100
120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // input methods, so creating DOM nodes at once here should be ok.
121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < inputMethodListData.length; i++) {
122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        var inputMethod = inputMethodListData[i];
123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        var input = document.createElement('input');
124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        input.type = 'checkbox';
125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        input.inputMethodId = inputMethod.id;
126bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Listen to user clicks.
127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        input.addEventListener('click',
128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                               this.handleCheckboxClick_.bind(this));
129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        var label = document.createElement('label');
130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        label.appendChild(input);
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // Adding a space between the checkbox and the text. This is a bit
13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // dirty, but we rely on a space character for all other checkboxes.
13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        label.appendChild(document.createTextNode(
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            ' ' + inputMethod.displayName));
135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        label.style.display = 'none';
136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        label.languageCodeSet = inputMethod.languageCodeSet;
137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Add the configure button if the config page is present for this
138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // input method.
139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (inputMethod.id in INPUT_METHOD_ID_TO_CONFIG_PAGE_NAME) {
140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          var pageName = INPUT_METHOD_ID_TO_CONFIG_PAGE_NAME[inputMethod.id];
141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          var button = this.createConfigureInputMethodButton_(inputMethod.id,
142bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                                              pageName);
143bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          label.appendChild(button);
144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        inputMethodList.appendChild(label);
147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
148bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Listen to pref change once the input method list is initialized.
149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      Preferences.getInstance().addEventListener(this.preloadEnginesPref,
150bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          this.handlePreloadEnginesPrefChange_.bind(this));
151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
153bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
154bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Creates a configure button for the given input method ID.
155bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {string} inputMethodId Input method ID (ex. "pinyin").
156bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {string} pageName Name of the config page (ex. "languagePinyin").
157bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
158bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    createConfigureInputMethodButton_: function(inputMethodId, pageName) {
160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var button = document.createElement('button');
161bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      button.textContent = localStrings.getString('configure');
162bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      button.onclick = function(e) {
163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Prevent the default action (i.e. changing the checked property
164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // of the checkbox). The button click here should not be handled
165bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // as checkbox click.
166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        e.preventDefault();
167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        chrome.send('inputMethodOptionsOpen', [inputMethodId]);
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        OptionsPage.navigateToPage(pageName);
169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return button;
171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
172bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
173bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Handles OptionsPage's visible property change event.
175bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {Event} e Property change event.
176bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    handleVisibleChange_: function(e) {
179bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      if (this.visible) {
180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        $('language-options-list').redraw();
181bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        chrome.send('languageOptionsOpen');
182bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Handles languageOptionsList's change event.
187bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {Event} e Change event.
188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
189bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    handleLanguageOptionsListChange_: function(e) {
191bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageOptionsList = $('language-options-list');
192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      var languageCode = languageOptionsList.getSelectedLanguageCode();
193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // Select the language if it's specified in the URL hash (ex. lang=ja).
194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // Used for automated testing.
195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      var match = document.location.hash.match(/\blang=([\w-]+)/);
196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (match) {
197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        var specifiedLanguageCode = match[1];
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        if (languageOptionsList.selectLanguageByCode(specifiedLanguageCode)) {
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          languageCode = specifiedLanguageCode;
200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        }
201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
202bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      this.updateSelectedLanguageName_(languageCode);
20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (cr.isWindows || cr.isChromeOS)
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        this.updateUiLanguageButton_(languageCode);
205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      this.updateSpellCheckLanguageButton_(languageCode);
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (cr.isChromeOS)
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        this.updateInputMethodList_(languageCode);
208bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      this.updateLanguageListInAddLanguageOverlay_();
209bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
210bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
211bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
212bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Handles languageOptionsList's save event.
213bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {Event} e Save event.
214bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
215bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
216bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    handleLanguageOptionsListSave_: function(e) {
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (cr.isChromeOS) {
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // Sort the preload engines per the saved languages before save.
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        this.preloadEngines_ = this.sortPreloadEngines_(this.preloadEngines_);
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        this.savePreloadEnginesPref_();
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
222bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
223bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
224bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
225bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Sorts preloadEngines_ by languageOptionsList's order.
226bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {Array} preloadEngines List of preload engines.
227bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @return {Array} Returns sorted preloadEngines.
228bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
229bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
230bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    sortPreloadEngines_: function(preloadEngines) {
231bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // For instance, suppose we have two languages and associated input
232bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // methods:
233bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      //
234bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // - Korean: hangul
235bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // - Chinese: pinyin
236bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      //
237bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // The preloadEngines preference should look like "hangul,pinyin".
238bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // If the user reverse the order, the preference should be reorderd
239bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // to "pinyin,hangul".
240bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageOptionsList = $('language-options-list');
241bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageCodes = languageOptionsList.getLanguageCodes();
242bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
243bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Convert the list into a dictonary for simpler lookup.
244bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var preloadEngineSet = {};
245bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < preloadEngines.length; i++) {
246bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        preloadEngineSet[preloadEngines[i]] = true;
247bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
248bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
249bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Create the new preload engine list per the language codes.
250bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var newPreloadEngines = [];
251bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < languageCodes.length; i++) {
252bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        var languageCode = languageCodes[i];
253bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        var inputMethodIds = this.languageCodeToInputMethodIdsMap_[
254bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            languageCode];
255bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Check if we have active input methods associated with the language.
256bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        for (var j = 0; j < inputMethodIds.length; j++) {
257bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          var inputMethodId = inputMethodIds[j];
258bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          if (inputMethodId in preloadEngineSet) {
259bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            // If we have, add it to the new engine list.
260bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            newPreloadEngines.push(inputMethodId);
261bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            // And delete it from the set. This is necessary as one input
262bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            // method can be associated with more than one language thus
263bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            // we should avoid having duplicates in the new list.
264bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            delete preloadEngineSet[inputMethodId];
265bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          }
266bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
267bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
268bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
269bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return newPreloadEngines;
270bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
271bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
272bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
273bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Initializes the map of language code to input method IDs.
274bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
275bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    initializeLanguageCodeToInputMethodIdsMap_: function() {
277bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var inputMethodList = templateData.inputMethodList;
278bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < inputMethodList.length; i++) {
279bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        var inputMethod = inputMethodList[i];
280bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        for (var languageCode in inputMethod.languageCodeSet) {
281bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          if (languageCode in this.languageCodeToInputMethodIdsMap_) {
282bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            this.languageCodeToInputMethodIdsMap_[languageCode].push(
283bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                inputMethod.id);
284bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          } else {
285bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            this.languageCodeToInputMethodIdsMap_[languageCode] =
286bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                [inputMethod.id];
287bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          }
288bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
289bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
290bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
291bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
292bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
293bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Updates the currently selected language name.
294bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {string} languageCode Language code (ex. "fr").
295bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
296bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
297bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    updateSelectedLanguageName_: function(languageCode) {
298bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageDisplayName = LanguageList.getDisplayNameFromLanguageCode(
299bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          languageCode);
300bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageNativeDisplayName =
301bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          LanguageList.getNativeDisplayNameFromLanguageCode(languageCode);
302bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // If the native name is different, add it.
303bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      if (languageDisplayName != languageNativeDisplayName) {
304bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        languageDisplayName += ' - ' + languageNativeDisplayName;
305bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
306bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Update the currently selected language name.
307bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      $('language-options-language-name').textContent = languageDisplayName;
308bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
309bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
310bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
311bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Updates the UI language button.
312bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {string} languageCode Language code (ex. "fr").
313bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
314bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
315bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    updateUiLanguageButton_: function(languageCode) {
316bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var uiLanguageButton = $('language-options-ui-language-button');
317bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Check if the language code matches the current UI language.
318bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      if (languageCode == templateData.currentUiLanguageCode) {
319bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // If it matches, the button just says that the UI language is
320bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // currently in use.
321bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        uiLanguageButton.textContent =
322bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            localStrings.getString('is_displayed_in_this_language');
323bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Make it look like a text label.
324bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        uiLanguageButton.className = 'text-button';
325bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Remove the event listner.
326bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        uiLanguageButton.onclick = undefined;
327bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      } else if (languageCode in templateData.uiLanguageCodeSet) {
328bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // If the language is supported as UI language, users can click on
329bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // the button to change the UI language.
330bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        uiLanguageButton.textContent =
331bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            localStrings.getString('display_in_this_language');
332bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        uiLanguageButton.className = '';
333bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Send the change request to Chrome.
334bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        uiLanguageButton.onclick = function(e) {
335bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          chrome.send('uiLanguageChange', [languageCode]);
336bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (cr.isChromeOS) {
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          $('language-options-ui-restart-button').onclick = function(e) {
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            chrome.send('uiLanguageRestart');
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          }
341bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
342bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      } else {
343bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // If the language is not supported as UI language, the button
344bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // just says that Chromium OS cannot be displayed in this language.
345bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        uiLanguageButton.textContent =
346bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            localStrings.getString('cannot_be_displayed_in_this_language');
347bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        uiLanguageButton.className = 'text-button';
348bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        uiLanguageButton.onclick = undefined;
349bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
350bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      uiLanguageButton.style.display = 'block';
351bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      $('language-options-ui-notification-bar').style.display = 'none';
352bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
353bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
354bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
355731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     * Updates the spell check language button.
356731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     * @param {string} languageCode Language code (ex. "fr").
357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     * @private
358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     */
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    updateSpellCheckLanguageButton_: function(languageCode) {
360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      var spellCheckLanguageButton = $(
361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          'language-options-spell-check-language-button');
362731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // Check if the language code matches the current spell check language.
363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (languageCode == this.spellCheckDictionary_) {
364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // If it matches, the button just says that the spell check language is
365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // currently in use.
366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.textContent =
367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            localStrings.getString('is_used_for_spell_checking');
368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // Make it look like a text label.
369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.className = 'text-button';
370731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // Remove the event listner.
371731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.onclick = undefined;
372731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      } else if (languageCode in templateData.spellCheckLanguageCodeSet) {
373731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // If the language is supported as spell check language, users can
374731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // click on the button to change the spell check language.
375731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.textContent =
376731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            localStrings.getString('use_this_for_spell_checking');
377731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.className = '';
378731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.languageCode = languageCode;
379731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // Add an event listner to the click event.
380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.addEventListener('click',
381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            this.handleSpellCheckLanguageButtonClick_.bind(this));
382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      } else {
383731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // If the language is not supported as spell check language, the
384731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // button just says that this language cannot be used for spell
385731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // checking.
386731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.textContent =
387731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            localStrings.getString('cannot_be_used_for_spell_checking');
388731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.className = 'text-button';
389731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        spellCheckLanguageButton.onclick = undefined;
390731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
391731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      spellCheckLanguageButton.style.display = 'block';
392731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      $('language-options-ui-notification-bar').style.display = 'none';
393731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    },
394731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
395731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    /**
396bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Updates the input method list.
397bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {string} languageCode Language code (ex. "fr").
398bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
399bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
400bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    updateInputMethodList_: function(languageCode) {
4014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      // Give one of the checkboxes or buttons focus, if it's specified in the
4024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      // URL hash (ex. focus=mozc). Used for automated testing.
403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      var focusInputMethodId = -1;
404731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      var match = document.location.hash.match(/\bfocus=([\w:-]+)\b/);
405731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (match) {
406731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        focusInputMethodId = match[1];
407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
408bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Change the visibility of the input method list. Input methods that
409bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // matches |languageCode| will become visible.
410bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var inputMethodList = $('language-options-input-method-list');
411bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var labels = inputMethodList.querySelectorAll('label');
412bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < labels.length; i++) {
413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        var label = labels[i];
414731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        if (languageCode in label.languageCodeSet) {
415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          label.style.display = 'block';
416731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          var input = label.childNodes[0];
417731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          // Give it focus if the ID matches.
418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          if (input.inputMethodId == focusInputMethodId) {
419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            input.focus();
420731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          }
421bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        } else {
422731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          label.style.display = 'none';
423bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
424bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (focusInputMethodId == 'add') {
4274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        $('language-options-add-button').focus();
4284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      }
429bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
430bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
431bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
432bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Updates the language list in the add language overlay.
433bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {string} languageCode Language code (ex. "fr").
434bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
435bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
436bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    updateLanguageListInAddLanguageOverlay_: function(languageCode) {
437bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Change the visibility of the language list in the add language
438bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // overlay. Languages that are already active will become invisible,
439bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // so that users don't add the same language twice.
440bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageOptionsList = $('language-options-list');
441bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageCodes = languageOptionsList.getLanguageCodes();
442bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageCodeSet = {};
443bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < languageCodes.length; i++) {
444bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        languageCodeSet[languageCodes[i]] = true;
445bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
446bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var addLanguageList = $('add-language-overlay-language-list');
447bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var lis = addLanguageList.querySelectorAll('li');
448bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < lis.length; i++) {
449bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // The first child button knows the language code.
450bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        var button = lis[i].childNodes[0];
451bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (button.languageCode in languageCodeSet) {
452bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          lis[i].style.display = 'none';
453bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        } else {
454bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          lis[i].style.display = 'block';
455bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
456bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
457bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
458bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
459bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
460bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Handles preloadEnginesPref change.
461bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {Event} e Change event.
462bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
463bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
464bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    handlePreloadEnginesPrefChange_: function(e) {
465bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var value = e.value.value;
466bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      this.preloadEngines_ = this.filterBadPreloadEngines_(value.split(','));
467bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      this.updateCheckboxesFromPreloadEngines_();
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      $('language-options-list').updateDeletable();
469bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
470bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
471bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
472bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Handles input method checkbox's click event.
473bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {Event} e Click event.
474bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
475bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
476bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    handleCheckboxClick_ : function(e) {
477bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var checkbox = e.target;
478bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      if (this.preloadEngines_.length == 1 && !checkbox.checked) {
479bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Don't allow disabling the last input method.
480bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        this.showNotification_(
481bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            localStrings.getString('please_add_another_input_method'),
482bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            localStrings.getString('ok_button'));
483bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        checkbox.checked = true;
484bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        return;
485bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
486bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      if (checkbox.checked) {
487bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        chrome.send('inputMethodEnable', [checkbox.inputMethodId]);
488bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      } else {
489bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        chrome.send('inputMethodDisable', [checkbox.inputMethodId]);
490bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
491bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      this.updatePreloadEnginesFromCheckboxes_();
492bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      this.preloadEngines_ = this.sortPreloadEngines_(this.preloadEngines_);
493bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      this.savePreloadEnginesPref_();
494bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
495bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
496bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
497bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Handles add language list's click event.
498bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {Event} e Click event.
499bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
500bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    handleAddLanguageListClick_ : function(e) {
501bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageOptionsList = $('language-options-list');
502bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageCode = e.target.languageCode;
503731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // languageCode can be undefined, if click was made on some random
504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // place in the overlay, rather than a button. Ignore it.
505731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (!languageCode) {
506731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        return;
507731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
508bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      languageOptionsList.addLanguage(languageCode);
509bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var inputMethodIds = this.languageCodeToInputMethodIdsMap_[languageCode];
510bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Enable the first input method for the language added.
511bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      if (inputMethodIds && inputMethodIds[0] &&
512bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          // Don't add the input method it's already present. This can
513bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          // happen if the same input method is shared among multiple
514bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          // languages (ex. English US keyboard is used for English US and
515bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          // Filipino).
516bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          this.preloadEngines_.indexOf(inputMethodIds[0]) == -1) {
517bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        this.preloadEngines_.push(inputMethodIds[0]);
518bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        this.updateCheckboxesFromPreloadEngines_();
519bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        this.savePreloadEnginesPref_();
520bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
52172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      OptionsPage.closeOverlay();
52272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    },
52372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
52472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    /**
52572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen     * Handles add language dialog ok button.
52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen     */
52772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    handleAddLanguageOkButtonClick_ : function() {
52872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      var languagesSelect = $('add-language-overlay-language-list');
52972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      var selectedIndex = languagesSelect.selectedIndex;
53072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (selectedIndex >= 0) {
53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        var selection = languagesSelect.options[selectedIndex];
53272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        $('language-options-list').addLanguage(String(selection.value));
53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        OptionsPage.closeOverlay();
53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
535bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
536bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
537bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Checks if languageCode is deletable or not.
539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * @param {String} languageCode the languageCode to check for deletability.
540bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    languageIsDeletable: function(languageCode) {
542bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Don't allow removing the language if it's as UI language.
543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (languageCode == templateData.currentUiLanguageCode)
544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return false;
545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return (!cr.isChromeOS ||
546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              this.canDeleteLanguage_(languageCode));
547bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
548bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
549bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
550731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     * Handles spellCheckDictionaryPref change.
551731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     * @param {Event} e Change event.
552731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     * @private
553731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     */
554731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    handleSpellCheckDictionaryPrefChange_: function(e) {
555731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      var languageCode = e.value.value
556731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      this.spellCheckDictionary_ = languageCode;
557731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      var languageOptionsList = $('language-options-list');
558731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      var selectedLanguageCode = languageOptionsList.getSelectedLanguageCode();
559731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      this.updateSpellCheckLanguageButton_(selectedLanguageCode);
560731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    },
561731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
562731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    /**
563731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     * Handles spellCheckLanguageButton click.
564731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     * @param {Event} e Click event.
565731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     * @private
566731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick     */
567731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    handleSpellCheckLanguageButtonClick_: function(e) {
568731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      var languageCode = e.target.languageCode;
569731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // Save the preference.
570731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      Preferences.setStringPref(this.spellCheckDictionaryPref,
571731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                languageCode);
572731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      chrome.send('spellCheckLanguageChange', [languageCode]);
573731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    },
574731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
575731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    /**
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Checks whether it's possible to remove the language specified by
577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * languageCode and returns true if possible. This function returns false
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * if the removal causes the number of preload engines to be zero.
579bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     *
580bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {string} languageCode Language code (ex. "fr").
581bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @return {boolean} Returns true on success.
582bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
583bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    canDeleteLanguage_: function(languageCode) {
585bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // First create the set of engines to be removed from input methods
586bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // associated with the language code.
587bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var enginesToBeRemovedSet = {};
588bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var inputMethodIds = this.languageCodeToInputMethodIdsMap_[languageCode];
589bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < inputMethodIds.length; i++) {
590bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        enginesToBeRemovedSet[inputMethodIds[i]] = true;
591bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
592bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
593bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Then eliminate engines that are also used for other active languages.
594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // For instance, if "xkb:us::eng" is used for both English and Filipino.
595bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var languageCodes = $('language-options-list').getLanguageCodes();
596bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < languageCodes.length; i++) {
597bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Skip the target language code.
598bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (languageCodes[i] == languageCode) {
599bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          continue;
600bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
601bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Check if input methods used in this language are included in
602bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // enginesToBeRemovedSet. If so, eliminate these from the set, so
603bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // we don't remove this time.
604bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        var inputMethodIdsForAnotherLanguage =
605bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            this.languageCodeToInputMethodIdsMap_[languageCodes[i]];
606bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        for (var j = 0; j < inputMethodIdsForAnotherLanguage.length; j++) {
607bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          var inputMethodId = inputMethodIdsForAnotherLanguage[j];
608bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          if (inputMethodId in enginesToBeRemovedSet) {
609bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen            delete enginesToBeRemovedSet[inputMethodId];
610bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          }
611bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
612bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
613bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
614bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Update the preload engine list with the to-be-removed set.
615bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var newPreloadEngines = [];
616bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < this.preloadEngines_.length; i++) {
617bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (!(this.preloadEngines_[i] in enginesToBeRemovedSet)) {
618bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          newPreloadEngines.push(this.preloadEngines_[i]);
619bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
620bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
621bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Don't allow this operation if it causes the number of preload
622bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // engines to be zero.
623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return (newPreloadEngines.length > 0);
624bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
625bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
626bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
627bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Saves the preload engines preference.
628bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
629bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
630bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    savePreloadEnginesPref_: function() {
631bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      Preferences.setStringPref(this.preloadEnginesPref,
632bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                this.preloadEngines_.join(','));
633bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
634bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
635bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
636bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Updates the checkboxes in the input method list from the preload
637bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * engines preference.
638bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
639bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
640bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    updateCheckboxesFromPreloadEngines_: function() {
641bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Convert the list into a dictonary for simpler lookup.
642bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var dictionary = {};
643bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < this.preloadEngines_.length; i++) {
644bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        dictionary[this.preloadEngines_[i]] = true;
645bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
646bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
647bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var inputMethodList = $('language-options-input-method-list');
648bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var checkboxes = inputMethodList.querySelectorAll('input');
649bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < checkboxes.length; i++) {
650bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        checkboxes[i].checked = (checkboxes[i].inputMethodId in dictionary);
651bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
652bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
653bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
654bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
655bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Updates the preload engines preference from the checkboxes in the
656bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * input method list.
657bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
658bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
659bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    updatePreloadEnginesFromCheckboxes_: function() {
660bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      this.preloadEngines_ = [];
661bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var inputMethodList = $('language-options-input-method-list');
662bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var checkboxes = inputMethodList.querySelectorAll('input');
663bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < checkboxes.length; i++) {
664bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (checkboxes[i].checked) {
665bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          this.preloadEngines_.push(checkboxes[i].inputMethodId);
666bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
667bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var languageOptionsList = $('language-options-list');
669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      languageOptionsList.updateDeletable();
670bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
671bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
672bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
673bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Filters bad preload engines in case bad preload engines are
674bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * stored in the preference. Removes duplicates as well.
675bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @param {Array} preloadEngines List of preload engines.
676bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
677bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
678bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    filterBadPreloadEngines_: function(preloadEngines) {
679bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Convert the list into a dictonary for simpler lookup.
680bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var dictionary = {};
681bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < templateData.inputMethodList.length; i++) {
682bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        dictionary[templateData.inputMethodList[i].id] = true;
683bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
684bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
685bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var filteredPreloadEngines = [];
686bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var seen = {};
687bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      for (var i = 0; i < preloadEngines.length; i++) {
688bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Check if the preload engine is present in the
689bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // dictionary, and not duplicate. Otherwise, skip it.
690bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (preloadEngines[i] in dictionary && !(preloadEngines[i] in seen)) {
691bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          filteredPreloadEngines.push(preloadEngines[i]);
692bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          seen[preloadEngines[i]] = true;
693bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
694bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
695bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      return filteredPreloadEngines;
696bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    },
697bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
698bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // TODO(kochi): This is an adapted copy from new_new_tab.js.
699bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // If this will go as final UI, refactor this to share the component with
700bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // new new tab page.
701bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    /**
702bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * Shows notification
703bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     * @private
704bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen     */
705bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    notificationTimeout_: null,
706bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    showNotification_ : function(text, actionText, opt_delay) {
707bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var notificationElement = $('notification');
708bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var actionLink = notificationElement.querySelector('.link-color');
709bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      var delay = opt_delay || 10000;
710bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
711bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      function show() {
712bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        window.clearTimeout(this.notificationTimeout_);
713bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        notificationElement.classList.add('show');
714bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        document.body.classList.add('notification-shown');
715bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
716bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
717bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      function hide() {
718bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        window.clearTimeout(this.notificationTimeout_);
719bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        notificationElement.classList.remove('show');
720bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        document.body.classList.remove('notification-shown');
721bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Prevent tabbing to the hidden link.
722bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        actionLink.tabIndex = -1;
723bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // Setting tabIndex to -1 only prevents future tabbing to it. If,
724bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // however, the user switches window or a tab and then moves back to
725bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // this tab the element may gain focus. We therefore make sure that we
726bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // blur the element so that the element focus is not restored when
727bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        // coming back to this window.
728bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        actionLink.blur();
729bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
730bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
731bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      function delayedHide() {
732bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        this.notificationTimeout_ = window.setTimeout(hide, delay);
733bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      }
734bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
735bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      notificationElement.firstElementChild.textContent = text;
736bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      actionLink.textContent = actionText;
737bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
738bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      actionLink.onclick = hide;
739bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      actionLink.onkeydown = function(e) {
740bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        if (e.keyIdentifier == 'Enter') {
741bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          hide();
742bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        }
743bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      };
744bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      notificationElement.onmouseover = show;
745bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      notificationElement.onmouseout = delayedHide;
746bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      actionLink.onfocus = show;
747bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      actionLink.onblur = delayedHide;
748bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      // Enable tabbing to the link now that it is shown.
749bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      actionLink.tabIndex = 0;
750bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
751bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      show();
752bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      delayedHide();
753bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    }
754bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  };
755bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
756bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  /**
757bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen   * Chrome callback for when the UI language preference is saved.
758bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen   */
759bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  LanguageOptions.uiLanguageSaved = function() {
760bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    $('language-options-ui-language-button').style.display = 'none';
761bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    $('language-options-ui-notification-bar').style.display = 'block';
762bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  };
763bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
764bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Export
765bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return {
766bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    LanguageOptions: LanguageOptions
767bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  };
768bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen});
769