diff options
6 files changed, 63 insertions, 1 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 82374d62f8..958eddc946 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -46,6 +46,7 @@ static bool is_platform_object(Type const& type) "Path2D"sv, "PerformanceEntry"sv, "PerformanceMark"sv, + "ReadableStreamDefaultReader"sv, "Range"sv, "ReadableStream"sv, "Request"sv, diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp index 8866a58be2..76eb467175 100644 --- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -20,6 +20,21 @@ namespace Web::Streams { +// https://streams.spec.whatwg.org/#acquire-readable-stream-reader +WebIDL::ExceptionOr<JS::NonnullGCPtr<ReadableStreamDefaultReader>> acquire_readable_stream_default_reader(ReadableStream& stream) +{ + auto& realm = stream.realm(); + + // 1. Let reader be a new ReadableStreamDefaultReader. + auto reader = TRY(realm.heap().allocate<ReadableStreamDefaultReader>(realm, realm)); + + // 2. Perform ? SetUpReadableStreamDefaultReader(reader, stream). + TRY(set_up_readable_stream_default_reader(reader, stream)); + + // 3. Return reader. + return reader; +} + // https://streams.spec.whatwg.org/#is-readable-stream-locked bool is_readable_stream_locked(ReadableStream const& stream) { diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h index bb67fa4043..593188fca6 100644 --- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h +++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h @@ -19,6 +19,7 @@ using PullAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::GCPtr<WebIDL::Pro using CancelAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::GCPtr<WebIDL::Promise>>(JS::Value)>; using StartAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::GCPtr<WebIDL::Promise>>()>; +WebIDL::ExceptionOr<JS::NonnullGCPtr<ReadableStreamDefaultReader>> acquire_readable_stream_default_reader(ReadableStream&); bool is_readable_stream_locked(ReadableStream const&); void readable_stream_close(ReadableStream&); diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStream.cpp b/Userland/Libraries/LibWeb/Streams/ReadableStream.cpp index 092ff2e4dd..054bd55f9e 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStream.cpp +++ b/Userland/Libraries/LibWeb/Streams/ReadableStream.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibJS/Runtime/PromiseCapability.h> #include <LibWeb/Bindings/Intrinsics.h> #include <LibWeb/Streams/AbstractOperations.h> #include <LibWeb/Streams/ReadableStream.h> @@ -60,6 +61,37 @@ ReadableStream::ReadableStream(JS::Realm& realm) ReadableStream::~ReadableStream() = default; +// https://streams.spec.whatwg.org/#rs-locked +bool ReadableStream::locked() +{ + // 1. Return ! IsReadableStreamLocked(this). + return is_readable_stream_locked(*this); +} + +// https://streams.spec.whatwg.org/#rs-cancel +WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> ReadableStream::cancel(JS::Value reason) +{ + // 1. If ! IsReadableStreamLocked(this) is true, return a promise rejected with a TypeError exception. + if (is_readable_stream_locked(*this)) { + auto exception = MUST_OR_THROW_OOM(JS::TypeError::create(realm(), "Cannot cancel a locked stream"sv)); + return WebIDL::create_rejected_promise(realm(), JS::Value { exception })->promise(); + } + + // 2. Return ! ReadableStreamCancel(this, reason). + return TRY(readable_stream_cancel(*this, reason))->promise(); +} + +// https://streams.spec.whatwg.org/#rs-get-reader +WebIDL::ExceptionOr<ReadableStreamReader> ReadableStream::get_reader() +{ + // FIXME: + // 1. If options["mode"] does not exist, return ? AcquireReadableStreamDefaultReader(this). + // 2. Assert: options["mode"] is "byob". + // 3. Return ? AcquireReadableStreamBYOBReader(this). + + return TRY(acquire_readable_stream_default_reader(*this)); +} + JS::ThrowCompletionOr<void> ReadableStream::initialize(JS::Realm& realm) { MUST_OR_THROW_OOM(Base::initialize(realm)); diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStream.h b/Userland/Libraries/LibWeb/Streams/ReadableStream.h index c12592142a..79c568490d 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStream.h +++ b/Userland/Libraries/LibWeb/Streams/ReadableStream.h @@ -36,6 +36,10 @@ public: virtual ~ReadableStream() override; + bool locked(); + WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> cancel(JS::Value view); + WebIDL::ExceptionOr<ReadableStreamReader> get_reader(); + ReadableStreamController controller() { return m_controller; } void set_controller(ReadableStreamController value) { m_controller = value; } diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStream.idl b/Userland/Libraries/LibWeb/Streams/ReadableStream.idl index 0cdc9aade6..c189da14e3 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStream.idl +++ b/Userland/Libraries/LibWeb/Streams/ReadableStream.idl @@ -1,8 +1,17 @@ -// Dummy definition so we can use ReadableStream as a type in Fetch. +#import <Streams/ReadableStreamDefaultReader.idl> // https://streams.spec.whatwg.org/#readablestream [Exposed=*, Transferable] interface ReadableStream { // FIXME: optional QueuingStrategy strategy = {} constructor(optional object underlyingSource); + + readonly attribute boolean locked; + + Promise<undefined> cancel(optional any reason); + // FIXME: optional ReadableStreamGetReaderOptions options = {} + ReadableStreamReader getReader(); }; + +// FIXME: typedef (ReadableStreamDefaultReader or ReadableStreamBYOBReader) ReadableStreamReader; +typedef ReadableStreamDefaultReader ReadableStreamReader; |