Skip to content

Instantly share code, notes, and snippets.

@lanterndev
Created December 18, 2013 01:39
Show Gist options
  • Save lanterndev/8015981 to your computer and use it in GitHub Desktop.
Save lanterndev/8015981 to your computer and use it in GitHub Desktop.
/**
* Translated from: https://github.com/mitsuhiko/babel/blob/e224a7b/babel/core.py
* License: https://github.com/mitsuhiko/babel/blob/e224a7b/LICENSE
*/
var LOCALE_ALIASES = {
'ar': 'ar_SY', 'bg': 'bg_BG', 'bs': 'bs_BA', 'ca': 'ca_ES', 'cs': 'cs_CZ',
'da': 'da_DK', 'de': 'de_DE', 'el': 'el_GR', 'en': 'en_US', 'es': 'es_ES',
'et': 'et_EE', 'fa': 'fa_IR', 'fi': 'fi_FI', 'fr': 'fr_FR', 'gl': 'gl_ES',
'he': 'he_IL', 'hu': 'hu_HU', 'id': 'id_ID', 'is': 'is_IS', 'it': 'it_IT',
'ja': 'ja_JP', 'km': 'km_KH', 'ko': 'ko_KR', 'lt': 'lt_LT', 'lv': 'lv_LV',
'mk': 'mk_MK', 'nl': 'nl_NL', 'nn': 'nn_NO', 'no': 'nb_NO', 'pl': 'pl_PL',
'pt': 'pt_PT', 'ro': 'ro_RO', 'ru': 'ru_RU', 'sk': 'sk_SK', 'sl': 'sl_SI',
'sv': 'sv_SE', 'th': 'th_TH', 'tr': 'tr_TR', 'uk': 'uk_UA'
};
/**
* Find the best match between available and requested locale strings.
*
* >>> negotiate_locale(['de_DE', 'en_US'], ['de_DE', 'de_AT'])
* 'de_DE'
* >>> negotiate_locale(['de_DE', 'en_US'], ['en', 'de'])
* 'de'
*
* Case is ignored by the algorithm, the result uses the case of the preferred
* locale identifier:
*
* >>> negotiate_locale(['de_DE', 'en_US'], ['de_de', 'de_at'])
* 'de_DE'
*
* >>> negotiate_locale(['de_DE', 'en_US'], ['de_de', 'de_at'])
* 'de_DE'
*
* By default, some web browsers unfortunately do not include the territory
* in the locale identifier for many locales, and some don't even allow the
* user to easily add the territory. So while you may prefer using qualified
* locale identifiers in your web-application, they would not normally match
* the language-only locale sent by such browsers. To workaround that, this
* function uses a default mapping of commonly used langauge-only locale
* identifiers to identifiers including the territory:
*
* >>> negotiate_locale(['ja', 'en_US'], ['ja_JP', 'en_US'])
* 'ja_JP'
*
* Some browsers even use an incorrect or outdated language code, such as "no"
* for Norwegian, where the correct locale identifier would actually be "nb_NO"
* (Bokmål) or "nn_NO" (Nynorsk). The aliases are intended to take care of
* such cases, too:
*
* >>> negotiate_locale(['no', 'sv'], ['nb_NO', 'sv_SE'])
* 'nb_NO'
*
* You can override this default mapping by passing a different `aliases`
* mapping to this function, or you can bypass the behavior althogher by
* setting the `aliases` parameter to something falsey.
*
* :param preferred: the list of locale strings preferred by the user
* :param available: the list of locale strings available
* :param sep: character that separates the different parts of the locale
* strings
* :param aliases: a mapping of aliases for locale identifiers
*/
function negotiate_locale(preferred, available, sep, aliases) {
sep = sep || '_';
aliases = aliases || LOCALE_ALIASES;
var avail = [];
for (var i=0, n=available.length; i<n; i++) {
if (available[i]) {
avail.push(angular.lowercase(available[i]));
}
}
for (var i=0, n=preferred.length; i<n; i++) {
var locale = preferred[i],
ll = angular.lowercase(locale);
if (avail.indexOf(ll) > -1) {
return locale;
}
if (aliases) {
if (ll in aliases) {
var alias = aliases[ll].replace('_', sep);
if (avail.indexOf(angular.lowercase(alias)) > -1) {
return alias;
}
}
}
var parts = locale.split(sep);
if (parts.length > 1 && avail.indexOf(angular.lowercase(parts[0])) > -1) {
return parts[0];
}
}
}
@lanterndev
Copy link
Author

Just noticed that 'ar' -> 'ar_AR' mapping looked funny to me and left a comment about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment