summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorMatthew Olsson <matthewcolsson@gmail.com>2023-04-02 08:27:37 -0700
committerLinus Groh <mail@linusgroh.de>2023-04-09 21:45:39 +0200
commitc421b6113c3f5e7cef3013e77a59da8db999f2c9 (patch)
tree0ec03e07ded02215f7ea4667dee66f315758570f /Userland/Libraries/LibWeb
parentae2d67c28b2a598f7d487557e4194d62e625329a (diff)
downloadserenity-c421b6113c3f5e7cef3013e77a59da8db999f2c9.zip
LibWeb: Implement WritableStream.abort()
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp54
-rw-r--r--Userland/Libraries/LibWeb/Streams/AbstractOperations.h1
-rw-r--r--Userland/Libraries/LibWeb/Streams/WritableStream.cpp15
-rw-r--r--Userland/Libraries/LibWeb/Streams/WritableStream.h1
-rw-r--r--Userland/Libraries/LibWeb/Streams/WritableStream.idl4
5 files changed, 72 insertions, 3 deletions
diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp
index e9bd5bca9a..2fb167a3bc 100644
--- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp
+++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp
@@ -8,6 +8,7 @@
#include <LibJS/Runtime/PromiseCapability.h>
#include <LibJS/Runtime/PromiseConstructor.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
+#include <LibWeb/DOM/AbortSignal.h>
#include <LibWeb/Streams/AbstractOperations.h>
#include <LibWeb/Streams/ReadableStream.h>
#include <LibWeb/Streams/ReadableStreamDefaultController.h>
@@ -839,6 +840,59 @@ WebIDL::ExceptionOr<void> set_up_writable_stream_default_writer(WritableStreamDe
return {};
}
+// https://streams.spec.whatwg.org/#writable-stream-abort
+WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_abort(WritableStream& stream, JS::Value reason)
+{
+ auto& realm = stream.realm();
+
+ // 1. If stream.[[state]] is "closed" or "errored", return a promise resolved with undefined.
+ auto state = stream.state();
+ if (state == WritableStream::State::Closed || state == WritableStream::State::Errored)
+ return WebIDL::create_resolved_promise(realm, JS::js_undefined());
+
+ // 2. Signal abort on stream.[[controller]].[[signal]] with reason.
+ stream.controller()->signal()->signal_abort(reason);
+
+ // 3. Let state be stream.[[state]].
+ state = stream.state();
+
+ // 4. If state is "closed" or "errored", return a promise resolved with undefined.
+ if (state == WritableStream::State::Closed || state == WritableStream::State::Errored)
+ return WebIDL::create_resolved_promise(realm, JS::js_undefined());
+
+ // 5. If stream.[[pendingAbortRequest]] is not undefined, return stream.[[pendingAbortRequest]]'s promise.
+ if (stream.pending_abort_request().has_value())
+ return stream.pending_abort_request()->promise;
+
+ // 6. Assert: state is "writable" or "erroring".
+ VERIFY(state == WritableStream::State::Writable || state == WritableStream::State::Erroring);
+
+ // 7. Let wasAlreadyErroring be false.
+ auto was_already_erroring = false;
+
+ // 8. If state is "erroring",
+ if (state == WritableStream::State::Erroring) {
+ // 1. Set wasAlreadyErroring to true.
+ was_already_erroring = true;
+
+ // 2. Set reason to undefined.
+ reason = JS::js_undefined();
+ }
+
+ // 9. Let promise be a new promise.
+ auto promise = WebIDL::create_promise(realm);
+
+ // 10. Set stream.[[pendingAbortRequest]] to a new pending abort request whose promise is promise, reason is reason, and was already erroring is wasAlreadyErroring.
+ stream.set_pending_abort_request(PendingAbortRequest { promise, reason, was_already_erroring });
+
+ // 11. If wasAlreadyErroring is false, perform ! WritableStreamStartErroring(stream, reason).
+ if (!was_already_erroring)
+ TRY(writable_stream_start_erroring(stream, reason));
+
+ // 12. Return promise.
+ return promise;
+}
+
// https://streams.spec.whatwg.org/#writable-stream-close
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_close(WritableStream& stream)
{
diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h
index a1153d28c8..d9a97f65cc 100644
--- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h
+++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h
@@ -56,6 +56,7 @@ WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller_from_underly
WebIDL::ExceptionOr<JS::NonnullGCPtr<WritableStreamDefaultWriter>> acquire_writable_stream_default_writer(WritableStream&);
bool is_writable_stream_locked(WritableStream const&);
WebIDL::ExceptionOr<void> set_up_writable_stream_default_writer(WritableStreamDefaultWriter&, WritableStream&);
+WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_abort(WritableStream&, JS::Value reason);
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_close(WritableStream&);
bool writable_stream_close_queued_or_in_flight(WritableStream const&);
diff --git a/Userland/Libraries/LibWeb/Streams/WritableStream.cpp b/Userland/Libraries/LibWeb/Streams/WritableStream.cpp
index 342f5d6abf..54ab3dbcd3 100644
--- a/Userland/Libraries/LibWeb/Streams/WritableStream.cpp
+++ b/Userland/Libraries/LibWeb/Streams/WritableStream.cpp
@@ -76,6 +76,21 @@ WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> WritableStream::close()
return TRY(writable_stream_close(*this))->promise();
}
+// https://streams.spec.whatwg.org/#ws-abort
+WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> WritableStream::abort(JS::Value reason)
+{
+ auto& realm = this->realm();
+
+ // 1. If ! IsWritableStreamLocked(this) is true, return a promise rejected with a TypeError exception.
+ if (is_writable_stream_locked(*this)) {
+ auto exception = MUST_OR_THROW_OOM(JS::TypeError::create(realm, "Cannot abort a locked stream"sv));
+ return WebIDL::create_rejected_promise(realm, exception)->promise();
+ }
+
+ // 2. Return ! WritableStreamAbort(this, reason).
+ return TRY(writable_stream_abort(*this, reason))->promise();
+}
+
// https://streams.spec.whatwg.org/#ws-get-writer
WebIDL::ExceptionOr<JS::NonnullGCPtr<WritableStreamDefaultWriter>> WritableStream::get_writer()
{
diff --git a/Userland/Libraries/LibWeb/Streams/WritableStream.h b/Userland/Libraries/LibWeb/Streams/WritableStream.h
index 4f25672ffa..9e02e9a382 100644
--- a/Userland/Libraries/LibWeb/Streams/WritableStream.h
+++ b/Userland/Libraries/LibWeb/Streams/WritableStream.h
@@ -47,6 +47,7 @@ public:
virtual ~WritableStream() = default;
bool locked() const;
+ WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> abort(JS::Value reason);
WebIDL::ExceptionOr<JS::GCPtr<JS::Object>> close();
WebIDL::ExceptionOr<JS::NonnullGCPtr<WritableStreamDefaultWriter>> get_writer();
diff --git a/Userland/Libraries/LibWeb/Streams/WritableStream.idl b/Userland/Libraries/LibWeb/Streams/WritableStream.idl
index 35bb0913a0..19977cfb85 100644
--- a/Userland/Libraries/LibWeb/Streams/WritableStream.idl
+++ b/Userland/Libraries/LibWeb/Streams/WritableStream.idl
@@ -7,9 +7,7 @@ interface WritableStream {
readonly attribute boolean locked;
- // FIXME:
- // Promise<undefined> abort(optional any reason);
-
+ Promise<undefined> abort(optional any reason);
Promise<undefined> close();
WritableStreamDefaultWriter getWriter();
};