Bug 1385416 - Remove Locale.jsm. r=kmag draft
authorZibi Braniecki <zbraniecki@mozilla.com>
Fri, 28 Jul 2017 13:30:51 -0700
changeset 620790 cfd14d21487070a5fa6583796e3f97f62d836f33
parent 620494 fa1da3c0b200abbd9cfab3cab19962824314044e
child 640815 43c1ea946cb79c30713ef44930bf1dbd6b92aed4
push id72162
push userbmo:gandalf@aviary.pl
push dateThu, 03 Aug 2017 23:31:19 +0000
reviewerskmag
bugs1385416
milestone57.0a1
Bug 1385416 - Remove Locale.jsm. r=kmag MozReview-Commit-ID: IeSJKWuIQ2c
toolkit/modules/Locale.jsm
toolkit/modules/moz.build
toolkit/mozapps/extensions/internal/XPIInstall.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
deleted file mode 100644
--- a/toolkit/modules/Locale.jsm
+++ /dev/null
@@ -1,81 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-this.EXPORTED_SYMBOLS = ["Locale"];
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-this.Locale = {
-  /**
-   * Gets the currently selected locale for display.
-   * @return  the selected locale or "en-US" if none is selected
-   */
-  getLocale() {
-    return Services.locale.getRequestedLocale() || "en-US";
-  },
-
-  /**
-   * Selects the closest matching locale from a list of locales.
-   *
-   * @param  aLocales
-   *         An array of locales
-   * @return the best match for the currently selected locale
-   */
-  findClosestLocale(aLocales) {
-    let appLocale = this.getLocale();
-
-    // Holds the best matching localized resource
-    var bestmatch = null;
-    // The number of locale parts it matched with
-    var bestmatchcount = 0;
-    // The number of locale parts in the match
-    var bestpartcount = 0;
-
-    var matchLocales = [appLocale.toLowerCase()];
-    /* If the current locale is English then it will find a match if there is
-       a valid match for en-US so no point searching that locale too. */
-    if (matchLocales[0].substring(0, 3) != "en-")
-      matchLocales.push("en-us");
-
-    for (let locale of matchLocales) {
-      var lparts = locale.split("-");
-      for (let localized of aLocales) {
-        for (let found of localized.locales) {
-          found = found.toLowerCase();
-          // Exact match is returned immediately
-          if (locale == found)
-            return localized;
-
-          var fparts = found.split("-");
-          /* If we have found a possible match and this one isn't any longer
-             then we dont need to check further. */
-          if (bestmatch && fparts.length < bestmatchcount)
-            continue;
-
-          // Count the number of parts that match
-          var maxmatchcount = Math.min(fparts.length, lparts.length);
-          var matchcount = 0;
-          while (matchcount < maxmatchcount &&
-                 fparts[matchcount] == lparts[matchcount])
-            matchcount++;
-
-          /* If we matched more than the last best match or matched the same and
-             this locale is less specific than the last best match. */
-          if (matchcount > bestmatchcount ||
-              (matchcount == bestmatchcount && fparts.length < bestpartcount)) {
-            bestmatch = localized;
-            bestmatchcount = matchcount;
-            bestpartcount = fparts.length;
-          }
-        }
-      }
-      // If we found a valid match for this locale return it
-      if (bestmatch)
-        return bestmatch;
-    }
-    return null;
-  },
-};
--- a/toolkit/modules/moz.build
+++ b/toolkit/modules/moz.build
@@ -89,19 +89,16 @@ with Files('JSONFile.jsm'):
     BUG_COMPONENT = ('Toolkit', 'Form Manager')
 
 with Files('LightweightThemeConsumer.jsm'):
     BUG_COMPONENT = ('Firefox', 'Toolbars and Customization')
 
 with Files('LoadContextInfo.jsm'):
     BUG_COMPONENT = ('Core', 'Networking: Cache')
 
