This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 24923 - What should happen to the mouse events if pointer event listener removes the target from document or hides it?
Summary: What should happen to the mouse events if pointer event listener removes the ...
Status: RESOLVED FIXED
Alias: None
Product: PointerEventsWG
Classification: Unclassified
Component: Pointer Events specification (show other bugs)
Version: unspecified
Hardware: PC Linux
: P2 normal
Target Milestone: ---
Assignee: Jacob Rossi [MSFT]
QA Contact: Pointer Events Bugzilla list
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-04 21:58 UTC by Olli Pettay
Modified: 2014-06-04 02:34 UTC (History)
4 users (show)

See Also:


Attachments
pointerdown removes e.target, mousedown never gets called (379 bytes, text/html)
2014-03-04 22:06 UTC, Patrick H. Lauke
Details
pointerdown removes e.target, what about mousedown? (672 bytes, text/html)
2014-03-04 22:15 UTC, Patrick H. Lauke
Details

Description Olli Pettay 2014-03-04 21:58:53 UTC
Per spec mouse events should be fired after pointer events, but it doesn't
talk about the target.
Should mouse events be targeted based on coordinates, or should they
use the same target as what the relevant pointer event had?
Comment 1 Patrick H. Lauke 2014-03-04 22:06:09 UTC
Created attachment 1447 [details]
pointerdown removes e.target, mousedown never gets called
Comment 2 Patrick H. Lauke 2014-03-04 22:15:04 UTC
Created attachment 1448 [details]
pointerdown removes e.target, what about mousedown?

added little test file. in IE11, once the button is removed following pointerdown, the mousedown event is still being fired at the parent div and bubbles up to window.
Comment 3 Patrick H. Lauke 2014-03-04 22:16:54 UTC
i would have actually expected that the compatibility mouse event silently vanishes into thin air in the case where the target of the pointer event suddenly disappears...
Comment 4 Scott González 2014-03-05 13:17:59 UTC
If the compatibility mouse event silently vanished, it could break a pretty common pattern. Because mouse events don't have pointer capture, it's common to implement dragging behaviors by binding a mousedown handler on a specific element, but then binding mousemove and mouseup handlers on the document and removing them on mouseup. This pattern already breaks if you move your mouse out of the window before the mouseup, but I don't think we want to introduce another scenario where this can break.

I haven't spent enough time thinking about how such code would be interacting with newer code that's leveraging pointer events, but I'm sure the mixture is going to happen quite a bit over the next few years.
Comment 5 Rick Byers 2014-03-05 16:37:45 UTC
Interesting, I assumed we wouldn't repeat the hit test (and so use the same target as the pointer event).  Even if the element isn't removed the difference is still observable - eg. what if you pointerdown on something while it's animating, and by the time the pointerdown handler finishes (and mousedown is dispatched) there's a new element under the cursor?  If we do a new hit test then it might cause surprises (code seeing only pointer or mouse events when you'd normally see both).

Scott, doesn't the scenario you describe also come up with mouse-only events when an element is removed while a mousemove is being dispatched to it?  That mousemove will never bubble up to the document, but in most cases you'll get another mousemove shortly.  Personally I think UAs should be dispatching a fake mousemove when the DOM element under the mouse cursor changes (we've got a bug for this in blink - I don't think we do it reliably today but I'm planning on getting it improved). Anyway, I don't think the compat mouse event issue with pointer events necessarily makes things any worse.
Comment 6 Scott González 2014-03-05 18:29:24 UTC
Rick: Yes, the same issue would occur if the element was removed during a mousemove, but that's not going to be nearly as common. Elements will generally be removed at the end of an interaction sequence (during the release of the button). Developers quickly understand if you say that removing an element in the middle of an interaction is going to break something, but it's harder to explain if it occurs after they've finished the interaction.

Regarding firing of fake mousemove events when the DOM changes, here's a test page I created a year ago: http://dev-test.nemikor.com/behavior/mouseover-when-element-is-shown.html. I discussed this with Jacob and Olli back then, but if we're going to address it at this level, I think we should try to get this into the mouse events spec.
Comment 7 Rick Byers 2014-03-05 19:26:06 UTC
Ah, so you're mainly worried about removal during a pointerdown event breaking someone that's waiting for the mousedown event?
Comment 8 Scott González 2014-03-05 19:38:14 UTC
My biggest concern is removal during a pointerup event breaking someone that's waiting for the mouseup event (which was likely bound to the document during the mousedown event). I would expect the target to be the same for the mouse event and the pointer event, but IE's behavior is better than Patrick's expectation of the event just vanishing because it would break less code.
Comment 9 Olli Pettay 2014-03-10 22:01:55 UTC
(In reply to Scott González from comment #6)
> but if we're going to address
> it at this level, I think we should try to get this into the mouse events
> spec.

This is a pointer events spec issue, about how legacy mouse events should
be dispatched and when.
I don't see a reason to handle this is mouse events spec.
Comment 10 Olli Pettay 2014-03-10 22:03:31 UTC
(In reply to Scott González from comment #6)
> Rick: Yes, the same issue would occur if the element was removed during a
> mousemove,
What is the issue there? Event target chain is created before
event dispatch.

This bug is about what should happen to the legacy mouse event.
Where should it be dispatched and when.
Comment 11 Jacob Rossi [MSFT] 2014-03-11 05:39:40 UTC
I strongly want to avoid hit testing again for compatibility mouse events. Primarily for perf reasons, but also because we saw developer confusion when pointer* and mouse* didn't go to the same element (an early preview of IE10 behaved this way).

This behavior is defined at the top of the section:

"Unless otherwise noted, the target of any mapped mouse event MAY be the same as the target for the pointer event from which it was mapped."

(MAY is used here as the entire section is optional)

Now, in the case of node removal, IE will fix up the target to its parent in the propagation path of the event.  This works well with most coding patterns similar to what Scott describes. In the case that the mouseup handler is on the node removed...we'll, I think you shot yourself in the foot. :-)

Do we want spec text to describe this fix up behavior?  I apologize that this nuance was left out of our spec proposal (this scenario doesn't come up often).
Comment 12 Patrick H. Lauke 2014-03-11 10:07:01 UTC
JR: "Do we want spec text to describe this fix up behavior?"

I'm all for making the spec as explicit as possible to avoid surprises and possible implementation divergence...so I'd favor something in the spec. I'd propose something like:

- add a break in the first paragraph of section 11, so that "Unless otherwise..." beings a new paragraph.
- at the end of the "Unless..." sentence, add something along the lines of "If the target of the pointer event is removed from the document before the relevant compatibility mouse event is fired, the compatibility mouse event MAY be fired on the parent of the original target."

Admittedly a mouthful and a bit awkward, but hopefully clear enough?
Comment 13 Olli Pettay 2014-03-11 12:48:16 UTC
(In reply to Jacob Rossi [MSFT] from comment #11)
> "Unless otherwise noted, the target of any mapped mouse event MAY be the
> same as the target for the pointer event from which it was mapped."
We have to remove such MAY then. If the section is implemented, it should
be implemented in MUST-way


> Now, in the case of node removal, IE will fix up the target to its parent in
> the propagation path of the event. 
So IE actually stores the event target chain for pointer event are reuses
(part of) it for mouse events? What if target, and its parent are removed?
What if target or its parent are moved to another document?


> Do we want spec text to describe this fix up behavior? 
I think not doing hit testing is ok (since it is indeed odd if pointer event
happens on a different element than mouse event), but we need explain
exactly also what the target of the mouse event should be when the target
(or any of its ancestors) of the pointer event is removed from the tree.
Comment 14 Olli Pettay 2014-03-17 20:00:54 UTC
Has anyone had time to test this some more on IE11?
Comment 15 Jacob Rossi [MSFT] 2014-03-17 21:16:42 UTC
I just looked more into this. The initial event path is built from the target node. If the target node is removed (whether by itself or as a part of a larger sub-tree removal, whether removed or simply moved elsewhere in the document or to another document), then the corresponding compatibility mouse event path is built from the nearest ancestor in the initial event path that is still in the tree.
Comment 16 Jacob Rossi [MSFT] 2014-03-17 21:22:28 UTC
Being a little more algorithmic in the description:

1. Hit test to determine target for pointer event. Store this as the "Hit Node".
2. Build (and lock) an event path, based on Hit Node.
3. Dispatch pointer event.
4. Build (and lock) an event path for the compat mouse event, based on Hit Node.
5. Dispatch the mouse event.

Then, in our code path for elements leaving the tree, if the element leaving the tree is Hit Node then Hit Node is updated (at the time of removal) to the nearest in-tree ancestor (which is the same as nearest in-tree ancestor from the event path in step 2).
Comment 17 Olli Pettay 2014-03-17 21:33:40 UTC
So it can go all the way up to Document object if document.documentElement is removed from document or something?
Comment 18 Jacob Rossi [MSFT] 2014-03-17 21:42:52 UTC
Yes.
Comment 19 Olli Pettay 2014-03-17 21:51:06 UTC
Also, what happens if the element to which pointerevent was dispatched
changed style to display: none before mouse event dispatch?



(I think using the nearest non-moved ancestor should be fine, and just not care
about layout. )
Comment 20 Jacob Rossi [MSFT] 2014-03-17 21:54:51 UTC
Style changes do not affect the event path. The mouse event is still dispatched to the original target.
Comment 21 Jacob Rossi [MSFT] 2014-06-03 05:37:53 UTC
As asked in Action-98, I think this is the simplest change to describe this behavior:

https://dvcs.w3.org/hg/pointerevents/rev/f07f819eaf5e

Feedback welcomed.
Comment 22 Patrick H. Lauke 2014-06-03 06:40:40 UTC
combining my suggestions from the mailing list - and some additional note about the event path thing - here, I'd suggest changing the second line from

<p>Unless otherwise noted, the target of any mapped mouse event SHOULD be the same target as the respective pointer event unless the target is no longer participating in its <code>ownerDocument</code>'s tree. In this case, the mouse event should be fired at the original target's parent node at the time it left the tree (meaning, a new even path is built for the mouse event).</p>

to

<p>Unless otherwise noted, the target of any mapped mouse event SHOULD be the same target as the respective pointer event, unless the target is no longer participating in its <code>ownerDocument</code>'s tree. In this case, the mouse event should be fired at the original target's nearest ancestor node (at the time it was removed from the tree), meaning that a new event path (based on the original path) is built for the mouse event.</p>
Comment 23 Jacob Rossi [MSFT] 2014-06-03 13:13:03 UTC
I agree with your suggestion. In particular, the change to "nearest ancestor node" to cover the subtree removal case. However, I would change "(based on the original path)" to "(based on the new target node)".  The former sounds like the original path is to be used as an input into the event path creation algorithm in some special way. Really you're just building a brand new path using the newly found target node.
Comment 24 Jacob Rossi [MSFT] 2014-06-04 02:34:13 UTC
Updated in this change: https://dvcs.w3.org/hg/pointerevents/rev/5b06a2e374b7

"In this case, the mouse event should be fired at the original target's nearest ancestor node (at the time it was removed from the tree) that still participates in its ownerDocument's tree, meaning that a new event path (based on the new target node) is built for the mouse event."