From ccd730a8b77c188657ec15b5d096f62a24bd0be6 Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Mon, 8 Nov 2021 23:37:06 +0100 Subject: [PATCH] feat(ext/web): add `AbortSignal.reason` (#12697) --- ext/web/03_abort_signal.js | 65 ++++++++++++++++++++++++++------------ test_util/wpt | 2 +- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js index 98f14f47a6..6b278ba074 100644 --- a/ext/web/03_abort_signal.js +++ b/ext/web/03_abort_signal.js @@ -8,7 +8,6 @@ const webidl = window.__bootstrap.webidl; const { setIsTrusted, defineEventHandler } = window.__bootstrap.event; const { - Boolean, Set, SetPrototypeAdd, SetPrototypeDelete, @@ -16,33 +15,42 @@ TypeError, } = window.__bootstrap.primordials; - const add = Symbol("add"); - const signalAbort = Symbol("signalAbort"); - const remove = Symbol("remove"); - const aborted = Symbol("aborted"); - const abortAlgos = Symbol("abortAlgos"); + const add = Symbol("[[add]]"); + const signalAbort = Symbol("[[signalAbort]]"); + const remove = Symbol("[[remove]]"); + const abortReason = Symbol("[[abortReason]]"); + const abortAlgos = Symbol("[[abortAlgos]]"); + const signal = Symbol("[[signal]]"); const illegalConstructorKey = Symbol("illegalConstructorKey"); class AbortSignal extends EventTarget { - static abort() { + static abort(reason = undefined) { + if (reason !== undefined) { + reason = webidl.converters.any(reason); + } const signal = new AbortSignal(illegalConstructorKey); - signal[signalAbort](); + signal[signalAbort](reason); return signal; } [add](algorithm) { + if (this.aborted) { + return; + } if (this[abortAlgos] === null) { this[abortAlgos] = new Set(); } SetPrototypeAdd(this[abortAlgos], algorithm); } - [signalAbort]() { - if (this[aborted]) { + [signalAbort]( + reason = new DOMException("The signal has been aborted", "AbortError"), + ) { + if (this.aborted) { return; } - this[aborted] = true; + this[abortReason] = reason; if (this[abortAlgos] !== null) { for (const algorithm of this[abortAlgos]) { algorithm(); @@ -63,13 +71,19 @@ throw new TypeError("Illegal constructor."); } super(); - this[aborted] = false; + this[abortReason] = undefined; this[abortAlgos] = null; this[webidl.brand] = webidl.brand; } get aborted() { - return Boolean(this[aborted]); + webidl.assertBranded(this, AbortSignal); + return this[abortReason] !== undefined; + } + + get reason() { + webidl.assertBranded(this, AbortSignal); + return this[abortReason]; } } defineEventHandler(AbortSignal.prototype, "abort"); @@ -77,14 +91,20 @@ webidl.configurePrototype(AbortSignal); class AbortController { - #signal = new AbortSignal(illegalConstructorKey); + [signal] = new AbortSignal(illegalConstructorKey); - get signal() { - return this.#signal; + constructor() { + this[webidl.brand] = webidl.brand; } - abort() { - this.#signal[signalAbort](); + get signal() { + webidl.assertBranded(this, AbortController); + return this[signal]; + } + + abort(reason) { + webidl.assertBranded(this, AbortController); + this[signal][signalAbort](reason); } } @@ -100,10 +120,15 @@ } function follow(followingSignal, parentSignal) { + if (followingSignal.aborted) { + return; + } if (parentSignal.aborted) { - followingSignal[signalAbort](); + followingSignal[signalAbort](parentSignal.reason); } else { - parentSignal[add](() => followingSignal[signalAbort]()); + parentSignal[add](() => + followingSignal[signalAbort](parentSignal.reason) + ); } } diff --git a/test_util/wpt b/test_util/wpt index 3904336d37..3757761835 160000 --- a/test_util/wpt +++ b/test_util/wpt @@ -1 +1 @@ -Subproject commit 3904336d37ed6f480fc8879ea8bd5683a39ede3d +Subproject commit 3757761835b6e888a196b668ae9db7249e7710a8