-with Files('Locale.jsm'):
-    BUG_COMPONENT = ('Core', 'Internationalization')
-
 with Files('Memory.jsm'):
     BUG_COMPONENT = ('Core', 'DOM: Content Processes')
 
 with Files('NLP.jsm'):
     BUG_COMPONENT = ('Toolkit', 'Find Toolbar')
 
 with Files('NewTabUtils.jsm'):
     BUG_COMPONENT = ('Firefox', 'Tabbed Browser')
@@ -202,17 +199,16 @@ EXTRA_JS_MODULES += [
     'HiddenFrame.jsm',
     'Http.jsm',
     'IndexedDB.jsm',
     'InlineSpellChecker.jsm',
     'InlineSpellCheckerContent.jsm',
     'Integration.jsm',
     'JSONFile.jsm',
     'LoadContextInfo.jsm',
-    'Locale.jsm',
     'Log.jsm',
     'Memory.jsm',
     'NewTabUtils.jsm',
     'NLP.jsm',
     'ObjectUtils.jsm',
     'PageMenu.jsm',
     'PageMetadata.jsm',
     'PermissionsUtils.jsm',
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -31,18 +31,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
                                   "resource://gre/modules/AppConstants.jsm");
 XPCOMUtils.defineLazyGetter(this, "CertUtils",
                             () => Cu.import("resource://gre/modules/CertUtils.jsm", {}));
 XPCOMUtils.defineLazyModuleGetter(this, "ChromeManifestParser",
                                   "resource://gre/modules/ChromeManifestParser.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionData",
                                   "resource://gre/modules/Extension.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Locale",
-                                  "resource://gre/modules/Locale.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyGetter(this, "IconDetails", () => {
   return Cu.import("resource://gre/modules/ExtensionParent.jsm", {}).ExtensionParent.IconDetails;
 });
 XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
                                   "resource://gre/modules/LightweightThemeManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -22,18 +22,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonSettings",
                                   "resource://gre/modules/addons/AddonSettings.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
                                   "resource://gre/modules/AppConstants.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ChromeManifestParser",
                                   "resource://gre/modules/ChromeManifestParser.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
                                   "resource://gre/modules/LightweightThemeManager.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Locale",
-                                  "resource://gre/modules/Locale.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ZipUtils",
                                   "resource://gre/modules/ZipUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PermissionsUtils",
                                   "resource://gre/modules/PermissionsUtils.jsm");
@@ -4806,18 +4804,59 @@ AddonInternal.prototype = {
    *   add-ons is not installed and enabled.
    */
   dependencies: Object.freeze([]),
   hasEmbeddedWebExtension: false,
 
   get selectedLocale() {
     if (this._selectedLocale)
       return this._selectedLocale;
-    let locale = Locale.findClosestLocale(this.locales);
-    this._selectedLocale = locale ? locale : this.defaultLocale;
+
+    /**
+     * this.locales is a list of objects that have property `locales`.
+     * It's value is an array of locale codes.
+     *
+     * First, we reduce this nested structure to a flat list of locale codes.
+     */
+    const locales = [].concat(...this.locales.map(loc => loc.locales));
+
+    let requestedLocales = Services.locale.getRequestedLocales();
+
+    /**
+     * If en is not the top locale, add "en-US" to the list.
+     */
+    if (!requestedLocales[0].startsWith("en")) {
+      requestedLocales.push("en-US");
+    }
+
+    /**
+     * Then we negotiate best locale code matching the app locales.
+     */
+    let bestLocale = Services.locale.negotiateLanguages(
+      requestedLocales,
+      locales,
+      "und",
+      Services.locale.langNegStrategyLookup
+    )[0];
+
+    /**
+     * If no match has been found, we'll assign the default locale as
+     * the selected one.
+     */
+    if (bestLocale === "und") {
+      this._selectedLocale = this.defaultLocale;
+    } else {
+      /**
+       * Otherwise, we'll go through all locale entries looking for the one
+       * that has the best match in it's locales list.
+       */
+      this._selectedLocale = this.locales.find(loc =>
+        loc.locales.includes(bestLocale));
+    }
+
     return this._selectedLocale;
   },
 
   get providesUpdatesSecurely() {
     return !!(this.updateKey || !this.updateURL ||
               this.updateURL.substring(0, 6) == "https:");
   },