mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibWeb: Implement WritableStream.abort()
This commit is contained in:
parent
ae2d67c28b
commit
c421b6113c
Notes:
sideshowbarker
2024-07-17 10:08:28 +09:00
Author: https://github.com/mattco98 Commit: https://github.com/SerenityOS/serenity/commit/c421b6113c Pull-request: https://github.com/SerenityOS/serenity/pull/18265 Reviewed-by: https://github.com/linusg ✅
5 changed files with 72 additions and 3 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue