Bug 1639515 - Part 2: Add mozIntl.DisplayNames. r=platform-i18n-reviewers,gregtatum

Expose `Intl.DisplayNames` to `mozIntl`. The exposed `Intl.DisplayNames` version
supports date-time types, which have been removed from the spec proposal, but
may be re-enabled at some point in the future.

The existing `getDisplayNames` WebIDL function had to be renamed, because WebIDL
doesn't allow specify an attribute named `DisplayNames` and a separate function
called `getDisplayNames`.

Drive-by change:
- Removed an out-dated comment in "mozIMozIntlHelper.idl" which mentioned calling
  `addDateTimeFormatConstructor` twice throws an error.

Differential Revision: https://phabricator.services.mozilla.com/D76114
This commit is contained in:
André Bargull 2021-09-14 06:52:32 +00:00
parent d527935302
commit 3607216c74
9 changed files with 73 additions and 10 deletions

View File

@ -390,7 +390,7 @@ class AboutProtectionsParent extends JSWindowActorParent {
break;
case "FetchContentBlockingEvents":
let dataToSend = {};
let weekdays = Services.intl.getDisplayNames(undefined, {
let weekdays = Services.intl.getDisplayNamesDeprecated(undefined, {
style: "short",
keys: [
"dates/gregorian/weekdays/sunday",

View File

@ -69,7 +69,7 @@ void IntlUtils::GetDisplayNames(const Sequence<nsString>& aLocales,
// Now call the method.
JS::Rooted<JS::Value> retVal(cx);
nsresult rv = mozIntl->GetDisplayNames(locales, options, &retVal);
nsresult rv = mozIntl->GetDisplayNamesDeprecated(locales, options, &retVal);
if (NS_FAILED(rv)) {
aError.Throw(rv);
return;

View File

@ -80,3 +80,26 @@ MozIntlHelper::AddDateTimeFormatConstructor(JS::Handle<JS::Value> val,
return NS_OK;
}
NS_IMETHODIMP
MozIntlHelper::AddDisplayNamesConstructor(JS::Handle<JS::Value> val,
JSContext* cx) {
if (!val.isObject()) {
return NS_ERROR_INVALID_ARG;
}
// We might be adding this constructor to a Window
JS::Rooted<JSObject*> realIntlObj(
cx, js::CheckedUnwrapDynamic(&val.toObject(), cx));
if (!realIntlObj) {
return NS_ERROR_INVALID_ARG;
}
JSAutoRealm ar(cx, realIntlObj);
if (!JS::AddMozDisplayNamesConstructor(cx, realIntlObj)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@ -38,7 +38,13 @@
interface mozIMozIntl : nsISupports
{
jsval getCalendarInfo([optional] in jsval locales);
jsval getDisplayNames([optional] in jsval locales, [optional] in jsval options);
/**
* Helper for IntlUtils.webidl, will be removed once Intl.DisplayNames
* supports date-time types in non-privileged code.
*/
jsval getDisplayNamesDeprecated([optional] in jsval locales, [optional] in jsval options);
/**
* Returns a list of locale codes for a given type.
@ -79,6 +85,7 @@ interface mozIMozIntl : nsISupports
readonly attribute jsval Collator;
readonly attribute jsval DateTimeFormat;
readonly attribute jsval DisplayNames;
readonly attribute jsval ListFormat;
readonly attribute jsval Locale;
readonly attribute jsval NumberFormat;

View File

@ -20,9 +20,7 @@ interface mozIMozIntlHelper : nsISupports
[implicit_jscontext] void addGetDisplayNames(in jsval intlObject);
/**
* Adds a MozDateTimeFormat contructor to the given object. This function may only
* be called once within a realm/global object: calling it multiple times will
* throw.
* Adds a MozDateTimeFormat contructor to the given object.
*
* The difference between regular Intl.DateTimeFormat and the method created here
* is that we support two more options:
@ -41,4 +39,26 @@ interface mozIMozIntlHelper : nsISupports
* This API should be used everywhere in the UI instead of regular Intl API.
*/
[implicit_jscontext] void addDateTimeFormatConstructor(in jsval intlObject);
/**
* Adds a MozDisplayNames contructor to the given object.
*
* The difference between regular Intl.DisplayNames and the method created here
* is that we additionally support the following values for the "type" option:
*
* weekday
* month
* quarter
* dayPeriod
*
* And we additionally support "abbreviated" for the "style" option.
*
* MozDisplayNames.prototype.of accepts the following inputs for these options:
*
* weekday: an integer in the range 1 = Monday to 7 = Sunday.
* month: an integer in the range 1 = January to 13 = Undecimber.
* quarter: an integer in the range 1 to 4.
* dayPeriod: a string from the set {"am", "pm"}.
*/
[implicit_jscontext] void addDisplayNamesConstructor(in jsval intlObject);
};

View File

@ -755,7 +755,7 @@ class MozIntl {
return this._cache.getCalendarInfo(locales, ...args);
}
getDisplayNames(locales, ...args) {
getDisplayNamesDeprecated(locales, ...args) {
if (!this._cache.hasOwnProperty("getDisplayNames")) {
mozIntlHelper.addGetDisplayNames(this._cache);
}
@ -915,6 +915,14 @@ class MozIntl {
return this._cache.MozDateTimeFormat;
}
get DisplayNames() {
if (!this._cache.hasOwnProperty("DisplayNames")) {
mozIntlHelper.addDisplayNamesConstructor(this._cache);
}
return this._cache.DisplayNames;
}
}
MozIntl.prototype.classID = Components.ID(

View File

@ -15,14 +15,15 @@ function run_test() {
function test_methods_presence() {
equal(Services.intl.getCalendarInfo instanceof Function, true);
equal(Services.intl.getDisplayNames instanceof Function, true);
equal(Services.intl.getDisplayNamesDeprecated instanceof Function, true);
equal(Services.intl.getLocaleDisplayNames instanceof Function, true);
}
function test_methods_calling() {
Services.intl.getCalendarInfo("pl");
Services.intl.getDisplayNames("ar");
Services.intl.getDisplayNamesDeprecated("ar");
new Services.intl.DateTimeFormat("fr");
new Services.intl.DisplayNames("fr", { type: "language" });
new Services.intl.ListFormat("fr");
new Services.intl.Locale("fr");
new Services.intl.RelativeTimeFormat("fr");

View File

@ -43,6 +43,7 @@ function test_methods_presence(miHelper) {
equal(miHelper.addGetCalendarInfo instanceof Function, true);
equal(miHelper.addGetDisplayNames instanceof Function, true);
equal(miHelper.addDateTimeFormatConstructor instanceof Function, true);
equal(miHelper.addDisplayNamesConstructor instanceof Function, true);
let x = {};
@ -54,4 +55,7 @@ function test_methods_presence(miHelper) {
miHelper.addDateTimeFormatConstructor(x);
equal(x.DateTimeFormat instanceof Function, true);
miHelper.addDisplayNamesConstructor(x);
equal(x.DisplayNames instanceof Function, true);
}

View File

@ -293,7 +293,7 @@ var DateTimePickerPanel = class {
}
getDisplayNames(locale, keys, style) {
const displayNames = Services.intl.getDisplayNames(locale, { keys, style });
const displayNames = Services.intl.getDisplayNamesDeprecated(locale, { keys, style });
return keys.map(key => displayNames.values[key]);
}