Browse Source

LibWeb: Add ReadableStream.locked/cancel()/getReader()

Matthew Olsson 2 years ago
parent
commit
36ca1386e8

+ 1 - 0
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,

+ 15 - 0
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)
 {

+ 1 - 0
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&);

+ 32 - 0
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));

+ 4 - 0
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; }
 

+ 10 - 1
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;