diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index 611aa9922118a1..5ece72ea1d9433 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -35,12 +35,13 @@ class Event { #cancelable = false; #timestamp = perf_hooks.performance.now(); - // Neither of these are currently used in the Node.js implementation + // None of these are currently used in the Node.js implementation // of EventTarget because there is no concept of bubbling or // composition. We preserve their values in Event but they are // non-ops and do not carry any semantics in Node.js #bubbles = false; #composed = false; + #propagationStopped = false; constructor(type, options) { @@ -51,6 +52,7 @@ class Event { this.#bubbles = !!bubbles; this.#composed = !!composed; this.#type = `${type}`; + this.#propagationStopped = false; // isTrusted is special (LegacyUnforgeable) Object.defineProperty(this, 'isTrusted', { get() { return false; }, @@ -109,11 +111,14 @@ class Event { get eventPhase() { return this[kTarget] ? 2 : 0; // Equivalent to AT_TARGET or NONE } - cancelBubble() { - // Non-op in Node.js. Alias for stopPropagation + get cancelBubble() { return this.#propagationStopped; } + set cancelBubble(value) { + if (value) { + this.stopPropagation(); + } } stopPropagation() { - // Non-op in Node.js + this.#propagationStopped = true; } get [Symbol.toStringTag]() { return 'Event'; } diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index 1b79a6bbb0ffd6..c0e760d13b1369 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -35,11 +35,30 @@ ok(EventTarget); strictEqual(ev.composed, false); strictEqual(ev.isTrusted, false); strictEqual(ev.eventPhase, 0); + strictEqual(ev.cancelBubble, false); // Not cancelable ev.preventDefault(); strictEqual(ev.defaultPrevented, false); } +{ + 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 });