Bug 492627 - Remove Placeholder Continuations [Part VII: More intelligent deletion of floats and overflow containers] r=roc
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -4902,27 +4902,27 @@ nsBlockFrame::RemoveFrame(nsIAtom* aLis
if (hasFloats) {
MarkSameFloatManagerLinesDirty(this);
}
}
else if (nsGkAtoms::absoluteList == aListName) {
return mAbsoluteContainer.RemoveFrame(this, aListName, aOldFrame);
}
else if (nsGkAtoms::floatList == aListName) {
- nsIFrame* curFrame = aOldFrame;
- // Make sure to delete all the continuations for the float frame
+ // Make sure to mark affected lines dirty for the float frame
// we are removing; this way is a bit messy, but so is the rest of the code.
// See bug 390762.
- do {
- nsIFrame* continuation = curFrame->GetNextContinuation();
- nsBlockFrame* curParent = static_cast<nsBlockFrame*>(curFrame->GetParent());
- curParent->RemoveFloat(curFrame);
- MarkSameFloatManagerLinesDirty(curParent);
- curFrame = continuation;
- } while (curFrame);
+ NS_ASSERTION(!aOldFrame->GetPrevContinuation(),
+ "RemoveFrame should not be called on float continuations.");
+ for (nsIFrame* f = aOldFrame;
+ f && !(f->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER);
+ f = f->GetNextContinuation()) {
+ MarkSameFloatManagerLinesDirty(static_cast<nsBlockFrame*>(f->GetParent()));
+ }
+ DoRemoveOutOfFlowFrame(aOldFrame);
}
#ifdef IBMBIDI
else if (nsGkAtoms::nextBidi == aListName) {
// Skip the call to |FrameNeedsReflow| below by returning now.
return DoRemoveFrame(aOldFrame, REMOVE_FIXED_CONTINUATIONS);
}
#endif // IBMBIDI
else {
@@ -5168,16 +5168,23 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aD
}
else {
nsContainerFrame::DeleteNextInFlowChild(presContext, aDeletedFrame,
(aFlags & FRAMES_ARE_EMPTY) != 0);
}
return NS_OK;
}
+ // If next-in-flow is an overflow container, must remove it first
+ nsIFrame* next = aDeletedFrame->GetNextInFlow();
+ if (next && next->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
+ static_cast<nsContainerFrame*>(next->GetParent())
+ ->DeleteNextInFlowChild(next->PresContext(), next, PR_FALSE);
+ }
+
nsIPresShell* presShell = presContext->PresShell();
// Find the line and the previous sibling that contains
// deletedFrame; we also find the pointer to the line.
nsLineList::iterator line_start = mLines.begin(),
line_end = mLines.end();
nsLineList::iterator line = line_start;
PRBool searchingOverflowList = PR_FALSE;
@@ -5469,18 +5476,18 @@ nsBlockFrame::StealFrame(nsPresContext*
void
nsBlockFrame::DeleteNextInFlowChild(nsPresContext* aPresContext,
nsIFrame* aNextInFlow,
PRBool aDeletingEmptyFrames)
{
NS_PRECONDITION(aNextInFlow->GetPrevInFlow(), "bad next-in-flow");
- if (aNextInFlow->GetPrevInFlow() && (aNextInFlow->GetStateBits() &
- (NS_FRAME_OUT_OF_FLOW | NS_FRAME_IS_OVERFLOW_CONTAINER))) {
+ if (aNextInFlow->GetStateBits() &
+ (NS_FRAME_OUT_OF_FLOW | NS_FRAME_IS_OVERFLOW_CONTAINER)) {
nsContainerFrame::DeleteNextInFlowChild(aPresContext,
aNextInFlow, aDeletingEmptyFrames);
}
else {
DoRemoveFrame(aNextInFlow,
aDeletingEmptyFrames ? FRAMES_ARE_EMPTY : 0);
}
}