From ef2ff5f88bc7a887593a7a785ccf7480ab354a43 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Mon, 19 Jul 2021 13:46:21 -0400 Subject: [PATCH] LibJS: Implement String.prototype.at with UTF-16 code units --- .../Libraries/LibJS/Runtime/StringPrototype.cpp | 13 +++++++++---- .../Tests/builtins/String/String.prototype.at.js | 8 ++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index fa63776a58..36fa791af3 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -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 JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at) { - auto string = ak_string_from(vm, global_object); - if (!string.has_value()) + auto string = utf16_string_from(vm, global_object); + if (vm.exception()) 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); if (vm.exception()) return {}; if (Value(relative_index).is_infinity()) return js_undefined(); + Checked index { 0 }; if (relative_index >= 0) { index += relative_index; @@ -768,7 +772,8 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::at) } if (index.has_overflow() || index.value() >= length) 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 diff --git a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.at.js b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.at.js index a551a96b17..b81ddd736d 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.at.js +++ b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.at.js @@ -13,3 +13,11 @@ test("basic functionality", () => { expect(string.at(-4)).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(); +});