Bug 15897 - Please implement getBoundingClientRect and getClientRects
Summary: Please implement getBoundingClientRect and getClientRects
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: DOM (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Enhancement
Assignee: Sam Weinig
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2007-11-08 05:44 PST by Marcus Better
Modified: 2009-02-28 15:32 PST (History)
20 users (show)

See Also:


Attachments
First pass (33.15 KB, patch)
2009-02-06 15:50 PST, Sam Weinig
no flags Details | Formatted Diff | Diff
Take 2 (43.56 KB, patch)
2009-02-06 22:48 PST, Sam Weinig
no flags Details | Formatted Diff | Diff
patch (53.75 KB, patch)
2009-02-08 14:39 PST, Sam Weinig
no flags Details | Formatted Diff | Diff
updated patch (60.72 KB, patch)
2009-02-10 13:00 PST, Sam Weinig
hyatt: review+
Details | Formatted Diff | Diff
Example (testcase) showing failure in Webkit (892 bytes, text/html)
2009-02-28 10:21 PST, Garrett Smith
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Marcus Better 2007-11-08 05:44:31 PST
The getBoundingClientRect method on HTMLElement is a reasonably clean way to find the position of an element. It was originally implemented in Internet Explorer [1] and has now been added to Gecko [2, 3]. Also its companion function getClientRects [4] could be useful.

The only option currently is an error prone summation along the offsetParent chain, followed by another one up the DOM tree to add in scrolling. This is very error-prone. Having a way to find element positions is absolutely necessary for rich web applications.

Since the request to add getBoxObjectFor (bug #8154) was rejected, please consider implementing this instead.


[1] http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=174397
[3] http://developer.mozilla.org/en/docs/DOM:element.getBoundingClientRect
[4] http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getclientrects.asp
Comment 1 Mark Wubben 2007-11-23 08:01:30 PST
I'd also like to see this added to Webkit. Especially getClientRects is useful for text editing applications.
Comment 2 José Jeria 2008-02-05 03:50:50 PST
Note that this has now also been implemented by Opera 9.5
Comment 3 Sjoerd Visscher 2008-03-05 03:40:58 PST
See also the new W3C spec for these methods: 
http://www.w3.org/TR/cssom-view/
Comment 4 Robbert Broersma 2008-03-13 01:49:53 PDT
I would also very much appreciate this feature being implemented.
Comment 5 William J. Edney 2008-04-02 10:29:15 PDT
Webkit guys -

I'll vote for this one as well. See John Resig's post here:

http://ejohn.org/blog/getboundingclientrect-is-awesome

on why this method is cool and useful.

Note that Firefox 3 is deprecating their getBoxObjectFor() method in deference to this mechanism.

Cheers,

- Bill
Comment 6 Alexey Proskuryakov 2008-08-10 23:02:10 PDT
<rdar://problem/6139669>
Comment 7 Simon Fraser (smfr) 2009-01-21 17:34:04 PST
Another reason to do this is that getBoundingClientRect() will take transforms into account, and therefore provide something better than offsetLeft/offsetParent.
Comment 8 Sam Weinig 2009-02-06 15:50:08 PST
Created attachment 27427 [details]
First pass

Uploading an initial implementation of the feature.  Some things to note:
1) It needs tests
2) It is based of the January 23, 2009 Draft found at http://dev.w3.org/csswg/cssom-view/ .
3) I don't think we handle SVG correctly according to that draft.
4) I am not sure what to do about transformations/zoom.
Comment 9 Sam Weinig 2009-02-06 22:48:50 PST
Created attachment 27443 [details]
Take 2

This takes care of transformations and adds a test.
Comment 10 Sam Weinig 2009-02-08 14:39:40 PST
Created attachment 27471 [details]
patch

I think this is ready for review now.  There are few known cases where we don't work correctly, but those can be handled in follow up bugs.
Comment 11 Eric Seidel (no email) 2009-02-08 15:36:41 PST
Comment on attachment 27471 [details]
patch

Soo so sad that we're propagating the silly term "client rect" even further. :(
Comment 12 Dave Hyatt 2009-02-08 22:12:18 PST
Comment on attachment 27471 [details]
patch

