mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-07 05:15:09 +00:00
349 lines
11 KiB
JavaScript
349 lines
11 KiB
JavaScript
const Ci = Components.interfaces;
|
|
const Cc = Components.classes;
|
|
const Cu = Components.utils;
|
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
Cu.import("resource://gre/modules/AddonManager.jsm");
|
|
Cu.import("resource:///modules/LocaleRepository.jsm");
|
|
|
|
let stringPrefs = [
|
|
{ selector: "#continue-in-button", pref: "continueIn", data: ["CURRENT_LANGUAGE"] },
|
|
{ selector: "#change-language", pref: "choose", data: null },
|
|
{ selector: "#picker-title", pref: "chooseLanguage", data: null },
|
|
{ selector: "#continue-button", pref: "continue", data: null },
|
|
{ selector: "#cancel-button", pref: "cancel", data: null },
|
|
{ selector: "#intalling-message", pref: "installing", data: ["CURRENT_LANGUAGE"] },
|
|
{ selector: "#cancel-install-button", pref: "cancel", data: null },
|
|
{ selector: "#installing-error", pref: "installerror", data: null },
|
|
{ selector: "#install-continue", pref: "continue", data: null }
|
|
];
|
|
|
|
let LocaleUI = {
|
|
_strings: null,
|
|
|
|
get strings() {
|
|
if (!this._strings)
|
|
this._strings = Services.strings.createBundle("chrome://browser/locale/localepicker.properties");
|
|
return this._strings;
|
|
},
|
|
|
|
set strings(aVal) {
|
|
this._strings = aVal;
|
|
},
|
|
|
|
get _mainPage() {
|
|
delete this._mainPage;
|
|
return this._mainPage = document.getElementById("main-page");
|
|
},
|
|
|
|
get _pickerPage() {
|
|
delete this._pickerPage;
|
|
return this._pickerPage = document.getElementById("picker-page");
|
|
},
|
|
|
|
get _installerPage() {
|
|
delete this._installerPage;
|
|
return this._installerPage = document.getElementById("installer-page");
|
|
},
|
|
|
|
get _deck() {
|
|
delete this._deck;
|
|
return this._deck = document.getElementById("language-deck");
|
|
},
|
|
|
|
_currentInstall: null, // used to cancel an install
|
|
|
|
get selectedPanel() {
|
|
return this._deck.selectedPanel;
|
|
},
|
|
|
|
set selectedPanel(aPanel) {
|
|
this._deck.selectedPanel = aPanel;
|
|
},
|
|
|
|
get list() {
|
|
delete this.list;
|
|
return this.list = document.getElementById("language-list");
|
|
},
|
|
|
|
_createItem: function(aId, aText, aLocale) {
|
|
let item = document.createElement("richlistitem");
|
|
item.setAttribute("id", aId);
|
|
|
|
let description = document.createElement("description");
|
|
description.appendChild(document.createTextNode(aText));
|
|
description.setAttribute('flex', 1);
|
|
item.appendChild(description);
|
|
item.setAttribute("locale", getTargetLanguage(aLocale.addon));
|
|
|
|
if (aLocale) {
|
|
item.locale = aLocale.addon;
|
|
let checkbox = document.createElement("image");
|
|
checkbox.classList.add("checkbox");
|
|
item.appendChild(checkbox);
|
|
} else {
|
|
item.classList.add("message");
|
|
}
|
|
return item;
|
|
},
|
|
|
|
addLocales: function(aLocales) {
|
|
let fragment = document.createDocumentFragment();
|
|
let selectedItem = null;
|
|
let bestMatch = NO_MATCH;
|
|
|
|
for each (let locale in aLocales) {
|
|
let targetLang = getTargetLanguage(locale.addon);
|
|
if (document.querySelector('[locale="' + targetLang + '"]'))
|
|
continue;
|
|
|
|
let item = this._createItem(targetLang, locale.addon.name, locale);
|
|
let match = localesMatch(targetLang, this.language);
|
|
if (match > bestMatch) {
|
|
bestMatch = match;
|
|
selectedItem = item;
|
|
}
|
|
fragment.appendChild(item);
|
|
}
|
|
this.list.appendChild(fragment);
|
|
if (selectedItem && !this.list.selectedItem);
|
|
this.list.selectedItem = selectedItem;
|
|
},
|
|
|
|
loadLocales: function() {
|
|
while (this.list.firstChild)
|
|
this.list.removeChild(this.list.firstChild);
|
|
this.addLocales(this.availableLocales);
|
|
LocaleRepository.getLocales(this.addLocales.bind(this));
|
|
},
|
|
|
|
showPicker: function() {
|
|
LocaleUI.selectedPanel = LocaleUI._pickerPage;
|
|
LocaleUI.loadLocales();
|
|
},
|
|
|
|
closePicker: function() {
|
|
if (this._currentInstall) {
|
|
Services.prefs.setBoolPref("intl.locale.matchOS", false);
|
|
Services.prefs.setCharPref("general.useragent.locale", getTargetLanguage(this._currentInstall));
|
|
}
|
|
this.selectedPanel = this._mainPage;
|
|
},
|
|
|
|
_language: "",
|
|
|
|
set language(aVal) {
|
|
if (aVal == this._language)
|
|
return;
|
|
|
|
Services.prefs.setBoolPref("intl.locale.matchOS", false);
|
|
Services.prefs.setCharPref("general.useragent.locale", aVal);
|
|
this._language = aVal;
|
|
|
|
this.strings = null;
|
|
this.updateStrings();
|
|
},
|
|
|
|
get language() {
|
|
return this._language;
|
|
},
|
|
|
|
set installStatus(aVal) {
|
|
this._installerPage.selectedPanel = document.getElementById("installer-page-" + aVal);
|
|
},
|
|
|
|
clearInstallError: function() {
|
|
this.installStatus = "installing";
|
|
this.selectedPanel = this._pickerPage;
|
|
},
|
|
|
|
selectLanguage: function(aEvent) {
|
|
let locale = this.list.selectedItem.locale;
|
|
if (locale.install)
|
|
this.updateStrings(locale);
|
|
else {
|
|
this.language = getTargetLanguage(locale);
|
|
if (this._currentInstall)
|
|
this._currentInstall = null;
|
|
}
|
|
},
|
|
|
|
installAddon: function() {
|
|
let locale = LocaleUI.list.selectedItem.locale;
|
|
LocaleUI._currentInstall = locale;
|
|
|
|
if (locale.install) {
|
|
LocaleUI.selectedPanel = LocaleUI._installerPage;
|
|
locale.install.addListener(installListener);
|
|
locale.install.install();
|
|
} else {
|
|
this.closePicker();
|
|
}
|
|
},
|
|
|
|
cancelPicker: function() {
|
|
if (this._currentInstall)
|
|
this._currentInstall = null;
|
|
// restore the last known "good" locale
|
|
this.language = this.defaultLanguage;
|
|
this.updateStrings();
|
|
this.closePicker();
|
|
},
|
|
|
|
closeWindow : function() {
|
|
// Trying to close this window and open a new one results in a corrupt UI.
|
|
if (false && LocaleUI._currentInstall) {
|
|
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
|
|
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
|
|
|
|
if (cancelQuit.data == false) {
|
|
let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
|
|
appStartup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eForceQuit);
|
|
Services.prefs.setBoolPref("browser.sessionstore.resume_session_once", false);
|
|
}
|
|
} else {
|
|
let argString = null;
|
|
if (window.arguments) {
|
|
argString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
|
argString.data = window.arguments.join(",");
|
|
}
|
|
let win = Services.ww.openWindow(window, "chrome://browser/content/browser.xul", "_blank", "chrome,dialog=no,all", argString);
|
|
window.close();
|
|
}
|
|
},
|
|
|
|
cancelInstall: function () {
|
|
if (LocaleUI._currentInstall) {
|
|
let addonInstall = LocaleUI._currentInstall.install;
|
|
try { addonInstall.cancel(); }
|
|
catch(ex) { }
|
|
LocaleUI._currentInstall = null;
|
|
|
|
this.language = this.defaultLanguage;
|
|
}
|
|
},
|
|
|
|
updateStrings: function (aAddon) {
|
|
stringPrefs.forEach(function(aPref) {
|
|
if (!aPref.element)
|
|
aPref.element = document.querySelector(aPref.selector);
|
|
|
|
let string = "";
|
|
try {
|
|
string = getString(aPref.pref, aPref.data, aAddon);
|
|
} catch(ex) { }
|
|
aPref.element.textContent = string;
|
|
});
|
|
}
|
|
}
|
|
|
|
// Gets the target language for a locale addon
|
|
// For now this returns the targetLocale, although if and addon doesn't
|
|
// specify a targetLocale we could attempt to guess the locale from the addon's name
|
|
function getTargetLanguage(aAddon) {
|
|
return aAddon.targetLocale;
|
|
}
|
|
|
|
// Gets a particular string for the passed in locale
|
|
// Parameters: aStringName - The name of the string property to get
|
|
// aDataset - an array of properties to use in a formatted string
|
|
// aAddon - An addon to attempt to get dataset properties from
|
|
function getString(aStringName, aDataSet, aAddon) {
|
|
if (aDataSet) {
|
|
let databundle = aDataSet.map(function(aData) {
|
|
switch (aData) {
|
|
case "CURRENT_LANGUAGE" :
|
|
if (aAddon)
|
|
return aAddon.name;
|
|
try { return LocaleUI.strings.GetStringFromName("name"); }
|
|
catch(ex) { return null; }
|
|
break;
|
|
default :
|
|
}
|
|
return "";
|
|
});
|
|
if (databundle.some(function(aItem) aItem === null))
|
|
throw("String not found");
|
|
return LocaleUI.strings.formatStringFromName(aStringName, databundle, databundle.length);
|
|
}
|
|
|
|
return LocaleUI.strings.GetStringFromName(aStringName);
|
|
}
|
|
|
|
let installListener = {
|
|
onNewInstall: function(install) { },
|
|
onDownloadStarted: function(install) { },
|
|
onDownloadProgress: function(install) { },
|
|
onDownloadEnded: function(install) { },
|
|
onDownloadCancelled: function(install) {
|
|
LocaleUI.cancelInstall();
|
|
LocaleUI.showPicker();
|
|
},
|
|
onDownloadFailed: function(install) {
|
|
LocaleUI.cancelInstall();
|
|
LocaleUI.installStatus = "error";
|
|
},
|
|
onInstallStarted: function(install) { },
|
|
onInstallEnded: function(install, addon) {
|
|
LocaleUI.updateStrings(LocaleUI._currentInstall);
|
|
LocaleUI.closePicker();
|
|
},
|
|
onInstallCancelled: function(install) {
|
|
LocaleUI.cancelInstall();
|
|
LocaleUI.showPicker();
|
|
},
|
|
onInstallFailed: function(install) {
|
|
LocaleUI.cancelInstall();
|
|
LocaleUI.installStatus = "error";
|
|
},
|
|
onExternalInstall: function(install, existingAddon, needsRestart) { }
|
|
}
|
|
|
|
const PERFECT_MATCH = 2;
|
|
const GOOD_MATCH = 1;
|
|
const NO_MATCH = 0;
|
|
//Compares two locales of the form AB or AB-CD
|
|
//returns GOOD_MATCH if AB == AB in both locales, PERFECT_MATCH if AB-CD == AB-CD
|
|
function localesMatch(aLocale1, aLocale2) {
|
|
if (aLocale1 == aLocale2)
|
|
return PERFECT_MATCH;
|
|
|
|
let short1 = aLocale1.split("-")[0];
|
|
let short2 = aLocale2.split("-")[0];
|
|
return (short1 == short2) ? GOOD_MATCH : NO_MATCH;
|
|
}
|
|
|
|
function start() {
|
|
let mouseModule = new MouseModule();
|
|
|
|
// if we have gotten this far, we can assume that we don't have anything matching the system
|
|
// locale and we should show the locale picker
|
|
let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
|
|
chrome.QueryInterface(Ci.nsIToolkitChromeRegistry);
|
|
let availableLocales = chrome.getLocalesForPackage("browser");
|
|
let strings = Services.strings.createBundle("chrome://browser/content/languages.properties");
|
|
LocaleUI.availableLocales = [];
|
|
while (availableLocales.hasMore()) {
|
|
let locale = availableLocales.getNext();
|
|
|
|
let label = locale;
|
|
try { label = strings.GetStringFromName(locale); }
|
|
catch (e) { }
|
|
LocaleUI.availableLocales.push({addon: { id: locale, name: label, targetLocale: locale }});
|
|
}
|
|
|
|
LocaleUI._language = chrome.getSelectedLocale("browser");
|
|
LocaleUI.updateStrings();
|
|
|
|
// update the page strings and show the correct page
|
|
LocaleUI.defaultLanguage = LocaleUI._language;
|
|
window.addEventListener("resize", resizeHandler, false);
|
|
}
|
|
|
|
function resizeHandler() {
|
|
let elements = document.getElementsByClassName("window-width");
|
|
for (let i = 0; i < elements.length; i++)
|
|
elements[i].setAttribute("width", Math.min(800, window.innerWidth));
|
|
}
|