michael@0: /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: var gLanguagesDialog = { michael@0: michael@0: _availableLanguagesList : [], michael@0: _acceptLanguages : { }, michael@0: michael@0: _selectedItemID : null, michael@0: michael@0: init: function () michael@0: { michael@0: if (!this._availableLanguagesList.length) michael@0: this._loadAvailableLanguages(); michael@0: }, michael@0: michael@0: get _activeLanguages() michael@0: { michael@0: return document.getElementById("activeLanguages"); michael@0: }, michael@0: michael@0: get _availableLanguages() michael@0: { michael@0: return document.getElementById("availableLanguages"); michael@0: }, michael@0: michael@0: _loadAvailableLanguages: function () michael@0: { michael@0: // This is a parser for: resource://gre/res/language.properties michael@0: // The file is formatted like so: michael@0: // ab[-cd].accept=true|false michael@0: // ab = language michael@0: // cd = region michael@0: var bundleAccepted = document.getElementById("bundleAccepted"); michael@0: var bundleRegions = document.getElementById("bundleRegions"); michael@0: var bundleLanguages = document.getElementById("bundleLanguages"); michael@0: var bundlePreferences = document.getElementById("bundlePreferences"); michael@0: michael@0: function LanguageInfo(aName, aABCD, aIsVisible) michael@0: { michael@0: this.name = aName; michael@0: this.abcd = aABCD; michael@0: this.isVisible = aIsVisible; michael@0: } michael@0: michael@0: // 1) Read the available languages out of language.properties michael@0: var strings = bundleAccepted.strings; michael@0: while (strings.hasMoreElements()) { michael@0: var currString = strings.getNext(); michael@0: if (!(currString instanceof Components.interfaces.nsIPropertyElement)) michael@0: break; michael@0: michael@0: var property = currString.key.split("."); // ab[-cd].accept michael@0: if (property[1] == "accept") { michael@0: var abCD = property[0]; michael@0: var abCDPairs = abCD.split("-"); // ab[-cd] michael@0: var useABCDFormat = abCDPairs.length > 1; michael@0: var ab = useABCDFormat ? abCDPairs[0] : abCD; michael@0: var cd = useABCDFormat ? abCDPairs[1] : ""; michael@0: if (ab) { michael@0: var language = ""; michael@0: try { michael@0: language = bundleLanguages.getString(ab); michael@0: } michael@0: catch (e) { continue; }; michael@0: michael@0: var region = ""; michael@0: if (useABCDFormat) { michael@0: try { michael@0: region = bundleRegions.getString(cd); michael@0: } michael@0: catch (e) { continue; } michael@0: } michael@0: michael@0: var name = ""; michael@0: if (useABCDFormat) michael@0: name = bundlePreferences.getFormattedString("languageRegionCodeFormat", michael@0: [language, region, abCD]); michael@0: else michael@0: name = bundlePreferences.getFormattedString("languageCodeFormat", michael@0: [language, abCD]); michael@0: michael@0: if (name && abCD) { michael@0: var isVisible = currString.value == "true" && michael@0: (!(abCD in this._acceptLanguages) || !this._acceptLanguages[abCD]); michael@0: var li = new LanguageInfo(name, abCD, isVisible); michael@0: this._availableLanguagesList.push(li); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: this._buildAvailableLanguageList(); michael@0: }, michael@0: michael@0: _buildAvailableLanguageList: function () michael@0: { michael@0: var availableLanguagesPopup = document.getElementById("availableLanguagesPopup"); michael@0: while (availableLanguagesPopup.hasChildNodes()) michael@0: availableLanguagesPopup.removeChild(availableLanguagesPopup.firstChild); michael@0: michael@0: // Sort the list of languages by name michael@0: this._availableLanguagesList.sort(function (a, b) { michael@0: return a.name.localeCompare(b.name); michael@0: }); michael@0: michael@0: // Load the UI with the data michael@0: for (var i = 0; i < this._availableLanguagesList.length; ++i) { michael@0: var abCD = this._availableLanguagesList[i].abcd; michael@0: if (this._availableLanguagesList[i].isVisible && michael@0: (!(abCD in this._acceptLanguages) || !this._acceptLanguages[abCD])) { michael@0: var menuitem = document.createElement("menuitem"); michael@0: menuitem.id = this._availableLanguagesList[i].abcd; michael@0: availableLanguagesPopup.appendChild(menuitem); michael@0: menuitem.setAttribute("label", this._availableLanguagesList[i].name); michael@0: } michael@0: } michael@0: }, michael@0: michael@0: readAcceptLanguages: function () michael@0: { michael@0: while (this._activeLanguages.hasChildNodes()) michael@0: this._activeLanguages.removeChild(this._activeLanguages.firstChild); michael@0: michael@0: var selectedIndex = 0; michael@0: var preference = document.getElementById("intl.accept_languages"); michael@0: if (preference.value == "") michael@0: return undefined; michael@0: var languages = preference.value.toLowerCase().split(/\s*,\s*/); michael@0: for (var i = 0; i < languages.length; ++i) { michael@0: var name = this._getLanguageName(languages[i]); michael@0: if (!name) michael@0: name = "[" + languages[i] + "]"; michael@0: var listitem = document.createElement("listitem"); michael@0: listitem.id = languages[i]; michael@0: if (languages[i] == this._selectedItemID) michael@0: selectedIndex = i; michael@0: this._activeLanguages.appendChild(listitem); michael@0: listitem.setAttribute("label", name); michael@0: michael@0: // Hash this language as an "Active" language so we don't michael@0: // show it in the list that can be added. michael@0: this._acceptLanguages[languages[i]] = true; michael@0: } michael@0: michael@0: if (this._activeLanguages.childNodes.length > 0) { michael@0: this._activeLanguages.ensureIndexIsVisible(selectedIndex); michael@0: this._activeLanguages.selectedIndex = selectedIndex; michael@0: } michael@0: michael@0: return undefined; michael@0: }, michael@0: michael@0: writeAcceptLanguages: function () michael@0: { michael@0: return undefined; michael@0: }, michael@0: michael@0: onAvailableLanguageSelect: function () michael@0: { michael@0: var addButton = document.getElementById("addButton"); michael@0: addButton.disabled = false; michael@0: michael@0: this._availableLanguages.removeAttribute("accesskey"); michael@0: }, michael@0: michael@0: addLanguage: function () michael@0: { michael@0: var selectedID = this._availableLanguages.selectedItem.id; michael@0: var preference = document.getElementById("intl.accept_languages"); michael@0: var arrayOfPrefs = preference.value.toLowerCase().split(/\s*,\s*/); michael@0: for (var i = 0; i < arrayOfPrefs.length; ++i ){ michael@0: if (arrayOfPrefs[i] == selectedID) michael@0: return; michael@0: } michael@0: michael@0: this._selectedItemID = selectedID; michael@0: michael@0: if (preference.value == "") michael@0: preference.value = selectedID; michael@0: else { michael@0: arrayOfPrefs.unshift(selectedID); michael@0: preference.value = arrayOfPrefs.join(","); michael@0: } michael@0: michael@0: this._acceptLanguages[selectedID] = true; michael@0: this._availableLanguages.selectedItem = null; michael@0: michael@0: // Rebuild the available list with the added item removed... michael@0: this._buildAvailableLanguageList(); michael@0: michael@0: this._availableLanguages.setAttribute("label", this._availableLanguages.getAttribute("label2")); michael@0: }, michael@0: michael@0: removeLanguage: function () michael@0: { michael@0: // Build the new preference value string. michael@0: var languagesArray = []; michael@0: for (var i = 0; i < this._activeLanguages.childNodes.length; ++i) { michael@0: var item = this._activeLanguages.childNodes[i]; michael@0: if (!item.selected) michael@0: languagesArray.push(item.id); michael@0: else michael@0: this._acceptLanguages[item.id] = false; michael@0: } michael@0: var string = languagesArray.join(","); michael@0: michael@0: // Get the item to select after the remove operation completes. michael@0: var selection = this._activeLanguages.selectedItems; michael@0: var lastSelected = selection[selection.length-1]; michael@0: var selectItem = lastSelected.nextSibling || lastSelected.previousSibling; michael@0: selectItem = selectItem ? selectItem.id : null; michael@0: michael@0: this._selectedItemID = selectItem; michael@0: michael@0: // Update the preference and force a UI rebuild michael@0: var preference = document.getElementById("intl.accept_languages"); michael@0: preference.value = string; michael@0: michael@0: this._buildAvailableLanguageList(); michael@0: }, michael@0: michael@0: _getLanguageName: function (aABCD) michael@0: { michael@0: if (!this._availableLanguagesList.length) michael@0: this._loadAvailableLanguages(); michael@0: for (var i = 0; i < this._availableLanguagesList.length; ++i) { michael@0: if (aABCD == this._availableLanguagesList[i].abcd) michael@0: return this._availableLanguagesList[i].name; michael@0: } michael@0: return ""; michael@0: }, michael@0: michael@0: moveUp: function () michael@0: { michael@0: var selectedItem = this._activeLanguages.selectedItems[0]; michael@0: var previousItem = selectedItem.previousSibling; michael@0: michael@0: var string = ""; michael@0: for (var i = 0; i < this._activeLanguages.childNodes.length; ++i) { michael@0: var item = this._activeLanguages.childNodes[i]; michael@0: string += (i == 0 ? "" : ","); michael@0: if (item.id == previousItem.id) michael@0: string += selectedItem.id; michael@0: else if (item.id == selectedItem.id) michael@0: string += previousItem.id; michael@0: else michael@0: string += item.id; michael@0: } michael@0: michael@0: this._selectedItemID = selectedItem.id; michael@0: michael@0: // Update the preference and force a UI rebuild michael@0: var preference = document.getElementById("intl.accept_languages"); michael@0: preference.value = string; michael@0: }, michael@0: michael@0: moveDown: function () michael@0: { michael@0: var selectedItem = this._activeLanguages.selectedItems[0]; michael@0: var nextItem = selectedItem.nextSibling; michael@0: michael@0: var string = ""; michael@0: for (var i = 0; i < this._activeLanguages.childNodes.length; ++i) { michael@0: var item = this._activeLanguages.childNodes[i]; michael@0: string += (i == 0 ? "" : ","); michael@0: if (item.id == nextItem.id) michael@0: string += selectedItem.id; michael@0: else if (item.id == selectedItem.id) michael@0: string += nextItem.id; michael@0: else michael@0: string += item.id; michael@0: } michael@0: michael@0: this._selectedItemID = selectedItem.id; michael@0: michael@0: // Update the preference and force a UI rebuild michael@0: var preference = document.getElementById("intl.accept_languages"); michael@0: preference.value = string; michael@0: }, michael@0: michael@0: onLanguageSelect: function () michael@0: { michael@0: var upButton = document.getElementById("up"); michael@0: var downButton = document.getElementById("down"); michael@0: var removeButton = document.getElementById("remove"); michael@0: switch (this._activeLanguages.selectedCount) { michael@0: case 0: michael@0: upButton.disabled = downButton.disabled = removeButton.disabled = true; michael@0: break; michael@0: case 1: michael@0: upButton.disabled = this._activeLanguages.selectedIndex == 0; michael@0: downButton.disabled = this._activeLanguages.selectedIndex == this._activeLanguages.childNodes.length - 1; michael@0: removeButton.disabled = false; michael@0: break; michael@0: default: michael@0: upButton.disabled = true; michael@0: downButton.disabled = true; michael@0: removeButton.disabled = false; michael@0: } michael@0: } michael@0: }; michael@0: