Bug 458296. When a block doesn't carry out the bottom-margin of its children, add that bottom-margin to its overflow area. Also, add the bottom-padding of a scrolled block to its overflow area. r+sr=dbaron

This commit is contained in:
Robert O'Callahan 2008-12-29 21:18:40 +13:00
Родитель e46ac01617
Коммит 9d2aaab3a6
8 изменённых файлов: 102 добавлений и 31 удалений

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

@ -1107,9 +1107,9 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
}
// Compute our final size
ComputeFinalSize(aReflowState, state, aMetrics);
ComputeCombinedArea(aReflowState, aMetrics);
nscoord bottomEdgeOfChildren;
ComputeFinalSize(aReflowState, state, aMetrics, &bottomEdgeOfChildren);
ComputeCombinedArea(aReflowState, aMetrics, bottomEdgeOfChildren);
// Factor overflow container child bounds into the overflow area
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea,
overflowContainerBounds);
@ -1272,7 +1272,8 @@ nsBlockFrame::CheckForCollapsedBottomMarginFromClearanceLine()
void
nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
nsBlockReflowState& aState,
nsHTMLReflowMetrics& aMetrics)
nsHTMLReflowMetrics& aMetrics,
nscoord* aBottomEdgeOfChildren)
{
const nsMargin& borderPadding = aState.BorderPadding();
#ifdef NOISY_FINAL_SIZE
@ -1310,6 +1311,32 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
aMetrics.mCarriedOutBottomMargin.Zero();
}
nscoord bottomEdgeOfChildren = aState.mY + nonCarriedOutVerticalMargin;
// Shrink wrap our height around our contents.
if (aState.GetFlag(BRS_ISBOTTOMMARGINROOT) ||
NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight()) {
// When we are a bottom-margin root make sure that our last
// childs bottom margin is fully applied. We also do this when
// we have a computed height, since in that case the carried out
// margin is not going to be applied anywhere, so we should note it
// here to be included in the overflow area.
// Apply the margin only if there's space for it.
if (bottomEdgeOfChildren < aState.mReflowState.availableHeight)
{
// Truncate bottom margin if it doesn't fit to our available height.
bottomEdgeOfChildren =
PR_MIN(bottomEdgeOfChildren + aState.mPrevBottomMargin.get(),
aState.mReflowState.availableHeight);
}
}
if (aState.GetFlag(BRS_SPACE_MGR)) {
// Include the space manager's state to properly account for the
// bottom margin of any floated elements; e.g., inside a table cell.
nscoord floatHeight =
aState.ClearFloats(bottomEdgeOfChildren, NS_STYLE_CLEAR_LEFT_AND_RIGHT);
bottomEdgeOfChildren = PR_MAX(bottomEdgeOfChildren, floatHeight);
}
// Compute final height
if (NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight()) {
// Figure out how much of the computed height should be
@ -1374,29 +1401,7 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
aMetrics.mCarriedOutBottomMargin.Zero();
}
else if (NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) {
nscoord autoHeight = aState.mY + nonCarriedOutVerticalMargin;
// Shrink wrap our height around our contents.
if (aState.GetFlag(BRS_ISBOTTOMMARGINROOT)) {
// When we are a bottom-margin root make sure that our last
// childs bottom margin is fully applied.
// Apply the margin only if there's space for it.
if (autoHeight < aState.mReflowState.availableHeight)
{
// Truncate bottom margin if it doesn't fit to our available height.
autoHeight = PR_MIN(autoHeight + aState.mPrevBottomMargin.get(), aState.mReflowState.availableHeight);
}
}
if (aState.GetFlag(BRS_SPACE_MGR)) {
// Include the space manager's state to properly account for the
// bottom margin of any floated elements; e.g., inside a table cell.
nscoord floatHeight =
aState.ClearFloats(autoHeight, NS_STYLE_CLEAR_LEFT_AND_RIGHT);
autoHeight = PR_MAX(autoHeight, floatHeight);
}
// Apply min/max values
nscoord autoHeight = bottomEdgeOfChildren;
autoHeight -= borderPadding.top;
nscoord oldAutoHeight = autoHeight;
aReflowState.ApplyMinMaxConstraints(nsnull, &autoHeight);
@ -1427,6 +1432,7 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
// Screen out negative heights --- can happen due to integer overflows :-(
aMetrics.height = PR_MAX(0, aMetrics.height);
*aBottomEdgeOfChildren = bottomEdgeOfChildren;
#ifdef DEBUG_blocks
if (CRAZY_WIDTH(aMetrics.width) || CRAZY_HEIGHT(aMetrics.height)) {
@ -1438,7 +1444,8 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
void
nsBlockFrame::ComputeCombinedArea(const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aMetrics)
nsHTMLReflowMetrics& aMetrics,
nscoord aBottomEdgeOfChildren)
{
// Compute the combined area of our children
// XXX_perf: This can be done incrementally. It is currently one of
@ -1469,6 +1476,20 @@ nsBlockFrame::ComputeCombinedArea(const nsHTMLReflowState& aReflowState,
if (mBullet) {
area.UnionRect(area, mBullet->GetRect());
}
// Factor in the bottom edge of the children. Child frames
// will be added to the overflow area as we iterate through the lines,
// but their margins won't, so we need to account for bottom margins
// here. If we're a scrolled block then we also need to account
// for the scrollframe's padding, which is logically below the
// bottom margins of the children.
nscoord bottomEdgeOfContents = aBottomEdgeOfChildren;
if (GetStyleContext()->GetPseudoType() == nsCSSAnonBoxes::scrolledContent) {
// We're a scrolled frame; the scrollframe's padding should be added
// to the bottom edge of the children
bottomEdgeOfContents += aReflowState.mComputedPadding.bottom;
}
area.height = PR_MAX(area.YMost(), bottomEdgeOfContents) - area.y;
}
#ifdef NOISY_COMBINED_AREA
ListTag(stdout);

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

@ -379,10 +379,12 @@ protected:
virtual void ComputeFinalSize(const nsHTMLReflowState& aReflowState,
nsBlockReflowState& aState,
nsHTMLReflowMetrics& aMetrics);
nsHTMLReflowMetrics& aMetrics,
nscoord* aBottomEdgeOfChildren);
void ComputeCombinedArea(const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aMetrics);
nsHTMLReflowMetrics& aMetrics,
nscoord aBottomEdgeOfChildren);
/** add the frames in aFrameList to this block after aPrevSibling
* this block thinks in terms of lines, but the frame construction code

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

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="overflow:auto; width:300px; height:300px; background:green;">
<div style="height:100px;"></div>
<div style="height:200px; margin-left:100px; width:100px; background:yellow;"></div>
<div style="height:100px;"></div>
</div>
</body>
</html>

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

@ -0,0 +1,8 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="overflow:auto; width:100px; height:100px; padding:100px; background:green;">
<div style="height:200px; width:100px; background:yellow;"></div>
</div>
</body>
</html>

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

@ -0,0 +1,8 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="overflow:auto; width:300px; height:300px; background:green;">
<div style="height:200px; width:100px; margin:100px; background:yellow;"></div>
</div>
</body>
</html>

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

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="overflow:auto; width:300px; height:300px; background:green;">
<div style="height:100px; margin-top:100px;">
<div style="height:200px; margin-left:100px; width:100px; margin-bottom:100px; background:yellow;"></div>
</div>
</div>
</body>
</html>

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

@ -0,0 +1,8 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="overflow:auto; width:300px; height:300px; background:green;">
<div style="height:200px; margin-left:100px; width:100px; margin-top:100px; float:left; margin-bottom:100px; background:yellow;"></div>
</div>
</body>
</html>

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

@ -798,7 +798,7 @@ fails == 411585-3.html 411585-3-ref.html # bug 426909
== 412607-1b.html 412607-1-ref.html
== 412679-1.html 412679-1-ref.html
== 412679-2.html 412679-2-ref.html
fails == 413027-1.html 413027-1-ref.html
== 413027-1.html 413027-1-ref.html
fails == 413027-2.html 413027-2-ref.html
fails == 413027-3.html 413027-3-ref.html
== 413027-4.html 413027-4-ref.html
@ -964,6 +964,10 @@ fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 456147.xul 456147-ref.html # bug 456147
== 456484-1.html 456484-1-ref.html
== 457398-1.html 457398-1-ref.html
== 457398-2.html 457398-2-ref.html
== 458296-1a.html 458926-1-ref.html
== 458296-1b.html 458926-1-ref.html
== 458296-1c.html 458926-1-ref.html
== 458296-1d.html 458926-1-ref.html
== 458487-1a.html 458487-1-ref.html
== 458487-1b.html 458487-1-ref.html
== 458487-1c.html 458487-1-ref.html