summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--op_crates/web/02_abort_signal.js27
-rw-r--r--op_crates/web/abort_controller_test.js18
2 files changed, 38 insertions, 7 deletions
diff --git a/op_crates/web/02_abort_signal.js b/op_crates/web/02_abort_signal.js
index 53745c52b..5e8943161 100644
--- a/op_crates/web/02_abort_signal.js
+++ b/op_crates/web/02_abort_signal.js
@@ -64,22 +64,35 @@
}
const handlerSymbol = Symbol("eventHandlers");
+
+ function makeWrappedHandler(handler) {
+ function wrappedHandler(...args) {
+ if (typeof wrappedHandler.handler !== "function") {
+ return;
+ }
+ return wrappedHandler.handler.call(this, ...args);
+ }
+ wrappedHandler.handler = handler;
+ return wrappedHandler;
+ }
function defineEventHandler(emitter, name) {
// HTML specification section 8.1.5.1
Object.defineProperty(emitter, `on${name}`, {
get() {
- return this[handlerSymbol]?.get(name);
+ return this[handlerSymbol]?.get(name)?.handler;
},
set(value) {
- const oldListener = this[handlerSymbol]?.get(name);
- if (oldListener) {
- this.removeEventListener(name, oldListener);
- }
if (!this[handlerSymbol]) {
this[handlerSymbol] = new Map();
}
- this.addEventListener(name, value);
- this[handlerSymbol].set(value);
+ let handlerWrapper = this[handlerSymbol]?.get(name);
+ if (handlerWrapper) {
+ handlerWrapper.handler = value;
+ } else {
+ handlerWrapper = makeWrappedHandler(value);
+ this.addEventListener(name, handlerWrapper);
+ }
+ this[handlerSymbol].set(name, handlerWrapper);
},
configurable: true,
enumerable: true,
diff --git a/op_crates/web/abort_controller_test.js b/op_crates/web/abort_controller_test.js
index 4d3741986..a65bc69ff 100644
--- a/op_crates/web/abort_controller_test.js
+++ b/op_crates/web/abort_controller_test.js
@@ -95,6 +95,23 @@ function abortSignalEventOrder() {
assertEquals(arr[1], 2);
assertEquals(arr[2], 3);
}
+
+function abortSignalEventOrderComplex() {
+ const arr = [];
+ const controller = new AbortController();
+ const { signal } = controller;
+ signal.addEventListener("abort", () => arr.push(1));
+ signal.onabort = () => {
+ throw new Error();
+ };
+ signal.addEventListener("abort", () => arr.push(3));
+ signal.onabort = () => arr.push(2);
+ controller.abort();
+ assertEquals(arr[0], 1);
+ assertEquals(arr[1], 2);
+ assertEquals(arr[2], 3);
+}
+
function abortSignalHandlerLocation() {
const controller = new AbortController();
const { signal } = controller;
@@ -109,6 +126,7 @@ function main() {
controllerHasProperToString();
abortSignalIllegalConstructor();
abortSignalEventOrder();
+ abortSignalEventOrderComplex();
abortSignalHandlerLocation();
}