summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-07-19 13:34:41 -0400
committerAndreas Kling <kling@serenityos.org>2021-07-22 09:10:44 +0200
commit892bfdbbcf187be044175773af5352f798f6c5a1 (patch)
treefee1dae8ea1d19074f5d13ef1b9d76a8bb66a521 /Userland/Libraries/LibJS
parent60d8852fc2c9b76f2e966d306847d2b024afad61 (diff)
downloadserenity-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.cpp17
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.substr.js11
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("");
+});