mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 19:45:12 +00:00
LibJS: Re-arrange and rename a few Intl properties
This is an editorial change in the ECMA-402 spec. See: https://github.com/tc39/ecma402/commit/a46e37d https://github.com/tc39/ecma402/commit/e102741 https://github.com/tc39/ecma402/commit/67a8417 https://github.com/tc39/ecma402/commit/ecb086c
This commit is contained in:
parent
8b0f6cb876
commit
aa61307392
Notes:
github-actions[bot]
2025-03-04 12:37:30 +00:00
Author: https://github.com/trflynn89 Commit: https://github.com/LadybirdBrowser/ladybird/commit/aa61307392b Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3785
23 changed files with 481 additions and 481 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2022-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -25,38 +25,15 @@ void CollatorPrototype::initialize(Realm& realm)
|
|||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 10.3.2 Intl.Collator.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.collator.prototype-@@tostringtag
|
||||
// 10.3.4 Intl.Collator.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.collator.prototype-%symbol.tostringtag%
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.Collator"_string), Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
define_native_accessor(realm, vm.names.compare, compare_getter, {}, attr);
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
define_native_accessor(realm, vm.names.compare, compare_getter, {}, attr);
|
||||
}
|
||||
|
||||
// 10.3.3 get Intl.Collator.prototype.compare, https://tc39.es/ecma402/#sec-intl.collator.prototype.compare
|
||||
JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let collator be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]).
|
||||
auto collator = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If collator.[[BoundCompare]] is undefined, then
|
||||
if (!collator->bound_compare()) {
|
||||
// a. Let F be a new built-in function object as defined in 10.3.3.1.
|
||||
// b. Set F.[[Collator]] to collator.
|
||||
auto function = CollatorCompareFunction::create(realm, collator);
|
||||
|
||||
// c. Set collator.[[BoundCompare]] to F.
|
||||
collator->set_bound_compare(function);
|
||||
}
|
||||
|
||||
// 4. Return collator.[[BoundCompare]].
|
||||
return collator->bound_compare();
|
||||
}
|
||||
|
||||
// 10.3.4 Intl.Collator.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.collator.prototype.resolvedoptions
|
||||
// 10.3.2 Intl.Collator.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.collator.prototype.resolvedoptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
@ -89,4 +66,27 @@ JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::resolved_options)
|
|||
return options;
|
||||
}
|
||||
|
||||
// 10.3.3 get Intl.Collator.prototype.compare, https://tc39.es/ecma402/#sec-intl.collator.prototype.compare
|
||||
JS_DEFINE_NATIVE_FUNCTION(CollatorPrototype::compare_getter)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let collator be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(collator, [[InitializedCollator]]).
|
||||
auto collator = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If collator.[[BoundCompare]] is undefined, then
|
||||
if (!collator->bound_compare()) {
|
||||
// a. Let F be a new built-in function object as defined in 10.3.3.1.
|
||||
// b. Set F.[[Collator]] to collator.
|
||||
auto function = CollatorCompareFunction::create(realm, collator);
|
||||
|
||||
// c. Set collator.[[BoundCompare]] to F.
|
||||
collator->set_bound_compare(function);
|
||||
}
|
||||
|
||||
// 4. Return collator.[[BoundCompare]].
|
||||
return collator->bound_compare();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2022-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -22,8 +22,8 @@ public:
|
|||
private:
|
||||
explicit CollatorPrototype(Realm&);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(compare_getter);
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(compare_getter);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@ladybird.org>
|
||||
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -28,128 +28,19 @@ void DateTimeFormatPrototype::initialize(Realm& realm)
|
|||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 11.3.2 Intl.DateTimeFormat.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype-@@tostringtag
|
||||
// 11.3.7 Intl.DateTimeFormat.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype-%symbol.tostringtag%
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.DateTimeFormat"_string), Attribute::Configurable);
|
||||
|
||||
define_native_accessor(realm, vm.names.format, format, nullptr, Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr);
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
define_native_function(realm, vm.names.formatRange, format_range, 2, attr);
|
||||
define_native_function(realm, vm.names.formatRangeToParts, format_range_to_parts, 2, attr);
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr);
|
||||
}
|
||||
|
||||
// 11.3.3 get Intl.DateTimeFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.format
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let dtf be the this value.
|
||||
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||
// a. Set dtf to ? UnwrapDateTimeFormat(dtf).
|
||||
// 3. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
|
||||
auto date_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 4. If dtf.[[BoundFormat]] is undefined, then
|
||||
if (!date_time_format->bound_format()) {
|
||||
// a. Let F be a new built-in function object as defined in DateTime Format Functions (11.1.6).
|
||||
// b. Set F.[[DateTimeFormat]] to dtf.
|
||||
auto bound_format = DateTimeFormatFunction::create(realm, date_time_format);
|
||||
|
||||
// c. Set dtf.[[BoundFormat]] to F.
|
||||
date_time_format->set_bound_format(bound_format);
|
||||
}
|
||||
|
||||
// 5. Return dtf.[[BoundFormat]].
|
||||
return date_time_format->bound_format();
|
||||
}
|
||||
|
||||
// 11.3.4 Intl.DateTimeFormat.prototype.formatToParts ( date ), https://tc39.es/ecma402/#sec-Intl.DateTimeFormat.prototype.formatToParts
|
||||
// 15.10.1 Intl.DateTimeFormat.prototype.formatToParts ( date ), https://tc39.es/proposal-temporal/#sec-Intl.DateTimeFormat.prototype.formatToParts
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_to_parts)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
auto date_value = vm.argument(0);
|
||||
|
||||
// 1. Let dtf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
|
||||
auto date_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
FormattableDateTime date { 0 };
|
||||
|
||||
// 3. If date is undefined, then
|
||||
if (date_value.is_undefined()) {
|
||||
// a. Let x be ! Call(%Date.now%, undefined).
|
||||
date = MUST(call(vm, *realm.intrinsics().date_constructor_now_function(), js_undefined())).as_double();
|
||||
}
|
||||
// 4. Else,
|
||||
else {
|
||||
// a. Let x be ? ToDateTimeFormattable(date).
|
||||
date = TRY(to_date_time_formattable(vm, date_value));
|
||||
}
|
||||
|
||||
// 5. Return ? FormatDateTimeToParts(dtf, x).
|
||||
return TRY(format_date_time_to_parts(vm, date_time_format, date));
|
||||
}
|
||||
|
||||
// 11.3.5 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.formatRange
|
||||
// 15.10.2 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/proposal-temporal/#sec-intl.datetimeformat.prototype.formatRange
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range)
|
||||
{
|
||||
auto start_date_value = vm.argument(0);
|
||||
auto end_date_value = vm.argument(1);
|
||||
|
||||
// 1. Let dtf be this value.
|
||||
// 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
|
||||
auto date_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If startDate is undefined or endDate is undefined, throw a TypeError exception.
|
||||
if (start_date_value.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "startDate"sv);
|
||||
if (end_date_value.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "endDate"sv);
|
||||
|
||||
// 4. Let x be ? ToDateTimeFormattable(startDate).
|
||||
auto start_date = TRY(to_date_time_formattable(vm, start_date_value));
|
||||
|
||||
// 5. Let y be ? ToDateTimeFormattable(endDate).
|
||||
auto end_date = TRY(to_date_time_formattable(vm, end_date_value));
|
||||
|
||||
// 6. Return ? FormatDateTimeRange(dtf, x, y).
|
||||
auto formatted = TRY(format_date_time_range(vm, date_time_format, start_date, end_date));
|
||||
return PrimitiveString::create(vm, move(formatted));
|
||||
}
|
||||
|
||||
// 11.3.6 Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate, endDate ), https://tc39.es/ecma402/#sec-Intl.DateTimeFormat.prototype.formatRangeToParts
|
||||
// 15.10.3 Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate, endDate ), https://tc39.es/proposal-temporal/#sec-Intl.DateTimeFormat.prototype.formatRangeToParts
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range_to_parts)
|
||||
{
|
||||
auto start_date_value = vm.argument(0);
|
||||
auto end_date_value = vm.argument(1);
|
||||
|
||||
// 1. Let dtf be this value.
|
||||
// 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
|
||||
auto date_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If startDate is undefined or endDate is undefined, throw a TypeError exception.
|
||||
if (start_date_value.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "startDate"sv);
|
||||
if (end_date_value.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "endDate"sv);
|
||||
|
||||
// 4. Let x be ? ToDateTimeFormattable(startDate).
|
||||
auto start_date = TRY(to_date_time_formattable(vm, start_date_value));
|
||||
|
||||
// 5. Let y be ? ToDateTimeFormattable(endDate).
|
||||
auto end_date = TRY(to_date_time_formattable(vm, end_date_value));
|
||||
|
||||
// 6. Return ? FormatDateTimeRangeToParts(dtf, x, y).
|
||||
return TRY(format_date_time_range_to_parts(vm, date_time_format, start_date, end_date));
|
||||
}
|
||||
|
||||
// 11.3.7 Intl.DateTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions
|
||||
// 11.3.2 Intl.DateTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
@ -229,4 +120,113 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::resolved_options)
|
|||
return options;
|
||||
}
|
||||
|
||||
// 11.3.3 get Intl.DateTimeFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.format
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let dtf be the this value.
|
||||
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||
// a. Set dtf to ? UnwrapDateTimeFormat(dtf).
|
||||
// 3. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
|
||||
auto date_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 4. If dtf.[[BoundFormat]] is undefined, then
|
||||
if (!date_time_format->bound_format()) {
|
||||
// a. Let F be a new built-in function object as defined in DateTime Format Functions (11.1.6).
|
||||
// b. Set F.[[DateTimeFormat]] to dtf.
|
||||
auto bound_format = DateTimeFormatFunction::create(realm, date_time_format);
|
||||
|
||||
// c. Set dtf.[[BoundFormat]] to F.
|
||||
date_time_format->set_bound_format(bound_format);
|
||||
}
|
||||
|
||||
// 5. Return dtf.[[BoundFormat]].
|
||||
return date_time_format->bound_format();
|
||||
}
|
||||
|
||||
// 11.3.4 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.formatRange
|
||||
// 15.10.2 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/proposal-temporal/#sec-intl.datetimeformat.prototype.formatRange
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range)
|
||||
{
|
||||
auto start_date_value = vm.argument(0);
|
||||
auto end_date_value = vm.argument(1);
|
||||
|
||||
// 1. Let dtf be this value.
|
||||
// 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
|
||||
auto date_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If startDate is undefined or endDate is undefined, throw a TypeError exception.
|
||||
if (start_date_value.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "startDate"sv);
|
||||
if (end_date_value.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "endDate"sv);
|
||||
|
||||
// 4. Let x be ? ToDateTimeFormattable(startDate).
|
||||
auto start_date = TRY(to_date_time_formattable(vm, start_date_value));
|
||||
|
||||
// 5. Let y be ? ToDateTimeFormattable(endDate).
|
||||
auto end_date = TRY(to_date_time_formattable(vm, end_date_value));
|
||||
|
||||
// 6. Return ? FormatDateTimeRange(dtf, x, y).
|
||||
auto formatted = TRY(format_date_time_range(vm, date_time_format, start_date, end_date));
|
||||
return PrimitiveString::create(vm, move(formatted));
|
||||
}
|
||||
|
||||
// 11.3.5 Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate, endDate ), https://tc39.es/ecma402/#sec-Intl.DateTimeFormat.prototype.formatRangeToParts
|
||||
// 15.10.3 Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate, endDate ), https://tc39.es/proposal-temporal/#sec-Intl.DateTimeFormat.prototype.formatRangeToParts
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range_to_parts)
|
||||
{
|
||||
auto start_date_value = vm.argument(0);
|
||||
auto end_date_value = vm.argument(1);
|
||||
|
||||
// 1. Let dtf be this value.
|
||||
// 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
|
||||
auto date_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If startDate is undefined or endDate is undefined, throw a TypeError exception.
|
||||
if (start_date_value.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "startDate"sv);
|
||||
if (end_date_value.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "endDate"sv);
|
||||
|
||||
// 4. Let x be ? ToDateTimeFormattable(startDate).
|
||||
auto start_date = TRY(to_date_time_formattable(vm, start_date_value));
|
||||
|
||||
// 5. Let y be ? ToDateTimeFormattable(endDate).
|
||||
auto end_date = TRY(to_date_time_formattable(vm, end_date_value));
|
||||
|
||||
// 6. Return ? FormatDateTimeRangeToParts(dtf, x, y).
|
||||
return TRY(format_date_time_range_to_parts(vm, date_time_format, start_date, end_date));
|
||||
}
|
||||
|
||||
// 11.3.6 Intl.DateTimeFormat.prototype.formatToParts ( date ), https://tc39.es/ecma402/#sec-Intl.DateTimeFormat.prototype.formatToParts
|
||||
// 15.10.1 Intl.DateTimeFormat.prototype.formatToParts ( date ), https://tc39.es/proposal-temporal/#sec-Intl.DateTimeFormat.prototype.formatToParts
|
||||
JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_to_parts)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
auto date_value = vm.argument(0);
|
||||
|
||||
// 1. Let dtf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]).
|
||||
auto date_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
FormattableDateTime date { 0 };
|
||||
|
||||
// 3. If date is undefined, then
|
||||
if (date_value.is_undefined()) {
|
||||
// a. Let x be ! Call(%Date.now%, undefined).
|
||||
date = MUST(call(vm, *realm.intrinsics().date_constructor_now_function(), js_undefined())).as_double();
|
||||
}
|
||||
// 4. Else,
|
||||
else {
|
||||
// a. Let x be ? ToDateTimeFormattable(date).
|
||||
date = TRY(to_date_time_formattable(vm, date_value));
|
||||
}
|
||||
|
||||
// 5. Return ? FormatDateTimeToParts(dtf, x).
|
||||
return TRY(format_date_time_to_parts(vm, date_time_format, date));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -22,11 +22,11 @@ public:
|
|||
private:
|
||||
explicit DateTimeFormatPrototype(Realm&);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_to_parts);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_range);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_range_to_parts);
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_to_parts);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -27,12 +27,42 @@ void DisplayNamesPrototype::initialize(Realm& realm)
|
|||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 12.3.2 Intl.DisplayNames.prototype[ @@toStringTag ], https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype-@@tostringtag
|
||||
// 12.3.4 Intl.DisplayNames.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.displaynames.prototype-%symbol.tostringtag%
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.DisplayNames"_string), Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
define_native_function(realm, vm.names.of, of, 1, attr);
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
define_native_function(realm, vm.names.of, of, 1, attr);
|
||||
}
|
||||
|
||||
// 12.3.2 Intl.DisplayNames.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype.resolvedOptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let displayNames be this value.
|
||||
// 2. Perform ? RequireInternalSlot(displayNames, [[InitializedDisplayNames]]).
|
||||
auto display_names = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto options = Object::create(realm, realm.intrinsics().object_prototype());
|
||||
|
||||
// 4. For each row of Table 18, except the header row, in table order, do
|
||||
// a. Let p be the Property value of the current row.
|
||||
// b. Let v be the value of displayNames's internal slot whose name is the Internal Slot value of the current row.
|
||||
// c. Assert: v is not undefined.
|
||||
// d. Perform ! CreateDataPropertyOrThrow(options, p, v).
|
||||
MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, display_names->locale())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, display_names->style_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.type, PrimitiveString::create(vm, display_names->type_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.fallback, PrimitiveString::create(vm, display_names->fallback_string())));
|
||||
|
||||
// NOTE: Step 4c indicates languageDisplay must not be undefined, but it is only set when the type option is language.
|
||||
if (display_names->has_language_display())
|
||||
MUST(options->create_data_property_or_throw(vm.names.languageDisplay, PrimitiveString::create(vm, display_names->language_display_string())));
|
||||
|
||||
// 5. Return options.
|
||||
return options;
|
||||
}
|
||||
|
||||
// 12.3.3 Intl.DisplayNames.prototype.of ( code ), https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype.of
|
||||
|
@ -89,34 +119,4 @@ JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::of)
|
|||
return js_undefined();
|
||||
}
|
||||
|
||||
// 12.3.4 Intl.DisplayNames.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.DisplayNames.prototype.resolvedOptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(DisplayNamesPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let displayNames be this value.
|
||||
// 2. Perform ? RequireInternalSlot(displayNames, [[InitializedDisplayNames]]).
|
||||
auto display_names = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto options = Object::create(realm, realm.intrinsics().object_prototype());
|
||||
|
||||
// 4. For each row of Table 18, except the header row, in table order, do
|
||||
// a. Let p be the Property value of the current row.
|
||||
// b. Let v be the value of displayNames's internal slot whose name is the Internal Slot value of the current row.
|
||||
// c. Assert: v is not undefined.
|
||||
// d. Perform ! CreateDataPropertyOrThrow(options, p, v).
|
||||
MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, display_names->locale())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, display_names->style_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.type, PrimitiveString::create(vm, display_names->type_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.fallback, PrimitiveString::create(vm, display_names->fallback_string())));
|
||||
|
||||
// NOTE: Step 4c indicates languageDisplay must not be undefined, but it is only set when the type option is language.
|
||||
if (display_names->has_language_display())
|
||||
MUST(options->create_data_property_or_throw(vm.names.languageDisplay, PrimitiveString::create(vm, display_names->language_display_string())));
|
||||
|
||||
// 5. Return options.
|
||||
return options;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -22,8 +22,8 @@ public:
|
|||
private:
|
||||
explicit DisplayNamesPrototype(Realm&);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(of);
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(of);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -26,13 +26,38 @@ void ListFormatPrototype::initialize(Realm& realm)
|
|||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 14.3.2 Intl.ListFormat.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype-toStringTag
|
||||
// 14.3.5 Intl.ListFormat.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype-toStringTag
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.ListFormat"_string), Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
define_native_function(realm, vm.names.format, format, 1, attr);
|
||||
define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr);
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
}
|
||||
|
||||
// 14.3.2 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let lf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(lf, [[InitializedListFormat]]).
|
||||
auto list_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto options = Object::create(realm, realm.intrinsics().object_prototype());
|
||||
|
||||
// 4. For each row of Table 24, except the header row, in table order, do
|
||||
// a. Let p be the Property value of the current row.
|
||||
// b. Let v be the value of lf's internal slot whose name is the Internal Slot value of the current row.
|
||||
// c. Assert: v is not undefined.
|
||||
// d. Perform ! CreateDataPropertyOrThrow(options, p, v).
|
||||
MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, list_format->locale())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.type, PrimitiveString::create(vm, list_format->type_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, list_format->style_string())));
|
||||
|
||||
// 5. Return options.
|
||||
return options;
|
||||
}
|
||||
|
||||
// 14.3.3 Intl.ListFormat.prototype.format ( list ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.format
|
||||
|
@ -68,29 +93,4 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::format_to_parts)
|
|||
return format_list_to_parts(vm, list_format, string_list);
|
||||
}
|
||||
|
||||
// 14.3.5 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let lf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(lf, [[InitializedListFormat]]).
|
||||
auto list_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto options = Object::create(realm, realm.intrinsics().object_prototype());
|
||||
|
||||
// 4. For each row of Table 24, except the header row, in table order, do
|
||||
// a. Let p be the Property value of the current row.
|
||||
// b. Let v be the value of lf's internal slot whose name is the Internal Slot value of the current row.
|
||||
// c. Assert: v is not undefined.
|
||||
// d. Perform ! CreateDataPropertyOrThrow(options, p, v).
|
||||
MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, list_format->locale())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.type, PrimitiveString::create(vm, list_format->type_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, list_format->style_string())));
|
||||
|
||||
// 5. Return options.
|
||||
return options;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -22,9 +22,9 @@ public:
|
|||
private:
|
||||
explicit ListFormatPrototype(Realm&);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_to_parts);
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ void LocalePrototype::initialize(Realm& realm)
|
|||
define_native_function(realm, vm.names.getTextInfo, get_text_info, 0, attr);
|
||||
define_native_function(realm, vm.names.getWeekInfo, get_week_info, 0, attr);
|
||||
|
||||
// 15.3.2 Intl.Locale.prototype[ @@toStringTag ], https://tc39.es/ecma402/#sec-Intl.Locale.prototype-@@tostringtag
|
||||
// 15.3.15 Intl.Locale.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.locale.prototype-%symbol.tostringtag%
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.Locale"_string), Attribute::Configurable);
|
||||
|
||||
define_native_accessor(realm, vm.names.baseName, base_name, {}, Attribute::Configurable);
|
||||
|
@ -48,57 +48,14 @@ void LocalePrototype::initialize(Realm& realm)
|
|||
define_native_accessor(realm, vm.names.collation, collation, {}, Attribute::Configurable);
|
||||
define_native_accessor(realm, vm.names.firstDayOfWeek, first_day_of_week, {}, Attribute::Configurable);
|
||||
define_native_accessor(realm, vm.names.hourCycle, hour_cycle, {}, Attribute::Configurable);
|
||||
define_native_accessor(realm, vm.names.language, language, {}, Attribute::Configurable);
|
||||
define_native_accessor(realm, vm.names.numberingSystem, numbering_system, {}, Attribute::Configurable);
|
||||
define_native_accessor(realm, vm.names.numeric, numeric, {}, Attribute::Configurable);
|
||||
define_native_accessor(realm, vm.names.language, language, {}, Attribute::Configurable);
|
||||
define_native_accessor(realm, vm.names.script, script, {}, Attribute::Configurable);
|
||||
define_native_accessor(realm, vm.names.region, region, {}, Attribute::Configurable);
|
||||
define_native_accessor(realm, vm.names.script, script, {}, Attribute::Configurable);
|
||||
}
|
||||
|
||||
// 15.3.3 Intl.Locale.prototype.maximize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set maximal to loc.[[Locale]].
|
||||
auto maximal = Unicode::add_likely_subtags(locale_object->locale()).value_or(locale_object->locale());
|
||||
|
||||
// 4. Return ! Construct(%Locale%, maximal).
|
||||
return Locale::create(realm, locale_object, move(maximal));
|
||||
}
|
||||
|
||||
// 15.3.4 Intl.Locale.prototype.minimize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set minimal to loc.[[Locale]].
|
||||
auto minimal = Unicode::remove_likely_subtags(locale_object->locale()).value_or(locale_object->locale());
|
||||
|
||||
// 4. Return ! Construct(%Locale%, minimal).
|
||||
return Locale::create(realm, locale_object, move(minimal));
|
||||
}
|
||||
|
||||
// 15.3.5 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::to_string)
|
||||
{
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Return loc.[[Locale]].
|
||||
return PrimitiveString::create(vm, locale_object->locale());
|
||||
}
|
||||
|
||||
// 15.3.6 get Intl.Locale.prototype.baseName, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.baseName
|
||||
// 15.3.2 get Intl.Locale.prototype.baseName, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.baseName
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::base_name)
|
||||
{
|
||||
// 1. Let loc be the this value.
|
||||
|
@ -121,12 +78,12 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::base_name)
|
|||
__JS_ENUMERATE(hour_cycle) \
|
||||
__JS_ENUMERATE(numbering_system)
|
||||
|
||||
// 15.3.7 get Intl.Locale.prototype.calendar, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar
|
||||
// 15.3.8 get Intl.Locale.prototype.caseFirst, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst
|
||||
// 15.3.9 get Intl.Locale.prototype.collation, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation
|
||||
// 15.3.3 get Intl.Locale.prototype.calendar, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.calendar
|
||||
// 15.3.4 get Intl.Locale.prototype.caseFirst, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.caseFirst
|
||||
// 15.3.5 get Intl.Locale.prototype.collation, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.collation
|
||||
// 1.4.10 get Intl.Locale.prototype.firstDayOfWeek, https://tc39.es/proposal-intl-locale-info/#sec-Intl.Locale.prototype.firstDayOfWeek
|
||||
// 15.3.10 get Intl.Locale.prototype.hourCycle, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle
|
||||
// 15.3.12 get Intl.Locale.prototype.numberingSystem, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numberingSystem
|
||||
// 15.3.6 get Intl.Locale.prototype.hourCycle, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.hourCycle
|
||||
// 15.3.10 get Intl.Locale.prototype.numberingSystem, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numberingSystem
|
||||
#define __JS_ENUMERATE(keyword) \
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::keyword) \
|
||||
{ \
|
||||
|
@ -138,18 +95,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::base_name)
|
|||
JS_ENUMERATE_LOCALE_KEYWORD_PROPERTIES
|
||||
#undef __JS_ENUMERATE
|
||||
|
||||
// 15.3.11 get Intl.Locale.prototype.numeric, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numeric
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::numeric)
|
||||
{
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Return loc.[[Numeric]].
|
||||
return Value(locale_object->numeric());
|
||||
}
|
||||
|
||||
// 15.3.13 get Intl.Locale.prototype.language, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.language
|
||||
// 15.3.7 get Intl.Locale.prototype.language, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.language
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::language)
|
||||
{
|
||||
// 1. Let loc be the this value.
|
||||
|
@ -166,7 +112,71 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::language)
|
|||
return PrimitiveString::create(vm, locale->language_id.language.release_value());
|
||||
}
|
||||
|
||||
// 15.3.14 get Intl.Locale.prototype.script, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.script
|
||||
// 15.3.8 Intl.Locale.prototype.maximize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.maximize
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::maximize)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set maximal to loc.[[Locale]].
|
||||
auto maximal = Unicode::add_likely_subtags(locale_object->locale()).value_or(locale_object->locale());
|
||||
|
||||
// 4. Return ! Construct(%Locale%, maximal).
|
||||
return Locale::create(realm, locale_object, move(maximal));
|
||||
}
|
||||
|
||||
// 15.3.9 Intl.Locale.prototype.minimize ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.minimize
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::minimize)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let minimal be the result of the Remove Likely Subtags algorithm applied to loc.[[Locale]]. If an error is signaled, set minimal to loc.[[Locale]].
|
||||
auto minimal = Unicode::remove_likely_subtags(locale_object->locale()).value_or(locale_object->locale());
|
||||
|
||||
// 4. Return ! Construct(%Locale%, minimal).
|
||||
return Locale::create(realm, locale_object, move(minimal));
|
||||
}
|
||||
|
||||
// 15.3.11 get Intl.Locale.prototype.numeric, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.numeric
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::numeric)
|
||||
{
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Return loc.[[Numeric]].
|
||||
return Value(locale_object->numeric());
|
||||
}
|
||||
|
||||
// 15.3.12 get Intl.Locale.prototype.region, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.region
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::region)
|
||||
{
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let locale be loc.[[Locale]].
|
||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
||||
|
||||
// 4. Assert: locale matches the unicode_locale_id production.
|
||||
VERIFY(locale.has_value());
|
||||
|
||||
// 5. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined.
|
||||
if (!locale->language_id.region.has_value())
|
||||
return js_undefined();
|
||||
|
||||
// 6. Return the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id.
|
||||
return PrimitiveString::create(vm, locale->language_id.region.release_value());
|
||||
}
|
||||
|
||||
// 15.3.13 get Intl.Locale.prototype.script, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.script
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::script)
|
||||
{
|
||||
// 1. Let loc be the this value.
|
||||
|
@ -187,25 +197,15 @@ JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::script)
|
|||
return PrimitiveString::create(vm, locale->language_id.script.release_value());
|
||||
}
|
||||
|
||||
// 15.3.15 get Intl.Locale.prototype.region, https://tc39.es/ecma402/#sec-Intl.Locale.prototype.region
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::region)
|
||||
// 15.3.14 Intl.Locale.prototype.toString ( ), https://tc39.es/ecma402/#sec-Intl.Locale.prototype.toString
|
||||
JS_DEFINE_NATIVE_FUNCTION(LocalePrototype::to_string)
|
||||
{
|
||||
// 1. Let loc be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(loc, [[InitializedLocale]]).
|
||||
auto locale_object = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let locale be loc.[[Locale]].
|
||||
auto locale = Unicode::parse_unicode_locale_id(locale_object->locale());
|
||||
|
||||
// 4. Assert: locale matches the unicode_locale_id production.
|
||||
VERIFY(locale.has_value());
|
||||
|
||||
// 5. If the unicode_language_id production of locale does not contain the ["-" unicode_region_subtag] sequence, return undefined.
|
||||
if (!locale->language_id.region.has_value())
|
||||
return js_undefined();
|
||||
|
||||
// 6. Return the substring of locale corresponding to the unicode_region_subtag production of the unicode_language_id.
|
||||
return PrimitiveString::create(vm, locale->language_id.region.release_value());
|
||||
// 3. Return loc.[[Locale]].
|
||||
return PrimitiveString::create(vm, locale_object->locale());
|
||||
}
|
||||
|
||||
#define JS_ENUMERATE_LOCALE_INFO_PROPERTIES \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2022, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -32,11 +32,11 @@ private:
|
|||
JS_DECLARE_NATIVE_FUNCTION(collation);
|
||||
JS_DECLARE_NATIVE_FUNCTION(first_day_of_week);
|
||||
JS_DECLARE_NATIVE_FUNCTION(hour_cycle);
|
||||
JS_DECLARE_NATIVE_FUNCTION(language);
|
||||
JS_DECLARE_NATIVE_FUNCTION(numbering_system);
|
||||
JS_DECLARE_NATIVE_FUNCTION(numeric);
|
||||
JS_DECLARE_NATIVE_FUNCTION(language);
|
||||
JS_DECLARE_NATIVE_FUNCTION(script);
|
||||
JS_DECLARE_NATIVE_FUNCTION(region);
|
||||
JS_DECLARE_NATIVE_FUNCTION(script);
|
||||
JS_DECLARE_NATIVE_FUNCTION(get_calendars);
|
||||
JS_DECLARE_NATIVE_FUNCTION(get_collations);
|
||||
JS_DECLARE_NATIVE_FUNCTION(get_hour_cycles);
|
||||
|
|
|
@ -27,113 +27,19 @@ void NumberFormatPrototype::initialize(Realm& realm)
|
|||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 16.3.2 Intl.NumberFormat.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.numberformat.prototype-@@tostringtag
|
||||
// 16.3.7 Intl.NumberFormat.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.numberformat.prototype-%symbol.tostringtag%
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.NumberFormat"_string), Attribute::Configurable);
|
||||
|
||||
define_native_accessor(realm, vm.names.format, format, nullptr, Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr);
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
define_native_function(realm, vm.names.formatRange, format_range, 2, attr);
|
||||
define_native_function(realm, vm.names.formatRangeToParts, format_range_to_parts, 2, attr);
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
define_native_function(realm, vm.names.formatToParts, format_to_parts, 1, attr);
|
||||
}
|
||||
|
||||
// 16.3.3 get Intl.NumberFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.numberformat.prototype.format
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let nf be the this value.
|
||||
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||
// a. Set nf to ? UnwrapNumberFormat(nf).
|
||||
// 3. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
|
||||
auto number_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 4. If nf.[[BoundFormat]] is undefined, then
|
||||
if (!number_format->bound_format()) {
|
||||
// a. Let F be a new built-in function object as defined in Number Format Functions (16.1.4).
|
||||
// b. Set F.[[NumberFormat]] to nf.
|
||||
auto bound_format = NumberFormatFunction::create(realm, number_format);
|
||||
|
||||
// c. Set nf.[[BoundFormat]] to F.
|
||||
number_format->set_bound_format(bound_format);
|
||||
}
|
||||
|
||||
// 5. Return nf.[[BoundFormat]].
|
||||
return number_format->bound_format();
|
||||
}
|
||||
|
||||
// 16.3.4 Intl.NumberFormat.prototype.formatToParts ( value ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formattoparts
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts)
|
||||
{
|
||||
auto value = vm.argument(0);
|
||||
|
||||
// 1. Let nf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
|
||||
auto number_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let x be ? ToIntlMathematicalValue(value).
|
||||
auto mathematical_value = TRY(to_intl_mathematical_value(vm, value));
|
||||
|
||||
// 4. Return ? FormatNumericToParts(nf, x).
|
||||
return format_numeric_to_parts(vm, number_format, move(mathematical_value));
|
||||
}
|
||||
|
||||
// 16.3.5 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrange
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range)
|
||||
{
|
||||
auto start = vm.argument(0);
|
||||
auto end = vm.argument(1);
|
||||
|
||||
// 1. Let nf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
|
||||
auto number_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
||||
if (start.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "start"sv);
|
||||
if (end.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
|
||||
|
||||
// 4. Let x be ? ToIntlMathematicalValue(start).
|
||||
auto x = TRY(to_intl_mathematical_value(vm, start));
|
||||
|
||||
// 5. Let y be ? ToIntlMathematicalValue(end).
|
||||
auto y = TRY(to_intl_mathematical_value(vm, end));
|
||||
|
||||
// 6. Return ? FormatNumericRange(nf, x, y).
|
||||
auto formatted = TRY(format_numeric_range(vm, number_format, move(x), move(y)));
|
||||
return PrimitiveString::create(vm, move(formatted));
|
||||
}
|
||||
|
||||
// 16.3.6 Intl.NumberFormat.prototype.formatRangeToParts ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrangetoparts
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts)
|
||||
{
|
||||
auto start = vm.argument(0);
|
||||
auto end = vm.argument(1);
|
||||
|
||||
// 1. Let nf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
|
||||
auto number_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
||||
if (start.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "start"sv);
|
||||
if (end.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
|
||||
|
||||
// 4. Let x be ? ToIntlMathematicalValue(start).
|
||||
auto x = TRY(to_intl_mathematical_value(vm, start));
|
||||
|
||||
// 5. Let y be ? ToIntlMathematicalValue(end).
|
||||
auto y = TRY(to_intl_mathematical_value(vm, end));
|
||||
|
||||
// 6. Return ? FormatNumericRangeToParts(nf, x, y).
|
||||
return TRY(format_numeric_range_to_parts(vm, number_format, move(x), move(y)));
|
||||
}
|
||||
|
||||
// 16.3.7 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions
|
||||
// 16.3.2 Intl.NumberFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.resolvedoptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
@ -188,4 +94,98 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options)
|
|||
return options;
|
||||
}
|
||||
|
||||
// 16.3.3 get Intl.NumberFormat.prototype.format, https://tc39.es/ecma402/#sec-intl.numberformat.prototype.format
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let nf be the this value.
|
||||
// 2. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
|
||||
// a. Set nf to ? UnwrapNumberFormat(nf).
|
||||
// 3. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
|
||||
auto number_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 4. If nf.[[BoundFormat]] is undefined, then
|
||||
if (!number_format->bound_format()) {
|
||||
// a. Let F be a new built-in function object as defined in Number Format Functions (16.1.4).
|
||||
// b. Set F.[[NumberFormat]] to nf.
|
||||
auto bound_format = NumberFormatFunction::create(realm, number_format);
|
||||
|
||||
// c. Set nf.[[BoundFormat]] to F.
|
||||
number_format->set_bound_format(bound_format);
|
||||
}
|
||||
|
||||
// 5. Return nf.[[BoundFormat]].
|
||||
return number_format->bound_format();
|
||||
}
|
||||
|
||||
// 16.3.4 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrange
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range)
|
||||
{
|
||||
auto start = vm.argument(0);
|
||||
auto end = vm.argument(1);
|
||||
|
||||
// 1. Let nf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
|
||||
auto number_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
||||
if (start.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "start"sv);
|
||||
if (end.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
|
||||
|
||||
// 4. Let x be ? ToIntlMathematicalValue(start).
|
||||
auto x = TRY(to_intl_mathematical_value(vm, start));
|
||||
|
||||
// 5. Let y be ? ToIntlMathematicalValue(end).
|
||||
auto y = TRY(to_intl_mathematical_value(vm, end));
|
||||
|
||||
// 6. Return ? FormatNumericRange(nf, x, y).
|
||||
auto formatted = TRY(format_numeric_range(vm, number_format, move(x), move(y)));
|
||||
return PrimitiveString::create(vm, move(formatted));
|
||||
}
|
||||
|
||||
// 16.3.5 Intl.NumberFormat.prototype.formatRangeToParts ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrangetoparts
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_range_to_parts)
|
||||
{
|
||||
auto start = vm.argument(0);
|
||||
auto end = vm.argument(1);
|
||||
|
||||
// 1. Let nf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
|
||||
auto number_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
||||
if (start.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "start"sv);
|
||||
if (end.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
|
||||
|
||||
// 4. Let x be ? ToIntlMathematicalValue(start).
|
||||
auto x = TRY(to_intl_mathematical_value(vm, start));
|
||||
|
||||
// 5. Let y be ? ToIntlMathematicalValue(end).
|
||||
auto y = TRY(to_intl_mathematical_value(vm, end));
|
||||
|
||||
// 6. Return ? FormatNumericRangeToParts(nf, x, y).
|
||||
return TRY(format_numeric_range_to_parts(vm, number_format, move(x), move(y)));
|
||||
}
|
||||
|
||||
// 16.3.6 Intl.NumberFormat.prototype.formatToParts ( value ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formattoparts
|
||||
JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts)
|
||||
{
|
||||
auto value = vm.argument(0);
|
||||
|
||||
// 1. Let nf be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(nf, [[InitializedNumberFormat]]).
|
||||
auto number_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let x be ? ToIntlMathematicalValue(value).
|
||||
auto mathematical_value = TRY(to_intl_mathematical_value(vm, value));
|
||||
|
||||
// 4. Return ? FormatNumericToParts(nf, x).
|
||||
return format_numeric_to_parts(vm, number_format, move(mathematical_value));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -22,11 +22,11 @@ public:
|
|||
private:
|
||||
explicit NumberFormatPrototype(Realm&);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_to_parts);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_range);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_range_to_parts);
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_to_parts);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -27,58 +27,16 @@ void PluralRulesPrototype::initialize(Realm& realm)
|
|||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 17.3.2 Intl.PluralRules.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.pluralrules.prototype-tostringtag
|
||||
// 17.3.5 Intl.PluralRules.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.pluralrules.prototype-%symbol.tostringtag%
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.PluralRules"_string), Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
define_native_function(realm, vm.names.select, select, 1, attr);
|
||||
define_native_function(realm, vm.names.selectRange, select_range, 2, attr);
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
}
|
||||
|
||||
// 17.3.3 Intl.PluralRules.prototype.select ( value ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.select
|
||||
JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select)
|
||||
{
|
||||
// 1. Let pr be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
|
||||
auto plural_rules = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let n be ? ToNumber(value).
|
||||
auto number = TRY(vm.argument(0).to_number(vm));
|
||||
|
||||
// 4. Return ! ResolvePlural(pr, n).[[PluralCategory]].
|
||||
auto plurality = resolve_plural(plural_rules, number);
|
||||
return PrimitiveString::create(vm, Unicode::plural_category_to_string(plurality));
|
||||
}
|
||||
|
||||
// 17.3.4 Intl.PluralRules.prototype.selectRange ( start, end ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.selectrange
|
||||
JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range)
|
||||
{
|
||||
auto start = vm.argument(0);
|
||||
auto end = vm.argument(1);
|
||||
|
||||
// 1. Let pr be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
|
||||
auto plural_rules = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
||||
if (start.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "start"sv);
|
||||
if (end.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
|
||||
|
||||
// 4. Let x be ? ToNumber(start).
|
||||
auto x = TRY(start.to_number(vm));
|
||||
|
||||
// 5. Let y be ? ToNumber(end).
|
||||
auto y = TRY(end.to_number(vm));
|
||||
|
||||
// 6. Return ? ResolvePluralRange(pr, x, y).
|
||||
auto plurality = TRY(resolve_plural_range(vm, plural_rules, x, y));
|
||||
return PrimitiveString::create(vm, Unicode::plural_category_to_string(plurality));
|
||||
}
|
||||
|
||||
// 17.3.5 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions
|
||||
// 17.3.2 Intl.PluralRules.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.resolvedoptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
@ -127,4 +85,46 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::resolved_options)
|
|||
return options;
|
||||
}
|
||||
|
||||
// 17.3.3 Intl.PluralRules.prototype.select ( value ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.select
|
||||
JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select)
|
||||
{
|
||||
// 1. Let pr be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
|
||||
auto plural_rules = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let n be ? ToNumber(value).
|
||||
auto number = TRY(vm.argument(0).to_number(vm));
|
||||
|
||||
// 4. Return ! ResolvePlural(pr, n).[[PluralCategory]].
|
||||
auto plurality = resolve_plural(plural_rules, number);
|
||||
return PrimitiveString::create(vm, Unicode::plural_category_to_string(plurality));
|
||||
}
|
||||
|
||||
// 17.3.4 Intl.PluralRules.prototype.selectRange ( start, end ), https://tc39.es/ecma402/#sec-intl.pluralrules.prototype.selectrange
|
||||
JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select_range)
|
||||
{
|
||||
auto start = vm.argument(0);
|
||||
auto end = vm.argument(1);
|
||||
|
||||
// 1. Let pr be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
|
||||
auto plural_rules = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. If start is undefined or end is undefined, throw a TypeError exception.
|
||||
if (start.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "start"sv);
|
||||
if (end.is_undefined())
|
||||
return vm.throw_completion<TypeError>(ErrorType::IsUndefined, "end"sv);
|
||||
|
||||
// 4. Let x be ? ToNumber(start).
|
||||
auto x = TRY(start.to_number(vm));
|
||||
|
||||
// 5. Let y be ? ToNumber(end).
|
||||
auto y = TRY(end.to_number(vm));
|
||||
|
||||
// 6. Return ? ResolvePluralRange(pr, x, y).
|
||||
auto plurality = TRY(resolve_plural_range(vm, plural_rules, x, y));
|
||||
return PrimitiveString::create(vm, Unicode::plural_category_to_string(plurality));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ public:
|
|||
private:
|
||||
explicit PluralRulesPrototype(Realm&);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(select);
|
||||
JS_DECLARE_NATIVE_FUNCTION(select_range);
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,13 +25,39 @@ void RelativeTimeFormatPrototype::initialize(Realm& realm)
|
|||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 18.3.2 Intl.RelativeTimeFormat.prototype[ @@toStringTag ], https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat.prototype-toStringTag
|
||||
// 18.3.5 Intl.RelativeTimeFormat.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat.prototype-toStringTag
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.RelativeTimeFormat"_string), Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
define_native_function(realm, vm.names.format, format, 2, attr);
|
||||
define_native_function(realm, vm.names.formatToParts, format_to_parts, 2, attr);
|
||||
define_native_function(realm, vm.names.resolvedOptions, resolved_options, 0, attr);
|
||||
}
|
||||
|
||||
// 18.3.2 Intl.RelativeTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.relativetimeformat.prototype.resolvedoptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let relativeTimeFormat be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]).
|
||||
auto relative_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto options = Object::create(realm, realm.intrinsics().object_prototype());
|
||||
|
||||
// 4. For each row of Table 30, except the header row, in table order, do
|
||||
// a. Let p be the Property value of the current row.
|
||||
// b. Let v be the value of relativeTimeFormat's internal slot whose name is the Internal Slot value of the current row.
|
||||
// c. Assert: v is not undefined.
|
||||
// d. Perform ! CreateDataPropertyOrThrow(options, p, v).
|
||||
MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, relative_time_format->locale())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, relative_time_format->style_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.numeric, PrimitiveString::create(vm, relative_time_format->numeric_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.numberingSystem, PrimitiveString::create(vm, relative_time_format->numbering_system())));
|
||||
|
||||
// 5. Return options.
|
||||
return options;
|
||||
}
|
||||
|
||||
// 18.3.3 Intl.RelativeTimeFormat.prototype.format ( value, unit ), https://tc39.es/ecma402/#sec-Intl.RelativeTimeFormat.prototype.format
|
||||
|
@ -69,30 +95,4 @@ JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::format_to_parts)
|
|||
return TRY(format_relative_time_to_parts(vm, relative_time_format, value.as_double(), unit.bytes_as_string_view()));
|
||||
}
|
||||
|
||||
// 18.3.5 Intl.RelativeTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.relativetimeformat.prototype.resolvedoptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(RelativeTimeFormatPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let relativeTimeFormat be the this value.
|
||||
// 2. Perform ? RequireInternalSlot(relativeTimeFormat, [[InitializedRelativeTimeFormat]]).
|
||||
auto relative_time_format = TRY(typed_this_object(vm));
|
||||
|
||||
// 3. Let options be OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto options = Object::create(realm, realm.intrinsics().object_prototype());
|
||||
|
||||
// 4. For each row of Table 30, except the header row, in table order, do
|
||||
// a. Let p be the Property value of the current row.
|
||||
// b. Let v be the value of relativeTimeFormat's internal slot whose name is the Internal Slot value of the current row.
|
||||
// c. Assert: v is not undefined.
|
||||
// d. Perform ! CreateDataPropertyOrThrow(options, p, v).
|
||||
MUST(options->create_data_property_or_throw(vm.names.locale, PrimitiveString::create(vm, relative_time_format->locale())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.style, PrimitiveString::create(vm, relative_time_format->style_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.numeric, PrimitiveString::create(vm, relative_time_format->numeric_string())));
|
||||
MUST(options->create_data_property_or_throw(vm.names.numberingSystem, PrimitiveString::create(vm, relative_time_format->numbering_system())));
|
||||
|
||||
// 5. Return options.
|
||||
return options;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2022-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -22,9 +22,9 @@ public:
|
|||
private:
|
||||
explicit RelativeTimeFormatPrototype(Realm&);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format);
|
||||
JS_DECLARE_NATIVE_FUNCTION(format_to_parts);
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@ namespace JS::Intl {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(SegmentIterator);
|
||||
|
||||
// 19.6.1 CreateSegmentIterator ( segmenter, string ), https://tc39.es/ecma402/#sec-createsegmentsobject
|
||||
// 19.6.1 CreateSegmentIterator ( segmenter, string ), https://tc39.es/ecma402/#sec-createsegmentiterator
|
||||
GC::Ref<SegmentIterator> SegmentIterator::create(Realm& realm, Unicode::Segmenter const& segmenter, Utf16View const& string, Segments const& segments)
|
||||
{
|
||||
// 1. Let internalSlotsList be « [[IteratingSegmenter]], [[IteratedString]], [[IteratedStringNextSegmentCodeUnitIndex]] ».
|
||||
// 2. Let iterator be OrdinaryObjectCreate(%SegmentIteratorPrototype%, internalSlotsList).
|
||||
// 2. Let iterator be OrdinaryObjectCreate(%IntlSegmentIteratorPrototype%, internalSlotsList).
|
||||
// 3. Set iterator.[[IteratingSegmenter]] to segmenter.
|
||||
// 4. Set iterator.[[IteratedString]] to string.
|
||||
// 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0.
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace JS::Intl {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(SegmentIteratorPrototype);
|
||||
|
||||
// 19.6.2 The %SegmentIteratorPrototype% Object, https://tc39.es/ecma402/#sec-%segmentiteratorprototype%-object
|
||||
// 19.6.2 The %IntlSegmentIteratorPrototype% Object, https://tc39.es/ecma402/#sec-%intlsegmentiteratorprototype%-object
|
||||
SegmentIteratorPrototype::SegmentIteratorPrototype(Realm& realm)
|
||||
: PrototypeObject(realm.intrinsics().iterator_prototype())
|
||||
{
|
||||
|
@ -26,14 +26,14 @@ void SegmentIteratorPrototype::initialize(Realm& realm)
|
|||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 19.6.2.2 %SegmentIteratorPrototype% [ @@toStringTag ], https://tc39.es/ecma402/#sec-%segmentiteratorprototype%.@@tostringtag
|
||||
// 19.6.2.2 %IntlSegmentIteratorPrototype% [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-%intlsegmentiteratorprototype%.%symbol.tostringtag%
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Segmenter String Iterator"_string), Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
define_native_function(realm, vm.names.next, next, 0, attr);
|
||||
}
|
||||
|
||||
// 19.6.2.1 %SegmentIteratorPrototype%.next ( ), https://tc39.es/ecma402/#sec-%segmentiteratorprototype%.next
|
||||
// 19.6.2.1 %IntlSegmentIteratorPrototype%.next ( ), https://tc39.es/ecma402/#sec-%intlsegmentiteratorprototype%.next
|
||||
JS_DEFINE_NATIVE_FUNCTION(SegmentIteratorPrototype::next)
|
||||
{
|
||||
// 1. Let iterator be the this value.
|
||||
|
|
|
@ -95,7 +95,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmenterConstructor::supported_locales_of)
|
|||
auto locales = vm.argument(0);
|
||||
auto options = vm.argument(1);
|
||||
|
||||
// 1. Let availableLocales be %Segmenter%.[[AvailableLocales]].
|
||||
// 1. Let availableLocales be %Intl.Segmenter%.[[AvailableLocales]].
|
||||
|
||||
// 2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
|
||||
auto requested_locales = TRY(canonicalize_locale_list(vm, locales));
|
||||
|
|
|
@ -25,7 +25,7 @@ void SegmenterPrototype::initialize(Realm& realm)
|
|||
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 19.3.2 Intl.Segmenter.prototype [ @@toStringTag ], https://tc39.es/ecma402/#sec-intl.segmenter.prototype-@@tostringtag
|
||||
// 19.3.4 Intl.Segmenter.prototype [ %Symbol.toStringTag% ], https://tc39.es/ecma402/#sec-intl.segmenter.prototype-%symbol.tostringtag%
|
||||
define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Intl.Segmenter"_string), Attribute::Configurable);
|
||||
|
||||
u8 attr = Attribute::Writable | Attribute::Configurable;
|
||||
|
@ -33,7 +33,7 @@ void SegmenterPrototype::initialize(Realm& realm)
|
|||
define_native_function(realm, vm.names.segment, segment, 1, attr);
|
||||
}
|
||||
|
||||
// 19.3.4 Intl.Segmenter.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.segmenter.prototype.resolvedoptions
|
||||
// 19.3.2 Intl.Segmenter.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.segmenter.prototype.resolvedoptions
|
||||
JS_DEFINE_NATIVE_FUNCTION(SegmenterPrototype::resolved_options)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
|
|
@ -22,8 +22,8 @@ public:
|
|||
private:
|
||||
explicit SegmenterPrototype(Realm&);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(segment);
|
||||
JS_DECLARE_NATIVE_FUNCTION(resolved_options);
|
||||
JS_DECLARE_NATIVE_FUNCTION(segment);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ GC_DEFINE_ALLOCATOR(Segments);
|
|||
GC::Ref<Segments> Segments::create(Realm& realm, Unicode::Segmenter const& segmenter, Utf16String string)
|
||||
{
|
||||
// 1. Let internalSlotsList be « [[SegmentsSegmenter]], [[SegmentsString]] ».
|
||||
// 2. Let segments be OrdinaryObjectCreate(%SegmentsPrototype%, internalSlotsList).
|
||||
// 2. Let segments be OrdinaryObjectCreate(%IntlSegmentsPrototype%, internalSlotsList).
|
||||
// 3. Set segments.[[SegmentsSegmenter]] to segmenter.
|
||||
// 4. Set segments.[[SegmentsString]] to string.
|
||||
// 5. Return segments.
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace JS::Intl {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(SegmentsPrototype);
|
||||
|
||||
// 19.5.2 The %SegmentsPrototype% Object, https://tc39.es/ecma402/#sec-%segmentsprototype%-object
|
||||
// 19.5.2 The %IntlSegmentsPrototype% Object, https://tc39.es/ecma402/#sec-%intlsegmentsprototype%-object
|
||||
SegmentsPrototype::SegmentsPrototype(Realm& realm)
|
||||
: PrototypeObject(realm.intrinsics().object_prototype())
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ void SegmentsPrototype::initialize(Realm& realm)
|
|||
define_native_function(realm, vm.names.containing, containing, 1, attr);
|
||||
}
|
||||
|
||||
// 19.5.2.1 %SegmentsPrototype%.containing ( index ), https://tc39.es/ecma402/#sec-%segmentsprototype%.containing
|
||||
// 19.5.2.1 %IntlSegmentsPrototype%.containing ( index ), https://tc39.es/ecma402/#sec-%intlsegmentsprototype%.containing
|
||||
JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::containing)
|
||||
{
|
||||
// 1. Let segments be the this value.
|
||||
|
@ -63,7 +63,7 @@ JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::containing)
|
|||
return TRY(create_segment_data_object(vm, segmenter, string, start_index, end_index));
|
||||
}
|
||||
|
||||
// 19.5.2.2 %SegmentsPrototype% [ @@iterator ] ( ), https://tc39.es/ecma402/#sec-%segmentsprototype%-@@iterator
|
||||
// 19.5.2.2 %IntlSegmentsPrototype% [ %Symbol.iterator% ] ( ), https://tc39.es/ecma402/#sec-%intlsegmentsprototype%-%symbol.iterator%
|
||||
JS_DEFINE_NATIVE_FUNCTION(SegmentsPrototype::symbol_iterator)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
|
Loading…
Add table
Reference in a new issue