mouseenter/mouseleave optimization doesn't work with shadow DOM
Reported by
opet...@mozilla.com,
Aug 14
|
|||||||
Issue descriptionUserAgent: Mozilla/5.0 (X11; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0 Steps to reproduce the problem: 1. open console 2. load the testcase 3. move mouse to top left of the page 4. move mouse over the first "Move mouse over me and look at the console" 5. move mouse over the second "Move mouse over me and look at the console" What is the expected behavior? Both times mouseenter listener should be called twice What went wrong? In the first case mouseenter listener fires only once Did this work before? N/A Does this work in other browsers? Yes Chrome version: 69.0.3464.0 (Official Build) dev (64-bit) Channel: n/a OS Version: Flash Version: Shockwave Flash 24.0 r0 Initially someone thought this was a bug in Firefox Nightly, but it is actually ea.com website relying on broken behavior in Chrome https://bugzilla.mozilla.org/show_bug.cgi?id=1478959
,
Aug 14
,
Aug 14
Why do you expect the mouseenter to be called twice at all in any case here? Shouldn't it be called once in both cases?
,
Aug 14
Why would there be just one listener call? Per spec mouseenter/leave are composed events. One event should fire on the shadow element and one on the host. The one which fires on shadow dom, propagates to host.
Then per spec:
Set event’s eventPhase attribute to CAPTURING_PHASE.
If activationTarget is non-null and activationTarget has legacy-pre-activation behavior, then run activationTarget’s legacy-pre-activation behavior.
For each tuple in event’s path, in reverse order:
If tuple’s target is null, then invoke with tuple, event, and legacyOutputDidListenersThrowFlag if given.
For each tuple in event’s path, in order:
If tuple’s target is non-null, then set event’s eventPhase attribute to AT_TARGET.
Otherwise, set event’s eventPhase attribute to BUBBLING_PHASE.
If either event’s eventPhase attribute is BUBBLING_PHASE and event’s bubbles attribute is true or event’s eventPhase attribute is AT_TARGET, then invoke with tuple, event, and legacyOutputDidListenersThrowFlag if given.
And AT_TARGET case calls both capturing and bubbling listeners.
,
Aug 15
Based on my understanding when composed=true and bubbles=true then event passes through the boundaries of the shadow root and goes to the shadow host and beyond. But in your example h2/h1 which is the shadow host has a non-capturing mouseenter listener and mouseenter doesn't bubble. So h2/h1 should get the mouseenter once based on the spec. What am I missing? If you expect two mouseenter where do they come from? Can you point at the steps that you expect them to fire?
,
Aug 15
bubbles=true doesn't affect whether the event propagates up to host. https://dom.spec.whatwg.org/#dispatching-events 5.15 For each tuple in event’s path, in order: -If tuple’s target is non-null, then set event’s eventPhase attribute to AT_TARGET. - Otherwise, set event’s eventPhase attribute to BUBBLING_PHASE. - If either event’s eventPhase attribute is BUBBLING_PHASE and event’s bubbles attribute is true or event’s eventPhase attribute is AT_TARGET, then invoke with tuple, event, and legacyOutputDidListenersThrowFlag if given. And since we're crossing the shadow boundary, tuple's target is non-null, so phase is AT_TARGET. Based on the current specs, one mouseenter should fire on the element in shadow dom, and propagate up to host, and another should fire on the host itself. And that happens when the element in shadow DOM has an event listener. If we want to change that behavior, we could make mouseenter/leave not composed. But that is not about this bug, where Chrome's behavior depends on whether or not there are event listeners on some node.
,
Aug 15
,
Aug 16
,
Aug 16
There is definitely an inconsistency in Chrome and we are going to fix that as soon as I find out what the correct behavior is. Regarding the bubbles I was looking at https://developer.mozilla.org/en-US/docs/Web/API/Event/composed "Propagation only occurs if the bubbles property is also true." Let's continue the discussion in the github issue. https://github.com/w3c/uievents/issues/208
,
Aug 17
,
Oct 31
We might want to fix this bug together with bug 876994 at the same timing, so there would be no significant observable behavior change.
,
Oct 31
We noticed that there's a regression in Chrome OS OOBE buttons, which looks similar to this issue: There's an on-tap event handler in paper-button: https://cs.chromium.org/chromium/src/chrome/browser/resources/chromeos/login/oobe_buttons.js?q=oobe_buttons.js&dr&l=31 If the "oobe-text-button" has "disabled" property, the event should stop bubbling up from inner "paper-button", therefore the button is effectively disabled. However, right now click events can never reach the "paper-button" level, thus the "onClick_" handler is useless. After debugging we found that the event only reaches the outer level of "oobe-text-button", but does not go down. Is it because the event cannot cross the shadow DOM boundary? This should be a regression since it used to work. Can we find a proper owner for this? Thanks!
,
Oct 31
wzang@, could you share a minimized reproducer case? It would be unclear how paper-button's regression is related to this issue.
,
Oct 31
Sorry! After a second look it seems that the regression in #12 is not related to this bug. |
|||||||
►
Sign in to add a comment |
|||||||
Comment 1 by opet...@mozilla.com
, Aug 14