dom icon indicating copy to clipboard operation
dom copied to clipboard

Should event.stopPropagation() during capturing prevent the bubbling phase?

Open domenic opened this issue 4 years ago • 8 comments

Originally https://github.com/jsdom/jsdom/issues/3070.

Example code (live version):

const element = document.createElement("div");

element.addEventListener("click", () => {
  console.log("capture listener");
  event.stopPropagation();
}, { capture: true });

element.addEventListener("click", () => {
  console.log("bubble listener");
});

element.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));

In Safari, and per the spec (and in jsdom): logs only "capture listener".

In Firefox and Chrome: logs "capture listener" and then "bubble listener"

Which should it be?

@alexreardon also notes that the domintro for stopPropagation, which reads

When dispatched in a tree, invoking this method prevents event from reaching any objects other than the current object.

implies to him it should be the Firefox and Chrome behavior.

domenic avatar Nov 05 '20 19:11 domenic

FWIW, I think Safari is right.

WebReflection avatar Nov 05 '20 22:11 WebReflection

This is the result of https://github.com/whatwg/dom/pull/686 and https://github.com/whatwg/dom/pull/750.

It took me a while to find the relevant bugs, but it seems they are:

  • https://bugs.chromium.org/p/chromium/issues/detail?id=1052152
  • https://bugzilla.mozilla.org/show_bug.cgi?id=1492446

It does seem we need to update the domintro here. What do you all think about adding "or event listeners on the current object whose capture is different"?

annevk avatar Nov 06 '20 12:11 annevk

Thanks for that research @annevk

I think those two bugs listed are regarding the ordering of which event listeners is called, where capture listeners are always called before bubble listeners, even on the target (which is great).

However, the issue being raised here regards calling event.preventDefault() inside of a capture listener on the target. Based on our understanding of the spec, calling event.preventDefault() inside of a capture listener on the target should prevent the bubble listener on the target from being called. That is the behaviour in Safari and jsdom. However, in Chrome and Firefox calling event.preventDefault() inside of a capture listener on the target will still result in the bubble listeners on the target being called.

alexreardon avatar Nov 07 '20 09:11 alexreardon

(there is also much more background information in the jsdom issue: https://github.com/jsdom/jsdom/issues/3070)

alexreardon avatar Nov 07 '20 09:11 alexreardon

Right, once the Chrome and Firefox bugs I listed are fixed, they will behave the same as Safari and jsdom.

annevk avatar Nov 08 '20 10:11 annevk

I wasn't sure if the bugs listed addressed the event.preventDefault() behaviour on the target

alexreardon avatar Nov 08 '20 21:11 alexreardon

Seems like there's no normative spec issue here. Should we leave this open to track updating the domintro?

domenic avatar Nov 19 '20 15:11 domenic

I am currently implementing https://bugs.chromium.org/p/chromium/issues/detail?id=1052152 and it looks like in the process of doing so I am also implementing the desired behavior of this issue as a side effect. I will add a WPT for it.

josepharhar avatar Dec 09 '20 18:12 josepharhar