From 8e05b49089546d96f7fd02ff5c49d327295b88b5 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Wed, 16 Jun 2021 17:30:41 +0300 Subject: [PATCH] LibJS: Add the String.prototype.codePointAt() method This commit also brings charAt & charCodeAt closer to the specification --- .../LibJS/Runtime/CommonPropertyNames.h | 1 + .../LibJS/Runtime/StringPrototype.cpp | 47 ++++++++++++------- .../Libraries/LibJS/Runtime/StringPrototype.h | 1 + 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index 1c97d1c43c..445f3e120d 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -78,6 +78,7 @@ namespace JS { P(cleanupSome) \ P(clear) \ P(clz32) \ + P(codePointAt) \ P(concat) \ P(configurable) \ P(console) \ diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index f0d0e3a353..230498838e 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -54,6 +54,7 @@ void StringPrototype::initialize(GlobalObject& global_object) define_native_function(vm.names.charAt, char_at, 1, attr); define_native_function(vm.names.charCodeAt, char_code_at, 1, attr); + define_native_function(vm.names.codePointAt, code_point_at, 1, attr); define_native_function(vm.names.repeat, repeat, 1, attr); define_native_function(vm.names.startsWith, starts_with, 1, attr); define_native_function(vm.names.endsWith, ends_with, 1, attr); @@ -117,16 +118,12 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_at) auto string = ak_string_from(vm, global_object); if (!string.has_value()) return {}; - i32 index = 0; - if (vm.argument_count()) { - index = vm.argument(0).to_i32(global_object); - if (vm.exception()) - return {}; - } - if (index < 0 || index >= static_cast(string->length())) + auto position = vm.argument(0).to_integer_or_infinity(global_object); + if (vm.exception()) + return {}; + if (position < 0 || position >= string->length()) return js_string(vm, String::empty()); - // FIXME: This should return a character corresponding to the i'th UTF-16 code point. - return js_string(vm, string->substring(index, 1)); + return js_string(vm, string->substring(position, 1)); } // 22.1.3.2 String.prototype.charCodeAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.charcodeat @@ -135,16 +132,30 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::char_code_at) auto string = ak_string_from(vm, global_object); if (!string.has_value()) return {}; - i32 index = 0; - if (vm.argument_count()) { - index = vm.argument(0).to_i32(global_object); - if (vm.exception()) - return {}; - } - if (index < 0 || index >= static_cast(string->length())) + auto position = vm.argument(0).to_integer_or_infinity(global_object); + if (vm.exception()) + return {}; + if (position < 0 || position >= string->length()) return js_nan(); - // FIXME: This should return the i'th UTF-16 code point. - return Value((i32)(*string)[index]); + return Value((*string)[position]); +} + +// 22.1.3.3 String.prototype.codePointAt ( pos ), https://tc39.es/ecma262/#sec-string.prototype.codepointat +JS_DEFINE_NATIVE_FUNCTION(StringPrototype::code_point_at) +{ + auto string = ak_string_from(vm, global_object); + if (!string.has_value()) + return {}; + auto position = vm.argument(0).to_integer_or_infinity(global_object); + if (vm.exception()) + return {}; + auto view = Utf8View(*string); + if (position < 0 || position >= view.length()) + return js_undefined(); + auto it = view.begin(); + for (auto i = 0; i < position; ++i) + ++it; + return Value(*it); } // 22.1.3.16 String.prototype.repeat ( count ), https://tc39.es/ecma262/#sec-string.prototype.repeat diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.h b/Userland/Libraries/LibJS/Runtime/StringPrototype.h index 64d67b11ca..16cbaedb42 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.h @@ -21,6 +21,7 @@ public: private: JS_DECLARE_NATIVE_FUNCTION(char_at); JS_DECLARE_NATIVE_FUNCTION(char_code_at); + JS_DECLARE_NATIVE_FUNCTION(code_point_at); JS_DECLARE_NATIVE_FUNCTION(repeat); JS_DECLARE_NATIVE_FUNCTION(starts_with); JS_DECLARE_NATIVE_FUNCTION(ends_with);