Skip to content

Commit

Permalink
Bug 442542. Make sure to reflow our possibly-size-dependent abs pos k…
Browse files Browse the repository at this point in the history
…ids on the followup reflow that happens if clearance is discovered. r+sr=roc
  • Loading branch information
bzbarsky committed Oct 15, 2008
1 parent 7faa6c0 commit a315484
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 34 deletions.
13 changes: 13 additions & 0 deletions layout/generic/nsAbsoluteContainingBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,19 @@ nsAbsoluteContainingBlock::DestroyFrames(nsIFrame* aDelegatingFrame)
mAbsoluteFrames.DestroyFrames();
}

void
nsAbsoluteContainingBlock::MarkSizeDependentFramesDirty()
{
for (nsIFrame* kidFrame = mAbsoluteFrames.FirstChild();
kidFrame;
kidFrame = kidFrame->GetNextSibling()) {
if (FrameDependsOnContainer(kidFrame, PR_TRUE, PR_TRUE)) {
// Add the weakest flags that will make sure we reflow this frame later
kidFrame->AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
}
}
}

// XXX Optimize the case where it's a resize reflow and the absolutely
// positioned child has the exact same size and position and skip the
// reflow...
Expand Down
2 changes: 2 additions & 0 deletions layout/generic/nsAbsoluteContainingBlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ class nsAbsoluteContainingBlock

PRBool HasAbsoluteFrames() {return mAbsoluteFrames.NotEmpty();}

void MarkSizeDependentFramesDirty();

protected:
// Returns PR_TRUE if the position of f depends on the position of
// its placeholder or if the position or size of f depends on a
Expand Down
76 changes: 42 additions & 34 deletions layout/generic/nsBlockFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1153,40 +1153,48 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// 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,
nsSize(aMetrics.width, aMetrics.height));

// Mark frames that depend on changes we just made to this frame as dirty:
// Now we can assume that the padding edge hasn't moved.
// We need to reflow the absolutes if one of them depends on
// its placeholder position, or the containing block size in a
// direction in which the containing block size might have
// changed.
PRBool cbWidthChanged = aMetrics.width != oldSize.width;
PRBool isRoot = !GetContent()->GetParent();
// If isRoot and we have auto height, then we are the initial
// containing block and the containing block height is the
// viewport height, which can't change during incremental
// reflow.
PRBool cbHeightChanged =
!(isRoot && NS_UNCONSTRAINEDSIZE == aReflowState.ComputedHeight()) &&
aMetrics.height != oldSize.height;

rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState,
state.mReflowStatus,
containingBlockSize.width,
containingBlockSize.height, PR_TRUE,
cbWidthChanged, cbHeightChanged,
&childBounds);

//XXXfr Why isn't this rv (and others in this file) checked/returned?

// Factor the absolutely positioned child bounds into the overflow area
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
if (mAbsoluteContainer.HasAbsoluteFrames()) {
if (aReflowState.WillReflowAgainForClearance()) {
// Make sure that when we reflow again we'll actually reflow all the abs
// pos frames that might conceivably depend on our size. Sadly, we can't
// do much better than that, because we don't really know what our size
// will be, and it might in fact not change on the followup reflow!
mAbsoluteContainer.MarkSizeDependentFramesDirty();
} else {
nsRect childBounds;
nsSize containingBlockSize =
CalculateContainingBlockSizeForAbsolutes(aReflowState,
nsSize(aMetrics.width,
aMetrics.height));

// Mark frames that depend on changes we just made to this frame as dirty:
// Now we can assume that the padding edge hasn't moved.
// We need to reflow the absolutes if one of them depends on
// its placeholder position, or the containing block size in a
// direction in which the containing block size might have
// changed.
PRBool cbWidthChanged = aMetrics.width != oldSize.width;
PRBool isRoot = !GetContent()->GetParent();
// If isRoot and we have auto height, then we are the initial
// containing block and the containing block height is the
// viewport height, which can't change during incremental
// reflow.
PRBool cbHeightChanged =
!(isRoot && NS_UNCONSTRAINEDSIZE == aReflowState.ComputedHeight()) &&
aMetrics.height != oldSize.height;

rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState,
state.mReflowStatus,
containingBlockSize.width,
containingBlockSize.height, PR_TRUE,
cbWidthChanged, cbHeightChanged,
&childBounds);

//XXXfr Why isn't this rv (and others in this file) checked/returned?

// Factor the absolutely positioned child bounds into the overflow area
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
}
}

// Determine if we need to repaint our border, background or outline
Expand Down
4 changes: 4 additions & 0 deletions layout/reftests/bugs/442542-1-ref.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!DOCTYPE html>
<body>
<iframe src="subframe.html" width="200" height="200"></iframe>
</body>
4 changes: 4 additions & 0 deletions layout/reftests/bugs/442542-1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!DOCTYPE html>
<body onload="document.getElementsByTagName('iframe')[0].width = 200">
<iframe src="subframe.html" width="300" height="200"></iframe>
</body>
8 changes: 8 additions & 0 deletions layout/reftests/bugs/442542-subframe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<body>
<div style="position:relative">
<div style="float:right; height: 10px"></div>
<div style="clear:right"></div>
<div style="position:absolute; top:4em; right:0; background:green; width: 100px; height: 100px"></div>
</div>
</body>
1 change: 1 addition & 0 deletions layout/reftests/bugs/reftest.list
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,7 @@ random == 429849-1.html 429849-1-ref.html # bug 432288
== 439910.html 439910-ref.html
== 441259-1.html 441259-1-ref.html
fails == 441259-2.html 441259-2-ref.html # bug 441400
== 442542-1.html 442542-1-ref.html
== 444015-1.html 444015-1-ref.html
== 444928-1.html 444928-1-ref.html
== 444928-2.html 444928-2-ref.html
Expand Down

0 comments on commit a315484

Please sign in to comment.