Bug 844178 - Make RecomputePosition adjust the CB size as ViewportFrame::Reflow does. r=tn

This commit is contained in:
Mats Palmgren 2013-04-24 18:17:55 +02:00
Родитель 5671b1d883
Коммит b00ebc0531
6 изменённых файлов: 127 добавлений и 29 удалений

Просмотреть файл

@ -92,6 +92,7 @@
#include "nsAnimationManager.h"
#include "nsTransitionManager.h"
#include "nsSVGIntegrationUtils.h"
#include "nsViewportFrame.h"
#include <algorithm>
#ifdef MOZ_XUL
@ -12453,7 +12454,7 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
// Construct a bogus parent reflow state so that there's a usable
// containing block reflow state.
nsIFrame *parentFrame = aFrame->GetParent();
nsIFrame* parentFrame = aFrame->GetParent();
nsSize parentSize = parentFrame->GetSize();
nsFrameState savedState = parentFrame->GetStateBits();
@ -12477,7 +12478,10 @@ nsCSSFrameConstructor::RecomputePosition(nsIFrame* aFrame)
nsSize availSize(parentSize.width, NS_INTRINSICSIZE);
nsSize size = aFrame->GetSize();
nsSize cbSize = aFrame->GetContainingBlock()->GetSize();
ViewportFrame* viewport = do_QueryFrame(parentFrame);
nsSize cbSize = viewport ?
viewport->AdjustReflowStateAsContainingBlock(&parentReflowState).Size()
: aFrame->GetContainingBlock()->GetSize();
const nsMargin& parentBorder =
parentReflowState.mStyleBorder->GetComputedBorder();
cbSize -= nsSize(parentBorder.LeftRight(), parentBorder.TopBottom());

Просмотреть файл

