events: support dispatching event from event

Co-authored-by: Benjamin Gruenbaum <benjamingr@gmail.com>

PR-URL: https://github.com/nodejs/node/pull/34015
Reviewed-By: Denys Otrishko <shishugi@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
James M Snell
2020-06-22 06:51:53 -07:00
parent 4bbd389d12
commit ef91096565
2 changed files with 6 additions and 15 deletions

View File

@@ -7,7 +7,6 @@ const {
Map,
NumberIsInteger,
Object,
Set,
Symbol,
SymbolFor,
SymbolToStringTag,
@@ -199,7 +198,6 @@ class EventTarget {
static [kIsEventTarget] = true;
[kEvents] = new Map();
#emitting = new Set();
[kNewListener](size, type, listener, once, capture, passive) {}
[kRemoveListener](size, type, listener, capture) {}
@@ -266,25 +264,20 @@ class EventTarget {
}
dispatchEvent(event) {
if (!(event instanceof Event)) {
if (!(event instanceof Event))
throw new ERR_INVALID_ARG_TYPE('event', 'Event', event);
}
if (!isEventTarget(this)) {
if (!isEventTarget(this))
throw new ERR_INVALID_THIS('EventTarget');
}
if (this.#emitting.has(event.type) ||
event[kTarget] !== null) {
if (event[kTarget] !== null)
throw new ERR_EVENT_RECURSION(event.type);
}
const root = this[kEvents].get(event.type);
if (root === undefined || root.next === undefined)
return true;
event[kTarget] = this;
this.#emitting.add(event.type);
let handler = root.next;
let next;
@@ -310,7 +303,6 @@ class EventTarget {
handler = next;
}
this.#emitting.delete(event.type);
event[kTarget] = undefined;
return event.defaultPrevented !== true;

View File

@@ -293,13 +293,12 @@ ok(EventTarget);
// Once handler only invoked once
const ev = common.mustCall((event) => {
throws(() => eventTarget.dispatchEvent(new Event('foo')), {
code: 'ERR_EVENT_RECURSION'
});
// Can invoke the same event name recursively
eventTarget.dispatchEvent(new Event('foo'));
});
// Errors in a handler won't stop calling the others.
eventTarget.addEventListener('foo', ev);
eventTarget.addEventListener('foo', ev, { once: true });
eventTarget.dispatchEvent(new Event('foo'));
}