diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2021-08-11 12:27:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-11 12:27:05 +0200 |
commit | a0285e2eb88f6254f6494b0ecd1878db3a3b2a58 (patch) | |
tree | 90671b004537e20f9493fd3277ffd21d30b39a0e /ext/web/03_abort_signal.js | |
parent | 3a6994115176781b3a93d70794b1b81bc95e42b4 (diff) |
Rename extensions/ directory to ext/ (#11643)
Diffstat (limited to 'ext/web/03_abort_signal.js')
-rw-r--r-- | ext/web/03_abort_signal.js | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/ext/web/03_abort_signal.js b/ext/web/03_abort_signal.js new file mode 100644 index 000000000..d67bfef26 --- /dev/null +++ b/ext/web/03_abort_signal.js @@ -0,0 +1,123 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +"use strict"; + +// @ts-check +/// <reference path="../../core/internal.d.ts" /> + +((window) => { + const webidl = window.__bootstrap.webidl; + const { setIsTrusted, defineEventHandler } = window.__bootstrap.event; + const { + Boolean, + Set, + SetPrototypeAdd, + SetPrototypeClear, + SetPrototypeDelete, + Symbol, + SymbolToStringTag, + TypeError, + } = window.__bootstrap.primordials; + + const add = Symbol("add"); + const signalAbort = Symbol("signalAbort"); + const remove = Symbol("remove"); + + const illegalConstructorKey = Symbol("illegalConstructorKey"); + + class AbortSignal extends EventTarget { + #aborted = false; + #abortAlgorithms = new Set(); + + static abort() { + const signal = new AbortSignal(illegalConstructorKey); + signal[signalAbort](); + return signal; + } + + [add](algorithm) { + SetPrototypeAdd(this.#abortAlgorithms, algorithm); + } + + [signalAbort]() { + if (this.#aborted) { + return; + } + this.#aborted = true; + for (const algorithm of this.#abortAlgorithms) { + algorithm(); + } + SetPrototypeClear(this.#abortAlgorithms); + const event = new Event("abort"); + setIsTrusted(event, true); + this.dispatchEvent(event); + } + + [remove](algorithm) { + SetPrototypeDelete(this.#abortAlgorithms, algorithm); + } + + constructor(key = null) { + if (key != illegalConstructorKey) { + throw new TypeError("Illegal constructor."); + } + super(); + this[webidl.brand] = webidl.brand; + } + + get aborted() { + return Boolean(this.#aborted); + } + + get [SymbolToStringTag]() { + return "AbortSignal"; + } + } + defineEventHandler(AbortSignal.prototype, "abort"); + + webidl.configurePrototype(AbortSignal); + + class AbortController { + #signal = new AbortSignal(illegalConstructorKey); + + get signal() { + return this.#signal; + } + + abort() { + this.#signal[signalAbort](); + } + + get [SymbolToStringTag]() { + return "AbortController"; + } + } + + webidl.configurePrototype(AbortController); + + webidl.converters["AbortSignal"] = webidl.createInterfaceConverter( + "AbortSignal", + AbortSignal, + ); + + function newSignal() { + return new AbortSignal(illegalConstructorKey); + } + + function follow(followingSignal, parentSignal) { + if (parentSignal.aborted) { + followingSignal[signalAbort](); + } else { + parentSignal[add](() => followingSignal[signalAbort]()); + } + } + + window.AbortSignal = AbortSignal; + window.AbortController = AbortController; + window.__bootstrap.abortSignal = { + add, + signalAbort, + remove, + follow, + newSignal, + }; +})(this); |