diff options
author | Timothy Flynn <trflynn89@pm.me> | 2021-07-19 13:34:41 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-22 09:10:44 +0200 |
commit | 892bfdbbcf187be044175773af5352f798f6c5a1 (patch) | |
tree | fee1dae8ea1d19074f5d13ef1b9d76a8bb66a521 /Userland/Libraries/LibJS | |
parent | 60d8852fc2c9b76f2e966d306847d2b024afad61 (diff) | |
download | serenity-892bfdbbcf187be044175773af5352f798f6c5a1.zip |
LibJS: Implement String.prototype.substr with UTF-16 code units
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/StringPrototype.cpp | 17 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js | 11 |
2 files changed, 18 insertions, 10 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index 4fb82ee1da..fa63776a58 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -527,14 +527,12 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substring) // B.2.3.1 String.prototype.substr ( start, length ), https://tc39.es/ecma262/#sec-string.prototype.substr JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr) { - auto string = ak_string_from(vm, global_object); - if (!string.has_value()) + auto string = utf16_string_from(vm, global_object); + if (vm.exception()) return {}; - if (vm.argument_count() == 0) - return js_string(vm, *string); - // FIXME: this should index a UTF-16 code_point view of the string. - auto size = (i32)string->length(); + Utf16View utf16_string_view { string }; + auto size = utf16_string_view.length_in_code_units(); auto int_start = vm.argument(0).to_integer_or_infinity(global_object); if (vm.exception()) @@ -551,15 +549,14 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::substr) return {}; if (Value(int_start).is_positive_infinity() || (int_length <= 0) || Value(int_length).is_positive_infinity()) - return js_string(vm, String("")); + return js_string(vm, String::empty()); auto int_end = min((i32)(int_start + int_length), size); if (int_start >= int_end) - return js_string(vm, String("")); + return js_string(vm, String::empty()); - auto string_part = string->substring(int_start, int_end - int_start); - return js_string(vm, string_part); + return js_string(vm, utf16_string_view.substring_view(int_start, int_end - int_start)); } // 22.1.3.7 String.prototype.includes ( searchString [ , position ] ), https://tc39.es/ecma262/#sec-string.prototype.includes diff --git a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js index b6d26f6023..d452643295 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js +++ b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js @@ -17,3 +17,14 @@ test("basic functionality", () => { expect("hello friends".substr(-7)).toBe("friends"); expect("hello friends".substr(-3, -5)).toBe(""); }); + +test("UTF-16", () => { + var s = "😀"; + expect(s).toHaveLength(2); + expect(s.substr()).toBe("😀"); + expect(s.substr(0)).toBe("😀"); + expect(s.substr(0, 2)).toBe("😀"); + expect(s.substr(0, 1)).toBe("\ud83d"); + expect(s.substr(1, 1)).toBe("\ude00"); + expect(s.substr(2, 1)).toBe(""); +}); |