1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:47:35 +00:00

LibJS: Implement String.prototype.at with UTF-16 code units

This commit is contained in:
Timothy Flynn 2021-07-19 13:46:21 -04:00 committed by Andreas Kling
parent 892bfdbbcf
commit ef2ff5f88b
2 changed files with 17 additions and 4 deletions

View file

@ -750,15 +750,19 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::last_index_of)
// 3.1 String.prototype.at ( index ), https://tc39.es/proposal-relative-indexing-method/#sec-string.prototype.at // 3.1 String.prototype.at ( index ), https://tc39.es/proposal-relative-indexing-method/#sec-string.prototype.at
JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at) JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at)
{ {
auto string = ak_string_from(vm, global_object); auto string = utf16_string_from(vm, global_object);
if (!string.has_value()) if (vm.exception())
return {}; return {};
auto length = string->length();
Utf16View utf16_string_view { string };
auto length = utf16_string_view.length_in_code_units();
auto relative_index = vm.argument(0).to_integer_or_infinity(global_object); auto relative_index = vm.argument(0).to_integer_or_infinity(global_object);
if (vm.exception()) if (vm.exception())
return {}; return {};
if (Value(relative_index).is_infinity()) if (Value(relative_index).is_infinity())
return js_undefined(); return js_undefined();
Checked<size_t> index { 0 }; Checked<size_t> index { 0 };
if (relative_index >= 0) { if (relative_index >= 0) {
index += relative_index; index += relative_index;
@ -768,7 +772,8 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at)
} }
if (index.has_overflow() || index.value() >= length) if (index.has_overflow() || index.value() >= length)
return js_undefined(); return js_undefined();
return js_string(vm, String::formatted("{}", (*string)[index.value()]));
return js_string(vm, utf16_string_view.substring_view(index.value(), 1));
} }
// 22.1.3.33 String.prototype [ @@iterator ] ( ), https://tc39.es/ecma262/#sec-string.prototype-@@iterator // 22.1.3.33 String.prototype [ @@iterator ] ( ), https://tc39.es/ecma262/#sec-string.prototype-@@iterator

View file

@ -13,3 +13,11 @@ test("basic functionality", () => {
expect(string.at(-4)).toBeUndefined(); expect(string.at(-4)).toBeUndefined();
expect(string.at(-Infinity)).toBeUndefined(); expect(string.at(-Infinity)).toBeUndefined();
}); });
test("UTF-16", () => {
var s = "😀";
expect(s).toHaveLength(2);
expect(s.at(0)).toBe("\ud83d");
expect(s.at(1)).toBe("\ude00");
expect(s.at(2)).toBeUndefined();
});