Bug 1143299 - Make frame insertion methods deal with aPrevFrame being on an overflow list. r=roc a=abillings

This commit is contained in:
Mats Palmgren 2015-04-11 00:21:06 +00:00
parent a39f108967
commit c9abe27bec
6 changed files with 52 additions and 25 deletions

View File

@ -1130,7 +1130,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
state.mOverflowTracker = &tracker;
// Drain & handle pushed floats
DrainPushedFloats(state);
DrainPushedFloats();
nsOverflowAreas fcBounds;
nsReflowStatus fcStatus = NS_FRAME_COMPLETE;
ReflowPushedFloats(state, fcBounds, fcStatus);
@ -4664,9 +4664,13 @@ nsBlockFrame::DrainSelfOverflowList()
* might push some of them on). Floats with placeholders in this block
* are reflowed by (nsBlockReflowState/nsLineLayout)::AddFloat, which
* also maintains these invariants.
*
* DrainSelfPushedFloats moves any pushed floats from this block's own
* PushedFloats list back into mFloats. DrainPushedFloats additionally
* moves frames from its prev-in-flow's PushedFloats list into mFloats.
*/
void
nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState)
nsBlockFrame::DrainSelfPushedFloats()
{
// If we're getting reflowed multiple times without our
// next-continuation being reflowed, we might need to pull back floats
@ -4720,12 +4724,18 @@ nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState)
RemovePushedFloats()->Delete(presContext->PresShell());
}
}
}
void
nsBlockFrame::DrainPushedFloats()
{
DrainSelfPushedFloats();
// After our prev-in-flow has completed reflow, it may have a pushed
// floats list, containing floats that we need to own. Take these.
nsBlockFrame* prevBlock = static_cast<nsBlockFrame*>(GetPrevInFlow());
if (prevBlock) {
AutoFrameListPtr list(presContext, prevBlock->RemovePushedFloats());
AutoFrameListPtr list(PresContext(), prevBlock->RemovePushedFloats());
if (list && list->NotEmpty()) {
mFloats.InsertFrames(this, nullptr, *list);
}
@ -4925,6 +4935,7 @@ nsBlockFrame::AppendFrames(ChildListID aListID,
}
if (aListID != kPrincipalList) {
if (kFloatList == aListID) {
DrainSelfPushedFloats(); // ensure the last frame is in mFloats
mFloats.AppendFrames(nullptr, aFrameList);
return;
}
@ -4965,6 +4976,7 @@ nsBlockFrame::InsertFrames(ChildListID aListID,
if (aListID != kPrincipalList) {
if (kFloatList == aListID) {
DrainSelfPushedFloats(); // ensure aPrevFrame is in mFloats
mFloats.InsertFrames(this, aPrevFrame, aFrameList);
return;
}

View File

@ -541,10 +541,16 @@ protected:
return GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS;
}
/** grab pushed floats from this block's prevInFlow, and splice
* them into this block's mFloats list.
*/
void DrainPushedFloats(nsBlockReflowState& aState);
/**
* Moves frames from our PushedFloats list back into our mFloats list.
*/
void DrainSelfPushedFloats();
/**
* First calls DrainSelfPushedFloats() then grabs pushed floats from this
* block's prev-in-flow, and splice them into this block's mFloats list too.
*/
void DrainPushedFloats();
/** Load all our floats into the float manager (without reflowing them).
* Assumes float manager is in our own coordinate system.

View File

@ -86,16 +86,18 @@ nsContainerFrame::AppendFrames(ChildListID aListID,
{
MOZ_ASSERT(aListID == kPrincipalList || aListID == kNoReflowPrincipalList,
"unexpected child list");
if (aFrameList.NotEmpty()) {
mFrames.AppendFrames(this, aFrameList);
// Ask the parent frame to reflow me.
if (aListID == kPrincipalList)
{
PresContext()->PresShell()->
FrameNeedsReflow(this, nsIPresShell::eTreeChange,
NS_FRAME_HAS_DIRTY_CHILDREN);
}
if (MOZ_UNLIKELY(aFrameList.IsEmpty())) {
return;
}
DrainSelfOverflowList(); // ensure the last frame is in mFrames
mFrames.AppendFrames(this, aFrameList);
if (aListID != kNoReflowPrincipalList) {
PresContext()->PresShell()->
FrameNeedsReflow(this, nsIPresShell::eTreeChange,
NS_FRAME_HAS_DIRTY_CHILDREN);
}
}
@ -109,16 +111,17 @@ nsContainerFrame::InsertFrames(ChildListID aListID,
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
if (aFrameList.NotEmpty()) {
// Insert frames after aPrevFrame
mFrames.InsertFrames(this, aPrevFrame, aFrameList);
if (MOZ_UNLIKELY(aFrameList.IsEmpty())) {
return;
}
if (aListID == kPrincipalList)
{
PresContext()->PresShell()->
FrameNeedsReflow(this, nsIPresShell::eTreeChange,
NS_FRAME_HAS_DIRTY_CHILDREN);
}
DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
mFrames.InsertFrames(this, aPrevFrame, aFrameList);
if (aListID != kNoReflowPrincipalList) {
PresContext()->PresShell()->
FrameNeedsReflow(this, nsIPresShell::eTreeChange,
NS_FRAME_HAS_DIRTY_CHILDREN);
}
}

View File

@ -2256,6 +2256,7 @@ nsTableFrame::AppendFrames(ChildListID aListID,
InsertColGroups(startColIndex,
nsFrameList::Slice(mColGroups, f, f->GetNextSibling()));
} else if (IsRowGroup(display->mDisplay)) {
DrainSelfOverflowList(); // ensure the last frame is in mFrames
// Append the new row group frame to the sibling chain
mFrames.AppendFrame(nullptr, f);
@ -2426,6 +2427,7 @@ nsTableFrame::HomogenousInsertFrames(ChildListID aListID,
InsertColGroups(startColIndex, newColgroups);
} else if (IsRowGroup(display->mDisplay)) {
NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
// Insert the frames in the sibling chain
const nsFrameList::Slice& newRowGroups =
mFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);

View File

@ -185,6 +185,7 @@ nsTableRowFrame::AppendFrames(ChildListID aListID,
{
NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
DrainSelfOverflowList(); // ensure the last frame is in mFrames
const nsFrameList::Slice& newCells = mFrames.AppendFrames(nullptr, aFrameList);
// Add the new cell frames to the table
@ -209,6 +210,7 @@ nsTableRowFrame::InsertFrames(ChildListID aListID,
NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
//Insert Frames in the frame list
const nsFrameList::Slice& newCells = mFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);

View File

@ -1390,6 +1390,7 @@ nsTableRowGroupFrame::AppendFrames(ChildListID aListID,
{
NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
DrainSelfOverflowList(); // ensure the last frame is in mFrames
ClearRowCursor();
// collect the new row frames in an array
@ -1429,6 +1430,7 @@ nsTableRowGroupFrame::InsertFrames(ChildListID aListID,
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
ClearRowCursor();
// collect the new row frames in an array