New issue
Advanced search Search tips

Issue 874082 link

Starred by 1 user

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux
Pri: 2
Type: Bug



Sign in to add a comment

mouseenter/mouseleave optimization doesn't work with shadow DOM

Reported by opet...@mozilla.com, Aug 14

Issue description

UserAgent: 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
 
mouseenter.html
1.1 KB View Download
Components: -Blink>DOM Blink>Input
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?
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.

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?
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.
Labels: Needs-Triage-M69
Cc: emilio@chromium.org
Cc: nzolghadr@chromium.org
Labels: -Needs-Triage-M69
Status: Available (was: Unconfirmed)
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


Cc: hayato@chromium.org
We might want to fix this bug together with bug 876994 at the same timing, so there would be no significant observable behavior change.
Cc: alemate@chromium.org wzang@chromium.org
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!
wzang@, could you share a minimized reproducer case?
It would be unclear how paper-button's regression is related to this issue.
Sorry! After a second look it seems that the regression in #12 is not related to this bug.

Sign in to add a comment