Bug 334765. Don't include scroll offsets in DOM element offset calculations. r+sr=bzbarsky
git-svn-id: svn://10.0.0.236/trunk@199159 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -142,6 +142,7 @@
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIEditorIMESupport.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
// XXX todo: add in missing out-of-memory checks
|
||||
|
||||
@@ -625,20 +626,7 @@ nsGenericHTMLElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
|
||||
}
|
||||
|
||||
// Get the union of all rectangles in this and continuation frames
|
||||
nsRect rcFrame;
|
||||
nsIFrame* next = frame;
|
||||
|
||||
do {
|
||||
rcFrame.UnionRect(rcFrame, next->GetRect());
|
||||
next = next->GetNextContinuation();
|
||||
} while (next);
|
||||
|
||||
if (rcFrame.IsEmpty()) {
|
||||
// It could happen that all the rects are empty (eg zero-width or
|
||||
// zero-height). In that case, use the first rect for the frame.
|
||||
rcFrame = frame->GetRect();
|
||||
}
|
||||
|
||||
nsRect rcFrame = nsLayoutUtils::GetUnionOfAllRects(frame);
|
||||
nsIContent *docElement = document->GetRootContent();
|
||||
|
||||
// Find the frame parent whose content's tagName either matches
|
||||
@@ -662,7 +650,7 @@ nsGenericHTMLElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
|
||||
PRBool is_absolutely_positioned = PR_FALSE;
|
||||
PRBool is_positioned = PR_FALSE;
|
||||
|
||||
origin = frame->GetPosition();
|
||||
origin = nsLayoutUtils::GetPositionIgnoringScrolling(frame);
|
||||
|
||||
const nsStyleDisplay* display = frame->GetStyleDisplay();
|
||||
|
||||
@@ -698,7 +686,7 @@ nsGenericHTMLElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
|
||||
// right coordinate system
|
||||
|
||||
if (!is_absolutely_positioned) {
|
||||
origin += parent->GetPosition();
|
||||
origin += nsLayoutUtils::GetPositionIgnoringScrolling(parent);
|
||||
}
|
||||
|
||||
content = parent->GetContent();
|
||||
|
||||
@@ -473,6 +473,47 @@ nsLayoutUtils::GetNearestScrollingView(nsIView* aView, Direction aDirection)
|
||||
return scrollableView;
|
||||
}
|
||||
|
||||
nsPoint
|
||||
nsLayoutUtils::GetPositionIgnoringScrolling(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* parent = aFrame->GetParent();
|
||||
if (!parent)
|
||||
return aFrame->GetPosition();
|
||||
nsIScrollableFrame* scrollable;
|
||||
CallQueryInterface(parent, &scrollable);
|
||||
if (!scrollable)
|
||||
return aFrame->GetPosition();
|
||||
// Compensate for the scroll position ... this might not result in (0,0)
|
||||
// if there is a scrollbar above or to the left of the content. Note that
|
||||
// scrolling moves the frame's position by the negative of GetScrollPosition.
|
||||
return aFrame->GetPosition() + scrollable->GetScrollPosition();
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsLayoutUtils::GetUnionOfAllRects(nsIFrame* aFrame)
|
||||
{
|
||||
nsRect rcFrame;
|
||||
nsIFrame* next = aFrame;
|
||||
nsIFrame* frameParent = aFrame->GetParent();
|
||||
if (!frameParent)
|
||||
return aFrame->GetRect();
|
||||
|
||||
do {
|
||||
nsRect r = next->GetRect() + next->GetParent()->GetOffsetTo(frameParent);
|
||||
rcFrame.UnionRect(rcFrame, r);
|
||||
next = next->GetNextContinuation();
|
||||
} while (next);
|
||||
|
||||
if (rcFrame.IsEmpty()) {
|
||||
// It could happen that all the rects are empty (eg zero-width or
|
||||
// zero-height). In that case, use the first rect for the frame, so the
|
||||
// x and y coordinates are usable.
|
||||
rcFrame = aFrame->GetRect();
|
||||
}
|
||||
|
||||
return rcFrame;
|
||||
}
|
||||
|
||||
nsPoint
|
||||
nsLayoutUtils::GetDOMEventCoordinatesRelativeTo(nsIDOMEvent* aDOMEvent, nsIFrame* aFrame)
|
||||
{
|
||||
|
||||
@@ -261,6 +261,19 @@ public:
|
||||
* its pres-shell
|
||||
*/
|
||||
static PRBool IsInitialContainingBlock(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* @return the offset of aFrame from its parent, as if it were scrolled to
|
||||
* the top.
|
||||
*/
|
||||
static nsPoint GetPositionIgnoringScrolling(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* @return a rectangle relative to aFrame's parent that is the union of
|
||||
* aFrame->GetRect() plus the GetRect()s of all aFrame's continuations. If
|
||||
* all the rects are empty we just return aFrame->GetRect().
|
||||
*/
|
||||
static nsRect GetUnionOfAllRects(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Get the coordinates of a given DOM mouse event, relative to a given
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
// Static IIDs/CIDs. Try to minimize these.
|
||||
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||
@@ -195,15 +196,10 @@ nsBoxObject::GetOffsetRect(nsRect& aRect)
|
||||
nsIFrame* frame = GetFrame(PR_TRUE);
|
||||
if (frame) {
|
||||
// Get its origin
|
||||
nsPoint origin = frame->GetPosition();
|
||||
nsPoint origin = nsLayoutUtils::GetPositionIgnoringScrolling(frame);
|
||||
|
||||
// Get the union of all rectangles in this and continuation frames
|
||||
nsRect rcFrame;
|
||||
nsIFrame* next = frame;
|
||||
do {
|
||||
rcFrame.UnionRect(rcFrame, next->GetRect());
|
||||
next = next->GetNextContinuation();
|
||||
} while (nsnull != next);
|
||||
nsRect rcFrame = nsLayoutUtils::GetUnionOfAllRects(frame);
|
||||
|
||||
// Find the frame parent whose content is the document element.
|
||||
nsIContent *docElement = mContent->GetCurrentDoc()->GetRootContent();
|
||||
@@ -216,7 +212,7 @@ nsBoxObject::GetOffsetRect(nsRect& aRect)
|
||||
|
||||
// Add the parent's origin to our own to get to the
|
||||
// right coordinate system
|
||||
origin += parent->GetPosition();
|
||||
origin += nsLayoutUtils::GetPositionIgnoringScrolling(parent);
|
||||
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user