зеркало из 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
|
||||
ureldatefmt_format(const URelativeDateTimeFormatter* reldatefmt, double offset,
|
||||
URelativeDateTimeUnit unit, UChar* result, int32_t resultCapacity,
|
||||
UErrorCode* status)
|
||||
URelativeDateTimeUnit unit, UChar* result, int32_t resultCapacity,
|
||||
UErrorCode* status)
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
|
@ -4015,6 +4023,19 @@ js::intl_RelativeTimeFormat_availableLocales(JSContext* cx, unsigned argc, Value
|
|||
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
|
||||
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;
|
||||
{
|
||||
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);
|
||||
|
||||
JSString* str = Call(cx, [rtf, t, relDateTimeUnit](UChar* chars, int32_t size, UErrorCode* status) {
|
||||
return ureldatefmt_format(rtf, t, relDateTimeUnit, chars, size, status);
|
||||
JSString* str = Call(cx, [rtf, t, relDateTimeUnit, relDateTimeType](UChar* chars, int32_t size, UErrorCode* status) {
|
||||
auto fmt = relDateTimeType == RelativeTimeType::Text
|
||||
? ureldatefmt_format
|
||||
: ureldatefmt_formatNumeric;
|
||||
return fmt(rtf, t, relDateTimeUnit, chars, size, status);
|
||||
});
|
||||
if (!str)
|
||||
return false;
|
||||
|
|
|
@ -3617,6 +3617,7 @@ function resolveRelativeTimeFormatInternals(lazyRelativeTimeFormatData) {
|
|||
// Step 17.
|
||||
internalProps.locale = r.locale;
|
||||
internalProps.style = lazyRelativeTimeFormatData.style;
|
||||
internalProps.type = lazyRelativeTimeFormatData.type;
|
||||
|
||||
return internalProps;
|
||||
}
|
||||
|
@ -3663,6 +3664,7 @@ function InitializeRelativeTimeFormat(relativeTimeFormat, locales, options) {
|
|||
// {
|
||||
// requestedLocales: List of locales,
|
||||
// style: "long" / "short" / "narrow",
|
||||
// type: "numeric" / "text",
|
||||
//
|
||||
// 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");
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -3780,6 +3787,7 @@ function Intl_RelativeTimeFormat_resolvedOptions() {
|
|||
var result = {
|
||||
locale: internals.locale,
|
||||
style: internals.style,
|
||||
type: internals.type,
|
||||
};
|
||||
|
||||
return result;
|
||||
|
|
|
@ -9,48 +9,91 @@ var rtf;
|
|||
|
||||
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, "second"), "now");
|
||||
assertEq(rtf.format(-0, "second"), "now");
|
||||
assertEq(rtf.format(-1, "second"), "1 second ago");
|
||||
assertEq(rtf.format(1, "second"), "in 1 second");
|
||||
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, "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, "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"), "in 0 days");
|
||||
assertEq(rtf.format(-0, "day"), "in 0 days");
|
||||
assertEq(rtf.format(-1, "day"), "1 day ago");
|
||||
assertEq(rtf.format(1, "day"), "in 1 day");
|
||||
|
||||
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"), "in 0 weeks");
|
||||
assertEq(rtf.format(-0, "week"), "in 0 weeks");
|
||||
assertEq(rtf.format(-1, "week"), "1 week ago");
|
||||
assertEq(rtf.format(1, "week"), "in 1 week");
|
||||
|
||||
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"), "in 0 months");
|
||||
assertEq(rtf.format(-0, "month"), "in 0 months");
|
||||
assertEq(rtf.format(-1, "month"), "1 month ago");
|
||||
assertEq(rtf.format(1, "month"), "in 1 month");
|
||||
|
||||
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"), "in 0 years");
|
||||
assertEq(rtf.format(-0, "year"), "in 0 years");
|
||||
assertEq(rtf.format(-1, "year"), "1 year ago");
|
||||
assertEq(rtf.format(1, "year"), "in 1 year");
|
||||
}
|
||||
|
||||
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");
|
||||
{
|
||||
// Text format
|
||||
rtf = new Intl.RelativeTimeFormat("en-US", {
|
||||
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"), "morgen");
|
||||
|
||||
rtf = new Intl.RelativeTimeFormat("ar");
|
||||
rtf = new Intl.RelativeTimeFormat("ar", {type: "text"});
|
||||
assertEq(rtf.format(-1, "day"), "أمس");
|
||||
assertEq(rtf.format(1, "day"), "غدًا");
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче