mousedown event's offsetX and offsetY values change after mouseup

RESOLVED FIXED in Firefox 43

Status

()

defect
RESOLVED FIXED
4 years ago
4 years ago

People

(Reporter: i93.borg, Assigned: bzbarsky)

Tracking

40 Branch
mozilla43
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(firefox43 fixed)

Details

Attachments

(1 attachment)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0 Iceweasel/40.0.3
Build ID: 20150831023214

Steps to reproduce:

From test case at https://gir.me.uk/files/tmp/20150909-iceweasel-bug/

```
var div = document.getElementById('test');

div.onmousedown = function (e1) {
    console.log('down');
    console.log(['offset', e1.offsetX, e1.offsetY]);

    console.log(['offset', e1.offsetX, e1.offsetY]);

    div.onmouseup = function (e2) {
        console.log('down');
        console.log(['offset', e1.offsetX, e1.offsetY]);
        console.log('up');
        console.log(['offset', e2.offsetX, e2.offsetY]);
    };
};
```

(onmouseup bound inside onmousedown callback because the real code uses a timer to detect holding of mouse, but that part is not necessary to reproduce).


Actual results:

e1 (the mousedown event object's offsetX and offsetY values change from their original value:

```
 ["down-offset", 1, 1]
test.js (line 4)
["down-offset", 12, 12]
test.js (line 7)
["up-offset", 1, 1]
```

Note that the values of mouseup event object correctly match the original mousedown event values.

This used to work fine before until quite recently, so looks like a regression.

Verified on Windows and Linux (with Debian Iceweasel).


Expected results:

mousedown event object's offsetX and offsetY should not change.
Sorry, test code should be:

```
var div = document.getElementById('test');

div.onmousedown = function (e1) {
    console.log(['down-offset', e1.offsetX, e1.offsetY]);

    div.onmouseup = function (e2) {
        console.log(['down-offset', e1.offsetX, e1.offsetY]);
        console.log(['up-offset', e2.offsetX, e2.offsetY]);
    };
};
```

(Pasted an older version that produced slightly different output.)
Component: Untriaged → DOM: Events
Product: Firefox → Core
Blocks: 69787
I believe this is according to spec:
https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
If you don't like it, request a spec change. But I think other browsers behave this way so it's unlikely the spec will be changed. Please correct me if I'm wrong.
Status: UNCONFIRMED → RESOLVED
Closed: 4 years ago
Resolution: --- → INVALID
I disagree with your assessment on the following grounds:

1. Other browsers do indeed return consistent value:

Chromium (Linux)
```
test.js:4 ["down-offset", 79, 53]
test.js:7 ["down-offset", 79, 53]
test.js:8 ["up-offset", 79, 53]
```

IE 11:
```
down-offset,54,50
   [
      0: "down-offset",
      1: 54,
      2: 50,
      length: 3
   ]

down-offset,54,50
   [
      0: "down-offset",
      1: 54,
      2: 50,
      length: 3
   ]

up-offset,54,50
   [
      0: "up-offset",
      1: 54,
      2: 50,
      length: 3
   ]
```

2. This is a change in Firefox behaviour - previously consistent value was shown (I am quite sure of this because this change broke an app I wrote that was working just fine for 18 months since I wrote it, causing some major WTF as I debugged it).

3. Nowhere in the spec you linked to does it say that the mousedown event coordinates should mutate somewhere between mousedown and mouseup (of course, I could be missing it somehow since I am not familiar with spec terminology).
Status: RESOLVED → UNCONFIRMED
Resolution: INVALID → ---
> Nowhere in the spec you linked to does it say that the mousedown event coordinates should
> mutate

It's in this bit:

  "If the event’s dispatch flag is set"

followed by different things returned depending on whether that flag is set or not.  That flag is set only while an event is being dispatched.  So in your testcase, it's set on the mousedown event during the mousedown handler but not the mouseup handler.  So the behavior you're seeing in Firefox is in fact what the spec says to do.

> This is a change in Firefox behaviour - previously consistent value was shown

Previously when?  The initial implementation of offsetX/Y in Firefox 39 has the spec behavior.  What Firefox release do you think the behavior was different in?

It does sound like the spec is not compatible with other UAs in this case, though... Anne, what's up with that?
Flags: needinfo?(annevk)
> Previously when?  The initial implementation of offsetX/Y in Firefox 39 has the spec behavior.  What Firefox release do you think the behavior was different in?

OK, so I checked my code again, and I do have this hack:

```
e.offsetX || e.pageX - el.offsetLeft
```

I guess that's why it's there - I should have added a comment because I myself have forgotten. Apologies for the confusion.

> That flag is set only while an event is being dispatched.  So in your testcase, it's set on the mousedown event during the mousedown handler but not the mouseup handler.  So the behavior you're seeing in Firefox is in fact what the spec says to do.

Maybe I have some fundamental misunderstanding of DOM, in which case I apologise for my ignorance, but why would an event that has already happened be modified when a different event happens? It just doesn't make any sense! :-( What is the benefit of something like that? I thought that an event object is a point in time representation of an event, that can be referred to later, but it seems this is a mistaken view?
Those are all questions about the spec, yes?  I hope that Anne will be able to answer them for sure.  Certainly having offsetX depend on target after dispatch is not a problem a priori; end of dispatch does not reset target....
I no longer work on CSS. And I've no idea how to view the history of that standard. An earlier version that still has my name on it doesn't have the dispatch flag conditional, but I can't say for sure who introduced that and why.
Flags: needinfo?(annevk) → needinfo?(zcorpan)
The spec was changed in https://www.w3.org/Bugs/Public/show_bug.cgi?id=16673 -- I'll look into fixing this.
Flags: needinfo?(zcorpan)
Ah.  The spec change in that bug didn't match the actual behavior description given in the initial bug report there.  So the spec is just wrong.

I think the simplest thing to do here is to do the pageX thing unless we have a target, else return coordinates relative to that target.
Status: UNCONFIRMED → NEW
Ever confirmed: true
And Anne, sorry for pinging you; I think I was looking at the DOM spec when I finished figuring out what the specs here are saying, so automatically assumed it was your bailiwick.  ;)
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
https://hg.mozilla.org/mozilla-central/rev/82767b12c233
Status: ASSIGNED → RESOLVED
Closed: 4 years ago4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla43
You need to log in before you can comment on or make changes to this bug.