Bug 1447189 - Support BCP47 private use subtags in MozLocale. r=jfkthame

MozReview-Commit-ID: LJSb3vTENR5

--HG--
extra : rebase_source : ec7023f3722b1d925a5b3684852331e5a8e7796f
This commit is contained in:
Zibi Braniecki 2018-03-22 15:19:15 -07:00
parent d8f53e0f08
commit c1d66520bf
4 changed files with 61 additions and 6 deletions

View File

@ -49,13 +49,24 @@ Locale::Locale(const nsACString& aLocale)
* ["-" script] 4ALPHA
* ["-" region] 2ALPHA
* *("-" variant) 3*8alphanum
* ["-"] privateuse] "x" 1*("-" (1*8alphanum))
*
* The `position` variable represents the currently expected section of the tag
* and intentionally skips positions (like `extlang`) which may be added later.
*
* language-extlangs-script-region-variant-extension-privateuse
* --- 0 -- --- 1 -- -- 2 - -- 3 - -- 4 -- --- x --- ---- 6 ---
*/
for (const nsACString& subTag : normLocale.Split('-')) {
auto slen = subTag.Length();
if (position == 0) {
if (slen > 8) {
mIsValid = false;
return;
} else if (position == 6) {
mPrivateUse.AppendElement(subTag);
} else if (subTag.LowerCaseEqualsLiteral("x")) {
position = 6;
} else if (position == 0) {
if (slen < 2 || slen > 3) {
mIsValid = false;
return;
@ -111,6 +122,19 @@ Locale::AsString() const
tag.AppendLiteral("-");
tag.Append(variant);
}
if (!mPrivateUse.IsEmpty()) {
if (tag.IsEmpty()) {
tag.AppendLiteral("x");
} else {
tag.AppendLiteral("-x");
}
for (const auto& subTag : mPrivateUse) {
tag.AppendLiteral("-");
tag.Append(subTag);
}
}
return tag;
}

View File

@ -85,7 +85,8 @@ class Locale {
mLanguage.Equals(aOther.mLanguage) &&
mScript.Equals(aOther.mScript) &&
mRegion.Equals(aOther.mRegion) &&
mVariants == aOther.mVariants;
mVariants == aOther.mVariants &&
mPrivateUse == aOther.mPrivateUse;
}
private:
@ -93,6 +94,7 @@ class Locale {
nsAutoCStringN<4> mScript;
nsAutoCStringN<2> mRegion;
nsTArray<nsCString> mVariants;
nsTArray<nsCString> mPrivateUse;
bool mIsValid = true;
};

View File

@ -5,6 +5,7 @@
#include "gtest/gtest.h"
#include "mozilla/intl/LocaleService.h"
#include "mozilla/intl/MozLocale.h"
#include "mozilla/Services.h"
#include "nsIToolkitChromeRegistry.h"
@ -73,11 +74,11 @@ TEST(Intl_Locale_LocaleService, GetPackagedLocales) {
}
TEST(Intl_Locale_LocaleService, GetDefaultLocale) {
nsAutoCString locale;
LocaleService::GetInstance()->GetDefaultLocale(locale);
nsAutoCString locStr;
LocaleService::GetInstance()->GetDefaultLocale(locStr);
int32_t len = locale.Length();
ASSERT_TRUE(len > 0);
ASSERT_FALSE(locStr.IsEmpty());
ASSERT_TRUE(Locale(locStr).IsValid());
}
TEST(Intl_Locale_LocaleService, IsAppLocaleRTL) {

View File

@ -62,3 +62,31 @@ TEST(Intl_Locale_Locale, MatchesRange) {
ASSERT_FALSE(loc.Matches(loc3, false, false));
ASSERT_TRUE(loc.Matches(loc3, true, true));
}
TEST(Intl_Locale_Locale, PrivateUse) {
Locale loc = Locale("x-test");
ASSERT_TRUE(loc.IsValid());
ASSERT_TRUE(loc.GetLanguage().Equals(""));
ASSERT_TRUE(loc.GetScript().Equals(""));
ASSERT_TRUE(loc.GetRegion().Equals(""));
ASSERT_TRUE(loc.GetVariants().Length() == 0);
ASSERT_TRUE(loc.AsString().Equals("x-test"));
Locale loc2 = Locale("fr-x-test");
ASSERT_TRUE(loc2.IsValid());
ASSERT_TRUE(loc2.GetLanguage().Equals("fr"));
ASSERT_TRUE(loc2.GetScript().Equals(""));
ASSERT_TRUE(loc2.GetRegion().Equals(""));
ASSERT_TRUE(loc2.GetVariants().Length() == 0);
ASSERT_TRUE(loc2.AsString().Equals("fr-x-test"));
// Make sure that we preserve private use tags order.
Locale loc3 = Locale("fr-x-foo-bar-baz");
ASSERT_TRUE(loc3.IsValid());
ASSERT_TRUE(loc3.AsString().Equals("fr-x-foo-bar-baz"));
}