gecko-dev/toolkit/modules/Locale.jsm
2015-08-03 10:41:24 -07:00

94 lines
3.2 KiB
JavaScript

/* 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");
Cu.import("resource://gre/modules/Preferences.jsm");
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
const PREF_SELECTED_LOCALE = "general.useragent.locale";
this.Locale = {
/**
* Gets the currently selected locale for display.
* @return the selected locale or "en-US" if none is selected
*/
getLocale() {
if (Preferences.get(PREF_MATCH_OS_LOCALE, false))
return Services.locale.getLocaleComponentForUserAgent();
try {
let locale = Preferences.get(PREF_SELECTED_LOCALE, null, Ci.nsIPrefLocalizedString);
if (locale)
return locale;
}
catch (e) {}
return Preferences.get(PREF_SELECTED_LOCALE, "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;
},
};