Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 3 part locale does not fallback to 2 part locale #465

Merged
merged 2 commits into from
Aug 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 72 additions & 8 deletions app/assets/javascripts/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,6 @@
I18n.locales["default"] = function(locale) {
var locales = []
, list = []
, countryCode
, count
;

// Handle the inline locale option that can be provided to
Expand All @@ -266,19 +264,85 @@
locales.push(I18n.defaultLocale);
}

// Locale code format 1:
// According to RFC4646 (http://www.ietf.org/rfc/rfc4646.txt)
// language codes for Traditional Chinese should be `zh-Hant`
//
// But due to backward compatibility
// We use older version of IETF language tag
// @see http://www.w3.org/TR/html401/struct/dirlang.html
// @see http://en.wikipedia.org/wiki/IETF_language_tag
//
// Format: `language-code = primary-code ( "-" subcode )*`
//
// primary-code uses ISO639-1
// @see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
// @see http://www.iso.org/iso/home/standards/language_codes.htm
//
// subcode uses ISO 3166-1 alpha-2
// @see http://en.wikipedia.org/wiki/ISO_3166
// @see http://www.iso.org/iso/country_codes.htm
//
// @note
// subcode can be in upper case or lower case
// defining it in upper case is a convention only


// Locale code format 2:
// Format: `code = primary-code ( "-" region-code )*`
// primary-code uses ISO 639-1
// script-code uses ISO 15924
// region-code uses ISO 3166-1 alpha-2
// Example: zh-Hant-TW, en-HK, zh-Hant-CN
//
// It is similar to RFC4646 (or actually the same),
// but seems to be limited to language, script, region

// Compute each locale with its country code.
// So this will return an array containing both
// `de-DE` and `de` locales.
// So this will return an array containing
// `de-DE` and `de`
// or
// `zh-hans-tw`, `zh-hans`, `zh`
// locales.
locales.forEach(function(locale) {
countryCode = locale.split("-")[0];
var localeParts = locale.split("-");
var firstFallback = null;
var secondFallback = null;
if (localeParts.length === 3) {
firstFallback = localeParts[0];
secondFallback = [
localeParts[0],
localeParts[1]
].join("-");
}
else if (localeParts.length === 2) {
firstFallback = localeParts[0];
}

if (!~list.indexOf(locale)) {
if (list.indexOf(locale) === -1) {
list.push(locale);
}

if (I18n.fallbacks && countryCode && countryCode !== locale && !~list.indexOf(countryCode)) {
list.push(countryCode);
if (! I18n.fallbacks) {
return;
}

[
firstFallback,
secondFallback
].forEach(function(nullableFallbackLocale) {
// We don't want null values
if (typeof nullableFallbackLocale === "undefined") { return; }
if (nullableFallbackLocale === null) { return; }
// We don't want duplicate values
//
// Comparing with `locale` first is faster than
// checking whether value's presence in the list
if (nullableFallbackLocale === locale) { return; }
if (list.indexOf(nullableFallbackLocale) !== -1) { return; }

list.push(nullableFallbackLocale);
});
});

// No locales set? English it is.
Expand Down
17 changes: 16 additions & 1 deletion spec/js/translate.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe("Translate", function(){
expect(I18n.t("hello", {locale: "pt-BR"})).toEqual("Olá Mundo!");
});

it("fallbacks to the default locale when I18n.fallbackss is enabled", function(){
it("fallbacks to the default locale when I18n.fallbacks is enabled", function(){
I18n.locale = "pt-BR";
I18n.fallbacks = true;
expect(I18n.t("greetings.stranger")).toEqual("Hello stranger!");
Expand All @@ -83,6 +83,21 @@ describe("Translate", function(){
expect(I18n.t("hello")).toEqual("Hallo Welt!");
});

describe("when a 3-part locale is used", function(){
beforeEach(function(){
I18n.locale = "zh-Hant-TW";
I18n.fallbacks = true;
});

it("fallbacks to 2-part locale when absent", function(){
expect(I18n.t("cat")).toEqual("貓");
});

it("fallbacks to 1-part locale when 2-part missing requested translation", function(){
expect(I18n.t("dog")).toEqual("狗");
});
});

it("fallbacks using custom rules (function)", function(){
I18n.locale = "no";
I18n.fallbacks = true;
Expand Down
8 changes: 8 additions & 0 deletions spec/js/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ var DEBUG = false;
hello: "Hei Verden!"
};

Translations["zh-Hant"] = {
cat: "貓"
};

Translations["zh"] = {
dog: "狗"
};

return Translations;
};

Expand Down