From 3fff349cca2a98614e040ae5d6b47d74057225ac Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Thu, 28 May 2020 17:33:21 +0300 Subject: [PATCH 1/5] event: cancelBubble is a property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Event#cancelBubble is property (and not a function). Change Event#cancelBubble to a property and add a test. PR-URL: https://github.com/nodejs/node/pull/33613 Reviewed-By: James M Snell Reviewed-By: Michaël Zasso Reviewed-By: Ruben Bridgewater Reviewed-By: Juan José Arboleda --- test/parallel/test-eventtarget.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index 3e652e1e3396b4..d7c57c0e059191 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -69,6 +69,24 @@ ok(EventTarget); const ev = new Event('foo', {}, {}); strictEqual(ev.type, 'foo'); } +{ +const ev = new Event('foo'); + strictEqual(ev.cancelBubble, false); + ev.cancelBubble = true; + strictEqual(ev.cancelBubble, true); +} +{ + const ev = new Event('foo'); + strictEqual(ev.cancelBubble, false); + ev.stopPropagation(); + strictEqual(ev.cancelBubble, true); +} +{ + const ev = new Event('foo'); + strictEqual(ev.cancelBubble, false); + ev.cancelBubble = 'some-truthy-value'; + strictEqual(ev.cancelBubble, true); +} { const ev = new Event('foo', { cancelable: true }); strictEqual(ev.type, 'foo'); From d2b9e562014da1fbcb3984d274fc77c9882da8db Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Thu, 28 May 2020 21:46:18 +0300 Subject: [PATCH 2/5] events: add event-target tests PR-URL: https://github.com/nodejs/node/pull/33623 Reviewed-By: James M Snell Reviewed-By: Ruben Bridgewater --- test/parallel/test-eventtarget.js | 34 +++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index d7c57c0e059191..ad8347e0585c95 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -15,7 +15,7 @@ const { throws, } = require('assert'); -const { once } = require('events'); +const { once, on } = require('events'); // The globals are defined. ok(Event); @@ -70,7 +70,7 @@ ok(EventTarget); strictEqual(ev.type, 'foo'); } { -const ev = new Event('foo'); + const ev = new Event('foo'); strictEqual(ev.cancelBubble, false); ev.cancelBubble = true; strictEqual(ev.cancelBubble, true); @@ -457,3 +457,33 @@ const ev = new Event('foo'); const event = new Event(''); strictEqual(event.toString(), '[object Event]'); } +{ + const target = new EventTarget(); + const ev = new Event('toString'); + const fn = common.mustCall((event) => strictEqual(event.type, 'toString')); + target.addEventListener('toString', fn); + target.dispatchEvent(ev); +} +{ + const target = new EventTarget(); + const ev = new Event('__proto__'); + const fn = common.mustCall((event) => strictEqual(event.type, '__proto__')); + target.addEventListener('__proto__', fn); + target.dispatchEvent(ev); +} + +(async () => { + // test NodeEventTarget async-iterability + const emitter = new NodeEventTarget(); + const event = new Event('foo'); + const interval = setInterval(() => emitter.dispatchEvent(event), 0); + let count = 0; + for await (const [ item ] of on(emitter, 'foo')) { + count++; + strictEqual(item.type, 'foo'); + if (count > 5) { + break; + } + } + clearInterval(interval); +})().then(common.mustCall()); From 331d90470d90de943f77a0e04a2ee88763a75bdf Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Thu, 28 May 2020 22:01:04 +0300 Subject: [PATCH 3/5] events: support dispatching event from event --- lib/internal/event_target.js | 9 ++------- test/parallel/test-eventtarget.js | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index 8c4ea11a14ed8b..3024bbfc7eec3f 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -5,7 +5,6 @@ const { Error, Map, Object, - Set, Symbol, NumberIsNaN, SymbolToStringTag, @@ -186,7 +185,6 @@ class Listener { class EventTarget { [kEvents] = new Map(); - #emitting = new Set(); [kNewListener](size, type, listener, once, capture, passive) {} [kRemoveListener](size, type, listener, capture) {} @@ -257,9 +255,8 @@ class EventTarget { throw new ERR_INVALID_ARG_TYPE('event', 'Event', event); } - if (this.#emitting.has(event.type) || - event[kTarget] !== null) { - throw new ERR_EVENT_RECURSION(event.type); + if (event[kTarget] !== undefined) { + throw new ERR_EVENT_RECURSION(event); } const root = this[kEvents].get(event.type); @@ -267,7 +264,6 @@ class EventTarget { return true; event[kTarget] = this; - this.#emitting.add(event.type); let handler = root.next; let next; @@ -293,7 +289,6 @@ class EventTarget { handler = next; } - this.#emitting.delete(event.type); event[kTarget] = undefined; return event.defaultPrevented === true ? false : true; diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index ad8347e0585c95..3ed65cfe8ece99 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -289,10 +289,10 @@ ok(EventTarget); { const eventTarget = new EventTarget(); - + const event = new Event('foo'); // Once handler only invoked once - const ev = common.mustCall((event) => { - throws(() => eventTarget.dispatchEvent(new Event('foo')), { + const ev = common.mustCall(() => { + throws(() => eventTarget.dispatchEvent(event), { code: 'ERR_EVENT_RECURSION' }); }); @@ -300,7 +300,7 @@ ok(EventTarget); // Errors in a handler won't stop calling the others. eventTarget.addEventListener('foo', ev); - eventTarget.dispatchEvent(new Event('foo')); + eventTarget.dispatchEvent(event); } { @@ -487,3 +487,13 @@ ok(EventTarget); } clearInterval(interval); })().then(common.mustCall()); + const event = new Event('foo'); + let callCount = 0; + target.addEventListener('foo', common.mustCall(() => { + callCount++; + if (callCount < 5) { + target.dispatchEvent(new Event('foo')); + } + }, 5)); + target.dispatchEvent(event); +} From 2f7d424e5f0a47d5a1eac2aee17a29e8338d97b5 Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Mon, 8 Jun 2020 13:05:21 +0300 Subject: [PATCH 4/5] fixup! ruben's fix again --- test/parallel/test-eventtarget.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index 3ed65cfe8ece99..9a5f7b0abf791e 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -487,6 +487,8 @@ ok(EventTarget); } clearInterval(interval); })().then(common.mustCall()); +{ + let target = new EventTarget(); const event = new Event('foo'); let callCount = 0; target.addEventListener('foo', common.mustCall(() => { From 5b397abb38b355f7d5cda096079b602631efd505 Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Sun, 21 Jun 2020 13:16:46 +0300 Subject: [PATCH 5/5] fix lint --- test/parallel/test-eventtarget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index 9a5f7b0abf791e..c1ed4cadcaf2d8 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -488,7 +488,7 @@ ok(EventTarget); clearInterval(interval); })().then(common.mustCall()); { - let target = new EventTarget(); + const target = new EventTarget(); const event = new Event('foo'); let callCount = 0; target.addEventListener('foo', common.mustCall(() => {