diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index bb64dd60476..d3cb804eafb 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -1378,6 +1378,13 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_well_formed) // 2. Let S be ? ToString(O). auto string = TRY(utf16_string_from(vm)); + // NOTE: Rest of steps in to_well_formed below + return PrimitiveString::create(vm, to_well_formed_string(string)); +} + +// https://tc39.es/ecma262/#sec-string.prototype.towellformed +String to_well_formed_string(Utf16String const& string) +{ // 3. Let strLen be the length of S. auto length = string.length_in_code_units(); @@ -1408,7 +1415,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::to_well_formed) } // 7. Return result. - return PrimitiveString::create(vm, MUST(result.to_string())); + return MUST(result.to_string()); } // 22.1.3.32.1 TrimString ( string, where ), https://tc39.es/ecma262/#sec-trimstring diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.h b/Userland/Libraries/LibJS/Runtime/StringPrototype.h index 608859ad3e5..a081ea36ab9 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.h @@ -19,6 +19,7 @@ struct CodePoint { Optional string_index_of(Utf16View const& string, Utf16View const& search_value, size_t from_index); CodePoint code_point_at(Utf16View const& string, size_t position); +String to_well_formed_string(Utf16String const&); static constexpr Utf8View whitespace_characters = Utf8View("\x09\x0A\x0B\x0C\x0D\x20\xC2\xA0\xE1\x9A\x80\xE2\x80\x80\xE2\x80\x81\xE2\x80\x82\xE2\x80\x83\xE2\x80\x84\xE2\x80\x85\xE2\x80\x86\xE2\x80\x87\xE2\x80\x88\xE2\x80\x89\xE2\x80\x8A\xE2\x80\xAF\xE2\x81\x9F\xE3\x80\x80\xE2\x80\xA8\xE2\x80\xA9\xEF\xBB\xBF"sv); ThrowCompletionOr trim_string(VM&, Value string, TrimMode where); diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 70a9c33df11..0a270fa4b41 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -453,6 +453,11 @@ ThrowCompletionOr Value::to_utf16_string(VM& vm) const return Utf16String::create(utf8_string.bytes_as_string_view()); } +ThrowCompletionOr Value::to_well_formed_string(VM& vm) const +{ + return ::JS::to_well_formed_string(TRY(to_utf16_string(vm))); +} + // 7.1.2 ToBoolean ( argument ), https://tc39.es/ecma262/#sec-toboolean bool Value::to_boolean_slow_case() const { diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index dda33b783bc..151035f9f27 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -384,6 +384,7 @@ public: ThrowCompletionOr to_string(VM&) const; ThrowCompletionOr to_byte_string(VM&) const; ThrowCompletionOr to_utf16_string(VM&) const; + ThrowCompletionOr to_well_formed_string(VM&) const; ThrowCompletionOr> to_primitive_string(VM&); ThrowCompletionOr to_primitive(VM&, PreferredType preferred_type = PreferredType::Default) const; ThrowCompletionOr> to_object(VM&) const;