diff --git a/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Libraries/LibWeb/Streams/AbstractOperations.cpp index 539dd745324..103ae128b10 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -5302,21 +5302,6 @@ WebIDL::ExceptionOr structured_clone(JS::Realm& realm, JS::Value valu return TRY(HTML::structured_deserialize(vm, serialized, realm)); } -// Non-standard function to aid in converting a user-provided function into a WebIDL::Callback. This is essentially -// what the Bindings generator would do at compile time, but at runtime instead. -JS::ThrowCompletionOr> property_to_callback(JS::VM& vm, JS::Value value, JS::PropertyKey const& property_key, WebIDL::OperationReturnsPromise operation_returns_promise) -{ - auto property = TRY(value.get(vm, property_key)); - - if (property.is_undefined()) - return GC::Root {}; - - if (!property.is_function()) - return vm.throw_completion(JS::ErrorType::NotAFunction, property.to_string_without_side_effects()); - - return vm.heap().allocate(property.as_object(), HTML::incumbent_realm(), operation_returns_promise); -} - // https://streams.spec.whatwg.org/#set-up-readable-byte-stream-controller-from-underlying-source WebIDL::ExceptionOr set_up_readable_byte_stream_controller_from_underlying_source(ReadableStream& stream, JS::Value underlying_source, UnderlyingSource const& underlying_source_dict, double high_water_mark) { diff --git a/Libraries/LibWeb/Streams/AbstractOperations.h b/Libraries/LibWeb/Streams/AbstractOperations.h index ef8a16808ef..ec181944ffd 100644 --- a/Libraries/LibWeb/Streams/AbstractOperations.h +++ b/Libraries/LibWeb/Streams/AbstractOperations.h @@ -179,8 +179,6 @@ bool can_transfer_array_buffer(JS::ArrayBuffer const& array_buffer); WebIDL::ExceptionOr clone_as_uint8_array(JS::Realm&, WebIDL::ArrayBufferView&); WebIDL::ExceptionOr structured_clone(JS::Realm&, JS::Value value); -JS::ThrowCompletionOr> property_to_callback(JS::VM& vm, JS::Value value, JS::PropertyKey const& property_key, WebIDL::OperationReturnsPromise); - // https://streams.spec.whatwg.org/#value-with-size struct ValueWithSize { JS::Value value; diff --git a/Libraries/LibWeb/Streams/Transformer.cpp b/Libraries/LibWeb/Streams/Transformer.cpp index 1d07ad4cbe6..3eaedc2e755 100644 --- a/Libraries/LibWeb/Streams/Transformer.cpp +++ b/Libraries/LibWeb/Streams/Transformer.cpp @@ -19,10 +19,10 @@ JS::ThrowCompletionOr Transformer::from_value(JS::VM& vm, JS::Value auto& object = value.as_object(); Transformer transformer { - .start = TRY(property_to_callback(vm, value, "start", WebIDL::OperationReturnsPromise::No)), - .transform = TRY(property_to_callback(vm, value, "transform", WebIDL::OperationReturnsPromise::Yes)), - .flush = TRY(property_to_callback(vm, value, "flush", WebIDL::OperationReturnsPromise::Yes)), - .cancel = TRY(property_to_callback(vm, value, "cancel", WebIDL::OperationReturnsPromise::Yes)), + .start = TRY(WebIDL::property_to_callback(vm, value, "start", WebIDL::OperationReturnsPromise::No)), + .transform = TRY(WebIDL::property_to_callback(vm, value, "transform", WebIDL::OperationReturnsPromise::Yes)), + .flush = TRY(WebIDL::property_to_callback(vm, value, "flush", WebIDL::OperationReturnsPromise::Yes)), + .cancel = TRY(WebIDL::property_to_callback(vm, value, "cancel", WebIDL::OperationReturnsPromise::Yes)), .readable_type = {}, .writable_type = {}, }; diff --git a/Libraries/LibWeb/Streams/UnderlyingSink.cpp b/Libraries/LibWeb/Streams/UnderlyingSink.cpp index 553b7a98619..cf036668f72 100644 --- a/Libraries/LibWeb/Streams/UnderlyingSink.cpp +++ b/Libraries/LibWeb/Streams/UnderlyingSink.cpp @@ -19,10 +19,10 @@ JS::ThrowCompletionOr UnderlyingSink::from_value(JS::VM& vm, JS: auto& object = value.as_object(); UnderlyingSink underlying_sink { - .start = TRY(property_to_callback(vm, value, "start", WebIDL::OperationReturnsPromise::No)), - .write = TRY(property_to_callback(vm, value, "write", WebIDL::OperationReturnsPromise::Yes)), - .close = TRY(property_to_callback(vm, value, "close", WebIDL::OperationReturnsPromise::Yes)), - .abort = TRY(property_to_callback(vm, value, "abort", WebIDL::OperationReturnsPromise::Yes)), + .start = TRY(WebIDL::property_to_callback(vm, value, "start", WebIDL::OperationReturnsPromise::No)), + .write = TRY(WebIDL::property_to_callback(vm, value, "write", WebIDL::OperationReturnsPromise::Yes)), + .close = TRY(WebIDL::property_to_callback(vm, value, "close", WebIDL::OperationReturnsPromise::Yes)), + .abort = TRY(WebIDL::property_to_callback(vm, value, "abort", WebIDL::OperationReturnsPromise::Yes)), .type = {}, }; diff --git a/Libraries/LibWeb/Streams/UnderlyingSource.cpp b/Libraries/LibWeb/Streams/UnderlyingSource.cpp index b2d92f6cb90..3c1cf531116 100644 --- a/Libraries/LibWeb/Streams/UnderlyingSource.cpp +++ b/Libraries/LibWeb/Streams/UnderlyingSource.cpp @@ -22,9 +22,9 @@ JS::ThrowCompletionOr UnderlyingSource::from_value(JS::VM& vm, auto& object = value.as_object(); UnderlyingSource underlying_source { - .start = TRY(property_to_callback(vm, value, "start", WebIDL::OperationReturnsPromise::No)), - .pull = TRY(property_to_callback(vm, value, "pull", WebIDL::OperationReturnsPromise::Yes)), - .cancel = TRY(property_to_callback(vm, value, "cancel", WebIDL::OperationReturnsPromise::Yes)), + .start = TRY(WebIDL::property_to_callback(vm, value, "start", WebIDL::OperationReturnsPromise::No)), + .pull = TRY(WebIDL::property_to_callback(vm, value, "pull", WebIDL::OperationReturnsPromise::Yes)), + .cancel = TRY(WebIDL::property_to_callback(vm, value, "cancel", WebIDL::OperationReturnsPromise::Yes)), .type = {}, .auto_allocate_chunk_size = {}, }; diff --git a/Libraries/LibWeb/WebIDL/CallbackType.cpp b/Libraries/LibWeb/WebIDL/CallbackType.cpp index 24dd1fc3cdc..8a363520eed 100644 --- a/Libraries/LibWeb/WebIDL/CallbackType.cpp +++ b/Libraries/LibWeb/WebIDL/CallbackType.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -26,4 +27,19 @@ void CallbackType::visit_edges(Cell::Visitor& visitor) visitor.visit(callback_context); } +// Non-standard function to aid in converting a user-provided function into a WebIDL::Callback. This is essentially +// what the Bindings generator would do at compile time, but at runtime instead. +JS::ThrowCompletionOr> property_to_callback(JS::VM& vm, JS::Value value, JS::PropertyKey const& property_key, OperationReturnsPromise operation_returns_promise) +{ + auto property = TRY(value.get(vm, property_key)); + + if (property.is_undefined()) + return GC::Root {}; + + if (!property.is_function()) + return vm.throw_completion(JS::ErrorType::NotAFunction, property.to_string_without_side_effects()); + + return vm.heap().allocate(property.as_object(), HTML::incumbent_realm(), operation_returns_promise); +} + } diff --git a/Libraries/LibWeb/WebIDL/CallbackType.h b/Libraries/LibWeb/WebIDL/CallbackType.h index f8ca51b5269..125e13110e7 100644 --- a/Libraries/LibWeb/WebIDL/CallbackType.h +++ b/Libraries/LibWeb/WebIDL/CallbackType.h @@ -39,4 +39,6 @@ private: virtual void visit_edges(Cell::Visitor&) override; }; +JS::ThrowCompletionOr> property_to_callback(JS::VM& vm, JS::Value value, JS::PropertyKey const& property_key, WebIDL::OperationReturnsPromise); + }