Bug 1312053 - Expose an API to get locale information. r=Waldo

MozReview-Commit-ID: LivVJzrb3X1

--HG--
extra : rebase_source : a8c566cf918f01216e9f22e953da935ce41b7654
This commit is contained in:
Zibi Braniecki 2017-02-17 20:06:43 -08:00
Родитель 7fc9ef1cd2
Коммит 27ba812587
11 изменённых файлов: 128 добавлений и 0 удалений

Просмотреть файл

@ -88,6 +88,7 @@ included_inclnames_to_ignore = set([
'unicode/udat.h', # ICU
'unicode/udatpg.h', # ICU
'unicode/uenum.h', # ICU
'unicode/uloc.h', # ICU
'unicode/unorm2.h', # ICU
'unicode/unum.h', # ICU
'unicode/unumsys.h', # ICU

Просмотреть файл

@ -33,6 +33,7 @@
#include "unicode/udat.h"
#include "unicode/udatpg.h"
#include "unicode/uenum.h"
#include "unicode/uloc.h"
#include "unicode/unum.h"
#include "unicode/unumsys.h"
#include "unicode/upluralrules.h"
@ -167,6 +168,12 @@ uloc_countAvailable()
MOZ_CRASH("uloc_countAvailable: Intl API disabled");
}
UBool
uloc_isRightToLeft(const char* locale)
{
MOZ_CRASH("uloc_isRightToLeft: Intl API disabled");
}
struct UFormattable;
void
@ -4173,6 +4180,34 @@ js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp)
return true;
}
bool
js::intl_GetLocaleInfo(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 1);
JSAutoByteString locale(cx, args[0].toString());
if (!locale)
return false;
RootedObject info(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!info)
return false;
if (!DefineProperty(cx, info, cx->names().locale, args[0]))
return false;
bool rtl = uloc_isRightToLeft(icuLocale(locale.ptr()));
RootedValue dir(cx, StringValue(rtl ? cx->names().rtl : cx->names().ltr));
if (!DefineProperty(cx, info, cx->names().direction, dir))
return false;
args.rval().setObject(*info);
return true;
}
const Class js::IntlClass = {
js_Object_str,
JSCLASS_HAS_CACHED_PROTO(JSProto_Intl)

Просмотреть файл

@ -509,6 +509,20 @@ intl_GetPluralCategories(JSContext* cx, unsigned argc, Value* vp);
extern MOZ_MUST_USE bool
intl_GetCalendarInfo(JSContext* cx, unsigned argc, Value* vp);
/**
* Returns a plain object with locale information for a single valid locale
* (callers must perform this validation). The object will have these
* properties:
*
* direction
* a string with a value "ltr" for left-to-right locale, and "rtl" for
* right-to-left locale.
* locale
* a BCP47 compilant locale string for the resolved locale.
*/
extern MOZ_MUST_USE bool
intl_GetLocaleInfo(JSContext* cx, unsigned argc, Value* vp);
/**
* Returns an Array with CLDR-based fields display names.
* The function takes three arguments:

Просмотреть файл

@ -3337,3 +3337,22 @@ function Intl_getDisplayNames(locales, options) {
return result;
}
function Intl_getLocaleInfo(locales) {
const requestedLocales = CanonicalizeLocaleList(locales);
// In the future, we may want to expose uloc_getAvailable and use it here.
const DateTimeFormat = dateTimeFormatInternalProperties;
const localeData = DateTimeFormat.localeData;
const localeOpt = new Record();
localeOpt.localeMatcher = "best fit";
const r = ResolveLocale(callFunction(DateTimeFormat.availableLocales, DateTimeFormat),
requestedLocales,
localeOpt,
DateTimeFormat.relevantExtensionKeys,
localeData);
return intl_GetLocaleInfo(r.locale);
}

Просмотреть файл

@ -939,6 +939,7 @@ AddIntlExtras(JSContext* cx, unsigned argc, Value* vp)
static const JSFunctionSpec funcs[] = {
JS_SELF_HOSTED_FN("getCalendarInfo", "Intl_getCalendarInfo", 1, 0),
JS_SELF_HOSTED_FN("getLocaleInfo", "Intl_getLocaleInfo", 1, 0),
JS_SELF_HOSTED_FN("getDisplayNames", "Intl_getDisplayNames", 2, 0),
JS_FS_END
};

Просмотреть файл

@ -0,0 +1,38 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.hasOwnProperty("addIntlExtras"))
/* 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/. */
// Tests the getCalendarInfo function with a diverse set of arguments.
function checkLocaleInfo(info, expected)
{
assertEq(Object.getPrototypeOf(info), Object.prototype);
assertEq(info.direction, expected.direction);
assertEq(info.locale, expected.locale);
}
addIntlExtras(Intl);
let gLI = Intl.getLocaleInfo;
assertEq(gLI.length, 1);
checkLocaleInfo(gLI('en-US'), {
direction: "ltr",
locale: "en-US"
});
checkLocaleInfo(gLI('fr'), {
direction: "ltr",
locale: "fr"
});
checkLocaleInfo(gLI('ar'), {
direction: "rtl",
locale: "ar"
});
if (typeof reportCompare === 'function')
reportCompare(0, 0);

Просмотреть файл

@ -91,6 +91,7 @@
macro(defineSetter, defineSetter, "__defineSetter__") \
macro(delete, delete_, "delete") \
macro(deleteProperty, deleteProperty, "deleteProperty") \
macro(direction, direction, "direction") \
macro(displayURL, displayURL, "displayURL") \
macro(do, do_, "do") \
macro(done, done, "done") \
@ -210,6 +211,7 @@
macro(locale, locale, "locale") \
macro(lookupGetter, lookupGetter, "__lookupGetter__") \
macro(lookupSetter, lookupSetter, "__lookupSetter__") \
macro(ltr, ltr, "ltr") \
macro(MapConstructorInit, MapConstructorInit, "MapConstructorInit") \
macro(MapIterator, MapIterator, "Map Iterator") \
macro(maximumFractionDigits, maximumFractionDigits, "maximumFractionDigits") \
@ -298,6 +300,7 @@
macro(resumeGenerator, resumeGenerator, "resumeGenerator") \
macro(return, return_, "return") \
macro(revoke, revoke, "revoke") \
macro(rtl, rtl, "rtl") \
macro(script, script, "script") \
macro(scripts, scripts, "scripts") \
macro(second, second, "second") \

Просмотреть файл

@ -2615,6 +2615,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("intl_FormatDateTime", intl_FormatDateTime, 2,0),
JS_FN("intl_FormatNumber", intl_FormatNumber, 2,0),
JS_FN("intl_GetCalendarInfo", intl_GetCalendarInfo, 1,0),
JS_FN("intl_GetLocaleInfo", intl_GetLocaleInfo, 1,0),
JS_FN("intl_ComputeDisplayNames", intl_ComputeDisplayNames, 3,0),
JS_FN("intl_IsValidTimeZoneName", intl_IsValidTimeZoneName, 1,0),
JS_FN("intl_NumberFormat", intl_NumberFormat, 2,0),

Просмотреть файл

@ -82,6 +82,17 @@ MozIntl::AddPluralRulesConstructor(JS::Handle<JS::Value> val, JSContext* cx)
return NS_OK;
}
NS_IMETHODIMP
MozIntl::AddGetLocaleInfo(JS::Handle<JS::Value> val, JSContext* cx)
{
static const JSFunctionSpec funcs[] = {
JS_SELF_HOSTED_FN("getLocaleInfo", "Intl_getLocaleInfo", 1, 0),
JS_FS_END
};
return AddFunctions(cx, val, funcs);
}
NS_GENERIC_FACTORY_CONSTRUCTOR(MozIntl)
NS_DEFINE_NAMED_CID(MOZ_MOZINTL_CID);

Просмотреть файл

@ -10,6 +10,7 @@ interface mozIMozIntl : nsISupports
{
[implicit_jscontext] void addGetCalendarInfo(in jsval intlObject);
[implicit_jscontext] void addGetDisplayNames(in jsval intlObject);
[implicit_jscontext] void addGetLocaleInfo(in jsval intlObject);
/**
* Adds a PluralRules constructor to the given object. This function may only

Просмотреть файл

@ -35,6 +35,7 @@ function test_cross_global(mozIntl) {
function test_methods_presence(mozIntl) {
equal(mozIntl.addGetCalendarInfo instanceof Function, true);
equal(mozIntl.addGetDisplayNames instanceof Function, true);
equal(mozIntl.addGetLocaleInfo instanceof Function, true);
let x = {};
@ -43,4 +44,7 @@ function test_methods_presence(mozIntl) {
mozIntl.addGetDisplayNames(x);
equal(x.getDisplayNames instanceof Function, true);
mozIntl.addGetLocaleInfo(x);
equal(x.getLocaleInfo instanceof Function, true);
}