Bug 854099 - Make nsPresShell::ScrollToShowRect take fixed position margins into account. r=roc

When fixed position margins are set, it indicates that chrome obscures the
viewport. Inflate the target rect by these margins when calling
ScrollToShowRect on the root scrollable frame.
This commit is contained in:
Chris Lord 2013-04-05 14:34:56 +01:00
parent dfae8f8295
commit 246158c9a8

View File

@ -3151,15 +3151,25 @@ ComputeWhereToScroll(int16_t aWhereToScroll,
*
* This needs to work even if aRect has a width or height of zero.
*/
static void ScrollToShowRect(nsIScrollableFrame* aScrollFrame,
static void ScrollToShowRect(nsIFrame* aFrame,
nsIScrollableFrame* aFrameAsScrollable,
const nsRect& aRect,
nsIPresShell::ScrollAxis aVertical,
nsIPresShell::ScrollAxis aHorizontal,
uint32_t aFlags)
{
nsPoint scrollPt = aScrollFrame->GetScrollPosition();
nsPoint scrollPt = aFrameAsScrollable->GetScrollPosition();
nsRect visibleRect(scrollPt,
aScrollFrame->GetScrollPositionClampingScrollPortSize());
aFrameAsScrollable->GetScrollPositionClampingScrollPortSize());
// If this is the root scroll frame, make sure to take into account the
// content document fixed position margins. When set, these indicate that
// chrome is obscuring the viewport.
nsRect targetRect(aRect);
nsIPresShell *presShell = aFrame->PresContext()->PresShell();
if (aFrameAsScrollable == presShell->GetRootScrollFrameAsScrollable()) {
targetRect.Inflate(presShell->GetContentDocumentFixedPositionMargins());
}
nsSize lineSize;
// Don't call GetLineScrollAmount unless we actually need it. Not only
@ -3169,12 +3179,12 @@ static void ScrollToShowRect(nsIScrollableFrame* aScrollFrame,
// it would assert and possible give the wrong result.
if (aVertical.mWhenToScroll == nsIPresShell::SCROLL_IF_NOT_VISIBLE ||
aHorizontal.mWhenToScroll == nsIPresShell::SCROLL_IF_NOT_VISIBLE) {
lineSize = aScrollFrame->GetLineScrollAmount();
lineSize = aFrameAsScrollable->GetLineScrollAmount();
}
nsPresContext::ScrollbarStyles ss = aScrollFrame->GetScrollbarStyles();
nsPresContext::ScrollbarStyles ss = aFrameAsScrollable->GetScrollbarStyles();
nsRect allowedRange(scrollPt, nsSize(0, 0));
bool needToScroll = false;
uint32_t directions = aScrollFrame->GetPerceivedScrollingDirections();
uint32_t directions = aFrameAsScrollable->GetPerceivedScrollingDirections();
if (((aFlags & nsIPresShell::SCROLL_OVERFLOW_HIDDEN) ||
ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN) &&
@ -3183,15 +3193,15 @@ static void ScrollToShowRect(nsIScrollableFrame* aScrollFrame,
if (ComputeNeedToScroll(aVertical.mWhenToScroll,
lineSize.height,
aRect.y,
aRect.YMost(),
targetRect.y,
targetRect.YMost(),
visibleRect.y,
visibleRect.YMost())) {
nscoord maxHeight;
scrollPt.y = ComputeWhereToScroll(aVertical.mWhereToScroll,
scrollPt.y,
aRect.y,
aRect.YMost(),
targetRect.y,
targetRect.YMost(),
visibleRect.y,
visibleRect.YMost(),
&allowedRange.y, &maxHeight);
@ -3207,15 +3217,15 @@ static void ScrollToShowRect(nsIScrollableFrame* aScrollFrame,
if (ComputeNeedToScroll(aHorizontal.mWhenToScroll,
lineSize.width,
aRect.x,
aRect.XMost(),
targetRect.x,
targetRect.XMost(),
visibleRect.x,
visibleRect.XMost())) {
nscoord maxWidth;
scrollPt.x = ComputeWhereToScroll(aHorizontal.mWhereToScroll,
scrollPt.x,
aRect.x,
aRect.XMost(),
targetRect.x,
targetRect.XMost(),
visibleRect.x,
visibleRect.XMost(),
&allowedRange.x, &maxWidth);
@ -3227,7 +3237,7 @@ static void ScrollToShowRect(nsIScrollableFrame* aScrollFrame,
// If we don't need to scroll, then don't try since it might cancel
// a current smooth scroll operation.
if (needToScroll) {
aScrollFrame->ScrollTo(scrollPt, nsIScrollableFrame::INSTANT, &allowedRange);
aFrameAsScrollable->ScrollTo(scrollPt, nsIScrollableFrame::INSTANT, &allowedRange);
}
}
@ -3366,7 +3376,7 @@ PresShell::ScrollFrameRectIntoView(nsIFrame* aFrame,
nsIScrollableFrame* sf = do_QueryFrame(container);
if (sf) {
nsPoint oldPosition = sf->GetScrollPosition();
ScrollToShowRect(sf, rect - sf->GetScrolledFrame()->GetPosition(),
ScrollToShowRect(container, sf, rect - sf->GetScrolledFrame()->GetPosition(),
aVertical, aHorizontal, aFlags);
nsPoint newPosition = sf->GetScrollPosition();
// If the scroll position increased, that means our content moved up,