LibWeb: Implement AbortSignal.abort()

This returns an AbortSignal that is already set as aborted.
This commit is contained in:
Tim Ledbetter 2024-02-20 20:51:29 +00:00 committed by Andreas Kling
parent fa95e5ec0e
commit 3b7c252175
Notes: sideshowbarker 2024-07-18 03:20:18 +09:00
5 changed files with 43 additions and 1 deletions

View File

@ -0,0 +1,4 @@
Aborted: true
Reason: "[object DOMException]"
Aborted: true
Reason: "This is a test"

View File

@ -0,0 +1,19 @@
<script src="include.js"></script>
<script>
asyncTest(async done => {
function testSignal(signal) {
return fetch("./basic.html", { signal })
.then(() => {
println("FAIL");
})
.catch(error => {
println(`Aborted: ${signal.aborted}`);
println(`Reason: "${error}"`);
});
}
testSignal(AbortSignal.abort())
.then(() => testSignal(AbortSignal.abort("This is a test")))
.finally(done);
});
</script>

View File

@ -116,4 +116,20 @@ void AbortSignal::follow(JS::NonnullGCPtr<AbortSignal> parent_signal)
});
}
// https://dom.spec.whatwg.org/#dom-abortsignal-abort
WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortSignal>> AbortSignal::abort(JS::VM& vm, JS::Value reason)
{
// 1. Let signal be a new AbortSignal object.
auto signal = TRY(construct_impl(*vm.current_realm()));
// 2. Set signals abort reason to reason if it is given; otherwise to a new "AbortError" DOMException.
if (reason.is_undefined())
reason = WebIDL::AbortError::create(*vm.current_realm(), "Aborted without reason"_fly_string).ptr();
signal->set_reason(reason);
// 3. Return signal.
return signal;
}
}

View File

@ -37,11 +37,14 @@ public:
// https://dom.spec.whatwg.org/#dom-abortsignal-reason
JS::Value reason() const { return m_abort_reason; }
void set_reason(JS::Value reason) { m_abort_reason = reason; }
JS::ThrowCompletionOr<void> throw_if_aborted() const;
void follow(JS::NonnullGCPtr<AbortSignal> parent_signal);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortSignal>> abort(JS::VM&, JS::Value reason);
private:
explicit AbortSignal(JS::Realm&);

View File

@ -4,7 +4,7 @@
// https://dom.spec.whatwg.org/#interface-AbortSignal
[Exposed=(Window,Worker), CustomVisit]
interface AbortSignal : EventTarget {
// FIXME: [NewObject] static AbortSignal abort(optional any reason);
[NewObject] static AbortSignal abort(optional any reason);
// FIXME: [Exposed=(Window,Worker), NewObject] static AbortSignal timeout([EnforceRange] unsigned long long milliseconds);
// FIXME: [NewObject] static AbortSignal _any(sequence<AbortSignal> signals);