Backing out bug 375304 to fix reftest failures.

This commit is contained in:
roc+@cs.cmu.edu 2007-12-01 03:49:13 -08:00
parent 91a44c37a7
commit 8e798bb181
4 changed files with 95 additions and 89 deletions

View File

@ -784,8 +784,12 @@ CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
// The issue here is that for a 'height' of 'auto' the reflow state
// code won't know how to calculate the containing block height
// because it's calculated bottom up. So we use our own computed
// size as the dimensions.
// size as the dimensions. We don't really want to do this for the
// initial containing block
nsIFrame* frame = aReflowState.frame;
if (nsLayoutUtils::IsInitialContainingBlock(frame)) {
return nsSize(-1, -1);
}
nsSize cbSize(aFrameSize);
// Containing block is relative to the padding edge
@ -821,9 +825,13 @@ CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
nsBoxLayoutState dummyState(aLastRS->frame->PresContext(),
aLastRS->rendContext);
scrollbars = scrollFrame->GetDesiredScrollbarSizes(&dummyState);
if (!lastButOneRS->mFlags.mAssumingHScrollbar) {
// XXX We should account for the horizontal scrollbar too --- but currently
// nsGfxScrollFrame assumes nothing depends on the presence (or absence) of
// a horizontal scrollbar, so accounting for it would create incremental
// reflow bugs.
//if (!lastButOneRS->mFlags.mAssumingHScrollbar) {
scrollbars.top = scrollbars.bottom = 0;
}
//}
if (!lastButOneRS->mFlags.mAssumingVScrollbar) {
scrollbars.left = scrollbars.right = 0;
}

View File

