diff --git a/Libraries/LibWeb/WebIDL/AbstractOperations.cpp b/Libraries/LibWeb/WebIDL/AbstractOperations.cpp index 91298c8a636..5476c6cc790 100644 --- a/Libraries/LibWeb/WebIDL/AbstractOperations.cpp +++ b/Libraries/LibWeb/WebIDL/AbstractOperations.cpp @@ -225,6 +225,33 @@ JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String return clean_up_on_return(stored_realm, relevant_realm, completion, callback.operation_returns_promise); } +// https://webidl.spec.whatwg.org/#ref-for-idl-ByteString%E2%91%A7 +JS::ThrowCompletionOr to_byte_string(JS::VM& vm, JS::Value value) +{ + // 1. Let x be ? ToString(V). + auto x = TRY(value.to_string(vm)); + + // 2. If the value of any element of x is greater than 255, then throw a TypeError. + for (auto character : x.code_points()) { + if (character > 0xFF) + return vm.throw_completion(JS::ErrorType::InvalidCodePoint); + } + + // 3. Return an IDL ByteString value whose length is the length of x, and where the value of each element is the value of the corresponding element of x. + // FIXME: This should return a ByteString. + return x; +} + +JS::ThrowCompletionOr to_string(JS::VM& vm, JS::Value value) +{ + return value.to_string(vm); +} + +JS::ThrowCompletionOr to_usv_string(JS::VM& vm, JS::Value value) +{ + return value.to_well_formed_string(vm); +} + // https://webidl.spec.whatwg.org/#invoke-a-callback-function // https://whatpr.org/webidl/1437.html#invoke-a-callback-function JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optional this_argument, GC::MarkedVector args) diff --git a/Libraries/LibWeb/WebIDL/AbstractOperations.h b/Libraries/LibWeb/WebIDL/AbstractOperations.h index 6051a8d0efc..7728588a3d8 100644 --- a/Libraries/LibWeb/WebIDL/AbstractOperations.h +++ b/Libraries/LibWeb/WebIDL/AbstractOperations.h @@ -23,6 +23,10 @@ ErrorOr get_buffer_source_copy(JS::Object const& buffer_source); JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String const& operation_name, Optional this_argument, GC::MarkedVector args); +JS::ThrowCompletionOr to_string(JS::VM&, JS::Value); +JS::ThrowCompletionOr to_usv_string(JS::VM&, JS::Value); +JS::ThrowCompletionOr to_byte_string(JS::VM&, JS::Value); + // https://webidl.spec.whatwg.org/#call-a-user-objects-operation template JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String const& operation_name, Optional this_argument, Args&&... args) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 3dd3da493de..e8878cd8c5b 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -342,10 +342,13 @@ static void emit_includes_for_all_imports(auto& interface, auto& generator, bool template static void generate_to_string(SourceGenerator& scoped_generator, ParameterType const& parameter, bool variadic, bool optional, Optional const& optional_default_value) { - if (parameter.type->name() == "USVString") - scoped_generator.set("to_string", "to_well_formed_string"sv); - else + if (parameter.type->name() == "USVString") { + scoped_generator.set("to_string", "to_usv_string"sv); + } else if (parameter.type->name() == "ByteString") { + scoped_generator.set("to_string", "to_byte_string"sv); + } else { scoped_generator.set("to_string", "to_string"sv); + } if (variadic) { scoped_generator.append(R"~~~( @@ -355,7 +358,7 @@ static void generate_to_string(SourceGenerator& scoped_generator, ParameterType @cpp_name@.ensure_capacity(vm.argument_count() - @js_suffix@); for (size_t i = @js_suffix@; i < vm.argument_count(); ++i) { - auto to_string_result = TRY(vm.argument(i).@to_string@(vm)); + auto to_string_result = TRY(WebIDL::@to_string@(vm, vm.argument(i))); @cpp_name@.unchecked_append(move(to_string_result)); } } @@ -365,14 +368,14 @@ static void generate_to_string(SourceGenerator& scoped_generator, ParameterType scoped_generator.append(R"~~~( @string_type@ @cpp_name@; if (!@legacy_null_to_empty_string@ || !@js_name@@js_suffix@.is_null()) { - @cpp_name@ = TRY(@js_name@@js_suffix@.@to_string@(vm)); + @cpp_name@ = TRY(WebIDL::@to_string@(vm, @js_name@@js_suffix@)); } )~~~"); } else { scoped_generator.append(R"~~~( Optional<@string_type@> @cpp_name@; if (!@js_name@@js_suffix@.is_nullish()) - @cpp_name@ = TRY(@js_name@@js_suffix@.@to_string@(vm)); + @cpp_name@ = TRY(WebIDL::@to_string@(vm, @js_name@@js_suffix@)); )~~~"); } } else { @@ -390,7 +393,7 @@ static void generate_to_string(SourceGenerator& scoped_generator, ParameterType scoped_generator.append(R"~~~( if (!@js_name@@js_suffix@.is_undefined()) { if (!@legacy_null_to_empty_string@ || !@js_name@@js_suffix@.is_null()) - @cpp_name@ = TRY(@js_name@@js_suffix@.@to_string@(vm)); + @cpp_name@ = TRY(WebIDL::@to_string@(vm, @js_name@@js_suffix@)); })~~~"); if (!may_be_null) { scoped_generator.append(R"~~~( else {