зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1421453 - Extend Intl.RelativeTimeFormat to support `type` option. r=Waldo
MozReview-Commit-ID: BUdmtVSF5La --HG-- extra : rebase_source : 47f5dbc9111eede3b7cdf905cc207d8dcaded119
This commit is contained in:
Родитель
1ee2ce9a65
Коммит
cc1a11fe27
|
@ -796,12 +796,20 @@ ureldatefmt_close(URelativeDateTimeFormatter *reldatefmt)
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
ureldatefmt_format(const URelativeDateTimeFormatter* reldatefmt, double offset,
|
ureldatefmt_format(const URelativeDateTimeFormatter* reldatefmt, double offset,
|
||||||
URelativeDateTimeUnit unit, UChar* result, int32_t resultCapacity,
|
URelativeDateTimeUnit unit, UChar* result, int32_t resultCapacity,
|
||||||
UErrorCode* status)
|
UErrorCode* status)
|
||||||
{
|
{
|
||||||
MOZ_CRASH("ureldatefmt_format: Intl API disabled");
|
MOZ_CRASH("ureldatefmt_format: Intl API disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t
|
||||||
|
ureldatefmt_formatNumeric(const URelativeDateTimeFormatter* reldatefmt, double offset,
|
||||||
|
URelativeDateTimeUnit unit, UChar* result, int32_t resultCapacity,
|
||||||
|
UErrorCode* status)
|
||||||
|
{
|
||||||
|
MOZ_CRASH("ureldatefmt_formatNumeric: Intl API disabled");
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -4015,6 +4023,19 @@ js::intl_RelativeTimeFormat_availableLocales(JSContext* cx, unsigned argc, Value
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class RelativeTimeType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Only strings with numeric components like `1 day ago`.
|
||||||
|
*/
|
||||||
|
Numeric,
|
||||||
|
/**
|
||||||
|
* Natural-language strings like `yesterday` when possible,
|
||||||
|
* otherwise strings with numeric components as in `7 months ago`.
|
||||||
|
*/
|
||||||
|
Text,
|
||||||
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp)
|
js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
|
@ -4056,6 +4077,23 @@ js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GetProperty(cx, internals, internals, cx->names().type, &value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RelativeTimeType relDateTimeType;
|
||||||
|
{
|
||||||
|
JSLinearString* type = value.toString()->ensureLinear(cx);
|
||||||
|
if (!type)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (StringEqualsAscii(type, "text")) {
|
||||||
|
relDateTimeType = RelativeTimeType::Text;
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(StringEqualsAscii(type, "numeric"));
|
||||||
|
relDateTimeType = RelativeTimeType::Numeric;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
URelativeDateTimeUnit relDateTimeUnit;
|
URelativeDateTimeUnit relDateTimeUnit;
|
||||||
{
|
{
|
||||||
JSLinearString* unit = args[2].toString()->ensureLinear(cx);
|
JSLinearString* unit = args[2].toString()->ensureLinear(cx);
|
||||||
|
@ -4098,8 +4136,11 @@ js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
|
||||||
ScopedICUObject<URelativeDateTimeFormatter, ureldatefmt_close> closeRelativeTimeFormat(rtf);
|
ScopedICUObject<URelativeDateTimeFormatter, ureldatefmt_close> closeRelativeTimeFormat(rtf);
|
||||||
|
|
||||||
JSString* str = Call(cx, [rtf, t, relDateTimeUnit](UChar* chars, int32_t size, UErrorCode* status) {
|
JSString* str = Call(cx, [rtf, t, relDateTimeUnit, relDateTimeType](UChar* chars, int32_t size, UErrorCode* status) {
|
||||||
return ureldatefmt_format(rtf, t, relDateTimeUnit, chars, size, status);
|
auto fmt = relDateTimeType == RelativeTimeType::Text
|
||||||
|
? ureldatefmt_format
|
||||||
|
: ureldatefmt_formatNumeric;
|
||||||
|
return fmt(rtf, t, relDateTimeUnit, chars, size, status);
|
||||||
});
|
});
|
||||||
if (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -3617,6 +3617,7 @@ function resolveRelativeTimeFormatInternals(lazyRelativeTimeFormatData) {
|
||||||
// Step 17.
|
// Step 17.
|
||||||
internalProps.locale = r.locale;
|
internalProps.locale = r.locale;
|
||||||
internalProps.style = lazyRelativeTimeFormatData.style;
|
internalProps.style = lazyRelativeTimeFormatData.style;
|
||||||
|
internalProps.type = lazyRelativeTimeFormatData.type;
|
||||||
|
|
||||||
return internalProps;
|
return internalProps;
|
||||||
}
|
}
|
||||||
|
@ -3663,6 +3664,7 @@ function InitializeRelativeTimeFormat(relativeTimeFormat, locales, options) {
|
||||||
// {
|
// {
|
||||||
// requestedLocales: List of locales,
|
// requestedLocales: List of locales,
|
||||||
// style: "long" / "short" / "narrow",
|
// style: "long" / "short" / "narrow",
|
||||||
|
// type: "numeric" / "text",
|
||||||
//
|
//
|
||||||
// opt: // opt object computer in InitializeRelativeTimeFormat
|
// opt: // opt object computer in InitializeRelativeTimeFormat
|
||||||
// {
|
// {
|
||||||
|
@ -3698,6 +3700,11 @@ function InitializeRelativeTimeFormat(relativeTimeFormat, locales, options) {
|
||||||
const style = GetOption(options, "style", "string", ["long", "short", "narrow"], "long");
|
const style = GetOption(options, "style", "string", ["long", "short", "narrow"], "long");
|
||||||
lazyRelativeTimeFormatData.style = style;
|
lazyRelativeTimeFormatData.style = style;
|
||||||
|
|
||||||
|
// This option is in the process of being added to the spec.
|
||||||
|
// See: https://github.com/tc39/proposal-intl-relative-time/issues/9
|
||||||
|
const type = GetOption(options, "type", "string", ["numeric", "text"], "numeric");
|
||||||
|
lazyRelativeTimeFormatData.type = type;
|
||||||
|
|
||||||
initializeIntlObject(relativeTimeFormat, "RelativeTimeFormat", lazyRelativeTimeFormatData);
|
initializeIntlObject(relativeTimeFormat, "RelativeTimeFormat", lazyRelativeTimeFormatData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3780,6 +3787,7 @@ function Intl_RelativeTimeFormat_resolvedOptions() {
|
||||||
var result = {
|
var result = {
|
||||||
locale: internals.locale,
|
locale: internals.locale,
|
||||||
style: internals.style,
|
style: internals.style,
|
||||||
|
type: internals.type,
|
||||||
};
|
};
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -9,48 +9,91 @@ var rtf;
|
||||||
|
|
||||||
addIntlExtras(Intl);
|
addIntlExtras(Intl);
|
||||||
|
|
||||||
|
{
|
||||||
|
// Numeric format
|
||||||
|
rtf = new Intl.RelativeTimeFormat("en-US");
|
||||||
|
assertEq(rtf.format(0, "second"), "in 0 seconds");
|
||||||
|
assertEq(rtf.format(-0, "second"), "in 0 seconds");
|
||||||
|
assertEq(rtf.format(-1, "second"), "1 second ago");
|
||||||
|
assertEq(rtf.format(1, "second"), "in 1 second");
|
||||||
|
|
||||||
rtf = new Intl.RelativeTimeFormat("en-US");
|
assertEq(rtf.format(0, "minute"), "in 0 minutes");
|
||||||
assertEq(rtf.format(0, "second"), "now");
|
assertEq(rtf.format(-0, "minute"), "in 0 minutes");
|
||||||
assertEq(rtf.format(-0, "second"), "now");
|
assertEq(rtf.format(-1, "minute"), "1 minute ago");
|
||||||
assertEq(rtf.format(-1, "second"), "1 second ago");
|
assertEq(rtf.format(1, "minute"), "in 1 minute");
|
||||||
assertEq(rtf.format(1, "second"), "in 1 second");
|
|
||||||
|
|
||||||
assertEq(rtf.format(0, "minute"), "in 0 minutes");
|
assertEq(rtf.format(0, "hour"), "in 0 hours");
|
||||||
assertEq(rtf.format(-0, "minute"), "in 0 minutes");
|
assertEq(rtf.format(-0, "hour"), "in 0 hours");
|
||||||
assertEq(rtf.format(-1, "minute"), "1 minute ago");
|
assertEq(rtf.format(-1, "hour"), "1 hour ago");
|
||||||
assertEq(rtf.format(1, "minute"), "in 1 minute");
|
assertEq(rtf.format(1, "hour"), "in 1 hour");
|
||||||
|
|
||||||
assertEq(rtf.format(0, "hour"), "in 0 hours");
|
assertEq(rtf.format(0, "day"), "in 0 days");
|
||||||
assertEq(rtf.format(-0, "hour"), "in 0 hours");
|
assertEq(rtf.format(-0, "day"), "in 0 days");
|
||||||
assertEq(rtf.format(-1, "hour"), "1 hour ago");
|
assertEq(rtf.format(-1, "day"), "1 day ago");
|
||||||
assertEq(rtf.format(1, "hour"), "in 1 hour");
|
assertEq(rtf.format(1, "day"), "in 1 day");
|
||||||
|
|
||||||
assertEq(rtf.format(0, "day"), "today");
|
assertEq(rtf.format(0, "week"), "in 0 weeks");
|
||||||
assertEq(rtf.format(-0, "day"), "today");
|
assertEq(rtf.format(-0, "week"), "in 0 weeks");
|
||||||
assertEq(rtf.format(-1, "day"), "yesterday");
|
assertEq(rtf.format(-1, "week"), "1 week ago");
|
||||||
assertEq(rtf.format(1, "day"), "tomorrow");
|
assertEq(rtf.format(1, "week"), "in 1 week");
|
||||||
|
|
||||||
assertEq(rtf.format(0, "week"), "this week");
|
assertEq(rtf.format(0, "month"), "in 0 months");
|
||||||
assertEq(rtf.format(-0, "week"), "this week");
|
assertEq(rtf.format(-0, "month"), "in 0 months");
|
||||||
assertEq(rtf.format(-1, "week"), "last week");
|
assertEq(rtf.format(-1, "month"), "1 month ago");
|
||||||
assertEq(rtf.format(1, "week"), "next week");
|
assertEq(rtf.format(1, "month"), "in 1 month");
|
||||||
|
|
||||||
assertEq(rtf.format(0, "month"), "this month");
|
assertEq(rtf.format(0, "year"), "in 0 years");
|
||||||
assertEq(rtf.format(-0, "month"), "this month");
|
assertEq(rtf.format(-0, "year"), "in 0 years");
|
||||||
assertEq(rtf.format(-1, "month"), "last month");
|
assertEq(rtf.format(-1, "year"), "1 year ago");
|
||||||
assertEq(rtf.format(1, "month"), "next month");
|
assertEq(rtf.format(1, "year"), "in 1 year");
|
||||||
|
}
|
||||||
|
|
||||||
assertEq(rtf.format(0, "year"), "this year");
|
{
|
||||||
assertEq(rtf.format(-0, "year"), "this year");
|
// Text format
|
||||||
assertEq(rtf.format(-1, "year"), "last year");
|
rtf = new Intl.RelativeTimeFormat("en-US", {
|
||||||
assertEq(rtf.format(1, "year"), "next year");
|
type: "text"
|
||||||
|
});
|
||||||
|
assertEq(rtf.format(0, "second"), "now");
|
||||||
|
assertEq(rtf.format(-0, "second"), "now");
|
||||||
|
assertEq(rtf.format(-1, "second"), "1 second ago");
|
||||||
|
assertEq(rtf.format(1, "second"), "in 1 second");
|
||||||
|
|
||||||
rtf = new Intl.RelativeTimeFormat("de");
|
assertEq(rtf.format(0, "minute"), "in 0 minutes");
|
||||||
|
assertEq(rtf.format(-0, "minute"), "in 0 minutes");
|
||||||
|
assertEq(rtf.format(-1, "minute"), "1 minute ago");
|
||||||
|
assertEq(rtf.format(1, "minute"), "in 1 minute");
|
||||||
|
|
||||||
|
assertEq(rtf.format(0, "hour"), "in 0 hours");
|
||||||
|
assertEq(rtf.format(-0, "hour"), "in 0 hours");
|
||||||
|
assertEq(rtf.format(-1, "hour"), "1 hour ago");
|
||||||
|
assertEq(rtf.format(1, "hour"), "in 1 hour");
|
||||||
|
|
||||||
|
assertEq(rtf.format(0, "day"), "today");
|
||||||
|
assertEq(rtf.format(-0, "day"), "today");
|
||||||
|
assertEq(rtf.format(-1, "day"), "yesterday");
|
||||||
|
assertEq(rtf.format(1, "day"), "tomorrow");
|
||||||
|
|
||||||
|
assertEq(rtf.format(0, "week"), "this week");
|
||||||
|
assertEq(rtf.format(-0, "week"), "this week");
|
||||||
|
assertEq(rtf.format(-1, "week"), "last week");
|
||||||
|
assertEq(rtf.format(1, "week"), "next week");
|
||||||
|
|
||||||
|
assertEq(rtf.format(0, "month"), "this month");
|
||||||
|
assertEq(rtf.format(-0, "month"), "this month");
|
||||||
|
assertEq(rtf.format(-1, "month"), "last month");
|
||||||
|
assertEq(rtf.format(1, "month"), "next month");
|
||||||
|
|
||||||
|
assertEq(rtf.format(0, "year"), "this year");
|
||||||
|
assertEq(rtf.format(-0, "year"), "this year");
|
||||||
|
assertEq(rtf.format(-1, "year"), "last year");
|
||||||
|
assertEq(rtf.format(1, "year"), "next year");
|
||||||
|
}
|
||||||
|
|
||||||
|
rtf = new Intl.RelativeTimeFormat("de", {type: "text"});
|
||||||
assertEq(rtf.format(-1, "day"), "gestern");
|
assertEq(rtf.format(-1, "day"), "gestern");
|
||||||
assertEq(rtf.format(1, "day"), "morgen");
|
assertEq(rtf.format(1, "day"), "morgen");
|
||||||
|
|
||||||
rtf = new Intl.RelativeTimeFormat("ar");
|
rtf = new Intl.RelativeTimeFormat("ar", {type: "text"});
|
||||||
assertEq(rtf.format(-1, "day"), "أمس");
|
assertEq(rtf.format(-1, "day"), "أمس");
|
||||||
assertEq(rtf.format(1, "day"), "غدًا");
|
assertEq(rtf.format(1, "day"), "غدًا");
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче