diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index 0ac0b9f71cc5..f3e3c9453a48 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -783,6 +783,8 @@ FrameManager::RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame) PL_DHASH_ADD)); if (!entry) return NS_ERROR_OUT_OF_MEMORY; + + NS_ASSERTION(!entry->placeholderFrame, "Registering a placeholder for a frame that already has a placeholder!"); entry->placeholderFrame = aPlaceholderFrame; return NS_OK; } diff --git a/layout/base/public/nsFrameList.h b/layout/base/public/nsFrameList.h index 4ebba61df817..043d156186a1 100644 --- a/layout/base/public/nsFrameList.h +++ b/layout/base/public/nsFrameList.h @@ -100,14 +100,11 @@ public: aFrameList.mFirstChild = nsnull; } - PRBool ReplaceFrame(nsIFrame* aParent, + PRBool ReplaceFrame(nsIPresContext* aPresContext, + nsIFrame* aParent, nsIFrame* aOldFrame, - nsIFrame* aNewFrame); - - PRBool ReplaceAndDestroyFrame(nsIPresContext* aPresContext, - nsIFrame* aParent, - nsIFrame* aOldFrame, - nsIFrame* aNewFrame); + nsIFrame* aNewFrame, + PRBool aDestroy); PRBool Split(nsIFrame* aAfterFrame, nsIFrame** aNextFrameResult); @@ -155,6 +152,11 @@ public: void List(nsIPresContext* aPresContext, FILE* out) const; #endif +private: + PRBool DoReplaceFrame(nsIFrame* aParent, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame); + protected: nsIFrame* mFirstChild; }; diff --git a/layout/base/src/nsFrameList.cpp b/layout/base/src/nsFrameList.cpp index 97477ccccd0e..75bb461d1041 100644 --- a/layout/base/src/nsFrameList.cpp +++ b/layout/base/src/nsFrameList.cpp @@ -281,44 +281,51 @@ nsFrameList::InsertFrames(nsIFrame* aParent, } PRBool -nsFrameList::ReplaceFrame(nsIFrame* aParent, - nsIFrame* aOldFrame, - nsIFrame* aNewFrame) +nsFrameList::DoReplaceFrame(nsIFrame* aParent, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame) { - NS_PRECONDITION(nsnull != aOldFrame, "null ptr"); - NS_PRECONDITION(nsnull != aNewFrame, "null ptr"); - if ((nsnull != aOldFrame) && (nsnull != aNewFrame)) { - nsIFrame* nextFrame; - aOldFrame->GetNextSibling(&nextFrame); - if (aOldFrame == mFirstChild) { - mFirstChild = aNewFrame; - aNewFrame->SetNextSibling(nextFrame); - } - else { - nsIFrame* prevSibling = GetPrevSiblingFor(aOldFrame); - if (nsnull != prevSibling) { - prevSibling->SetNextSibling(aNewFrame); - aNewFrame->SetNextSibling(nextFrame); - } - } - if (nsnull != aParent) { - aNewFrame->SetParent(aParent); - } - return PR_TRUE; + NS_PRECONDITION(aOldFrame, "null ptr"); + NS_PRECONDITION(aNewFrame, "null ptr"); + if (!aOldFrame || !aNewFrame) { + return PR_FALSE; } - return PR_FALSE; + + nsIFrame* nextFrame; + aOldFrame->GetNextSibling(&nextFrame); + if (aOldFrame == mFirstChild) { + mFirstChild = aNewFrame; + } + else { + nsIFrame* prevSibling = GetPrevSiblingFor(aOldFrame); + if (!prevSibling) { + NS_WARNING("nsFrameList::ReplaceFrame: aOldFrame not found in list"); + return PR_FALSE; + } + prevSibling->SetNextSibling(aNewFrame); + } + + aNewFrame->SetNextSibling(nextFrame); + + if (aParent) { + aNewFrame->SetParent(aParent); + } + return PR_TRUE; } PRBool -nsFrameList::ReplaceAndDestroyFrame(nsIPresContext* aPresContext, - nsIFrame* aParent, - nsIFrame* aOldFrame, - nsIFrame* aNewFrame) +nsFrameList::ReplaceFrame(nsIPresContext* aPresContext, + nsIFrame* aParent, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame, + PRBool aDestroy) { - NS_PRECONDITION(nsnull != aOldFrame, "null ptr"); - NS_PRECONDITION(nsnull != aNewFrame, "null ptr"); - if (ReplaceFrame(aParent, aOldFrame, aNewFrame)) { - aNewFrame->Destroy(aPresContext); + NS_PRECONDITION(aOldFrame, "null ptr"); + NS_PRECONDITION(aNewFrame, "null ptr"); + if (DoReplaceFrame(aParent, aOldFrame, aNewFrame)) { + if (aDestroy) { + aOldFrame->Destroy(aPresContext); + } return PR_TRUE; } return PR_FALSE; diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp index a6f06c35a0e6..7c3e6e063d6a 100644 --- a/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/layout/generic/nsAbsoluteContainingBlock.cpp @@ -138,6 +138,21 @@ nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame, return result ? NS_OK : NS_ERROR_FAILURE; } +nsresult +nsAbsoluteContainingBlock::ReplaceFrame(nsIFrame* aDelegatingFrame, + nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame) +{ + PRBool result = mAbsoluteFrames.ReplaceFrame(aPresContext, aDelegatingFrame, + aOldFrame, aNewFrame, PR_TRUE); + NS_ASSERTION(result, "Problems replacing a frame"); + return result ? NS_OK : NS_ERROR_FAILURE; +} + + // Destructor function for the collapse offset frame property static void DestroyRectFunc(nsIPresContext* aPresContext, diff --git a/layout/generic/nsAbsoluteContainingBlock.h b/layout/generic/nsAbsoluteContainingBlock.h index 911cf4202101..7ccd50040713 100644 --- a/layout/generic/nsAbsoluteContainingBlock.h +++ b/layout/generic/nsAbsoluteContainingBlock.h @@ -82,7 +82,13 @@ public: nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aOldFrame); - + nsresult ReplaceFrame(nsIFrame* aDelegatingFrame, + nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame); + // Called by the delegating frame after it has done its reflow first. This // function will reflow any absolutely positioned child frames that need to // be reflowed, e.g., because the absolutely positioned child frame has diff --git a/layout/generic/nsFrameList.cpp b/layout/generic/nsFrameList.cpp index 97477ccccd0e..75bb461d1041 100644 --- a/layout/generic/nsFrameList.cpp +++ b/layout/generic/nsFrameList.cpp @@ -281,44 +281,51 @@ nsFrameList::InsertFrames(nsIFrame* aParent, } PRBool -nsFrameList::ReplaceFrame(nsIFrame* aParent, - nsIFrame* aOldFrame, - nsIFrame* aNewFrame) +nsFrameList::DoReplaceFrame(nsIFrame* aParent, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame) { - NS_PRECONDITION(nsnull != aOldFrame, "null ptr"); - NS_PRECONDITION(nsnull != aNewFrame, "null ptr"); - if ((nsnull != aOldFrame) && (nsnull != aNewFrame)) { - nsIFrame* nextFrame; - aOldFrame->GetNextSibling(&nextFrame); - if (aOldFrame == mFirstChild) { - mFirstChild = aNewFrame; - aNewFrame->SetNextSibling(nextFrame); - } - else { - nsIFrame* prevSibling = GetPrevSiblingFor(aOldFrame); - if (nsnull != prevSibling) { - prevSibling->SetNextSibling(aNewFrame); - aNewFrame->SetNextSibling(nextFrame); - } - } - if (nsnull != aParent) { - aNewFrame->SetParent(aParent); - } - return PR_TRUE; + NS_PRECONDITION(aOldFrame, "null ptr"); + NS_PRECONDITION(aNewFrame, "null ptr"); + if (!aOldFrame || !aNewFrame) { + return PR_FALSE; } - return PR_FALSE; + + nsIFrame* nextFrame; + aOldFrame->GetNextSibling(&nextFrame); + if (aOldFrame == mFirstChild) { + mFirstChild = aNewFrame; + } + else { + nsIFrame* prevSibling = GetPrevSiblingFor(aOldFrame); + if (!prevSibling) { + NS_WARNING("nsFrameList::ReplaceFrame: aOldFrame not found in list"); + return PR_FALSE; + } + prevSibling->SetNextSibling(aNewFrame); + } + + aNewFrame->SetNextSibling(nextFrame); + + if (aParent) { + aNewFrame->SetParent(aParent); + } + return PR_TRUE; } PRBool -nsFrameList::ReplaceAndDestroyFrame(nsIPresContext* aPresContext, - nsIFrame* aParent, - nsIFrame* aOldFrame, - nsIFrame* aNewFrame) +nsFrameList::ReplaceFrame(nsIPresContext* aPresContext, + nsIFrame* aParent, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame, + PRBool aDestroy) { - NS_PRECONDITION(nsnull != aOldFrame, "null ptr"); - NS_PRECONDITION(nsnull != aNewFrame, "null ptr"); - if (ReplaceFrame(aParent, aOldFrame, aNewFrame)) { - aNewFrame->Destroy(aPresContext); + NS_PRECONDITION(aOldFrame, "null ptr"); + NS_PRECONDITION(aNewFrame, "null ptr"); + if (DoReplaceFrame(aParent, aOldFrame, aNewFrame)) { + if (aDestroy) { + aOldFrame->Destroy(aPresContext); + } return PR_TRUE; } return PR_FALSE; diff --git a/layout/generic/nsFrameList.h b/layout/generic/nsFrameList.h index 4ebba61df817..043d156186a1 100644 --- a/layout/generic/nsFrameList.h +++ b/layout/generic/nsFrameList.h @@ -100,14 +100,11 @@ public: aFrameList.mFirstChild = nsnull; } - PRBool ReplaceFrame(nsIFrame* aParent, + PRBool ReplaceFrame(nsIPresContext* aPresContext, + nsIFrame* aParent, nsIFrame* aOldFrame, - nsIFrame* aNewFrame); - - PRBool ReplaceAndDestroyFrame(nsIPresContext* aPresContext, - nsIFrame* aParent, - nsIFrame* aOldFrame, - nsIFrame* aNewFrame); + nsIFrame* aNewFrame, + PRBool aDestroy); PRBool Split(nsIFrame* aAfterFrame, nsIFrame** aNextFrameResult); @@ -155,6 +152,11 @@ public: void List(nsIPresContext* aPresContext, FILE* out) const; #endif +private: + PRBool DoReplaceFrame(nsIFrame* aParent, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame); + protected: nsIFrame* mFirstChild; }; diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 1b7e8d3a3b80..ec3e2295b544 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -311,21 +311,22 @@ nsInlineFrame::ReplaceFrame(nsIPresContext* aPresContext, nsIFrame* aOldFrame, nsIFrame* aNewFrame) { - if (nsnull != aListName) { + if (aListName) { + NS_ERROR("Don't have any special lists on inline frames!"); return NS_ERROR_INVALID_ARG; } if (!aOldFrame || !aNewFrame) { + NS_ERROR("Missing aOldFrame or aNewFrame"); return NS_ERROR_INVALID_ARG; } - // Replace the old frame with the new frame in the list, then remove the old frame - mFrames.ReplaceFrame(this, aOldFrame, aNewFrame); - aOldFrame->Destroy(aPresContext); - + PRBool retval = + mFrames.ReplaceFrame(aPresContext, this, aOldFrame, aNewFrame, PR_TRUE); + // Ask the parent frame to reflow me. ReflowDirtyChild(&aPresShell, nsnull); - return NS_OK; + return retval ? NS_OK : NS_ERROR_FAILURE; } @@ -1195,6 +1196,22 @@ nsPositionedInlineFrame::RemoveFrame(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +nsPositionedInlineFrame::ReplaceFrame(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame) +{ + if (nsLayoutAtoms::absoluteList == aListName) { + return mAbsoluteContainer.ReplaceFrame(this, aPresContext, aPresShell, + aListName, aOldFrame, aNewFrame); + } else { + return nsInlineFrame::ReplaceFrame(aPresContext, aPresShell, aListName, + aOldFrame, aNewFrame); + } +} + NS_IMETHODIMP nsPositionedInlineFrame::GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const diff --git a/layout/generic/nsInlineFrame.h b/layout/generic/nsInlineFrame.h index fdc1f52d6ce0..6843586d2706 100644 --- a/layout/generic/nsInlineFrame.h +++ b/layout/generic/nsInlineFrame.h @@ -224,6 +224,11 @@ public: nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aOldFrame); + NS_IMETHOD ReplaceFrame(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame); NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const; diff --git a/layout/html/base/src/nsAbsoluteContainingBlock.cpp b/layout/html/base/src/nsAbsoluteContainingBlock.cpp index a6f06c35a0e6..7c3e6e063d6a 100644 --- a/layout/html/base/src/nsAbsoluteContainingBlock.cpp +++ b/layout/html/base/src/nsAbsoluteContainingBlock.cpp @@ -138,6 +138,21 @@ nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame, return result ? NS_OK : NS_ERROR_FAILURE; } +nsresult +nsAbsoluteContainingBlock::ReplaceFrame(nsIFrame* aDelegatingFrame, + nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame) +{ + PRBool result = mAbsoluteFrames.ReplaceFrame(aPresContext, aDelegatingFrame, + aOldFrame, aNewFrame, PR_TRUE); + NS_ASSERTION(result, "Problems replacing a frame"); + return result ? NS_OK : NS_ERROR_FAILURE; +} + + // Destructor function for the collapse offset frame property static void DestroyRectFunc(nsIPresContext* aPresContext, diff --git a/layout/html/base/src/nsAbsoluteContainingBlock.h b/layout/html/base/src/nsAbsoluteContainingBlock.h index 911cf4202101..7ccd50040713 100644 --- a/layout/html/base/src/nsAbsoluteContainingBlock.h +++ b/layout/html/base/src/nsAbsoluteContainingBlock.h @@ -82,7 +82,13 @@ public: nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aOldFrame); - + nsresult ReplaceFrame(nsIFrame* aDelegatingFrame, + nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame); + // Called by the delegating frame after it has done its reflow first. This // function will reflow any absolutely positioned child frames that need to // be reflowed, e.g., because the absolutely positioned child frame has diff --git a/layout/html/base/src/nsFrameManager.cpp b/layout/html/base/src/nsFrameManager.cpp index 0ac0b9f71cc5..f3e3c9453a48 100644 --- a/layout/html/base/src/nsFrameManager.cpp +++ b/layout/html/base/src/nsFrameManager.cpp @@ -783,6 +783,8 @@ FrameManager::RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame) PL_DHASH_ADD)); if (!entry) return NS_ERROR_OUT_OF_MEMORY; + + NS_ASSERTION(!entry->placeholderFrame, "Registering a placeholder for a frame that already has a placeholder!"); entry->placeholderFrame = aPlaceholderFrame; return NS_OK; } diff --git a/layout/html/base/src/nsInlineFrame.cpp b/layout/html/base/src/nsInlineFrame.cpp index 1b7e8d3a3b80..ec3e2295b544 100644 --- a/layout/html/base/src/nsInlineFrame.cpp +++ b/layout/html/base/src/nsInlineFrame.cpp @@ -311,21 +311,22 @@ nsInlineFrame::ReplaceFrame(nsIPresContext* aPresContext, nsIFrame* aOldFrame, nsIFrame* aNewFrame) { - if (nsnull != aListName) { + if (aListName) { + NS_ERROR("Don't have any special lists on inline frames!"); return NS_ERROR_INVALID_ARG; } if (!aOldFrame || !aNewFrame) { + NS_ERROR("Missing aOldFrame or aNewFrame"); return NS_ERROR_INVALID_ARG; } - // Replace the old frame with the new frame in the list, then remove the old frame - mFrames.ReplaceFrame(this, aOldFrame, aNewFrame); - aOldFrame->Destroy(aPresContext); - + PRBool retval = + mFrames.ReplaceFrame(aPresContext, this, aOldFrame, aNewFrame, PR_TRUE); + // Ask the parent frame to reflow me. ReflowDirtyChild(&aPresShell, nsnull); - return NS_OK; + return retval ? NS_OK : NS_ERROR_FAILURE; } @@ -1195,6 +1196,22 @@ nsPositionedInlineFrame::RemoveFrame(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +nsPositionedInlineFrame::ReplaceFrame(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame) +{ + if (nsLayoutAtoms::absoluteList == aListName) { + return mAbsoluteContainer.ReplaceFrame(this, aPresContext, aPresShell, + aListName, aOldFrame, aNewFrame); + } else { + return nsInlineFrame::ReplaceFrame(aPresContext, aPresShell, aListName, + aOldFrame, aNewFrame); + } +} + NS_IMETHODIMP nsPositionedInlineFrame::GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const diff --git a/layout/html/base/src/nsInlineFrame.h b/layout/html/base/src/nsInlineFrame.h index fdc1f52d6ce0..6843586d2706 100644 --- a/layout/html/base/src/nsInlineFrame.h +++ b/layout/html/base/src/nsInlineFrame.h @@ -224,6 +224,11 @@ public: nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aOldFrame); + NS_IMETHOD ReplaceFrame(nsIPresContext* aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame, + nsIFrame* aNewFrame); NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const; diff --git a/layout/mathml/base/src/nsMathMLContainerFrame.cpp b/layout/mathml/base/src/nsMathMLContainerFrame.cpp index f48f07345d6d..c912a841f960 100644 --- a/layout/mathml/base/src/nsMathMLContainerFrame.cpp +++ b/layout/mathml/base/src/nsMathMLContainerFrame.cpp @@ -734,7 +734,7 @@ nsMathMLContainerFrame::WrapForeignFrames(nsIPresContext* aPresContext) wrapper->Destroy(aPresContext); return rv; } - mFrames.ReplaceFrame(this, child, wrapper); + mFrames.ReplaceFrame(aPresContext, this, child, wrapper, PR_FALSE); child->SetParent(wrapper); child->SetNextSibling(nsnull); aPresContext->ReParentStyleContext(child, newStyleContext); @@ -1013,13 +1013,7 @@ nsMathMLContainerFrame::ReplaceFrame(nsIPresContext* aPresContext, return NS_ERROR_INVALID_ARG; } // Replace the old frame with the new frame in the list - mFrames.ReplaceFrame(this, aOldFrame, aNewFrame); - - // XXX now destroy the old frame, really? the usage of ReplaceFrame() vs. - // XXX ReplaceFrameAndDestroy() is ambiguous - see bug 122748 - // XXX The style system doesn't call ReplaceFrame() and that's why - // XXX nobody seems to have been biten by the ambiguity yet - aOldFrame->Destroy(aPresContext); + mFrames.ReplaceFrame(aPresContext, this, aOldFrame, aNewFrame, PR_TRUE); return ChildListChanged(aPresContext, nsIDOMMutationEvent::MODIFICATION); }