diff options
-rw-r--r-- | Userland/Libraries/LibWeb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Forward.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Streams/UnderlyingSource.cpp | 59 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Streams/UnderlyingSource.h | 31 |
4 files changed, 92 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index fe7450e723..a66c0eb03b 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -459,6 +459,7 @@ set(SOURCES Streams/ReadableStreamDefaultController.cpp Streams/ReadableStreamDefaultReader.cpp Streams/ReadableStreamGenericReader.cpp + Streams/UnderlyingSource.cpp SVG/AttributeNames.cpp SVG/AttributeParser.cpp SVG/SVGAnimatedLength.cpp diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index f7e8a948c3..28f4d2ed68 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -422,6 +422,7 @@ class ReadableStreamDefaultController; class ReadableStreamDefaultReader; class ReadableStreamGenericReaderMixin; class ReadRequest; +struct UnderlyingSource; } namespace Web::SVG { diff --git a/Userland/Libraries/LibWeb/Streams/UnderlyingSource.cpp b/Userland/Libraries/LibWeb/Streams/UnderlyingSource.cpp new file mode 100644 index 0000000000..7ea43d3e44 --- /dev/null +++ b/Userland/Libraries/LibWeb/Streams/UnderlyingSource.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibJS/Runtime/VM.h> +#include <LibWeb/HTML/Scripting/Environments.h> +#include <LibWeb/Streams/UnderlyingSource.h> +#include <LibWeb/WebIDL/CallbackType.h> + +namespace Web::Streams { + +// 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. +static JS::ThrowCompletionOr<JS::Handle<WebIDL::CallbackType>> property_to_callback(JS::VM& vm, JS::Value value, JS::PropertyKey const& property_key) +{ + auto property = TRY(value.get(vm, property_key)); + + if (property.is_undefined()) + return JS::Handle<WebIDL::CallbackType> {}; + + if (!property.is_function()) + return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAFunction, TRY_OR_THROW_OOM(vm, property.to_string_without_side_effects())); + + return vm.heap().allocate_without_realm<WebIDL::CallbackType>(property.as_object(), HTML::incumbent_settings_object()); +} + +JS::ThrowCompletionOr<UnderlyingSource> UnderlyingSource::from_value(JS::VM& vm, JS::Value value) +{ + if (!value.is_object()) + return UnderlyingSource {}; + + auto& object = value.as_object(); + + UnderlyingSource underlying_source { + .start = TRY(property_to_callback(vm, value, "start")), + .pull = TRY(property_to_callback(vm, value, "pull")), + .cancel = TRY(property_to_callback(vm, value, "cancel")), + .type = {}, + .auto_allocate_chunk_size = {}, + }; + + if (TRY(object.has_property("type"))) { + auto type_value = TRY(TRY(object.get("type")).to_string(object.vm())); + if (type_value == "bytes"sv) { + underlying_source.type = ReadableStreamType::Bytes; + } else { + return vm.throw_completion<JS::TypeError>(DeprecatedString::formatted("Unknown stream type '{}'", type_value)); + } + } + + if (TRY(object.has_property("autoAllocateChunkSize"))) + underlying_source.auto_allocate_chunk_size = TRY(TRY(object.get("autoAllocateChunkSize")).to_bigint_int64(object.vm())); + + return underlying_source; +} + +} diff --git a/Userland/Libraries/LibWeb/Streams/UnderlyingSource.h b/Userland/Libraries/LibWeb/Streams/UnderlyingSource.h new file mode 100644 index 0000000000..08daab383a --- /dev/null +++ b/Userland/Libraries/LibWeb/Streams/UnderlyingSource.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Forward.h> +#include <LibJS/Forward.h> +#include <LibWeb/Bindings/PlatformObject.h> +#include <LibWeb/Forward.h> +#include <LibWeb/WebIDL/Promise.h> + +namespace Web::Streams { + +enum class ReadableStreamType { + Bytes +}; + +struct UnderlyingSource { + JS::Handle<WebIDL::CallbackType> start; + JS::Handle<WebIDL::CallbackType> pull; + JS::Handle<WebIDL::CallbackType> cancel; + Optional<ReadableStreamType> type; + Optional<i64> auto_allocate_chunk_size; + + static JS::ThrowCompletionOr<UnderlyingSource> from_value(JS::VM&, JS::Value); +}; + +} |