From cb3a9ac56c0dbc65b96f3a87d31bdb8d651f97ea Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Thu, 28 May 2020 17:33:21 +0300 Subject: [PATCH 1/2] event: cancelBubble is a property Event#cancelBubble is property (and not a function). Change Event#cancelBubble to a property and add a test. --- lib/internal/event_target.js | 3 ++- test/parallel/test-eventtarget.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index 611aa9922118a1..c2ab97973048e6 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -109,7 +109,8 @@ class Event { get eventPhase() { return this[kTarget] ? 2 : 0; // Equivalent to AT_TARGET or NONE } - cancelBubble() { + get cancelBubble() { return false; } + set cancelBubble() { // Non-op in Node.js. Alias for stopPropagation } stopPropagation() { diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index 1b79a6bbb0ffd6..bf6941a2bde35a 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -35,6 +35,7 @@ ok(EventTarget); strictEqual(ev.composed, false); strictEqual(ev.isTrusted, false); strictEqual(ev.eventPhase, 0); + strictEqual(ev.cancelBubble, false); // Not cancelable ev.preventDefault(); From 412d82d273a95ad4bd93f1edcc351a7dbcd61ff4 Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Thu, 28 May 2020 17:53:57 +0300 Subject: [PATCH 2/2] fixup! set actual properties --- lib/internal/event_target.js | 14 +++++++++----- test/parallel/test-eventtarget.js | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index c2ab97973048e6..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,12 +111,14 @@ class Event { get eventPhase() { return this[kTarget] ? 2 : 0; // Equivalent to AT_TARGET or NONE } - get cancelBubble() { return false; } - set 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 bf6941a2bde35a..c0e760d13b1369 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -41,6 +41,24 @@ ok(EventTarget); 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 });