229 lines
8.8 KiB
Diff
229 lines
8.8 KiB
Diff
From 4dcbca8b3c26b451e1376cd1b7c88ab984a45b39 Mon Sep 17 00:00:00 2001
|
|
From: Mats Palmgren <mats@mozilla.com>
|
|
Date: Tue, 14 Apr 2015 22:12:39 -0400
|
|
Subject: [PATCH] Bug 1143299 - Make frame insertion methods deal with
|
|
aPrevFrame being on an overflow list. r=roc, a=bkerensa
|
|
|
|
---
|
|
layout/generic/nsBlockFrame.cpp | 18 ++++++++++++---
|
|
layout/generic/nsBlockFrame.h | 14 ++++++++----
|
|
layout/generic/nsContainerFrame.cpp | 41 +++++++++++++++++++---------------
|
|
layout/tables/nsTableFrame.cpp | 2 ++
|
|
layout/tables/nsTableRowFrame.cpp | 2 ++
|
|
layout/tables/nsTableRowGroupFrame.cpp | 2 ++
|
|
6 files changed, 54 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
|
|
index a011bcf..70d5297 100644
|
|
--- a/layout/generic/nsBlockFrame.cpp
|
|
+++ b/layout/generic/nsBlockFrame.cpp
|
|
@@ -1049,7 +1049,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);
|
|
@@ -4438,9 +4438,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()
|
|
{
|
|
#ifdef DEBUG
|
|
// Between when we drain pushed floats and when we complete reflow,
|
|
@@ -4503,12 +4507,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);
|
|
}
|
|
@@ -4711,6 +4721,7 @@ nsBlockFrame::AppendFrames(ChildListID aListID,
|
|
return nsContainerFrame::AppendFrames(aListID, aFrameList);
|
|
}
|
|
else if (kFloatList == aListID) {
|
|
+ DrainSelfPushedFloats(); // ensure the last frame is in mFloats
|
|
mFloats.AppendFrames(nullptr, aFrameList);
|
|
return NS_OK;
|
|
}
|
|
@@ -4757,6 +4768,7 @@ nsBlockFrame::InsertFrames(ChildListID aListID,
|
|
return nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
|
|
}
|
|
else if (kFloatList == aListID) {
|
|
+ DrainSelfPushedFloats(); // ensure aPrevFrame is in mFloats
|
|
mFloats.InsertFrames(this, aPrevFrame, aFrameList);
|
|
return NS_OK;
|
|
}
|
|
diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h
|
|
index 1a6bb1e..07f7508 100644
|
|
--- a/layout/generic/nsBlockFrame.h
|
|
+++ b/layout/generic/nsBlockFrame.h
|
|
@@ -533,10 +533,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.
|
|
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
|
|
index 76f0748..3ffcba7 100644
|
|
--- a/layout/generic/nsContainerFrame.cpp
|
|
+++ b/layout/generic/nsContainerFrame.cpp
|
|
@@ -102,16 +102,18 @@ nsContainerFrame::AppendFrames(ChildListID aListID,
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
}
|
|
- 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 NS_OK;
|
|
+ }
|
|
+
|
|
+ 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);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
@@ -131,16 +133,19 @@ nsContainerFrame::InsertFrames(ChildListID aListID,
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
}
|
|
- if (aFrameList.NotEmpty()) {
|
|
- // Insert frames after aPrevFrame
|
|
- mFrames.InsertFrames(this, aPrevFrame, aFrameList);
|
|
|
|
- if (aListID == kPrincipalList)
|
|
- {
|
|
- PresContext()->PresShell()->
|
|
- FrameNeedsReflow(this, nsIPresShell::eTreeChange,
|
|
- NS_FRAME_HAS_DIRTY_CHILDREN);
|
|
- }
|
|
+ if (MOZ_UNLIKELY(aFrameList.IsEmpty())) {
|
|
+ return NS_OK;
|
|
+ }
|
|
+
|
|
+ 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);
|
|
+
|
|
}
|
|
return NS_OK;
|
|
}
|
|
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
|
|
index 60613ba..44088da 100644
|
|
--- a/layout/tables/nsTableFrame.cpp
|
|
+++ b/layout/tables/nsTableFrame.cpp
|
|
@@ -2232,6 +2232,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);
|
|
|
|
@@ -2404,6 +2405,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);
|
|
diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp
|
|
index d1c493b..2351de3 100644
|
|
--- a/layout/tables/nsTableRowFrame.cpp
|
|
+++ b/layout/tables/nsTableRowFrame.cpp
|
|
@@ -182,6 +182,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
|
|
@@ -208,6 +209,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);
|
|
|
|
diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp
|
|
index 34aaf02..40b349b 100644
|
|
--- a/layout/tables/nsTableRowGroupFrame.cpp
|
|
+++ b/layout/tables/nsTableRowGroupFrame.cpp
|
|
@@ -1389,6 +1389,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
|
|
@@ -1430,6 +1431,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
|
|
--
|
|
2.2.1
|
|
|