Bug 1457021 - Migrate the JS of Preferences::Languages to Fluent. r=flod,Gijs
authorZibi Braniecki <zbraniecki@mozilla.com>
Wed, 25 Apr 2018 15:46:50 -0700
changeset 417605 4332073c7382
parent 417604 8f74f964537d
child 417606 4d66223323b4
push id33974
push userncsoregi@mozilla.com
push dateThu, 10 May 2018 09:47:43 +0000
treeherdermozilla-central@b52b2eb81d1e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflod, Gijs
bugs1457021
milestone62.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 1457021 - Migrate the JS of Preferences::Languages to Fluent. r=flod,Gijs MozReview-Commit-ID: 6RTJGkrhoWY
browser/components/preferences/languages.js
browser/components/preferences/languages.xul
browser/locales/en-US/browser/preferences/languages.ftl
browser/locales/en-US/chrome/browser/preferences/preferences.properties
--- a/browser/components/preferences/languages.js
+++ b/browser/components/preferences/languages.js
@@ -46,21 +46,20 @@ var gLanguagesDialog = {
 
   _loadAvailableLanguages() {
     // This is a parser for: resource://gre/res/language.properties
     // The file is formatted like so:
     // ab[-cd].accept=true|false
     //  ab = language
     //  cd = region
     var bundleAccepted    = document.getElementById("bundleAccepted");
-    var bundlePreferences = document.getElementById("bundlePreferences");
 
-    function LanguageInfo(aName, aABCD, aIsVisible) {
-      this.name = aName;
-      this.abcd = aABCD;
+    function LocaleInfo(aLocaleName, aLocaleCode, aIsVisible) {
+      this.name = aLocaleName;
+      this.code = aLocaleCode;
       this.isVisible = aIsVisible;
     }
 
     // 1) Read the available languages out of language.properties
     var strings = bundleAccepted.strings;
 
     let localeCodes = [];
     let localeValues = [];
@@ -77,68 +76,87 @@ var gLanguagesDialog = {
     }
 
     let localeNames = Services.intl.getLocaleDisplayNames(undefined, localeCodes);
 
     for (let i in localeCodes) {
       let isVisible = localeValues[i] == "true" &&
         (!(localeCodes[i] in this._acceptLanguages) || !this._acceptLanguages[localeCodes[i]]);
 
-      let name = bundlePreferences.getFormattedString("languageCodeFormat",
-        [localeNames[i], localeCodes[i]]);
-      let li = new LanguageInfo(name, localeCodes[i], isVisible);
+      let li = new LocaleInfo(localeNames[i], localeCodes[i], isVisible);
       this._availableLanguagesList.push(li);
     }
 
     this._buildAvailableLanguageList();
   },
 
-  _buildAvailableLanguageList() {
+  async _buildAvailableLanguageList() {
     var availableLanguagesPopup = document.getElementById("availableLanguagesPopup");
     while (availableLanguagesPopup.hasChildNodes())
       availableLanguagesPopup.firstChild.remove();
 
-    // Sort the list of languages by name
-    this._availableLanguagesList.sort(function(a, b) {
-                                        return a.name.localeCompare(b.name);
-                                      });
+    let frag = document.createDocumentFragment();
 
     // Load the UI with the data
     for (var i = 0; i < this._availableLanguagesList.length; ++i) {
-      var abCD = this._availableLanguagesList[i].abcd;
-      if (this._availableLanguagesList[i].isVisible &&
-          (!(abCD in this._acceptLanguages) || !this._acceptLanguages[abCD])) {
+      let locale = this._availableLanguagesList[i];
+      let localeCode = locale.code;
+      if (locale.isVisible &&
+          (!(localeCode in this._acceptLanguages) || !this._acceptLanguages[localeCode])) {
         var menuitem = document.createElement("menuitem");
-        menuitem.id = this._availableLanguagesList[i].abcd;
-        availableLanguagesPopup.appendChild(menuitem);
-        menuitem.setAttribute("label", this._availableLanguagesList[i].name);
+        menuitem.id = localeCode;
+        document.l10n.setAttributes(menuitem, "languages-code-format", {
+          locale: locale.name,
+          code: localeCode,
+        });
+        frag.appendChild(menuitem);
       }
     }
+
+    await document.l10n.translateFragment(frag);
+
+    // Sort the list of languages by name
+    let comp = new Services.intl.Collator(undefined, {
+      usage: "sort"
+    });
+
+    let items = Array.from(frag.children);
+
+    items.sort((a, b) => {
+      return comp.compare(a.getAttribute("label"), b.getAttribute("label"));
+    });
+
+    // Re-append items in the correct order:
+    items.forEach(item => frag.appendChild(item));
+
+    availableLanguagesPopup.appendChild(frag);
+
     this._availableLanguages.setAttribute("label", this._availableLanguages.getAttribute("placeholder"));
   },
 
   readAcceptLanguages() {
     while (this._activeLanguages.hasChildNodes())
       this._activeLanguages.firstChild.remove();
 
     var selectedIndex = 0;
     var preference = Preferences.get("intl.accept_languages");
     if (preference.value == "")
       return undefined;
     var languages = preference.value.toLowerCase().split(/\s*,\s*/);
     for (var i = 0; i < languages.length; ++i) {
-      var name = this._getLanguageName(languages[i]);
-      if (!name)
-        name = "[" + languages[i] + "]";
       var listitem = document.createElement("listitem");
       listitem.id = languages[i];
       if (languages[i] == this._selectedItemID)
         selectedIndex = i;
       this._activeLanguages.appendChild(listitem);
-      listitem.setAttribute("label", name);
+      var localeName = this._getLocaleName(languages[i]);
+      document.l10n.setAttributes(listitem, "languages-code-format", {
+        locale: localeName,
+        code: languages[i],
+      });
 
       // Hash this language as an "Active" language so we don't
       // show it in the list that can be added.
       this._acceptLanguages[languages[i]] = true;
     }
 
     if (this._activeLanguages.childNodes.length > 0) {
       this._activeLanguages.ensureIndexIsVisible(selectedIndex);
@@ -212,21 +230,21 @@ var gLanguagesDialog = {
 
     // Update the preference and force a UI rebuild
     var preference = Preferences.get("intl.accept_languages");
     preference.value = string;
 
     this._buildAvailableLanguageList();
   },
 
-  _getLanguageName(aABCD) {
+  _getLocaleName(localeCode) {
     if (!this._availableLanguagesList.length)
       this._loadAvailableLanguages();
     for (var i = 0; i < this._availableLanguagesList.length; ++i) {
-      if (aABCD == this._availableLanguagesList[i].abcd)
+      if (localeCode == this._availableLanguagesList[i].code)
         return this._availableLanguagesList[i].name;
     }
     return "";
   },
 
   moveUp() {
     var selectedItem = this._activeLanguages.selectedItems[0];
     var previousItem = selectedItem.previousSibling;
--- a/browser/components/preferences/languages.xul
+++ b/browser/components/preferences/languages.xul
@@ -28,17 +28,16 @@
 
   <keyset>
     <key data-l10n-id="languages-close-key" modifiers="accel" oncommand="Preferences.close(event)"/>
   </keyset>
 
   <vbox id="LanguagesDialogPane" class="prefpane largeDialogContainer">
 
     <stringbundleset id="languageSet">
-      <stringbundle id="bundlePreferences"  src="chrome://browser/locale/preferences/preferences.properties"/>
       <stringbundle id="bundleAccepted"     src="resource://gre/res/language.properties"/>
     </stringbundleset>
 
     <description data-l10n-id="languages-description"/>
     <checkbox id="spoofEnglish"
               data-l10n-id="languages-customize-spoof-english"
               preference="privacy.spoof_english"
               onsyncfrompreference="return gLanguagesDialog.readSpoofEnglish();"
--- a/browser/locales/en-US/browser/preferences/languages.ftl
+++ b/browser/locales/en-US/browser/preferences/languages.ftl
@@ -27,8 +27,21 @@ languages-customize-remove =
     .accesskey = R
 
 languages-customize-select-language =
     .placeholder = Select a language to add…
 
 languages-customize-add =
     .label = Add
     .accesskey = A
+
+# The pattern used to generate strings presented to the user in the
+# locale selection list.
+#
+# Example:
+#   Icelandic [is]
+#   Spanish (Chile) [es-CL]
+#
+# Variables:
+#   $locale (String) - A name of the locale (for example: "Icelandic", "Spanish (Chile)")
+#   $code (String) - Locale code of the locale (for example: "is", "es-CL")
+languages-code-format =
+    .label = { $locale } [{ $code }]
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -9,25 +9,16 @@
 #                    check-every-page-as-I-load-it phishing protection).
 phishBeforeText=Selecting this option will send the address of web pages you are viewing to %S. To continue, please review and accept the following terms of service.
 
 #### Master Password
 
 pw_change2empty_in_fips_mode=You are currently in FIPS mode. FIPS requires a non-empty Master Password.
 pw_change_failed_title=Password Change Failed
 
-#### Fonts
-
-# LOCALIZATION NOTE: The string represents a localized locale name
-#   followed by the BCP47 locale code.
-#
-# Example: "French (Canada)  [fr-ca]"
-#   %1$S = locale name, %2$S = locale code
-languageCodeFormat=%1$S  [%2$S]
-
 #### Downloads
 
 desktopFolderName=Desktop
 downloadsFolderName=Downloads
 chooseDownloadFolderTitle=Choose Download Folder:
 
 #### Applications