Bug 658278 - Use locale picker in preferences UI. r=mfinkle
authorWes Johnston <wjohnston@mozilla.com>
Fri, 23 Sep 2011 11:27:28 -0700
changeset 78742 611545ce43579e42dbf7da46a41cd533c190ac92
parent 78741 878c2c7f81599ed660b76f28c56a273a7c318af7
child 78743 7226c37145cdf20bb3c1bad26593d5c2b9f28a4f
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs658278
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 658278 - Use locale picker in preferences UI. r=mfinkle
mobile/chrome/content/browser.xul
mobile/chrome/content/extensions.js
mobile/chrome/content/localePicker.js
mobile/chrome/content/preferences.js
mobile/components/BrowserCLH.js
--- a/mobile/chrome/content/browser.xul
+++ b/mobile/chrome/content/browser.xul
@@ -458,21 +458,17 @@
 # these two point to the same page, this just matters for what shows up in the
 # URL bar
                             oncommand="BrowserUI.newTab('about:firefox', Browser.selectedTab);"/>
 #else
                             oncommand="BrowserUI.newTab('about:fennec', Browser.selectedTab);"/>
 #endif
                   </setting>
                   <setting id="prefs-uilanguage" title="&language.title;" type="menulist">
-                    <menulist id="prefs-languages" oncommand="PreferencesView.updateLocale();">
-                      <menupopup>
-                        <menuitem id="prefs-languages-auto" label="&language.auto;" value="auto"/>
-                      </menupopup>
-                    </menulist>
+                    <button id="prefs-uilanguage-button" label="&language.title;" onclick="PreferencesView.showLocalePicker();"/>
                   </setting>
                   <setting id="prefs-homepage" title="&homepage.title;" type="menulist">
                     <menulist id="prefs-homepage-options" oncommand="PreferencesView.updateHomePage();">
                       <menupopup onpopupshowing="PreferencesView.updateHomePageList();">
                         <menuitem id="prefs-homepage-default" label="&homepage.default;" value="default"/>
                         <menuitem id="prefs-homepage-none" label="&homepage.none;" value="none"/>
                         <menuitem id="prefs-homepage-currentpage" label="&homepage.currentpage;" value="currentpage"/>
                       </menupopup>
--- a/mobile/chrome/content/extensions.js
+++ b/mobile/chrome/content/extensions.js
@@ -922,17 +922,19 @@ AddonInstallListener.prototype = {
       needsRestart = true;
       mode = "normal";
     }
 
     // if we already have a mode, then we need to show a restart notification
     // otherwise, we are likely a bootstrapped addon
     if (needsRestart)
       ExtensionsView.showRestart(mode);
