Bug 1457021 - Migrate the JS of Preferences::Languages to Fluent. r?gijs,flod draft
authorZibi Braniecki <zbraniecki@mozilla.com>
Wed, 25 Apr 2018 15:46:50 -0700
changeset 793211 f3464739227bca34277ff128a53d4b1d6ef82e48
parent 793210 18799588dae9012bdaa420a2fa7c76d2ed07ae8d
child 793212 b78569950e09025d2b6ef95ea144773ac9314fe1
push id109319
push userbmo:gandalf@aviary.pl
push dateWed, 09 May 2018 19:05:09 +0000
reviewersgijs, flod
bugs1457021
milestone62.0a1
Bug 1457021 - Migrate the JS of Preferences::Languages to Fluent. r?gijs,flod 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