fix incorrect loop test condition for skipping irrelevant frames; update code to deal properly with skipped frames;
b=404213 r+sr=roc
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -1304,17 +1304,18 @@ nsOverflowContinuationTracker::SetUpList
if (mOverflowContList) {
nsIFrame* cur = mOverflowContList->FirstChild();
if (mSkipOverflowContainerChildren) {
while (cur && (cur->GetPrevInFlow()->GetStateBits()
& NS_FRAME_IS_OVERFLOW_CONTAINER)) {
mPrevOverflowCont = cur;
cur = cur->GetNextSibling();
}
- while (cur && (mWalkOOFFrames == cur->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
+ while (cur && (!(cur->GetStateBits() & NS_FRAME_OUT_OF_FLOW)
+ == mWalkOOFFrames)) {
mPrevOverflowCont = cur;
cur = cur->GetNextSibling();
}
}
if (cur) {
mSentry = cur->GetPrevInFlow();
}
}
@@ -1337,33 +1338,37 @@ nsOverflowContinuationTracker::StepForwa
}
else {
mPrevOverflowCont = mOverflowContList->FirstChild();
}
// Skip over oof or non-oof frames as appropriate
if (mSkipOverflowContainerChildren) {
nsIFrame* cur = mPrevOverflowCont->GetNextSibling();
- while (cur && (mWalkOOFFrames == cur->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
+ while (cur && (!(cur->GetStateBits() & NS_FRAME_OUT_OF_FLOW)
+ == mWalkOOFFrames)) {
mPrevOverflowCont = cur;
cur = cur->GetNextSibling();
}
}
// Set up the sentry
mSentry = (mPrevOverflowCont->GetNextSibling())
? mPrevOverflowCont->GetNextSibling()->GetPrevInFlow()
: nsnull;
}
nsresult
nsOverflowContinuationTracker::Insert(nsIFrame* aOverflowCont,
nsReflowStatus& aReflowStatus)
{
NS_PRECONDITION(aOverflowCont, "null frame pointer");
+ NS_PRECONDITION(!mSkipOverflowContainerChildren || mWalkOOFFrames ==
+ !!(aOverflowCont->GetStateBits() & NS_FRAME_OUT_OF_FLOW),
+ "shouldn't insert frame that doesn't match walker type");
NS_PRECONDITION(aOverflowCont->GetPrevInFlow(),
"overflow containers must have a prev-in-flow");
nsresult rv = NS_OK;
if (!mSentry || aOverflowCont != mSentry->GetNextInFlow()) {
// Not in our list, so we need to add it
nsPresContext* presContext = aOverflowCont->PresContext();
if (aOverflowCont->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) {
// aOverflowCont is in some other overflow container list,
@@ -1395,18 +1400,21 @@ nsOverflowContinuationTracker::Insert(ns
}
// If we need to reflow it, mark it dirty
if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW)
aOverflowCont->AddStateBits(NS_FRAME_IS_DIRTY);
// It's in our list, just step forward
StepForward();
- NS_ASSERTION(mPrevOverflowCont == aOverflowCont,
- "OverflowContTracker logic error");
+ NS_ASSERTION(mPrevOverflowCont == aOverflowCont ||
+ (mSkipOverflowContainerChildren &&
+ (mPrevOverflowCont->GetStateBits() & NS_FRAME_OUT_OF_FLOW) !=
+ (aOverflowCont->GetStateBits() & NS_FRAME_OUT_OF_FLOW)),
+ "OverflowContTracker in unexpected state");
return rv;
}
void
nsOverflowContinuationTracker::Finish(nsIFrame* aChild)
{
NS_PRECONDITION(aChild, "null ptr");
NS_PRECONDITION(aChild->GetNextInFlow(),
@@ -1417,21 +1425,24 @@ nsOverflowContinuationTracker::Finish(ns
if (mOverflowContList->FirstChild() == aChild->GetNextInFlow()
&& !aChild->GetNextInFlow()->GetNextSibling()) {
mOverflowContList = nsnull;
mPrevOverflowCont = nsnull;
mSentry = nsnull;
mParent = static_cast<nsContainerFrame*>(aChild->GetParent());
}
else {
- // Don't move the mPrevOverflowCont, but shift the sentry
- // The intervening overflow continuation will be deleted by our caller
+ // Step past aChild
nsIFrame* prevOverflowCont = mPrevOverflowCont;
StepForward();
- mPrevOverflowCont = prevOverflowCont;
+ if (mPrevOverflowCont == aChild) {
+ // Pull mPrevOverflowChild back to aChild's prevSibling:
+ // aChild will be removed from our list by our caller
+ mPrevOverflowCont = prevOverflowCont;
+ }
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Debugging
#ifdef NS_DEBUG