w3c / uievents

UI Events
https://w3c.github.io/uievents/
Other
147 stars 52 forks source link

Clearify whether `mouseover`, `mouseout`, `mouseenter` and `mouseleave` are fired or not fired when the target is removed by `mousedown` or `mouseup` #359

Open masayuki-nakano opened 11 months ago

masayuki-nakano commented 11 months ago

mouseenter

A user agent MUST also dispatch this event when the element or one of its descendants moves to be underneath the primary pointing device.

mouseleave

A user agent MUST also dispatch this event when the element or one of its descendants moves to be no longer underneath the primary pointing device.

mouseout

A user agent MUST dispatch this event when or when the element is moved to be no longer underneath the primary pointing device.

mouseover

A user agent MUST dispatch this event when or when the element is moved to be underneath the primary pointing device.

I wrote this tentative test and the result is here and here

The expectation of the test is:

  1. When mousedown or mouseup listener removes the event target, mouseout and mouseleave should be fired on the removed element because mouseover and mouseenter were already fired on it and it's now moved to be "no longer underneath the primary pointing device".
  2. Then, mouseover should be fired on the parent of the removed element because it's not been received mouseover yet but it's now "moved to be no longer underneath the primary pointing device".
  3. However, mouseenter should not be fired on any elements because mouseneter has already been fired on the inclusive ancestors of the removed elements.

Unfortunately, Safari fails the test with ERROR. Therefore, we can check only the result of Chrome and Firefox for now.

Actual result of both of them in the first list item case is, both Chrome and Firefox do not fire the events on the removed node. Therefore, I suggest that they should be clarified as "never fired on targets which are not connected to the document node".

Then, in the second list item case, both Chrome and Firefox fire mouseover event on the parent node (Although Chrome's buttons value is wrong for non-primary button). I think that this is reasonable and web apps in the wild may depend on this event even though pointerover is defined as it should be fired only when the pointer moves. In other words, dispatching mouseover in this case is not consistent with Pointer Events, but keep dispatching it may be important for keeping the backward compatibility.

Finally, in the last list item case, both Chrome and Firefox dispatch mouseenter too because they lost the last mouseenter element due to the removal. So, I think that this is an issue of the approach to implement mouseenter event, whether browsers store only the deepest descendant or all inclusive descendants from the root elements.

My conclusion is, only the mouseout and mouselaeve expectations should be changed and this case should be clarified in the spec, maybe in the event order section?

benoit-sy commented 9 months ago

mouseleave

A user agent MUST also dispatch this event when the element or one of its descendants moves to be no longer underneath the primary pointing device.

Hello there 👋

quick derived use-case → what about one of the descendant, which was absolutely positioned, and thus visually not over the element boundary, is removed from the DOM. The pointer did not move, and technically the element is not underneath it.

I would expect the mouseleave to be fired in this case. Am i right? (spoiler it is not fired as of today)

masayuki-nakano commented 8 months ago

Current agreements in https://github.com/web-platform-tests/interop/issues/380:

I also added a new WPT for testing the mouse boundary events at first mousemove after a click event listener removes its target. Its result is here.

masayuki-nakano commented 8 months ago

Ccing @garykac, @mustaqahmed, @zcorpan and @smaug----