diff options
author | satorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-04 04:13:26 +0000 |
---|---|---|
committer | satorux@chromium.org <satorux@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-04 04:13:26 +0000 |
commit | 30cb7a44b47b8ec5ef9607ef65dcd6aead29bbe9 (patch) | |
tree | 16197c92f6a3dafe7a658ce0a89c142b1c88ae25 /chrome | |
parent | 674b382acde1e6f5f8919fff715388a37afcedee (diff) | |
download | chromium_src-30cb7a44b47b8ec5ef9607ef65dcd6aead29bbe9.zip chromium_src-30cb7a44b47b8ec5ef9607ef65dcd6aead29bbe9.tar.gz chromium_src-30cb7a44b47b8ec5ef9607ef65dcd6aead29bbe9.tar.bz2 |
Implement "Add" and "Remove" buttons in Language and Input page.
Along the way, remove translation for language codes in
|localStrings| (ex "fr" -> "French").
Instead introduce templateData.languageList, with which
we can retrieve language information.
TEST=manually
BUG=4573
Review URL: http://codereview.chromium.org/3041025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54869 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
9 files changed, 286 insertions, 28 deletions
diff --git a/chrome/browser/chromeos/dom_ui/language_options_handler.cc b/chrome/browser/chromeos/dom_ui/language_options_handler.cc index a28eae1..7bbdbb8 100644 --- a/chrome/browser/chromeos/dom_ui/language_options_handler.cc +++ b/chrome/browser/chromeos/dom_ui/language_options_handler.cc @@ -45,15 +45,8 @@ void LanguageOptionsHandler::GetLocalizedValues( IDS_OPTIONS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE, l10n_util::GetString(IDS_PRODUCT_OS_NAME))); - // Build mappings of locale code (language code) to display name - // (ex. "en-US" => "English (United States)". - const std::vector<std::string>& locales = l10n_util::GetAvailableLocales(); - for (size_t i = 0; i < locales.size(); ++i) { - localized_strings->SetString(UTF8ToWide(locales[i]), - chromeos::input_method::GetLanguageDisplayNameFromCode(locales[i])); - } - localized_strings->Set(L"inputMethodList", GetInputMethodList()); + localized_strings->Set(L"languageList", GetLanguageList()); } ListValue* LanguageOptionsHandler::GetInputMethodList() { @@ -80,3 +73,18 @@ ListValue* LanguageOptionsHandler::GetInputMethodList() { return input_method_list; } + +ListValue* LanguageOptionsHandler::GetLanguageList() { + ListValue* language_list = new ListValue(); + + const std::vector<std::string>& locales = l10n_util::GetAvailableLocales(); + for (size_t i = 0; i < locales.size(); ++i) { + DictionaryValue* dictionary = new DictionaryValue(); + dictionary->SetString(L"code", UTF8ToWide(locales[i])); + dictionary->SetString(L"displayName", + chromeos::input_method::GetLanguageDisplayNameFromCode(locales[i])); + language_list->Append(dictionary); + } + + return language_list; +} diff --git a/chrome/browser/chromeos/dom_ui/language_options_handler.h b/chrome/browser/chromeos/dom_ui/language_options_handler.h index 5d8a02d..102d3df 100644 --- a/chrome/browser/chromeos/dom_ui/language_options_handler.h +++ b/chrome/browser/chromeos/dom_ui/language_options_handler.h @@ -24,6 +24,9 @@ class LanguageOptionsHandler : public OptionsPageUIHandler { // Get the list of input methods. ListValue* GetInputMethodList(); + // Get the list of languages. + ListValue* GetLanguageList(); + DISALLOW_COPY_AND_ASSIGN(LanguageOptionsHandler); }; diff --git a/chrome/browser/resources/options.html b/chrome/browser/resources/options.html index 020c23e..fc0a277 100644 --- a/chrome/browser/resources/options.html +++ b/chrome/browser/resources/options.html @@ -24,6 +24,7 @@ <if expr="pp_ifdef('chromeos')"> <script src="options/chromeos_internet_network_element.js"></script> <script src="options/chromeos_internet_options.js"></script> + <script src="options/chromeos_language_add_language_overlay.js"></script> <script src="options/chromeos_language_list.js"></script> <script src="options/chromeos_language_options.js"></script> <script src="options/chromeos_system_options.js"></script> @@ -159,6 +160,9 @@ window.onpopstate = function(e) { <include src="options/font_settings_overlay.html"> <include src="options/import_data_overlay.html"> <include src="options/stop_syncing_overlay.html"> + <if expr="pp_ifdef('chromeos')"> + <include src="options/chromeos_language_add_language_overlay.html"> + </if> </div> </div> <div id="main-content"> diff --git a/chrome/browser/resources/options/chromeos_language_add_language_overlay.html b/chrome/browser/resources/options/chromeos_language_add_language_overlay.html new file mode 100644 index 0000000..78747a1 --- /dev/null +++ b/chrome/browser/resources/options/chromeos_language_add_language_overlay.html @@ -0,0 +1,6 @@ +<div class="page hidden" id="add-language-overlay-page"> + <ul id="add-language-overlay-language-list"> + </ul> + <button id="add-language-overlay-cancel-button" + i18n-content="cancel"></button> +</div> diff --git a/chrome/browser/resources/options/chromeos_language_add_language_overlay.js b/chrome/browser/resources/options/chromeos_language_add_language_overlay.js new file mode 100644 index 0000000..5cfe42f --- /dev/null +++ b/chrome/browser/resources/options/chromeos_language_add_language_overlay.js @@ -0,0 +1,65 @@ +// Copyright (c) 2010 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. + +/////////////////////////////////////////////////////////////////////////////// +// AddLanguageOverlay class: + +cr.define('options.language', function() { + + const OptionsPage = options.OptionsPage; + + /** + * Encapsulated handling of ChromeOS add language overlay page. + * @constructor + */ + function AddLanguageOverlay() { + OptionsPage.call(this, 'addLanguageOverlay', + localStrings.getString('add_button'), + 'add-language-overlay-page'); + } + + cr.addSingletonGetter(AddLanguageOverlay); + + AddLanguageOverlay.prototype = { + // Inherit AddLanguageOverlay from OptionsPage. + __proto__: OptionsPage.prototype, + + /** + * Initializes AddLanguageOverlay page. + * Calls base class implementation to starts preference initialization. + */ + initializePage: function() { + // Call base class implementation to starts preference initialization. + OptionsPage.prototype.initializePage.call(this); + + // Set up the cancel button. + $('add-language-overlay-cancel-button').onclick = function(e) { + OptionsPage.clearOverlays(); + }; + + // Create the language list with which users can add a language. + // Note that we have about 40 languages. + var addLanguageList = $('add-language-overlay-language-list'); + var languageListData = templateData.languageList; + for (var i = 0; i < languageListData.length; i++) { + var language = languageListData[i]; + var button = document.createElement('button'); + button.className = 'link-button'; + button.textContent = language.displayName; + button.languageCode = language.code; + // Listen to user clicks. + button.addEventListener('click', + cr.bind(this.handleLanguageClick_, this)); + var li = document.createElement('li'); + li.languageCode = language.code; + li.appendChild(button); + addLanguageList.appendChild(li); + } + }, + }; + + return { + AddLanguageOverlay: AddLanguageOverlay + }; +}); diff --git a/chrome/browser/resources/options/chromeos_language_list.js b/chrome/browser/resources/options/chromeos_language_list.js index a4f7972..ac0c8b9 100644 --- a/chrome/browser/resources/options/chromeos_language_list.js +++ b/chrome/browser/resources/options/chromeos_language_list.js @@ -6,6 +6,7 @@ cr.define('options.language', function() { const List = cr.ui.List; const ListItem = cr.ui.ListItem; const ArrayDataModel = cr.ui.ArrayDataModel; + const LanguageOptions = options.LanguageOptions; /** * Creates a new language list. @@ -15,6 +16,24 @@ cr.define('options.language', function() { */ var LanguageList = cr.ui.define('list'); + /** + * Gets display name from the given language code. + * @param {string} languageCode Language code (ex. "fr"). + */ + LanguageList.getDisplayNameFromLanguageCode = function(languageCode) { + // Build the language code to display name dictionary at first time. + if (!this.languageCodeToDisplayName_) { + this.languageCodeToDisplayName_ = {}; + var languageList = templateData.languageList; + for (var i = 0; i < languageList.length; i++) { + var language = languageList[i]; + this.languageCodeToDisplayName_[language.code] = language.displayName; + } + } + + return this.languageCodeToDisplayName_[languageCode]; + } + LanguageList.prototype = { __proto__: List.prototype, @@ -33,10 +52,61 @@ cr.define('options.language', function() { }, createItem: function(languageCode) { - var languageDisplayName = localStrings.getString(languageCode); + var languageDisplayName = + LanguageList.getDisplayNameFromLanguageCode(languageCode); return new ListItem({label: languageDisplayName}); }, + /* + * Adds a language to the language list. + * @param {string} languageCode language code (ex. "fr"). + */ + addLanguage: function(languageCode) { + var dataModel = this.dataModel; + dataModel.push(languageCode); + + this.updateBackend_(); + }, + + /* + * Gets the language codes of the currently listed languages. + */ + getLanguageCodes: function() { + return this.dataModel.slice(); + }, + + /* + * Gets the language code of the selected language. + */ + getSelectedLanguageCode: function() { + return this.selectedItem; + }, + + /* + * Removes the currently selected language. + */ + removeSelectedLanguage: function() { + if (this.selectionModel.selectedIndex >= 0 && + // Don't allow removing the last language. + this.dataModel.length > 1) { + // TODO(satorux): Until we switch to the single selection model, + // it's possible that multiple languages are selected, but we don't + // handle that case here. + var originalIndex = this.selectionModel.selectedIndex; + this.dataModel.splice(this.selectionModel.selectedIndex, 1); + // Select the item at the original index if possible. Otherwise, + // select the last item. + // TODO(satorux): This should be handled by the selection model + // See crbug.com/49893. + this.selectionModel.selectedIndex = Math.min( + originalIndex, + this.dataModel.length - 1); + var newLanguageCodes = this.dataModel.slice(); + this.load_(newLanguageCodes); + this.updateBackend_(); + } + }, + /** * Handles pref change. * @param {Event} e The change event object. @@ -82,7 +152,7 @@ cr.define('options.language', function() { for (var i = 0; i < languageCodes.length; i++) { // Check if the translation for the language code is // present. Otherwise, skip it. - if (localStrings.getString(languageCodes[i])) { + if (LanguageList.getDisplayNameFromLanguageCode(languageCodes[i])) { filteredLanguageCodes.push(languageCodes[i]); } } diff --git a/chrome/browser/resources/options/chromeos_language_options.css b/chrome/browser/resources/options/chromeos_language_options.css index 24b543d..eb26df8 100644 --- a/chrome/browser/resources/options/chromeos_language_options.css +++ b/chrome/browser/resources/options/chromeos_language_options.css @@ -61,3 +61,14 @@ padding-top: 2px; padding-bottom: 2px; } + +#add-language-overlay-language-list { + -webkit-column-count: 2; + -webkit-column-gap: 20px; +} + +#add-language-overlay-cancel-button { + /* Place the button in the center. */ + display: block; + margin: auto; +} diff --git a/chrome/browser/resources/options/chromeos_language_options.js b/chrome/browser/resources/options/chromeos_language_options.js index 59d4a75..3a14612 100644 --- a/chrome/browser/resources/options/chromeos_language_options.js +++ b/chrome/browser/resources/options/chromeos_language_options.js @@ -4,7 +4,9 @@ cr.define('options', function() { - var OptionsPage = options.OptionsPage; + const OptionsPage = options.OptionsPage; + const AddLanguageOverlay = options.language.AddLanguageOverlay; + const LanguageList = options.language.LanguageList; ///////////////////////////////////////////////////////////////////////////// // LanguageOptions class: @@ -32,15 +34,31 @@ cr.define('options', function() { OptionsPage.prototype.initializePage.call(this); var languageOptionsList = $('language-options-list'); - options.language.LanguageList.decorate(languageOptionsList); + LanguageList.decorate(languageOptionsList); languageOptionsList.addEventListener('change', cr.bind(this.handleLanguageOptionsListChange_, this)); - this.addEventListener('visibleChange', + this.addEventListener('visibleChange', cr.bind(this.handleVisibleChange_, this)); this.initializeInputMethodList_(); + + // Set up add button. + $('language-options-add-button').onclick = function(e) { + OptionsPage.showOverlay('addLanguageOverlay'); + }; + // Set up remove button. + $('language-options-remove-button').addEventListener('click', + cr.bind(this.handleRemoveButtonClick_, this)); + + // Setup add language overlay page. + OptionsPage.registerOverlay(AddLanguageOverlay.getInstance()); + + // Listen to user clicks on the add language list. + var addLanguageList = $('add-language-overlay-language-list'); + addLanguageList.addEventListener('click', + cr.bind(this.handleAddLanguageListClick_, this)); }, languageListInitalized_: false, @@ -82,18 +100,6 @@ cr.define('options', function() { }, /** - * Handler for OptionsPage's visible property change event. - * @param {Event} e Property change event. - * @private - */ - handleVisibleChange_ : function(e) { - if (!this.languageListInitalized_ && this.visible) { - this.languageListInitalized_ = true; - $('language-options-list').redraw(); - } - }, - - /** * Handler for languageOptionsList's change event. * @param {Event} e Change event. * @private @@ -104,8 +110,9 @@ cr.define('options', function() { if (index == -1) return; - var languageCode = languageOptionsList.dataModel.item(index); - var languageDisplayName = localStrings.getString(languageCode); + var languageCode = languageOptionsList.getLanguageCodes()[index]; + var languageDisplayName = LanguageList.getDisplayNameFromLanguageCode( + languageCode); $('language-options-language-name').textContent = languageDisplayName; // TODO(satorux): The button text should be changed to @@ -125,6 +132,26 @@ cr.define('options', function() { labels[i].style.display = 'none'; } } + + // 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 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'; + } + } }, /** @@ -144,6 +171,63 @@ cr.define('options', function() { */ handleCheckboxClick_ : function(e) { this.updatePreloadEnginesFromCheckboxes_(); + this.savePreloadEnginesPref_(); + }, + + /** + * Handles add language list's click event. + * @param {Event} e Click event. + */ + handleAddLanguageListClick_ : function(e) { + var languageOptionsList = $('language-options-list'); + languageOptionsList.addLanguage(e.target.languageCode); + OptionsPage.clearOverlays(); + }, + + /** + * Handles remove button's click event. + * @param {Event} e Click event. + */ + handleRemoveButtonClick_: function(e) { + var languageOptionsList = $('language-options-list'); + var languageCode = languageOptionsList.getSelectedLanguageCode(); + // Disable input methods associated with |languageCode|. + this.removePreloadEnginesByLanguageCode_(languageCode); + languageOptionsList.removeSelectedLanguage(); + }, + + /** + * Removes preload engines associated with the given language code. + * @param {string} languageCode Language code (ex. "fr"). + * @private + */ + removePreloadEnginesByLanguageCode_: function(languageCode) { + // First create the set of engines to be removed. + var enginesToBeRemoved = {}; + var inputMethodList = templateData.inputMethodList; + for (var i = 0; i < inputMethodList.length; i++) { + var inputMethod = inputMethodList[i]; + if (inputMethod.languageCode == languageCode) { + enginesToBeRemoved[inputMethod.id] = true; + } + } + + // 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 enginesToBeRemoved) { + newPreloadEngines.push(this.preloadEngines_[i]); + } + } + this.preloadEngines_ = newPreloadEngines; + this.savePreloadEnginesPref_(); + }, + + /** + * Saves the preload engines preference. + * @private + */ + savePreloadEnginesPref_: function() { Preferences.setStringPref(this.preloadEnginesPref, this.preloadEngines_.join(',')); }, @@ -214,4 +298,3 @@ cr.define('options', function() { }; }); - diff --git a/chrome/browser/resources/options/options_page.css b/chrome/browser/resources/options/options_page.css index 16ccd42..d268ada 100644 --- a/chrome/browser/resources/options/options_page.css +++ b/chrome/browser/resources/options/options_page.css @@ -180,3 +180,11 @@ section > div:only-of-type label { input[type="checkbox"] { margin-top: 6px; } + +.link-button { + background-color: transparent; + border: none; + color: blue; + cursor: pointer; + text-decoration: underline; +} |