diff options
author | Colin Ihrig <cjihrig@gmail.com> | 2022-05-16 10:46:39 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-16 10:46:39 -0400 |
commit | 1fa75f75c90b744d63e451519311f27ba55c21d7 (patch) | |
tree | eb51197993a50948bba422b219ea781455c10d53 | |
parent | 8af81d98a6d673fde3a5c2acacf6ad00c53b9223 (diff) |
fix(ext/web): throw if listener and signal are null (#14601)
This commit fixes a failing WPT test by making EventTarget's
addEventListener() method throw if both the listener and the
signal option are null.
Fixes: https://github.com/denoland/deno/issues/14593
-rw-r--r-- | ext/web/02_event.js | 66 | ||||
-rw-r--r-- | tools/wpt/expectation.json | 26 |
2 files changed, 55 insertions, 37 deletions
diff --git a/ext/web/02_event.js b/ext/web/02_event.js index 06df6429c..9d5169b9e 100644 --- a/ext/web/02_event.js +++ b/ext/web/02_event.js @@ -797,20 +797,6 @@ } } - function normalizeAddEventHandlerOptions( - options, - ) { - if (typeof options === "boolean" || typeof options === "undefined") { - return { - capture: Boolean(options), - once: false, - passive: false, - }; - } else { - return options; - } - } - function normalizeEventHandlerOptions( options, ) { @@ -889,6 +875,45 @@ }; } + // This is lazy loaded because there is a circular dependency with AbortSignal. + let addEventListenerOptionsConverter; + + function lazyAddEventListenerOptionsConverter() { + addEventListenerOptionsConverter ??= webidl.createDictionaryConverter( + "AddEventListenerOptions", + [ + { + key: "capture", + defaultValue: false, + converter: webidl.converters.boolean, + }, + { + key: "passive", + defaultValue: false, + converter: webidl.converters.boolean, + }, + { + key: "once", + defaultValue: false, + converter: webidl.converters.boolean, + }, + { + key: "signal", + converter: webidl.converters.AbortSignal, + }, + ], + ); + } + + webidl.converters.AddEventListenerOptions = (V, opts) => { + if (webidl.type(V) !== "Object" || V === null) { + V = { capture: Boolean(V) }; + } + + lazyAddEventListenerOptionsConverter(); + return addEventListenerOptionsConverter(V, opts); + }; + class EventTarget { constructor() { this[eventTargetData] = getDefaultTargetData(); @@ -899,14 +924,21 @@ callback, options, ) { + const prefix = "Failed to execute 'addEventListener' on 'EventTarget'"; + webidl.requiredArguments(arguments.length, 2, { - prefix: "Failed to execute 'addEventListener' on 'EventTarget'", + prefix, }); + + options = webidl.converters.AddEventListenerOptions(options, { + prefix, + context: "Argument 3", + }); + if (callback === null) { return; } - options = normalizeAddEventHandlerOptions(options); const { listeners } = (this ?? globalThis)[eventTargetData]; if (!(ReflectHas(listeners, type))) { @@ -936,8 +968,6 @@ this.removeEventListener(type, callback, options); }); } - } else if (options?.signal === null) { - throw new TypeError("signal must be non-null"); } ArrayPrototypePush(listeners[type], { callback, options }); diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 2fa5f6e68..018b3ebd3 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -902,28 +902,16 @@ "event.any.worker.html": true }, "events": { - "AddEventListenerOptions-once.any.html": [ - "Once listener should be added / removed like normal listeners" - ], - "AddEventListenerOptions-once.any.worker.html": [ - "Once listener should be added / removed like normal listeners" - ], + "AddEventListenerOptions-once.any.html": true, + "AddEventListenerOptions-once.any.worker.html": true, "AddEventListenerOptions-passive.any.html": [ - "Supports passive option on addEventListener only", - "returnValue should be ignored if-and-only-if the passive option is true", - "Equivalence of option values" + "returnValue should be ignored if-and-only-if the passive option is true" ], "AddEventListenerOptions-passive.any.worker.html": [ - "Supports passive option on addEventListener only", - "returnValue should be ignored if-and-only-if the passive option is true", - "Equivalence of option values" - ], - "AddEventListenerOptions-signal.any.html": [ - "Passing null as the signal should throw (listener is also null)" - ], - "AddEventListenerOptions-signal.any.worker.html": [ - "Passing null as the signal should throw (listener is also null)" + "returnValue should be ignored if-and-only-if the passive option is true" ], + "AddEventListenerOptions-signal.any.html": true, + "AddEventListenerOptions-signal.any.worker.html": true, "Event-isTrusted.any.html": true, "Event-isTrusted.any.worker.html": true, "EventTarget-add-remove-listener.any.html": true, @@ -4787,4 +4775,4 @@ "idlharness.https.any.worker.html": true, "idlharness-shadowrealm.window.html": false } -}
\ No newline at end of file +} |