瀏覽代碼

LibWeb: Implement WritableStreamDefaultWriter.close()

Matthew Olsson 2 年之前
父節點
當前提交
5f4da20a56

+ 13 - 0
Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp

@@ -1321,6 +1321,19 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_default_w
     return writable_stream_abort(*stream, reason);
 }
 
+// https://streams.spec.whatwg.org/#writable-stream-default-writer-close
+WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_default_writer_close(WritableStreamDefaultWriter& writer)
+{
+    // 1. Let stream be writer.[[stream]].
+    auto stream = writer.stream();
+
+    // 2. Assert: stream is not undefined.
+    VERIFY(stream);
+
+    // 3. Return ! WritableStreamClose(stream).
+    return writable_stream_close(*stream);
+}
+
 // https://streams.spec.whatwg.org/#writable-stream-default-writer-ensure-ready-promise-rejected
 void writable_stream_default_writer_ensure_ready_promise_rejected(WritableStreamDefaultWriter& writer, JS::Value error)
 {

+ 1 - 0
Userland/Libraries/LibWeb/Streams/AbstractOperations.h

@@ -74,6 +74,7 @@ WebIDL::ExceptionOr<void> writable_stream_start_erroring(WritableStream&, JS::Va
 void writable_stream_update_backpressure(WritableStream&, bool backpressure);
 
 WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_default_writer_abort(WritableStreamDefaultWriter&, JS::Value reason);
+WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_default_writer_close(WritableStreamDefaultWriter&);
 void writable_stream_default_writer_ensure_ready_promise_rejected(WritableStreamDefaultWriter&, JS::Value error);
 Optional<double> writable_stream_default_writer_get_desired_size(WritableStreamDefaultWriter const&);
 

+ 23 - 0
Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.cpp

@@ -64,6 +64,29 @@ WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> WritableStreamDefaultWriter::abort(JS
     return TRY(writable_stream_default_writer_abort(*this, reason))->promise();
 }
 
+// https://streams.spec.whatwg.org/#default-writer-close
+WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> WritableStreamDefaultWriter::close()
+{
+    auto& realm = this->realm();
+
+    // 1. Let stream be this.[[stream]].
+
+    // 2. If stream is undefined, return a promise rejected with a TypeError exception.
+    if (!m_stream) {
+        auto exception = MUST_OR_THROW_OOM(JS::TypeError::create(realm, "Cannot close a writer that has no locked stream"sv));
+        return WebIDL::create_rejected_promise(realm, exception)->promise();
+    }
+
+    // 3. If ! WritableStreamCloseQueuedOrInFlight(stream) is true, return a promise rejected with a TypeError exception.
+    if (writable_stream_close_queued_or_in_flight(*m_stream)) {
+        auto exception = MUST_OR_THROW_OOM(JS::TypeError::create(realm, "Cannot close a stream that is already closed or errored"sv));
+        return WebIDL::create_rejected_promise(realm, exception)->promise();
+    }
+
+    // 4. Return ! WritableStreamDefaultWriterClose(this).
+    return TRY(writable_stream_default_writer_close(*this))->promise();
+}
+
 WritableStreamDefaultWriter::WritableStreamDefaultWriter(JS::Realm& realm)
     : Bindings::PlatformObject(realm)
 {

+ 1 - 0
Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.h

@@ -28,6 +28,7 @@ public:
     WebIDL::ExceptionOr<Optional<double>> desired_size() const;
     JS::GCPtr<JS::Object> ready();
     WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> abort(JS::Value reason);
+    WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> close();
 
     JS::GCPtr<WebIDL::Promise> closed_promise() { return m_closed_promise; }
     void set_closed_promise(JS::GCPtr<WebIDL::Promise> value) { m_closed_promise = value; }

+ 1 - 1
Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.idl

@@ -9,9 +9,9 @@ interface WritableStreamDefaultWriter {
     readonly attribute Promise<undefined> ready;
 
     Promise<undefined> abort(optional any reason);
+    Promise<undefined> close();
 
     // FIXME:
-    // Promise<undefined> close();
     // undefined releaseLock();
     // Promise<undefined> write(optional any chunk);
 };