diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index 133edc23b2423a..d1af4db3c58dd9 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -36,12 +36,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) { @@ -54,6 +55,7 @@ class Event { this.#cancelable = !!cancelable; this.#bubbles = !!bubbles; this.#composed = !!composed; + this.#propagationStopped = false; this.#type = String(type); // isTrusted is special (LegacyUnforgeable) Object.defineProperty(this, 'isTrusted', { @@ -113,11 +115,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 82a89caae1fea4..f9a95a8983cddd 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -36,6 +36,7 @@ ok(EventTarget); strictEqual(ev.composed, false); strictEqual(ev.isTrusted, false); strictEqual(ev.eventPhase, 0); + strictEqual(ev.cancelBubble, false); // Not cancelable ev.preventDefault(); @@ -50,6 +51,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');