Fix ReplaceChild() on positioned inlines to delegate to

nsAbsoluteContainingBlock.h.  Bug 176915, r=dbaron, sr=rbs
This commit is contained in:
bzbarsky%mit.edu 2002-11-12 03:30:13 +00:00
parent 6181c9aea0
commit 92d1146ffc
15 changed files with 202 additions and 100 deletions

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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;
};

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}