My big high-level concern here is that absoluteQuads isn't going to be a match for what you want.  It's really sort of doing just what Web inspector needs it to do, and so is very inconsistent.  It doesn't include visible overflow for blocks (or any spillage from floats/positioned elements).  For inlines, taller elements on the line *are* included, etc.

Ultimately absoluteRects/Quads may need a big set of options passed into them regarding what kind of rects we return.

We will need a lot of tests to know if these methods are a good fit.
Comment 13 Sam Weinig 2009-02-10 13:00:21 PST
Created attachment 27535 [details]
updated patch

This updated patch includes a few more tests, some of which are known to fail, and a fix to RenderInline not to include children in the absoluteQuad/absoluteRect functions.  I will file bugs on all the remaining known issues so we can follow up on them individually.
Comment 14 Dave Hyatt 2009-02-10 14:45:09 PST
Comment on attachment 27535 [details]
updated patch

r=me
Comment 15 Sam Weinig 2009-02-10 15:44:34 PST
Landed in r40837.
Comment 16 Robert O'Callahan 2009-02-10 17:41:24 PST
I was actually hoping the spec would treat CSS transforms like foreignobject, as establishing a new viewport.
Comment 17 Garrett Smith 2009-02-28 10:21:22 PST
Created attachment 28118 [details]
Example (testcase) showing failure in Webkit

When the window is scrolled, the value returned is incorrect.

getBoundingClientRect method is designed to return the distance from viewport's top/left [1].  It works this way in IE, Gecko, Opera. 

However in Webkit, getBoundingClientRect returns the distance from the top/left of the documentElement. 

[1]http://msdn.microsoft.com/en-us/library/ms536433(VS.85).aspx

This means that if the viewport is scrolled, the returned position of box.top is incorrect. This is because the position is taken from documentElement, not viewport.  The example result shows that to be true.

Test Results:
Gecko, Opera:
  top: -100
  left: -99

Webkit:
  top: 0
  left: 1

Comment #10, Sam, can you please specify which known cases do not work correctly? 

Comment #4, it seems strange that work on this bug began without tests. Even more strange that the work got checked in. However, since I see no tests, it seems to be true. Can you please explain?
Comment 18 Sam Weinig 2009-02-28 15:32:30 PST
(In reply to comment #17)
> Created an attachment (id=28118) [review]
> Example (testcase) showing failure in Webkit
> 
> When the window is scrolled, the value returned is incorrect.
> 
> getBoundingClientRect method is designed to return the distance from viewport's
> top/left [1].  It works this way in IE, Gecko, Opera. 
> 
> However in Webkit, getBoundingClientRect returns the distance from the top/left
> of the documentElement. 
> 
> [1]http://msdn.microsoft.com/en-us/library/ms536433(VS.85).aspx
> 
> This means that if the viewport is scrolled, the returned position of box.top
> is incorrect. This is because the position is taken from documentElement, not
> viewport.  The example result shows that to be true.
> 
> Test Results:
> Gecko, Opera:
>   top: -100
>   left: -99
> 
> Webkit:
>   top: 0
>   left: 1

This bug was fixed in http://trac.webkit.org/changeset/41207 .

> 
> Comment #10, Sam, can you please specify which known cases do not work
> correctly? 
> 
> Comment #4, it seems strange that work on this bug began without tests. Even
> more strange that the work got checked in. However, since I see no tests, it
> seems to be true. Can you please explain?
> 

This patch was checked in with two tests.
- http://trac.webkit.org/browser/trunk/LayoutTests/fast/dom/getBoundingClientRect.html
- http://trac.webkit.org/browser/trunk/LayoutTests/fast/dom/getClientRects.html

They are even in the attached patch so I am a little confused.

A subsequent test was added when fixing the scrolling issue.
- http://trac.webkit.org/browser/trunk/LayoutTests/fast/dom/getBoundingClientRect-getClientRects-relative-to-viewport.html

Regarding what is known not to work, the provided tests include known failures including an inline in a column, and a float in an inline for getBoundingClientRect and a table with a caption for getClientRects.  If you find other bugs, please file them in a new report.