Bug 505482. Make sure to not leave frames on overflow lists when we interrupt reflow. Also fixes bug 478527 and bug 496742. r=roc

This commit is contained in:
Boris Zbarsky 2009-07-24 09:32:32 -04:00
parent 8b46045669
commit fa8b53c57c
5 changed files with 56 additions and 0 deletions

View File

@ -1857,6 +1857,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
aState.ReconstructMarginAbove(line);
}
PRBool reflowedPrevLine = !needToRecoverState;
if (needToRecoverState) {
needToRecoverState = PR_FALSE;
@ -2001,6 +2002,15 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
}
needToRecoverState = PR_TRUE;
if (reflowedPrevLine && !line->IsBlock() &&
aState.mPresContext->HasPendingInterrupt()) {
// Need to make sure to pull overflows from any prev-in-flows
for (nsIFrame* inlineKid = line->mFirstChild; inlineKid;
inlineKid = inlineKid->GetFirstChild(nsnull)) {
inlineKid->PullOverflowsFromPrevInFlow();
}
}
}
// Record if we need to clear floats before reflowing the next

View File

@ -901,6 +901,9 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
// Don't support interruption in columns
nsPresContext::InterruptPreventer noInterrupts(aPresContext);
DO_GLOBAL_REFLOW_COUNT("nsColumnSetFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);

View File

@ -2315,6 +2315,12 @@ NS_PTR_TO_INT32(frame->GetProperty(nsGkAtoms::embeddingLevel))
*/
virtual nsILineIterator* GetLineIterator() = 0;
/**
* If this frame is a next-in-flow, and its prev-in-flow has something on its
* overflow list, pull those frames into the child list of this one.
*/
virtual void PullOverflowsFromPrevInFlow() {}
protected:
// Members
nsRect mRect;

View File

@ -398,6 +398,21 @@ nsInlineFrame::CanContinueTextRun() const
return PR_TRUE;
}
/* virtual */ void
nsInlineFrame::PullOverflowsFromPrevInFlow()
{
nsInlineFrame* prevInFlow = static_cast<nsInlineFrame*>(GetPrevInFlow());
if (prevInFlow) {
nsPresContext* presContext = PresContext();
nsIFrame* prevOverflowFrames =
prevInFlow->GetOverflowFrames(presContext, PR_TRUE);
if (prevOverflowFrames) {
// Assume that our prev-in-flow has the same line container that we do.
mFrames.InsertFrames(this, nsnull, prevOverflowFrames);
}
}
}
nsresult
nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
@ -1036,6 +1051,24 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext,
return rv;
}
/* virtual */ void
nsFirstLineFrame::PullOverflowsFromPrevInFlow()
{
nsFirstLineFrame* prevInFlow = static_cast<nsFirstLineFrame*>(GetPrevInFlow());
if (prevInFlow) {
nsPresContext* presContext = PresContext();
nsIFrame* prevOverflowFrames =
prevInFlow->GetOverflowFrames(presContext, PR_TRUE);
if (prevOverflowFrames) {
nsFrameList frames(prevOverflowFrames);
// Assume that our prev-in-flow has the same line container that we do.
mFrames.InsertFrames(this, nsnull, prevOverflowFrames);
ReParentChildListStyle(presContext, frames, this);
}
}
}
//////////////////////////////////////////////////////////////////////
nsIFrame*

View File

@ -123,6 +123,8 @@ public:
virtual PRBool CanContinueTextRun() const;
virtual void PullOverflowsFromPrevInFlow();
// Take all of the frames away from this frame. The caller is
// presumed to keep them alive.
void StealAllFrames() {
@ -222,6 +224,8 @@ public:
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual void PullOverflowsFromPrevInFlow();
// Take frames starting at aFrame until the end of the frame-list
// away from this frame. The caller is presumed to keep them alive.
void StealFramesFrom(nsIFrame* aFrame);