diff options
author | carles escrig royo <esroyo@gmail.com> | 2024-09-23 11:19:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-23 11:19:59 +0200 |
commit | 8f32a1577ec00d239bce39dd1f526b5678041b8b (patch) | |
tree | 73d09797f5bcb0a05573e4def6a23cec2fc6553e | |
parent | 37cedefb4dc4f582311d7478d414d59469e4af5e (diff) |
fix(ext/web): don't ignore capture in EventTarget.removeEventListener (#25788)
-rw-r--r-- | ext/web/02_event.js | 8 | ||||
-rw-r--r-- | tests/unit/event_target_test.ts | 58 |
2 files changed, 59 insertions, 7 deletions
diff --git a/ext/web/02_event.js b/ext/web/02_event.js index f031d0aed..a3e40ab99 100644 --- a/ext/web/02_event.js +++ b/ext/web/02_event.js @@ -7,7 +7,6 @@ import { core, primordials } from "ext:core/mod.js"; const { - ArrayPrototypeFilter, ArrayPrototypeIncludes, ArrayPrototypeIndexOf, ArrayPrototypeMap, @@ -982,12 +981,7 @@ class EventTarget { ); const { listeners } = self[eventTargetData]; - if (callback !== null && listeners[type]) { - listeners[type] = ArrayPrototypeFilter( - listeners[type], - (listener) => listener.callback !== callback, - ); - } else if (callback === null || !listeners[type]) { + if (callback === null || !listeners[type]) { return; } diff --git a/tests/unit/event_target_test.ts b/tests/unit/event_target_test.ts index 3577587d1..3f7d8ee24 100644 --- a/tests/unit/event_target_test.ts +++ b/tests/unit/event_target_test.ts @@ -67,6 +67,64 @@ Deno.test(function anEventTargetCanBeSubclassed() { assertEquals(callCount, 0); }); +Deno.test(function removeEventListenerTest() { + const target = new EventTarget(); + let callCount = 0; + const listener = () => { + ++callCount; + }; + + target.addEventListener("incr", listener, true); + + target.dispatchEvent(new Event("incr")); + assertEquals(callCount, 1); + + // Should not remove the listener because useCapture does not match + target.removeEventListener("incr", listener, false); + + target.dispatchEvent(new Event("incr")); + assertEquals(callCount, 2); + + // Should remove the listener because useCapture matches + target.removeEventListener("incr", listener, true); + + target.dispatchEvent(new Event("incr")); + assertEquals(callCount, 2); + + // Only the capture setting matters to removeEventListener + target.addEventListener("incr", listener, { passive: true }); + + target.dispatchEvent(new Event("incr")); + assertEquals(callCount, 3); + + // Should not remove the listener because useCapture does not match + target.removeEventListener("incr", listener, { capture: true }); + target.removeEventListener("incr", listener, true); + + target.dispatchEvent(new Event("incr")); + assertEquals(callCount, 4); + + // Should remove the listener because useCapture matches + target.removeEventListener("incr", listener); + + target.dispatchEvent(new Event("incr")); + assertEquals(callCount, 4); + + // Again, should remove the listener because useCapture matches + target.addEventListener("incr", listener, { passive: true }); + target.removeEventListener("incr", listener, false); + + target.dispatchEvent(new Event("incr")); + assertEquals(callCount, 4); + + // Again, should remove the listener because useCapture matches + target.addEventListener("incr", listener, { passive: true }); + target.removeEventListener("incr", listener, { capture: false }); + + target.dispatchEvent(new Event("incr")); + assertEquals(callCount, 4); +}); + Deno.test(function removingNullEventListenerShouldSucceed() { const document = new EventTarget(); assertEquals(document.removeEventListener("x", null, false), undefined); |