@ -28,6 +28,9 @@ NS_NewViewportFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
}
NS_IMPL_FRAMEARENA_HELPERS(ViewportFrame)
NS_QUERYFRAME_HEAD(ViewportFrame)
NS_QUERYFRAME_ENTRY(ViewportFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
void
ViewportFrame::Init(nsIContent* aContent,
@ -132,13 +135,9 @@ ViewportFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
nsPoint
ViewportFrame::AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const
{
// Calculate how much room is available for fixed frames. That means
// determining if the viewport is scrollable and whether the vertical and/or
// horizontal scrollbars are visible
// Get our prinicpal child frame and see if we're scrollable
nsIFrame* kidFrame = mFrames.FirstChild();
nsIScrollableFrame *scrollingFrame = do_QueryFrame(kidFrame);
nsIScrollableFrame* scrollingFrame = do_QueryFrame(kidFrame);
if (scrollingFrame) {
nsMargin scrollbars = scrollingFrame->GetActualScrollbarSizes();
@ -152,6 +151,32 @@ ViewportFrame::AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) c
return nsPoint(0, 0);
}
nsRect
ViewportFrame::AdjustReflowStateAsContainingBlock(nsHTMLReflowState* aReflowState) const
{
#ifdef DEBUG
nsPoint offset =
#endif
AdjustReflowStateForScrollbars(aReflowState);
NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
(offset.x == 0 && offset.y == 0),
"We don't handle correct positioning of fixed frames with "
"scrollbars in odd positions");
// If a scroll position clamping scroll-port size has been set, layout
// fixed position elements to this size instead of the computed size.
nsRect rect(0, 0, aReflowState->ComputedWidth(), aReflowState->ComputedHeight());
nsIPresShell* ps = PresContext()->PresShell();
if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
rect.SizeTo(ps->GetScrollPositionClampingScrollPortSize());
}
// Make sure content document fixed-position margins are respected.
rect.Deflate(ps->GetContentDocumentFixedPositionMargins());
return rect;
}
NS_IMETHODIMP
ViewportFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -238,28 +263,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext,
reflowState.SetComputedHeight(aDesiredSize.height);
}
#ifdef DEBUG
nsPoint offset =
#endif
AdjustReflowStateForScrollbars(&reflowState);
NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
(offset.x == 0 && offset.y == 0),
"We don't handle correct positioning of fixed frames with "
"scrollbars in odd positions");
// If a scroll position clamping scroll-port size has been set, layout
// fixed position elements to this size instead of the computed size.
nsRect rect(0, 0, reflowState.ComputedWidth(), reflowState.ComputedHeight());
if (aPresContext->PresShell()->IsScrollPositionClampingScrollPortSizeSet()) {
nsSize size = aPresContext->PresShell()->
GetScrollPositionClampingScrollPortSize();
rect.width = size.width;
rect.height = size.height;
}
// Make sure content document fixed-position margins are respected.
rect.Deflate(aPresContext->PresShell()->GetContentDocumentFixedPositionMargins());
nsRect rect = AdjustReflowStateAsContainingBlock(&reflowState);
// Just reflow all the fixed-pos frames.
rv = GetAbsoluteContainingBlock()->Reflow(this, aPresContext, reflowState, aStatus,

Просмотреть файл

@ -24,6 +24,8 @@ class nsPresContext;
*/
class ViewportFrame : public nsContainerFrame {
public:
NS_DECL_QUERYFRAME_TARGET(ViewportFrame)
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS
typedef nsContainerFrame Super;
@ -68,6 +70,14 @@ public:
*/
virtual nsIAtom* GetType() const MOZ_OVERRIDE;
/**
* Adjust aReflowState to account for scrollbars and pres shell
* GetScrollPositionClampingScrollPortSizeSet and
* GetContentDocumentFixedPositionMargins adjustments.
* @return the rect to use as containing block rect
*/
nsRect AdjustReflowStateAsContainingBlock(nsHTMLReflowState* aReflowState) const;
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
#endif
@ -76,6 +86,13 @@ private:
virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const { return kFixedList; }
protected:
/**
* Calculate how much room is available for fixed frames. That means
* determining if the viewport is scrollable and whether the vertical and/or
* horizontal scrollbars are visible. Adjust the computed width/height and
* available width for aReflowState accordingly.
* @return the current scroll position, or 0,0 if not scrollable
*/
nsPoint AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const;
};

Просмотреть файл

@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html><head>
<meta charset="utf-8">
<title>Testcase for bug 844178</title>
<style type="text/css">
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0;
}
body {
position: fixed;
right: 5px;
top: 100px;
width: 100px;
height: 10px;
margin:0;
padding:0;
}
:root { overflow:scroll; }
span {
background:lime;
display:inline-block;
width:100px;
}
</style>
</head>
<body><span>Hello</span></body>
</html>

Просмотреть файл

@ -0,0 +1,40 @@
<!DOCTYPE HTML>
<html class="reftest-wait"><head>
<meta charset="utf-8">
<title>Testcase for bug 844178</title>
<style type="text/css">
html,body {
color:black; background-color:white; font-size:16px; padding:0; margin:0;
}
body {
position: fixed;
right: 0px;
top: 100px;
width: 100px;
height: 10px;
margin:0;
padding:0;
}
:root { overflow:scroll; }
span {
background:lime;
display:inline-block;
width:100px;
}
</style>
<script>
function doTest() {
document.body.style.right='5px';
document.body.offsetHeight;
document.documentElement.removeAttribute('class');
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</head>
<body><span>Hello</span></body>
</html>

Просмотреть файл

@ -1749,6 +1749,7 @@ skip-if(B2G) == 818276-1.html 818276-1-ref.html
== 827799-1.html about:blank
== 836844-1.html 836844-1-ref.html
== 841192-1.html 841192-1-ref.html
== 844178.html 844178-ref.html
== 846144-1.html 846144-1-ref.html
== 847850-1.html 847850-1-ref.html
== 848421-1.html 848421-1-ref.html