From d71ccf1e465f39d9bde228cfa532206861b88fb7 Mon Sep 17 00:00:00 2001 From: "karnaze%netscape.com" Date: Tue, 24 Sep 2002 22:13:20 +0000 Subject: [PATCH] bug 157915 - Use the parent of the continued frame when calling DeleteChildsNextInFlow. sr=kin, r=alexsavulov --- layout/generic/nsBlockFrame.cpp | 16 ++++++++---- layout/generic/nsBlockFrame.h | 10 ++++---- layout/generic/nsInlineFrame.cpp | 27 ++++++++++++++------- layout/generic/nsLineLayout.h | 4 +++ layout/generic/nsPlaceholderFrame.cpp | 10 ++++++++ layout/generic/nsPlaceholderFrame.h | 2 ++ layout/html/base/src/nsBlockFrame.cpp | 16 ++++++++---- layout/html/base/src/nsBlockFrame.h | 10 ++++---- layout/html/base/src/nsInlineFrame.cpp | 27 ++++++++++++++------- layout/html/base/src/nsLineLayout.h | 4 +++ layout/html/base/src/nsPlaceholderFrame.cpp | 10 ++++++++ layout/html/base/src/nsPlaceholderFrame.h | 2 ++ 12 files changed, 100 insertions(+), 38 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index d2a129f153e5..624ef25ee480 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -975,7 +975,6 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, state.mOverflowFloaters.GetLength(), PR_FALSE); if (!newLine) return NS_ERROR_OUT_OF_MEMORY; - state.mOverflowFloaters.SetFrames(nsnull); mLines.push_back(newLine); nsLineList::iterator nextToLastLine = ----end_lines(); PushLines(state, nextToLastLine); @@ -5281,11 +5280,17 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext, nsIFrame* aChild) { #ifdef DEBUG + // out-of-flow and placeholders frames don't satisfy the IsChild condition because + // DeleteChildsNextInFlow needs to be called on the parent of the next-in-flow nsFrameState childState; aChild->GetFrameState(&childState); - NS_PRECONDITION((childState & NS_FRAME_OUT_OF_FLOW) || IsChild(aPresContext, aChild), - "bad geometric parent"); + nsCOMPtr frameType; + aChild->GetFrameType(getter_AddRefs(frameType)); + if ((nsLayoutAtoms::placeholderFrame != frameType) && !(childState & NS_FRAME_OUT_OF_FLOW)) { + NS_PRECONDITION(IsChild(aPresContext, aChild), "bad geometric parent"); + } #endif + nsIFrame* nextInFlow; aChild->GetNextInFlow(&nextInFlow); NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow"); @@ -5321,9 +5326,10 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsIFrame* nextInFlow; aPlaceholder->GetNextInFlow(&nextInFlow); if (nextInFlow) { + // Use nextInFlow's parent since it always will be able to find nextInFlow. + // If aPlaceholder's parent is an inline, nextInFlow's will be a block. nsHTMLContainerFrame* parent; - aPlaceholder->GetParent((nsIFrame**)&parent); - NS_ASSERTION(parent, "no parent"); + nextInFlow->GetParent((nsIFrame**)&parent); parent->DeleteChildsNextInFlow(aState.mPresContext, aPlaceholder); } // Reflow the floater. diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index dd1b272c9faf..0bac95e69630 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -199,6 +199,11 @@ public: inline nscoord GetAscent() { return mAscent; } + // Create a contination for aPlaceholder and its out of flow frame and + // add it to the list of overflow floaters + nsresult SplitPlaceholder(nsBlockReflowState& aState, + nsIFrame& aPlaceholder); + protected: nsBlockFrame(); virtual ~nsBlockFrame(); @@ -428,11 +433,6 @@ protected: nsIFrame* aLastPlaceholder, PRBool& aKeepReflowGoing); - // Create a contination for aPlaceholder and its out of flow frame and - // add it to the list of overflow floaters - nsresult SplitPlaceholder(nsBlockReflowState& aState, - nsIFrame& aPlaceholder); - nsresult SplitLine(nsBlockReflowState& aState, nsLineLayout& aLineLayout, line_iterator aLine, diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 6404150c2faa..b1c14a429d9f 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -36,6 +36,7 @@ * ***** END LICENSE BLOCK ***** */ #include "nsCOMPtr.h" #include "nsInlineFrame.h" +#include "nsBlockFrame.h" #include "nsHTMLAtoms.h" #include "nsHTMLParts.h" #include "nsIStyleContext.h" @@ -784,16 +785,24 @@ nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext, } } else if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { - nsIFrame* newFrame; - rv = CreateNextInFlow(aPresContext, this, aFrame, newFrame); - if (NS_FAILED(rv)) { - return rv; + nsCOMPtr frameType; + aFrame->GetFrameType(getter_AddRefs(frameType)); + if (nsLayoutAtoms::placeholderFrame == frameType) { + nsBlockReflowState* blockRS = lineLayout->mBlockRS; + blockRS->mBlock->SplitPlaceholder(*blockRS, *aFrame); } - if (!reflowingFirstLetter) { - nsIFrame* nextFrame; - aFrame->GetNextSibling(&nextFrame); - if (nsnull != nextFrame) { - PushFrames(aPresContext, nextFrame, aFrame); + else { + nsIFrame* newFrame; + rv = CreateNextInFlow(aPresContext, this, aFrame, newFrame); + if (NS_FAILED(rv)) { + return rv; + } + if (!reflowingFirstLetter) { + nsIFrame* nextFrame; + aFrame->GetNextSibling(&nextFrame); + if (nsnull != nextFrame) { + PushFrames(aPresContext, nextFrame, aFrame); + } } } } diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h index b071fa37ee1a..118244712ead 100644 --- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -272,6 +272,10 @@ protected: nsSpaceManager* mSpaceManager; const nsStyleText* mStyleText; // for the block const nsHTMLReflowState* mBlockReflowState; + + // XXX remove this when landing bug 154892 (splitting absolute positioned frames) + friend class nsInlineFrame; + nsBlockReflowState* mBlockRS;/* XXX hack! */ nsCompatibility mCompatMode; nscoord mMinLineHeight; diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp index 91c456dbe954..ceaf208e09cd 100644 --- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -57,6 +57,15 @@ NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } +// These are useful for debugging +nsPlaceholderFrame::nsPlaceholderFrame() +{ +} + +nsPlaceholderFrame::~nsPlaceholderFrame() +{ +} + NS_IMETHODIMP nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, @@ -160,4 +169,5 @@ nsPlaceholderFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const *aResult = sizeof(*this); return NS_OK; } + #endif diff --git a/layout/generic/nsPlaceholderFrame.h b/layout/generic/nsPlaceholderFrame.h index 86bbe8993142..78b53a51b9d1 100644 --- a/layout/generic/nsPlaceholderFrame.h +++ b/layout/generic/nsPlaceholderFrame.h @@ -51,6 +51,8 @@ public: * Create a new placeholder frame */ friend nsresult NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsIFrame** aInstancePtrResult); + nsPlaceholderFrame(); + virtual ~nsPlaceholderFrame(); // Get/Set the associated out of flow frame nsIFrame* GetOutOfFlowFrame() const {return mOutOfFlowFrame;} diff --git a/layout/html/base/src/nsBlockFrame.cpp b/layout/html/base/src/nsBlockFrame.cpp index d2a129f153e5..624ef25ee480 100644 --- a/layout/html/base/src/nsBlockFrame.cpp +++ b/layout/html/base/src/nsBlockFrame.cpp @@ -975,7 +975,6 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, state.mOverflowFloaters.GetLength(), PR_FALSE); if (!newLine) return NS_ERROR_OUT_OF_MEMORY; - state.mOverflowFloaters.SetFrames(nsnull); mLines.push_back(newLine); nsLineList::iterator nextToLastLine = ----end_lines(); PushLines(state, nextToLastLine); @@ -5281,11 +5280,17 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext, nsIFrame* aChild) { #ifdef DEBUG + // out-of-flow and placeholders frames don't satisfy the IsChild condition because + // DeleteChildsNextInFlow needs to be called on the parent of the next-in-flow nsFrameState childState; aChild->GetFrameState(&childState); - NS_PRECONDITION((childState & NS_FRAME_OUT_OF_FLOW) || IsChild(aPresContext, aChild), - "bad geometric parent"); + nsCOMPtr frameType; + aChild->GetFrameType(getter_AddRefs(frameType)); + if ((nsLayoutAtoms::placeholderFrame != frameType) && !(childState & NS_FRAME_OUT_OF_FLOW)) { + NS_PRECONDITION(IsChild(aPresContext, aChild), "bad geometric parent"); + } #endif + nsIFrame* nextInFlow; aChild->GetNextInFlow(&nextInFlow); NS_PRECONDITION(nsnull != nextInFlow, "null next-in-flow"); @@ -5321,9 +5326,10 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsIFrame* nextInFlow; aPlaceholder->GetNextInFlow(&nextInFlow); if (nextInFlow) { + // Use nextInFlow's parent since it always will be able to find nextInFlow. + // If aPlaceholder's parent is an inline, nextInFlow's will be a block. nsHTMLContainerFrame* parent; - aPlaceholder->GetParent((nsIFrame**)&parent); - NS_ASSERTION(parent, "no parent"); + nextInFlow->GetParent((nsIFrame**)&parent); parent->DeleteChildsNextInFlow(aState.mPresContext, aPlaceholder); } // Reflow the floater. diff --git a/layout/html/base/src/nsBlockFrame.h b/layout/html/base/src/nsBlockFrame.h index dd1b272c9faf..0bac95e69630 100644 --- a/layout/html/base/src/nsBlockFrame.h +++ b/layout/html/base/src/nsBlockFrame.h @@ -199,6 +199,11 @@ public: inline nscoord GetAscent() { return mAscent; } + // Create a contination for aPlaceholder and its out of flow frame and + // add it to the list of overflow floaters + nsresult SplitPlaceholder(nsBlockReflowState& aState, + nsIFrame& aPlaceholder); + protected: nsBlockFrame(); virtual ~nsBlockFrame(); @@ -428,11 +433,6 @@ protected: nsIFrame* aLastPlaceholder, PRBool& aKeepReflowGoing); - // Create a contination for aPlaceholder and its out of flow frame and - // add it to the list of overflow floaters - nsresult SplitPlaceholder(nsBlockReflowState& aState, - nsIFrame& aPlaceholder); - nsresult SplitLine(nsBlockReflowState& aState, nsLineLayout& aLineLayout, line_iterator aLine, diff --git a/layout/html/base/src/nsInlineFrame.cpp b/layout/html/base/src/nsInlineFrame.cpp index 6404150c2faa..b1c14a429d9f 100644 --- a/layout/html/base/src/nsInlineFrame.cpp +++ b/layout/html/base/src/nsInlineFrame.cpp @@ -36,6 +36,7 @@ * ***** END LICENSE BLOCK ***** */ #include "nsCOMPtr.h" #include "nsInlineFrame.h" +#include "nsBlockFrame.h" #include "nsHTMLAtoms.h" #include "nsHTMLParts.h" #include "nsIStyleContext.h" @@ -784,16 +785,24 @@ nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext, } } else if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { - nsIFrame* newFrame; - rv = CreateNextInFlow(aPresContext, this, aFrame, newFrame); - if (NS_FAILED(rv)) { - return rv; + nsCOMPtr frameType; + aFrame->GetFrameType(getter_AddRefs(frameType)); + if (nsLayoutAtoms::placeholderFrame == frameType) { + nsBlockReflowState* blockRS = lineLayout->mBlockRS; + blockRS->mBlock->SplitPlaceholder(*blockRS, *aFrame); } - if (!reflowingFirstLetter) { - nsIFrame* nextFrame; - aFrame->GetNextSibling(&nextFrame); - if (nsnull != nextFrame) { - PushFrames(aPresContext, nextFrame, aFrame); + else { + nsIFrame* newFrame; + rv = CreateNextInFlow(aPresContext, this, aFrame, newFrame); + if (NS_FAILED(rv)) { + return rv; + } + if (!reflowingFirstLetter) { + nsIFrame* nextFrame; + aFrame->GetNextSibling(&nextFrame); + if (nsnull != nextFrame) { + PushFrames(aPresContext, nextFrame, aFrame); + } } } } diff --git a/layout/html/base/src/nsLineLayout.h b/layout/html/base/src/nsLineLayout.h index b071fa37ee1a..118244712ead 100644 --- a/layout/html/base/src/nsLineLayout.h +++ b/layout/html/base/src/nsLineLayout.h @@ -272,6 +272,10 @@ protected: nsSpaceManager* mSpaceManager; const nsStyleText* mStyleText; // for the block const nsHTMLReflowState* mBlockReflowState; + + // XXX remove this when landing bug 154892 (splitting absolute positioned frames) + friend class nsInlineFrame; + nsBlockReflowState* mBlockRS;/* XXX hack! */ nsCompatibility mCompatMode; nscoord mMinLineHeight; diff --git a/layout/html/base/src/nsPlaceholderFrame.cpp b/layout/html/base/src/nsPlaceholderFrame.cpp index 91c456dbe954..ceaf208e09cd 100644 --- a/layout/html/base/src/nsPlaceholderFrame.cpp +++ b/layout/html/base/src/nsPlaceholderFrame.cpp @@ -57,6 +57,15 @@ NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } +// These are useful for debugging +nsPlaceholderFrame::nsPlaceholderFrame() +{ +} + +nsPlaceholderFrame::~nsPlaceholderFrame() +{ +} + NS_IMETHODIMP nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, @@ -160,4 +169,5 @@ nsPlaceholderFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const *aResult = sizeof(*this); return NS_OK; } + #endif diff --git a/layout/html/base/src/nsPlaceholderFrame.h b/layout/html/base/src/nsPlaceholderFrame.h index 86bbe8993142..78b53a51b9d1 100644 --- a/layout/html/base/src/nsPlaceholderFrame.h +++ b/layout/html/base/src/nsPlaceholderFrame.h @@ -51,6 +51,8 @@ public: * Create a new placeholder frame */ friend nsresult NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsIFrame** aInstancePtrResult); + nsPlaceholderFrame(); + virtual ~nsPlaceholderFrame(); // Get/Set the associated out of flow frame nsIFrame* GetOutOfFlowFrame() const {return mOutOfFlowFrame;}