@ -420,19 +420,6 @@ nsHTMLScrollFrame::ReflowScrolledFrame(const ScrollReflowState& aState,
nscoord availWidth = aState.mReflowState.ComputedWidth() + paddingLR;
nscoord computedHeight = aState.mReflowState.ComputedHeight();
nscoord computedMinHeight = aState.mReflowState.mComputedMinHeight;
nscoord computedMaxHeight = aState.mReflowState.mComputedMaxHeight;
if (aAssumeHScroll) {
nsSize hScrollbarPrefSize =
mInner.mHScrollbarBox->GetPrefSize(const_cast<nsBoxLayoutState&>(aState.mBoxState));
if (computedHeight != NS_UNCONSTRAINEDSIZE)
computedHeight = PR_MAX(0, computedHeight - hScrollbarPrefSize.height);
computedMinHeight = PR_MAX(0, computedMinHeight - hScrollbarPrefSize.height);
if (computedMaxHeight != NS_UNCONSTRAINEDSIZE)
computedMaxHeight = PR_MAX(0, computedMaxHeight - hScrollbarPrefSize.height);
}
if (aAssumeVScroll) {
nsSize vScrollbarPrefSize =
mInner.mVScrollbarBox->GetPrefSize(const_cast<nsBoxLayoutState&>(aState.mBoxState));
@ -456,9 +443,6 @@ nsHTMLScrollFrame::ReflowScrolledFrame(const ScrollReflowState& aState,
&aState.mReflowState.mComputedPadding);
kidReflowState.mFlags.mAssumingHScrollbar = aAssumeHScroll;
kidReflowState.mFlags.mAssumingVScrollbar = aAssumeVScroll;
kidReflowState.SetComputedHeight(computedHeight);
kidReflowState.mComputedMinHeight = computedMinHeight;
kidReflowState.mComputedMaxHeight = computedMaxHeight;
nsReflowStatus status;
nsresult rv = ReflowChild(mInner.mScrolledFrame, presContext, *aMetrics,
@ -542,14 +526,13 @@ nsresult
nsHTMLScrollFrame::ReflowContents(ScrollReflowState* aState,
const nsHTMLReflowMetrics& aDesiredSize)
{
PRBool lastUsedVScrollbar = GuessVScrollbarNeeded(*aState);
PRBool lastUsedHScrollbar = mInner.mHasHorizontalScrollbar; // XXX is this good enough?
PRBool currentlyUsingVScrollbar = GuessVScrollbarNeeded(*aState);
nsHTMLReflowMetrics kidDesiredSize(aDesiredSize.mFlags);
nsresult rv = ReflowScrolledFrame(*aState, lastUsedHScrollbar, lastUsedVScrollbar,
nsresult rv = ReflowScrolledFrame(*aState, PR_FALSE, currentlyUsingVScrollbar,
&kidDesiredSize, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
PRBool relativeHeight = (mInner.mScrolledFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT) != 0;
if (NS_FAILED(rv))
return rv;
PRBool didUseScrollbar = currentlyUsingVScrollbar;
// There's an important special case ... if the child appears to fit
// in the inside-border rect (but overflows the scrollport), we
@ -567,10 +550,7 @@ nsHTMLScrollFrame::ReflowContents(ScrollReflowState* aState,
// Detecting when we enter this special case is important for when
// people design layouts that exactly fit the container "most of the
// time".
// XXX Is this check really sufficient to catch all the incremental cases
// where the ideal case doesn't have a scrollbar?
if ((lastUsedVScrollbar || (lastUsedHScrollbar && relativeHeight)) &&
if (currentlyUsingVScrollbar &&
aState->mStyles.mVertical != NS_STYLE_OVERFLOW_SCROLL &&
aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_SCROLL) {
nsSize insideBorderSize =
@ -579,66 +559,56 @@ nsHTMLScrollFrame::ReflowContents(ScrollReflowState* aState,
nsRect scrolledRect = mInner.GetScrolledRect(insideBorderSize);
if (nsRect(nsPoint(0, 0), insideBorderSize).Contains(scrolledRect)) {
// Let's pretend we had no vertical scrollbar coming in here
rv = ReflowScrolledFrame(*aState, PR_FALSE, PR_FALSE,
currentlyUsingVScrollbar = PR_FALSE;
rv = ReflowScrolledFrame(*aState, PR_FALSE, currentlyUsingVScrollbar,
&kidDesiredSize, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
lastUsedVScrollbar = PR_FALSE;
lastUsedHScrollbar = PR_FALSE;
if (NS_FAILED(rv))
return rv;
didUseScrollbar = PR_FALSE;
}
}
// First try a layout without a horizontal scrollbar, then with.
if (!relativeHeight) {
if (TryLayout(aState, kidDesiredSize, lastUsedVScrollbar, PR_FALSE, PR_FALSE))
return NS_OK;
if (TryLayout(aState, kidDesiredSize, lastUsedVScrollbar, PR_TRUE, PR_FALSE))
return NS_OK;
} else {
if (TryLayout(aState, kidDesiredSize, lastUsedVScrollbar, lastUsedHScrollbar, PR_FALSE))
return NS_OK;
}
if (TryLayout(aState, kidDesiredSize, didUseScrollbar, PR_FALSE, PR_FALSE))
return NS_OK;
// XXX Adding a horizontal scrollbar could cause absolute children positioned
// relative to the bottom padding-edge to need to be reflowed. But we don't,
// because that would be slow.
if (TryLayout(aState, kidDesiredSize, didUseScrollbar, PR_TRUE, PR_FALSE))
return NS_OK;
PRBool canHaveVerticalScrollbar =
aState->mStyles.mVertical != NS_STYLE_OVERFLOW_HIDDEN;
PRBool canHaveHorizontalScrollbar =
aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN;
// That didn't work. Try the other setting for the vertical scrollbar.
// But don't try to show a scrollbar if we know there can't be one.
if (lastUsedVScrollbar || canHaveVerticalScrollbar) {
rv = ReflowScrolledFrame(*aState, PR_FALSE, !lastUsedVScrollbar,
&kidDesiredSize, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
lastUsedHScrollbar = PR_FALSE;
lastUsedVScrollbar = !lastUsedVScrollbar;
if (!relativeHeight) {
if (TryLayout(aState, kidDesiredSize, lastUsedVScrollbar, PR_FALSE, PR_FALSE))
return NS_OK;
if (TryLayout(aState, kidDesiredSize, lastUsedVScrollbar, PR_TRUE, PR_FALSE))
return NS_OK;
} else {
if (TryLayout(aState, kidDesiredSize, lastUsedVScrollbar, lastUsedHScrollbar, PR_FALSE))
return NS_OK;
}
}
if ((lastUsedHScrollbar || canHaveHorizontalScrollbar) && relativeHeight) {
rv = ReflowScrolledFrame(*aState, PR_TRUE, PR_FALSE,
&kidDesiredSize, PR_FALSE);
lastUsedHScrollbar = PR_TRUE;
lastUsedVScrollbar = PR_FALSE;
NS_ENSURE_SUCCESS(rv, rv);
if (TryLayout(aState, kidDesiredSize, lastUsedVScrollbar, lastUsedHScrollbar, PR_FALSE))
if (currentlyUsingVScrollbar || canHaveVerticalScrollbar) {
nsHTMLReflowMetrics kidRetrySize(aDesiredSize.mFlags);
rv = ReflowScrolledFrame(*aState, PR_FALSE, !currentlyUsingVScrollbar,
&kidRetrySize, PR_FALSE);
if (NS_FAILED(rv))
return rv;
didUseScrollbar = !currentlyUsingVScrollbar;
// XXX Adding a horizontal scrollbar could cause absolute children positioned
// relative to the bottom padding-edge to need to be reflowed. But we don't,
// because that would be slow.
if (TryLayout(aState, kidRetrySize, didUseScrollbar, PR_FALSE, PR_FALSE))
return NS_OK;
if (TryLayout(aState, kidRetrySize, didUseScrollbar, PR_TRUE, PR_FALSE))
return NS_OK;
NS_WARNING("Strange content ... we can't find logically consistent scrollbar settings");
} else {
NS_WARNING("Strange content ... we can't find logically consistent scrollbar settings");
}
rv = ReflowScrolledFrame(*aState, PR_TRUE, PR_TRUE,
&kidDesiredSize, PR_FALSE);
lastUsedHScrollbar = PR_TRUE;
lastUsedVScrollbar = PR_TRUE;
NS_ENSURE_SUCCESS(rv, rv);
TryLayout(aState, kidDesiredSize, lastUsedVScrollbar, lastUsedHScrollbar, PR_TRUE);
// Fall back to no scrollbars --- even if NS_STYLE_OVERFLOW_SCROLL is
// in effect. They might not fit anyway.
if (didUseScrollbar) {
rv = ReflowScrolledFrame(*aState, PR_FALSE, PR_FALSE, &kidDesiredSize, PR_FALSE);
if (NS_FAILED(rv))
return rv;
}
TryLayout(aState, kidDesiredSize, PR_FALSE, PR_FALSE, PR_TRUE);
return NS_OK;
}

View File

@ -362,7 +362,16 @@ IsQuirkContainingBlockHeight(const nsHTMLReflowState* rs)
nsIAtom* frameType = rs->frame->GetType();
if (nsGkAtoms::blockFrame == frameType ||
nsGkAtoms::areaFrame == frameType ||
nsGkAtoms::scrollFrame == frameType) {
nsGkAtoms::scrollFrame == frameType) {
if (nsGkAtoms::areaFrame == frameType) {
// Skip over scrolled-content area frames
if (rs->frame->GetStyleContext()->GetPseudoType() ==
nsCSSAnonBoxes::scrolledContent) {
return PR_FALSE;
}
}
// Note: This next condition could change due to a style change,
// but that would cause a style reflow anyway, which means we're ok.
if (NS_AUTOHEIGHT == rs->ComputedHeight()) {
@ -415,7 +424,7 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext)
mStylePosition->mMinHeight.GetUnit() == eStyleUnit_Percent ||
mStylePosition->mMaxHeight.GetUnit() == eStyleUnit_Percent ||
mStylePosition->mOffset.GetTopUnit() == eStyleUnit_Percent ||
mStylePosition->mOffset.GetBottomUnit() != eStyleUnit_Auto ||
mStylePosition->mOffset.GetBottomUnit() == eStyleUnit_Percent ||
frame->IsBoxFrame() ||
frame->GetIntrinsicSize().height.GetUnit() == eStyleUnit_Percent;
@ -1408,6 +1417,14 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState* aCBReflowState)
if (nsGkAtoms::blockFrame == frameType ||
nsGkAtoms::areaFrame == frameType ||
nsGkAtoms::scrollFrame == frameType) {
if (nsGkAtoms::areaFrame == frameType) {
// Skip over scrolled-content area frames
if (rs->frame->GetStyleContext()->GetPseudoType() ==
nsCSSAnonBoxes::scrolledContent) {
continue;
}
}
secondAncestorRS = firstAncestorRS;
firstAncestorRS = (nsHTMLReflowState*)rs;
@ -1425,7 +1442,12 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState* aCBReflowState)
}
}
else if (nsGkAtoms::canvasFrame == frameType) {
// Always continue on to the height calculation
// Use scroll frames' computed height if we have one, this will
// allow us to get viewport height for native scrollbars.
nsHTMLReflowState* scrollState = (nsHTMLReflowState *)rs->parentReflowState;
if (nsGkAtoms::scrollFrame == scrollState->frame->GetType()) {
rs = scrollState;
}
}
else if (nsGkAtoms::pageContentFrame == frameType) {
nsIFrame* prevInFlow = rs->frame->GetPrevInFlow();
@ -1646,14 +1668,24 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
// content
nsIAtom* fType;
if (NS_AUTOHEIGHT == aContainingBlockHeight) {
// See if the containing block is a cell frame which needs
// See if the containing block is (1) a scrolled frame, i.e. its
// parent is a scroll frame. The presence of the intervening
// frame (that the scroll frame scrolls) needs to be hidden from
// the containingBlockHeight calcuation, or (2) a cell frame which needs
// to use the mComputedHeight of the cell instead of what the cell block passed in.
// XXX It seems like this could lead to bugs with min-height and friends
if (cbrs->parentReflowState) {
fType = cbrs->frame->GetType();
if (IS_TABLE_CELL(fType)) {
// use the cell's computed height
aContainingBlockHeight = cbrs->mComputedHeight;
nsIFrame* f = cbrs->parentReflowState->frame;
fType = f->GetType();
if (nsGkAtoms::scrollFrame == fType) {
// Use the scroll frame's computed height instead
aContainingBlockHeight = cbrs->parentReflowState->mComputedHeight;
}
else {
fType = cbrs->frame->GetType();
if (IS_TABLE_CELL(fType)) {
// use the cell's computed height
aContainingBlockHeight = cbrs->mComputedHeight;
}
}
}
}

View File

@ -80,7 +80,3 @@ include ib-split/reftest.list
# line-breaking
include line-breaking/reftest.list
# percent-overflow-sizing
include percent-overflow-sizing/reftest.list