-    this._showInstallCompleteAlert(true, needsRestart);
+
+    if (aAddon.type != "locale")
+      this._showInstallCompleteAlert(true, needsRestart);
 
     // only do this if the view has already been inited
     if (!ExtensionsView._list)
       return;
 
     let element = ExtensionsView.getElementForAddon(aAddon.id);
     if (!element) {
       element = ExtensionsView._createLocalAddon(aAddon);
--- a/mobile/chrome/content/localePicker.js
+++ b/mobile/chrome/content/localePicker.js
@@ -28,34 +28,34 @@ let LocaleUI = {
       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 mainPage() {
+    delete this.mainPage;
+    return this.mainPage = document.getElementById("main-page");
   },
 
-  get _pickerPage() {
-    delete this._pickerPage;
-    return this._pickerPage = document.getElementById("picker-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 installerPage() {
+    delete this.installerPage;
+    return this.installerPage = document.getElementById("installer-page");
   },
 
-  get _deck() {
-    delete this._deck;
-    return this._deck = document.getElementById("language-deck");
+  get deck() {
+    delete this.deck;
+    return this.deck = document.getElementById("language-deck");
   },
 
   _availableLocales: null,
   get availableLocales() {
     if (!this._availableLocales) {
       let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
       chrome.QueryInterface(Ci.nsIToolkitChromeRegistry);
       let strings = Services.strings.createBundle("chrome://browser/content/languages.properties");
@@ -68,24 +68,24 @@ let LocaleUI = {
         try { label = strings.GetStringFromName(locale); }
         catch (e) { }
         this._availableLocales.push({ addon: { id: locale, name: label, targetLocale: locale }});
       }
     }
     return this._availableLocales;
   },
 
-  _currentInstall: null, // used to cancel an install
+  pendingInstall: null, // used to cancel an install
 
   get selectedPanel() {
-    return this._deck.selectedPanel;
+    return this.deck.selectedPanel;
   },
 
   set selectedPanel(aPanel) {
-    this._deck.selectedPanel = aPanel;
+    this.deck.selectedPanel = aPanel;
   },
 
   get list() {
     delete this.list;
     return this.list = document.getElementById("language-list");
   },
 
   _createItem: function(aId, aText, aLocale) {
@@ -135,26 +135,29 @@ let LocaleUI = {
   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.selectedPanel = LocaleUI.pickerpage;
     LocaleUI.loadLocales();
   },
 
   closePicker: function() {
-    if (this._currentInstall) {
+    if (this.pendingInstall) {
       Services.prefs.setBoolPref("intl.locale.matchOS", false);
-      Services.prefs.setCharPref("general.useragent.locale", getTargetLocale(this._currentInstall));
+      Services.prefs.setCharPref("general.useragent.locale", getTargetLocale(this.pendingInstall));
     }
-    this.selectedPanel = this._mainPage;
+    if (window.opener)
+      this.closeWindow();
+    else
+      this.selectedPanel = this.mainPage;
   },
 
   _locale: "",
 
   set locale(aVal) {
     if (aVal == this._locale)
       return;
 
@@ -166,89 +169,94 @@ let LocaleUI = {
     this.updateStrings();
   },
 
   get locale() {
     return this._locale;
   },
 
   set installStatus(aVal) {
-    this._installerPage.selectedPanel = document.getElementById("installer-page-" + aVal);
+    this.installerPage.selectedPanel = document.getElementById("installer-page-" + aVal);
   },
 
   clearInstallError: function() {
     this.installStatus = "installing";
-    this.selectedPanel = this._pickerPage;
+    this.selectedPanel = this.pickerpage;
   },
 
   selectLocale: function(aEvent) {
     let locale = this.list.selectedItem.locale;
     if (locale.install) {
       LocaleUI.strings = new FakeStringBundle(locale);
-      this.updateStrings();
+      this.updateStrings(locale);
     } else {
       this.locale = getTargetLocale(locale);
-      if (this._currentInstall)
-        this._currentInstall = null;
+      if (this.pendingInstall)
+        this.pendingInstall = null;
     }
   },
 
   installAddon: function() {
     let locale = LocaleUI.list.selectedItem.locale;
-    LocaleUI._currentInstall = locale;
 
     if (locale.install) {
-      LocaleUI.selectedPanel = LocaleUI._installerPage;
+      LocaleUI.pendingInstall = locale;
+      LocaleUI.selectedPanel = LocaleUI.installerPage;
       locale.install.addListener(installListener);
       locale.install.install();
     } else {
-      this.closePicker();
+      this.closeWindow();
     }
   },
 
   cancelPicker: function() {
-    if (this._currentInstall)
-      this._currentInstall = null;
+    if (this.pendingInstall)
+      this.pendingInstall = null;
     // restore the last known "good" locale
     this.locale = this.defaultLocale;
     this.updateStrings();
     this.closePicker();
   },
 
   closeWindow : function() {
     var buildID =  Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).platformBuildID;
     Services.prefs.setCharPref("extensions.compatability.locales.buildid", buildID);
+
     // Trying to close this window and open a new one results in a corrupt UI.
-    if (LocaleUI._currentInstall) {
+    if (!window.opener && LocaleUI.pendingInstall) {
       // a new locale was installed, restart the browser
       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);
+        return;
       }
-    } else {
-      // selected locale is already installed, just open the window
-      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();
     }
+
+    // just open the window
+    let argString = null;
+    if (window.arguments) {
+      argString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
+      argString.data = window.arguments.join(",");
+    }
+
+    if (!Services.wm.getMostRecentWindow("navigator:browser"))
+      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;
+    if (LocaleUI.pendingInstall) {
+      let addonInstall = LocaleUI.pendingInstall.install;
       try { addonInstall.cancel(); }
       catch(ex) { }
-      LocaleUI._currentInstall = null;
+      LocaleUI.pendingInstall = null;
 
       this.locale = this.defaultLocale;
     }
   },
 
   updateStrings: function (aAddon) {
     stringPrefs.forEach(function(aPref) {
       if (!aPref.element)
@@ -306,17 +314,17 @@ let installListener = {
     LocaleUI.showPicker();
   },
   onDownloadFailed: function(install) {
     LocaleUI.cancelInstall();
     LocaleUI.installStatus = "error";
   },
   onInstallStarted: function(install) { },
   onInstallEnded: function(install, addon) {
-    LocaleUI.locale = getTargetLocale(LocaleUI._currentInstall);
+    LocaleUI.locale = getTargetLocale(LocaleUI.pendingInstall);
     LocaleUI.closeWindow();
   },
   onInstallCancelled: function(install) {
     LocaleUI.cancelInstall();
     LocaleUI.showPicker();
   },
   onInstallFailed: function(install) {
     LocaleUI.cancelInstall();
@@ -339,35 +347,48 @@ function localesMatch(aLocale1, aLocale2
   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
-  LocaleUI._mainPage.setAttribute("mode", "loading");
+  LocaleUI.mainPage.setAttribute("mode", "loading");
   let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
   chrome.QueryInterface(Ci.nsIToolkitChromeRegistry);
   LocaleUI._locale = chrome.getSelectedLocale("browser");
   LocaleUI.updateStrings();
 
   // if we haven't gotten the list of available locales from AMO within 5 seconds, we give up
   // users can try downloading the list again by selecting "Choose another locale"
   let timeout = setTimeout(function() {
-    LocaleUI._mainPage.removeAttribute("mode");
+    LocaleUI.mainPage.removeAttribute("mode");
     timeout = null;
   }, 5000);
 
+  // update the page strings and show the correct page
+  LocaleUI.defaultLocale = LocaleUI._locale;
+  window.addEventListener("resize", resizeHandler, false);
+
+  // if we have an opener, we are probably coming from the prefs pane
+  // and can jump straight to the list of languages
+  if (window.opener) {
+    LocaleUI.updateStrings();
+    LocaleUI.showPicker();
+    resizeHandler();
+    return;
+  }
+
   // Look on AMO for something that matches the system locale
   LocaleRepository.getLocales(function lp_initalDownload(aLocales) {
-    if (!LocaleUI._mainPage.hasAttribute("mode")) return;
+    if (!LocaleUI.mainPage.hasAttribute("mode")) return;
 
     clearTimeout(timeout);
-    LocaleUI._mainPage.removeAttribute("mode");
+    LocaleUI.mainPage.removeAttribute("mode");
 
     let localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService);
     let currentLocale = localeService.getSystemLocale().getCategory("NSILOCALE_CTYPE");
     if (Services.prefs.prefHasUserValue("general.useragent.locale")) {
       currentLocale = Services.prefs.getCharPref("general.useragent.locale");
     }
 
     let match = NO_MATCH;
@@ -390,28 +411,24 @@ function start() {
         if (aAddon && aAddon.userDisabled) {
           Services.prefs.clearUserPref("general.useragent.locale");
           LocaleUI.closeWindow();
           return;
         }
         // if we found something, try to install it automatically
         LocaleUI.strings = new FakeStringBundle(matchingLocale.addon);
         LocaleUI.updateStrings();
-        LocaleUI._currentInstall = matchingLocale.addon;
+        LocaleUI.pendingInstall = matchingLocale.addon;
   
-        LocaleUI.selectedPanel = LocaleUI._installerPage;
+        LocaleUI.selectedPanel = LocaleUI.installerPage;
         matchingLocale.addon.install.addListener(installListener);
         matchingLocale.addon.install.install();
       });
     }
   });
-
-  // update the page strings and show the correct page
-  LocaleUI.defaultLocale = LocaleUI._locale;
-  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));
 }
 
--- a/mobile/chrome/content/preferences.js
+++ b/mobile/chrome/content/preferences.js
@@ -99,85 +99,58 @@ var PreferencesView = {
     this._msg = document.getElementById("prefs-messages");
     this._languages = document.getElementById("prefs-languages");
     this._loadLocales();
 
     this._loadHomePage();
 
     MasterPasswordUI.updatePreference();
     WeaveGlue.init();
+
+    Services.prefs.addObserver("general.useragent.locale", this, false);
+  },
+
+  observe: function(aSubject, aTopic, aData) {
+    if (aData == "general.useragent.locale") {
+      this.showRestart();
+      this._loadLocales();
+    }
   },
 
   _loadLocales: function _loadLocales() {
     // Query available and selected locales
     let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
     chrome.QueryInterface(Ci.nsIToolkitChromeRegistry);
 
-    let selectedLocale = chrome.getSelectedLocale("browser");
+    let selectedLocale = Services.prefs.getCharPref("general.useragent.locale");
     let availableLocales = chrome.getLocalesForPackage("browser");
 
     let strings = Services.strings.createBundle("chrome://browser/content/languages.properties");
 
     // Render locale menulist by iterating through the query result from getLocalesForPackage()
     let selectedItem = null;
-    let localeCount = 0;
+    let selectedLabel = selectedLocale;
     while (availableLocales.hasMore()) {
       let locale = availableLocales.getNext();
       try {
         var label = strings.GetStringFromName(locale);
       } catch (e) {
         label = locale;
       }
-      let item = this._languages.appendItem(label, locale);
       if (locale == selectedLocale) {
+        selectedLabel = label;
         this._currentLocale = locale;
-        selectedItem = item;
+        break;
       }
-      localeCount++;
-    }
-
-    // Are we using auto-detection?
-    let autoDetect = false;
-    try {
-      autoDetect = Services.prefs.getBoolPref("intl.locale.matchOS");
     }
-    catch (e) {}
-
-    // Highlight current locale (or auto-detect entry)
-    if (autoDetect) {
-      this._languages.selectedItem = document.getElementById("prefs-languages-auto");
-      this._currentLocale = "auto";
-    } else {
-      this._languages.selectedItem = selectedItem;
-    }
-
-    // Hide the setting if we only have one locale
-    if (localeCount == 1)
-      document.getElementById("prefs-uilanguage").hidden = true;
+    document.getElementById("prefs-uilanguage-button").setAttribute("label", selectedLabel);
   },
 
-  updateLocale: function updateLocale() {
-    // Which locale did the user select?
-    let newLocale = this._languages.selectedItem.value;
-    let prefs = Services.prefs;
-
-    if (newLocale == "auto") {
-      if (prefs.prefHasUserValue("general.useragent.locale"))
-        prefs.clearUserPref("general.useragent.locale");
-      prefs.setBoolPref("intl.locale.matchOS", true);
-    } else {
-      prefs.setBoolPref("intl.locale.matchOS", false);
-      prefs.setCharPref("general.useragent.locale", newLocale);
-    }
-
-    // Show the restart notification, if needed
-    if (this._currentLocale == newLocale)
-      this.hideRestart();
-    else
-      this.showRestart();
+  showLocalePicker: function showLocalePicker() {
+    Services.ww.openWindow(window, "chrome://browser/content/localePicker.xul", "_browser", "chrome,dialog=no,all", null);
   },
 
   _showHomePageHint: function _showHomePageHint(aHint) {
     if (aHint)
       document.getElementById("prefs-homepage").setAttribute("desc", aHint);
     else
       document.getElementById("prefs-homepage").removeAttribute("desc");
   },
--- a/mobile/components/BrowserCLH.js
+++ b/mobile/components/BrowserCLH.js
@@ -122,17 +122,17 @@ function haveSystemLocale() {
   let localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService);
   let systemLocale = localeService.getSystemLocale().getCategory("NSILOCALE_CTYPE");
   return isLocaleAvailable(systemLocale);
 }
 
 function checkCurrentLocale() {
   if (Services.prefs.prefHasUserValue("general.useragent.locale")) {
     // if the user has a compatible locale from a different buildid, we need to update
-    var buildID = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).appBuildID;
+    var buildID = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).platformBuildID;
     let localeBuildID = Services.prefs.getCharPref("extensions.compatability.locales.buildid");
     if (buildID != localeBuildID)
       return false;
 
     let currentLocale = Services.prefs.getCharPref("general.useragent.locale");
     return isLocaleAvailable(currentLocale);
   }
   return true;