Bug 406568. Don't reflow abs-pos kids of a block if we're going to reflow it again because of a clearance change. r=sr=dbaron

git-svn-id: svn://10.0.0.236/trunk@240489 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
roc+%cs.cmu.edu 2007-12-05 02:57:53 +00:00
parent 0dd03f61dd
commit 90eb0469a3
5 changed files with 45 additions and 3 deletions

View File

@ -877,6 +877,8 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
}
#endif
// See comment below about oldSize. Use *only* for the
// abs-pos-containing-block-size-change optimization!
nsSize oldSize = GetSize();
// Should we create a space manager?
@ -1131,7 +1133,15 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// can use our rect (the border edge) since if the border style
// changed, the reflow would have been targeted at us so we'd satisfy
// condition 1.
if (mAbsoluteContainer.HasAbsoluteFrames()) {
// XXX checking oldSize is bogus, there are various reasons we might have
// reflowed but our size might not have been changed to what we
// asked for (e.g., we ended up being pushed to a new page)
// When WillReflowAgainForClearance is true, we will reflow again without
// resetting the size. Because of this, we must not reflow our abs-pos children
// in that situation --- what we think is our "new size"
// will not be our real new size. This also happens to be more efficient.
if (mAbsoluteContainer.HasAbsoluteFrames() &&
!aReflowState.WillReflowAgainForClearance()) {
nsRect childBounds;
nsSize containingBlockSize
= CalculateContainingBlockSizeForAbsolutes(aReflowState,
@ -1866,13 +1876,15 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
nscoord oldY = line->mBounds.y;
nscoord oldYMost = line->mBounds.YMost();
NS_ASSERTION(!willReflowAgain || !line->IsBlock(),
"Don't reflow blocks while willReflowAgain is true, reflow of block abs-pos children depends on this");
// Reflow the dirty line. If it's an incremental reflow, then force
// it to invalidate the dirty area if necessary
rv = ReflowLine(aState, line, &keepGoing);
NS_ENSURE_SUCCESS(rv, rv);
if (aState.mReflowState.mDiscoveredClearance &&
*aState.mReflowState.mDiscoveredClearance) {
if (aState.mReflowState.WillReflowAgainForClearance()) {
line->MarkDirty();
willReflowAgain = PR_TRUE;
// Note that once we've entered this state, every line that gets here

View File

@ -466,6 +466,10 @@ public:
void SetTruncated(const nsHTMLReflowMetrics& aMetrics, nsReflowStatus* aStatus) const;
PRBool WillReflowAgainForClearance() const {
return mDiscoveredClearance && *mDiscoveredClearance;
}
protected:
void InitFrameType();
void InitCBReflowState();

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<body>
&nbsp;
<div style="position:relative; width:300px; background:grey;">
<div style="position:absolute; left:0; bottom:0px; width:250px; background:lime;">abs.pos.</div>
<div style="float:left; width:200px; height:200px; background:cyan;"></div>
<div style="clear:both;"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<body>
&nbsp;
<div style="position:relative; width:300px; background:grey;">
<div style="position:absolute; left:0; bottom:0px; width:250px; background:lime;">abs.pos.</div>
<div style="float:left; width:200px; height:200px; background:cyan;"></div>
<script>document.body.offsetTop;</script>
<div style="clear:both;"></div>
</div>
<script>document.body.offsetTop;</script>
</body>
</html>

View File

@ -506,3 +506,5 @@ random == 403134-1.html 403134-1-ref.html # bug 405377
== 405305-1.html 405305-1-ref.html
== 405584-1.html 405584-1-ref.html
== 406484-1.html 406484-1-ref.html
== 406568-1.html 406568-1-ref.html