From 50795d851635fc907e76090889dd97914285f238 Mon Sep 17 00:00:00 2001 From: "troy%netscape.com" Date: Fri, 25 Sep 1998 05:13:06 +0000 Subject: [PATCH] Moved ContentDeleted() document notification code to the style system which generates the reflow command --- content/base/src/nsStyleSet.cpp | 4 - content/html/style/src/nsHTMLStyleSheet.cpp | 42 +++ layout/base/public/nsIFrame.h | 17 -- .../base/public/nsIStyleFrameConstruction.h | 6 + layout/base/src/nsFrame.cpp | 9 - layout/base/src/nsFrame.h | 5 - layout/base/src/nsPresShell.cpp | 17 +- layout/base/src/nsStyleSet.cpp | 4 - layout/generic/nsBlockFrame.cpp | 263 +++++++----------- layout/generic/nsBlockReflowState.cpp | 263 +++++++----------- layout/generic/nsBlockReflowState.h | 263 +++++++----------- layout/generic/nsHTMLContainerFrame.cpp | 93 ------- layout/generic/nsHTMLContainerFrame.h | 6 - layout/generic/nsIFrame.h | 17 -- layout/generic/nsInlineFrame.cpp | 67 ++++- layout/generic/nsPlaceholderFrame.cpp | 17 -- layout/generic/nsPlaceholderFrame.h | 5 - layout/html/base/src/nsAbsoluteFrame.cpp | 37 --- layout/html/base/src/nsAbsoluteFrame.h | 16 -- layout/html/base/src/nsBlockFrame.cpp | 263 +++++++----------- layout/html/base/src/nsBlockReflowState.cpp | 263 +++++++----------- layout/html/base/src/nsBlockReflowState.h | 263 +++++++----------- layout/html/base/src/nsBodyFrame.cpp | 13 - layout/html/base/src/nsBodyFrame.h | 6 - layout/html/base/src/nsHTMLContainerFrame.cpp | 93 ------- layout/html/base/src/nsHTMLContainerFrame.h | 6 - layout/html/base/src/nsInlineFrame.cpp | 67 ++++- layout/html/base/src/nsPlaceholderFrame.cpp | 17 -- layout/html/base/src/nsPlaceholderFrame.h | 5 - layout/html/style/src/nsHTMLStyleSheet.cpp | 42 +++ layout/style/nsHTMLStyleSheet.cpp | 42 +++ layout/style/nsStyleSet.cpp | 4 - 32 files changed, 836 insertions(+), 1399 deletions(-) diff --git a/content/base/src/nsStyleSet.cpp b/content/base/src/nsStyleSet.cpp index 4bceb4f28e46..c96e86b6d647 100644 --- a/content/base/src/nsStyleSet.cpp +++ b/content/base/src/nsStyleSet.cpp @@ -788,12 +788,8 @@ NS_IMETHODIMP StyleSetImpl::ContentRemoved(nsIPresContext* aPresContext, nsIContent* aChild, PRInt32 aIndexInContainer) { -#if 0 return mFrameConstructor->ContentRemoved(aPresContext, aDocument, aContainer, aChild, aIndexInContainer); -#else - return NS_OK; -#endif } // xxx style rules enumeration diff --git a/content/html/style/src/nsHTMLStyleSheet.cpp b/content/html/style/src/nsHTMLStyleSheet.cpp index 2613d7ec625d..e3d116b87f3b 100644 --- a/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/content/html/style/src/nsHTMLStyleSheet.cpp @@ -252,6 +252,12 @@ public: nsIContent* aChild, PRInt32 aIndexInContainer); + NS_IMETHOD ContentRemoved(nsIPresContext* aPresContext, + nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer); + // XXX style rule enumerations virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; @@ -1565,6 +1571,42 @@ HTMLStyleSheetImpl::ContentInserted(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +HTMLStyleSheetImpl::ContentRemoved(nsIPresContext* aPresContext, + nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) +{ + nsIPresShell* shell = aPresContext->GetShell(); + nsresult rv = NS_OK; + + // Find the child frame + nsIFrame* childFrame = shell->FindFrameWithContent(aChild); + + if (nsnull != childFrame) { + // Get the parent frame. + // Note that we use the content parent, and not the geometric parent, + // in case the frame has been moved out of the flow... + nsIFrame* parentFrame; + childFrame->GetContentParent(parentFrame); + NS_ASSERTION(nsnull != parentFrame, "null content parent frame"); + + // Notify the parent frame with a reflow command. + nsIReflowCommand* reflowCmd; + rv = NS_NewHTMLReflowCommand(&reflowCmd, parentFrame, + nsIReflowCommand::FrameDeleted, childFrame); + + if (NS_SUCCEEDED(rv)) { + shell->AppendReflowCommand(reflowCmd); + NS_RELEASE(reflowCmd); + } + } + + NS_RELEASE(shell); + return rv; +} + void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const { nsAutoString buffer; diff --git a/layout/base/public/nsIFrame.h b/layout/base/public/nsIFrame.h index ca4292d7f070..281e9e23bff3 100644 --- a/layout/base/public/nsIFrame.h +++ b/layout/base/public/nsIFrame.h @@ -494,23 +494,6 @@ public: nsIContent* aNewChild, PRInt32 aIndexInParent) = 0; - /** - * This call is invoked when content is deleted from the content - * tree. The container frame that maps that content is asked to deal - * with the deleted content by deleting frames and updating the - * index-in-parent values for it's affected children. In addition, - * the call must generate reflow commands that will incrementally - * reflow and repair the damaged portion of the frame tree. - * - * @param aIndexInParent the index in the content container where - * the new content was deleted. - */ - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) = 0; - /** * This call is invoked when content is changed in the content tree. * The first frame that maps that content is asked to deal with the diff --git a/layout/base/public/nsIStyleFrameConstruction.h b/layout/base/public/nsIStyleFrameConstruction.h index d2e03042855f..8d4a59608890 100644 --- a/layout/base/public/nsIStyleFrameConstruction.h +++ b/layout/base/public/nsIStyleFrameConstruction.h @@ -48,6 +48,12 @@ public: nsIContent* aContainer, nsIContent* aChild, PRInt32 aIndexInContainer) = 0; + + NS_IMETHOD ContentRemoved(nsIPresContext* aPresContext, + nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) = 0; }; #endif /* nsIStyleFrameConstruction_h___ */ diff --git a/layout/base/src/nsFrame.cpp b/layout/base/src/nsFrame.cpp index 8b94b7476dcd..2c0425e5adb8 100644 --- a/layout/base/src/nsFrame.cpp +++ b/layout/base/src/nsFrame.cpp @@ -1151,15 +1151,6 @@ NS_METHOD nsFrame::ContentReplaced(nsIPresShell* aShell, return NS_OK; } -NS_METHOD nsFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - return NS_OK; -} - NS_METHOD nsFrame::ContentChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/base/src/nsFrame.h b/layout/base/src/nsFrame.h index 62aeaa3e0bc9..8f4cf7cab0db 100644 --- a/layout/base/src/nsFrame.h +++ b/layout/base/src/nsFrame.h @@ -154,11 +154,6 @@ public: nsIContent* aOldChild, nsIContent* aNewChild, PRInt32 aIndexInParent); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); NS_IMETHOD ContentChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/base/src/nsPresShell.cpp b/layout/base/src/nsPresShell.cpp index bbd669d01807..4349e4518ba1 100644 --- a/layout/base/src/nsPresShell.cpp +++ b/layout/base/src/nsPresShell.cpp @@ -793,24 +793,11 @@ PresShell::ContentRemoved(nsIDocument *aDocument, nsIContent* aChild, PRInt32 aIndexInContainer) { -#ifdef FRAME_CONSTRUCTION + EnterReflowLock(); nsresult rv = mPresContext->ContentRemoved(aDocument, aContainer, aChild, aIndexInContainer); - ProcessReflowCommands(); + ExitReflowLock(); return rv; -#else - NS_PRECONDITION(nsnull != mRootFrame, "null root frame"); - - nsIFrame* frame = FindFrameWithContent(aContainer); - NS_PRECONDITION(nsnull != frame, "null frame"); - NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, - ("PresShell::ContentDeleted: container=%p child=%p[%d] frame=%p", - aContainer, aChild, aIndexInContainer, frame)); - frame->ContentDeleted(this, mPresContext, aContainer, aChild, - aIndexInContainer); - ProcessReflowCommands(); - return NS_OK; -#endif } NS_IMETHODIMP diff --git a/layout/base/src/nsStyleSet.cpp b/layout/base/src/nsStyleSet.cpp index 4bceb4f28e46..c96e86b6d647 100644 --- a/layout/base/src/nsStyleSet.cpp +++ b/layout/base/src/nsStyleSet.cpp @@ -788,12 +788,8 @@ NS_IMETHODIMP StyleSetImpl::ContentRemoved(nsIPresContext* aPresContext, nsIContent* aChild, PRInt32 aIndexInContainer) { -#if 0 return mFrameConstructor->ContentRemoved(aPresContext, aDocument, aContainer, aChild, aIndexInContainer); -#else - return NS_OK; -#endif } // xxx style rules enumeration diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index d8cdf87d366f..a76afe42bd12 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -243,12 +243,6 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); - NS_IMETHOD List(FILE* out, PRInt32 aIndent, nsIListFilter *aFilter) const; NS_IMETHOD ListTag(FILE* out) const; NS_IMETHOD VerifyTree() const; @@ -2332,7 +2326,101 @@ nsBlockFrame::FrameDeletedReflow(nsBlockReflowState& aState) if (nsnull == mLines) { return NS_OK; } - LineData* line = mLines; + + // Get the deleted frame + nsIFrame* deletedFrame; + aState.reflowCommand->GetChildFrame(deletedFrame); + + // Find the previous sibling frame + nsIFrame* prevSibling = nsnull; + for (nsIFrame* f = mLines->mFirstChild; f != deletedFrame; f->GetNextSibling(f)) { + if (nsnull == f) { + // We didn't find the deleted frame in our child list + NS_WARNING("Can't find deleted frame"); + return NS_OK; + } + + prevSibling = f; + } + + // Find the line that contains deletedFrame; we also find the pointer to + // the line. + nsBlockFrame* flow = this; + LineData** linep = &flow->mLines; + LineData* line = flow->mLines; + while (nsnull != line) { + if (line->Contains(deletedFrame)) { + break; + } + linep = &line->mNext; + line = line->mNext; + } + + // Remove frame and its continuations + while (nsnull != deletedFrame) { + while ((nsnull != line) && (nsnull != deletedFrame)) { +#ifdef NS_DEBUG + nsIFrame* parent; + deletedFrame->GetGeometricParent(parent); + NS_ASSERTION(flow == parent, "messed up delete code"); +#endif + NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, + ("nsBlockFrame::ContentDeleted: deadFrame=%p", deletedFrame)); + + // Remove deletedFrame from the line + if (line->mFirstChild == deletedFrame) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + line->mFirstChild = nextFrame; + } + else { + nsIFrame* lastFrame = line->LastChild(); + if (lastFrame == deletedFrame) { + line->SetLastContentIsComplete(); + } + } + + // Take deletedFrame out of the sibling list + if (nsnull != prevSibling) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + prevSibling->SetNextSibling(nextFrame); + } + + // Destroy frame; capture its next-in-flow first in case we need + // to destroy that too. + nsIFrame* nextInFlow; + deletedFrame->GetNextInFlow(nextInFlow); + if (nsnull != nextInFlow) { + deletedFrame->BreakFromNextFlow(); + } + deletedFrame->DeleteFrame(aState.mPresContext); + deletedFrame = nextInFlow; + + // If line is empty, remove it now + LineData* next = line->mNext; + if (0 == --line->mChildCount) { + *linep = next; + line->mNext = nsnull; + delete line; + } + else { + linep = &line->mNext; + } + line = next; + } + + // Advance to next flow block if the frame has more continuations + if (nsnull != deletedFrame) { + flow = (nsBlockFrame*) flow->mNextInFlow; + NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); + line = flow->mLines; + prevSibling = nsnull; + } + } + + // Find the first dirty line. That's where we start to reflow + line = mLines; while (nsnull != line->mNext) { if (line->IsDirty()) { break; @@ -3467,167 +3555,6 @@ nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame, return NS_OK; } -NS_IMETHODIMP -nsBlockFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - // Find the frame that precedes the frame to destroy and the frame - // to destroy (the first-in-flow if the frame is continued). We also - // find which of our next-in-flows contain the dead frame. - nsBlockFrame* flow; - nsIFrame* deadFrame; - nsIFrame* prevSibling; - if (aIndexInParent > 0) { - nsIContent* precedingContent; - aContainer->ChildAt(aIndexInParent - 1, precedingContent); - prevSibling = aShell->FindFrameWithContent(precedingContent); - NS_RELEASE(precedingContent); - - // The frame may have a next-in-flow. Get the last-in-flow; we do - // it the hard way because we can't assume that prevSibling is a - // subclass of nsSplittableFrame. - nsIFrame* nextInFlow; - do { - prevSibling->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - prevSibling = nextInFlow; - } - } while (nsnull != nextInFlow); - - // Get the dead frame (maybe) - prevSibling->GetGeometricParent((nsIFrame*&)flow); - prevSibling->GetNextSibling(deadFrame); - if (nsnull == deadFrame) { - // The deadFrame must be prevSibling's parent's next-in-flows - // first frame. Therefore it doesn't have a prevSibling. - flow = (nsBlockFrame*) flow->mNextInFlow; - if (nsnull != flow) { - deadFrame = flow->mLines->mFirstChild; - } - prevSibling = nsnull; - } - } - else { - prevSibling = nsnull; - flow = this; - deadFrame = mLines->mFirstChild; - } - NS_ASSERTION(nsnull != deadFrame, "yikes! couldn't find frame"); - if (nsnull == deadFrame) { - return NS_OK; - } - - // Generate a reflow command for the appropriate flow frame - nsIReflowCommand* cmd; - nsresult rv = NS_NewHTMLReflowCommand(&cmd, flow, - nsIReflowCommand::FrameDeleted); - if (NS_OK != rv) { - return rv; - } - aShell->AppendReflowCommand(cmd); - NS_RELEASE(cmd); - - // Find line that contains deadFrame; we also find the pointer to - // the line. - LineData** linep = &flow->mLines; - LineData* line = flow->mLines; - while (nsnull != line) { - if (line->Contains(deadFrame)) { - break; - } - linep = &line->mNext; - line = line->mNext; - } - - // Remove frame and its continuations - PRBool pseudos = flow->IsPseudoFrame(); - while (nsnull != deadFrame) { - while ((nsnull != line) && (nsnull != deadFrame)) { -#ifdef NS_DEBUG - nsIFrame* parent; - deadFrame->GetGeometricParent(parent); - NS_ASSERTION(flow == parent, "messed up delete code"); -#endif - NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, - ("nsBlockFrame::ContentDeleted: deadFrame=%p", - deadFrame)); - - // Remove deadFrame from the line - if (line->mFirstChild == deadFrame) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - line->mFirstChild = nextFrame; - } - else { - nsIFrame* lastFrame = line->LastChild(); - if (lastFrame == deadFrame) { - line->SetLastContentIsComplete(); - } - } - - // Take deadFrame out of the sibling list - if (nsnull != prevSibling) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - prevSibling->SetNextSibling(nextFrame); - } - - // Destroy frame; capture its next-in-flow first in case we need - // to destroy that too. - nsIFrame* nextInFlow; - deadFrame->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - deadFrame->BreakFromNextFlow(); - } - deadFrame->DeleteFrame(*aPresContext); - deadFrame = nextInFlow; - - // If line is empty, remove it now - LineData* next = line->mNext; - if (0 == --line->mChildCount) { - *linep = next; - line->mNext = nsnull; - delete line; - } - else { - linep = &line->mNext; - } - line = next; - } - - // Advance to next flow block if the frame has more continuations - if (nsnull != deadFrame) { - flow = (nsBlockFrame*) flow->mNextInFlow; - NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); - line = flow->mLines; - prevSibling = nsnull; - } - } - -#ifdef NS_DEBUG - if (GetVerifyTreeEnable()) { - // Verify that the above delete code actually deleted the frames! - flow = this; - while (nsnull != flow) { - nsIFrame* frame = flow->mLines->mFirstChild; - while (nsnull != frame) { - nsIContent* content; - frame->GetContent(content); - NS_ASSERTION(content != aChild, "delete failed"); - NS_RELEASE(content); - frame->GetNextSibling(frame); - } - flow = (nsBlockFrame*) flow->mNextInFlow; - } - } -#endif - - return rv; -} - PRBool nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext, nsIFrame* aChild) diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index d8cdf87d366f..a76afe42bd12 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -243,12 +243,6 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); - NS_IMETHOD List(FILE* out, PRInt32 aIndent, nsIListFilter *aFilter) const; NS_IMETHOD ListTag(FILE* out) const; NS_IMETHOD VerifyTree() const; @@ -2332,7 +2326,101 @@ nsBlockFrame::FrameDeletedReflow(nsBlockReflowState& aState) if (nsnull == mLines) { return NS_OK; } - LineData* line = mLines; + + // Get the deleted frame + nsIFrame* deletedFrame; + aState.reflowCommand->GetChildFrame(deletedFrame); + + // Find the previous sibling frame + nsIFrame* prevSibling = nsnull; + for (nsIFrame* f = mLines->mFirstChild; f != deletedFrame; f->GetNextSibling(f)) { + if (nsnull == f) { + // We didn't find the deleted frame in our child list + NS_WARNING("Can't find deleted frame"); + return NS_OK; + } + + prevSibling = f; + } + + // Find the line that contains deletedFrame; we also find the pointer to + // the line. + nsBlockFrame* flow = this; + LineData** linep = &flow->mLines; + LineData* line = flow->mLines; + while (nsnull != line) { + if (line->Contains(deletedFrame)) { + break; + } + linep = &line->mNext; + line = line->mNext; + } + + // Remove frame and its continuations + while (nsnull != deletedFrame) { + while ((nsnull != line) && (nsnull != deletedFrame)) { +#ifdef NS_DEBUG + nsIFrame* parent; + deletedFrame->GetGeometricParent(parent); + NS_ASSERTION(flow == parent, "messed up delete code"); +#endif + NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, + ("nsBlockFrame::ContentDeleted: deadFrame=%p", deletedFrame)); + + // Remove deletedFrame from the line + if (line->mFirstChild == deletedFrame) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + line->mFirstChild = nextFrame; + } + else { + nsIFrame* lastFrame = line->LastChild(); + if (lastFrame == deletedFrame) { + line->SetLastContentIsComplete(); + } + } + + // Take deletedFrame out of the sibling list + if (nsnull != prevSibling) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + prevSibling->SetNextSibling(nextFrame); + } + + // Destroy frame; capture its next-in-flow first in case we need + // to destroy that too. + nsIFrame* nextInFlow; + deletedFrame->GetNextInFlow(nextInFlow); + if (nsnull != nextInFlow) { + deletedFrame->BreakFromNextFlow(); + } + deletedFrame->DeleteFrame(aState.mPresContext); + deletedFrame = nextInFlow; + + // If line is empty, remove it now + LineData* next = line->mNext; + if (0 == --line->mChildCount) { + *linep = next; + line->mNext = nsnull; + delete line; + } + else { + linep = &line->mNext; + } + line = next; + } + + // Advance to next flow block if the frame has more continuations + if (nsnull != deletedFrame) { + flow = (nsBlockFrame*) flow->mNextInFlow; + NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); + line = flow->mLines; + prevSibling = nsnull; + } + } + + // Find the first dirty line. That's where we start to reflow + line = mLines; while (nsnull != line->mNext) { if (line->IsDirty()) { break; @@ -3467,167 +3555,6 @@ nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame, return NS_OK; } -NS_IMETHODIMP -nsBlockFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - // Find the frame that precedes the frame to destroy and the frame - // to destroy (the first-in-flow if the frame is continued). We also - // find which of our next-in-flows contain the dead frame. - nsBlockFrame* flow; - nsIFrame* deadFrame; - nsIFrame* prevSibling; - if (aIndexInParent > 0) { - nsIContent* precedingContent; - aContainer->ChildAt(aIndexInParent - 1, precedingContent); - prevSibling = aShell->FindFrameWithContent(precedingContent); - NS_RELEASE(precedingContent); - - // The frame may have a next-in-flow. Get the last-in-flow; we do - // it the hard way because we can't assume that prevSibling is a - // subclass of nsSplittableFrame. - nsIFrame* nextInFlow; - do { - prevSibling->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - prevSibling = nextInFlow; - } - } while (nsnull != nextInFlow); - - // Get the dead frame (maybe) - prevSibling->GetGeometricParent((nsIFrame*&)flow); - prevSibling->GetNextSibling(deadFrame); - if (nsnull == deadFrame) { - // The deadFrame must be prevSibling's parent's next-in-flows - // first frame. Therefore it doesn't have a prevSibling. - flow = (nsBlockFrame*) flow->mNextInFlow; - if (nsnull != flow) { - deadFrame = flow->mLines->mFirstChild; - } - prevSibling = nsnull; - } - } - else { - prevSibling = nsnull; - flow = this; - deadFrame = mLines->mFirstChild; - } - NS_ASSERTION(nsnull != deadFrame, "yikes! couldn't find frame"); - if (nsnull == deadFrame) { - return NS_OK; - } - - // Generate a reflow command for the appropriate flow frame - nsIReflowCommand* cmd; - nsresult rv = NS_NewHTMLReflowCommand(&cmd, flow, - nsIReflowCommand::FrameDeleted); - if (NS_OK != rv) { - return rv; - } - aShell->AppendReflowCommand(cmd); - NS_RELEASE(cmd); - - // Find line that contains deadFrame; we also find the pointer to - // the line. - LineData** linep = &flow->mLines; - LineData* line = flow->mLines; - while (nsnull != line) { - if (line->Contains(deadFrame)) { - break; - } - linep = &line->mNext; - line = line->mNext; - } - - // Remove frame and its continuations - PRBool pseudos = flow->IsPseudoFrame(); - while (nsnull != deadFrame) { - while ((nsnull != line) && (nsnull != deadFrame)) { -#ifdef NS_DEBUG - nsIFrame* parent; - deadFrame->GetGeometricParent(parent); - NS_ASSERTION(flow == parent, "messed up delete code"); -#endif - NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, - ("nsBlockFrame::ContentDeleted: deadFrame=%p", - deadFrame)); - - // Remove deadFrame from the line - if (line->mFirstChild == deadFrame) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - line->mFirstChild = nextFrame; - } - else { - nsIFrame* lastFrame = line->LastChild(); - if (lastFrame == deadFrame) { - line->SetLastContentIsComplete(); - } - } - - // Take deadFrame out of the sibling list - if (nsnull != prevSibling) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - prevSibling->SetNextSibling(nextFrame); - } - - // Destroy frame; capture its next-in-flow first in case we need - // to destroy that too. - nsIFrame* nextInFlow; - deadFrame->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - deadFrame->BreakFromNextFlow(); - } - deadFrame->DeleteFrame(*aPresContext); - deadFrame = nextInFlow; - - // If line is empty, remove it now - LineData* next = line->mNext; - if (0 == --line->mChildCount) { - *linep = next; - line->mNext = nsnull; - delete line; - } - else { - linep = &line->mNext; - } - line = next; - } - - // Advance to next flow block if the frame has more continuations - if (nsnull != deadFrame) { - flow = (nsBlockFrame*) flow->mNextInFlow; - NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); - line = flow->mLines; - prevSibling = nsnull; - } - } - -#ifdef NS_DEBUG - if (GetVerifyTreeEnable()) { - // Verify that the above delete code actually deleted the frames! - flow = this; - while (nsnull != flow) { - nsIFrame* frame = flow->mLines->mFirstChild; - while (nsnull != frame) { - nsIContent* content; - frame->GetContent(content); - NS_ASSERTION(content != aChild, "delete failed"); - NS_RELEASE(content); - frame->GetNextSibling(frame); - } - flow = (nsBlockFrame*) flow->mNextInFlow; - } - } -#endif - - return rv; -} - PRBool nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext, nsIFrame* aChild) diff --git a/layout/generic/nsBlockReflowState.h b/layout/generic/nsBlockReflowState.h index d8cdf87d366f..a76afe42bd12 100644 --- a/layout/generic/nsBlockReflowState.h +++ b/layout/generic/nsBlockReflowState.h @@ -243,12 +243,6 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); - NS_IMETHOD List(FILE* out, PRInt32 aIndent, nsIListFilter *aFilter) const; NS_IMETHOD ListTag(FILE* out) const; NS_IMETHOD VerifyTree() const; @@ -2332,7 +2326,101 @@ nsBlockFrame::FrameDeletedReflow(nsBlockReflowState& aState) if (nsnull == mLines) { return NS_OK; } - LineData* line = mLines; + + // Get the deleted frame + nsIFrame* deletedFrame; + aState.reflowCommand->GetChildFrame(deletedFrame); + + // Find the previous sibling frame + nsIFrame* prevSibling = nsnull; + for (nsIFrame* f = mLines->mFirstChild; f != deletedFrame; f->GetNextSibling(f)) { + if (nsnull == f) { + // We didn't find the deleted frame in our child list + NS_WARNING("Can't find deleted frame"); + return NS_OK; + } + + prevSibling = f; + } + + // Find the line that contains deletedFrame; we also find the pointer to + // the line. + nsBlockFrame* flow = this; + LineData** linep = &flow->mLines; + LineData* line = flow->mLines; + while (nsnull != line) { + if (line->Contains(deletedFrame)) { + break; + } + linep = &line->mNext; + line = line->mNext; + } + + // Remove frame and its continuations + while (nsnull != deletedFrame) { + while ((nsnull != line) && (nsnull != deletedFrame)) { +#ifdef NS_DEBUG + nsIFrame* parent; + deletedFrame->GetGeometricParent(parent); + NS_ASSERTION(flow == parent, "messed up delete code"); +#endif + NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, + ("nsBlockFrame::ContentDeleted: deadFrame=%p", deletedFrame)); + + // Remove deletedFrame from the line + if (line->mFirstChild == deletedFrame) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + line->mFirstChild = nextFrame; + } + else { + nsIFrame* lastFrame = line->LastChild(); + if (lastFrame == deletedFrame) { + line->SetLastContentIsComplete(); + } + } + + // Take deletedFrame out of the sibling list + if (nsnull != prevSibling) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + prevSibling->SetNextSibling(nextFrame); + } + + // Destroy frame; capture its next-in-flow first in case we need + // to destroy that too. + nsIFrame* nextInFlow; + deletedFrame->GetNextInFlow(nextInFlow); + if (nsnull != nextInFlow) { + deletedFrame->BreakFromNextFlow(); + } + deletedFrame->DeleteFrame(aState.mPresContext); + deletedFrame = nextInFlow; + + // If line is empty, remove it now + LineData* next = line->mNext; + if (0 == --line->mChildCount) { + *linep = next; + line->mNext = nsnull; + delete line; + } + else { + linep = &line->mNext; + } + line = next; + } + + // Advance to next flow block if the frame has more continuations + if (nsnull != deletedFrame) { + flow = (nsBlockFrame*) flow->mNextInFlow; + NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); + line = flow->mLines; + prevSibling = nsnull; + } + } + + // Find the first dirty line. That's where we start to reflow + line = mLines; while (nsnull != line->mNext) { if (line->IsDirty()) { break; @@ -3467,167 +3555,6 @@ nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame, return NS_OK; } -NS_IMETHODIMP -nsBlockFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - // Find the frame that precedes the frame to destroy and the frame - // to destroy (the first-in-flow if the frame is continued). We also - // find which of our next-in-flows contain the dead frame. - nsBlockFrame* flow; - nsIFrame* deadFrame; - nsIFrame* prevSibling; - if (aIndexInParent > 0) { - nsIContent* precedingContent; - aContainer->ChildAt(aIndexInParent - 1, precedingContent); - prevSibling = aShell->FindFrameWithContent(precedingContent); - NS_RELEASE(precedingContent); - - // The frame may have a next-in-flow. Get the last-in-flow; we do - // it the hard way because we can't assume that prevSibling is a - // subclass of nsSplittableFrame. - nsIFrame* nextInFlow; - do { - prevSibling->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - prevSibling = nextInFlow; - } - } while (nsnull != nextInFlow); - - // Get the dead frame (maybe) - prevSibling->GetGeometricParent((nsIFrame*&)flow); - prevSibling->GetNextSibling(deadFrame); - if (nsnull == deadFrame) { - // The deadFrame must be prevSibling's parent's next-in-flows - // first frame. Therefore it doesn't have a prevSibling. - flow = (nsBlockFrame*) flow->mNextInFlow; - if (nsnull != flow) { - deadFrame = flow->mLines->mFirstChild; - } - prevSibling = nsnull; - } - } - else { - prevSibling = nsnull; - flow = this; - deadFrame = mLines->mFirstChild; - } - NS_ASSERTION(nsnull != deadFrame, "yikes! couldn't find frame"); - if (nsnull == deadFrame) { - return NS_OK; - } - - // Generate a reflow command for the appropriate flow frame - nsIReflowCommand* cmd; - nsresult rv = NS_NewHTMLReflowCommand(&cmd, flow, - nsIReflowCommand::FrameDeleted); - if (NS_OK != rv) { - return rv; - } - aShell->AppendReflowCommand(cmd); - NS_RELEASE(cmd); - - // Find line that contains deadFrame; we also find the pointer to - // the line. - LineData** linep = &flow->mLines; - LineData* line = flow->mLines; - while (nsnull != line) { - if (line->Contains(deadFrame)) { - break; - } - linep = &line->mNext; - line = line->mNext; - } - - // Remove frame and its continuations - PRBool pseudos = flow->IsPseudoFrame(); - while (nsnull != deadFrame) { - while ((nsnull != line) && (nsnull != deadFrame)) { -#ifdef NS_DEBUG - nsIFrame* parent; - deadFrame->GetGeometricParent(parent); - NS_ASSERTION(flow == parent, "messed up delete code"); -#endif - NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, - ("nsBlockFrame::ContentDeleted: deadFrame=%p", - deadFrame)); - - // Remove deadFrame from the line - if (line->mFirstChild == deadFrame) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - line->mFirstChild = nextFrame; - } - else { - nsIFrame* lastFrame = line->LastChild(); - if (lastFrame == deadFrame) { - line->SetLastContentIsComplete(); - } - } - - // Take deadFrame out of the sibling list - if (nsnull != prevSibling) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - prevSibling->SetNextSibling(nextFrame); - } - - // Destroy frame; capture its next-in-flow first in case we need - // to destroy that too. - nsIFrame* nextInFlow; - deadFrame->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - deadFrame->BreakFromNextFlow(); - } - deadFrame->DeleteFrame(*aPresContext); - deadFrame = nextInFlow; - - // If line is empty, remove it now - LineData* next = line->mNext; - if (0 == --line->mChildCount) { - *linep = next; - line->mNext = nsnull; - delete line; - } - else { - linep = &line->mNext; - } - line = next; - } - - // Advance to next flow block if the frame has more continuations - if (nsnull != deadFrame) { - flow = (nsBlockFrame*) flow->mNextInFlow; - NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); - line = flow->mLines; - prevSibling = nsnull; - } - } - -#ifdef NS_DEBUG - if (GetVerifyTreeEnable()) { - // Verify that the above delete code actually deleted the frames! - flow = this; - while (nsnull != flow) { - nsIFrame* frame = flow->mLines->mFirstChild; - while (nsnull != frame) { - nsIContent* content; - frame->GetContent(content); - NS_ASSERTION(content != aChild, "delete failed"); - NS_RELEASE(content); - frame->GetNextSibling(frame); - } - flow = (nsBlockFrame*) flow->mNextInFlow; - } - } -#endif - - return rv; -} - PRBool nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext, nsIFrame* aChild) diff --git a/layout/generic/nsHTMLContainerFrame.cpp b/layout/generic/nsHTMLContainerFrame.cpp index 00223a7a54cc..8ef0a52e205a 100644 --- a/layout/generic/nsHTMLContainerFrame.cpp +++ b/layout/generic/nsHTMLContainerFrame.cpp @@ -140,99 +140,6 @@ NS_METHOD nsHTMLContainerFrame::GetCursorAndContentAt(nsIPresContext& aPresConte return NS_OK; } -NS_IMETHODIMP -nsHTMLContainerFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - // Find the frame that precedes the deletion point - nsHTMLContainerFrame* flow; - nsIFrame* deadFrame; - nsIFrame* prevSibling; - if (aIndexInParent > 0) { - nsIContent* precedingContent; - aContainer->ChildAt(aIndexInParent - 1, precedingContent); - prevSibling = aShell->FindFrameWithContent(precedingContent); - NS_RELEASE(precedingContent); - - // The frame may have a next-in-flow. Get the last-in-flow - nsIFrame* nextInFlow; - do { - prevSibling->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - prevSibling = nextInFlow; - } - } while (nsnull != nextInFlow); - - // Get the dead frame (maybe) - prevSibling->GetGeometricParent((nsIFrame*&)flow); - prevSibling->GetNextSibling(deadFrame); - if (nsnull == deadFrame) { - // The deadFrame must be prevSibling's parent's next-in-flows - // first frame. Therefore it doesn't have a prevSibling. - flow = (nsHTMLContainerFrame*) flow->mNextInFlow; - if (nsnull != flow) { - deadFrame = flow->mFirstChild; - } - prevSibling = nsnull; - } - } - else { - prevSibling = nsnull; - flow = this; - deadFrame = flow->mFirstChild; - } - NS_ASSERTION(nsnull != deadFrame, "yikes! couldn't find frame"); - if (nsnull == deadFrame) { - return NS_OK; - } - - // Generate a reflow command - nsIReflowCommand* cmd; - nsresult rv = NS_NewHTMLReflowCommand(&cmd, flow, - nsIReflowCommand::FrameDeleted); - if (NS_OK != rv) { - return rv; - } - aShell->AppendReflowCommand(cmd); - NS_RELEASE(cmd); - - // Take the frame away; Note that we also have to take away any - // continuations so we loop here until deadFrame is nsnull. - while (nsnull != deadFrame) { - // Remove frame from sibling list - nsIFrame* nextSib; - deadFrame->GetNextSibling(nextSib); - if (nsnull != prevSibling) { - prevSibling->SetNextSibling(nextSib); - } - else { - flow->mFirstChild = nextSib; - } - - // Break frame out of its flow and then destroy it - nsIFrame* nextInFlow; - deadFrame->GetNextInFlow(nextInFlow); - deadFrame->BreakFromNextFlow(); - deadFrame->DeleteFrame(*aPresContext); - deadFrame = nextInFlow; - - if (nsnull != deadFrame) { - // Get the parent of deadFrame's continuation - deadFrame->GetGeometricParent((nsIFrame*&) flow); - - // When we move to a next-in-flow then the deadFrame will be the - // first child of the new parent. Therefore we know that - // prevSibling will be null. - prevSibling = nsnull; - } - } - - return rv; -} - nsPlaceholderFrame* nsHTMLContainerFrame::CreatePlaceholderFrame(nsIPresContext& aPresContext, nsIFrame* aFloatedFrame) diff --git a/layout/generic/nsHTMLContainerFrame.h b/layout/generic/nsHTMLContainerFrame.h index 5ee163d1dfe3..56c4564c13c7 100644 --- a/layout/generic/nsHTMLContainerFrame.h +++ b/layout/generic/nsHTMLContainerFrame.h @@ -41,12 +41,6 @@ public: nsIContent** aContent, PRInt32& aCursor); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); - NS_IMETHOD AttributeChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index ca4292d7f070..281e9e23bff3 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -494,23 +494,6 @@ public: nsIContent* aNewChild, PRInt32 aIndexInParent) = 0; - /** - * This call is invoked when content is deleted from the content - * tree. The container frame that maps that content is asked to deal - * with the deleted content by deleting frames and updating the - * index-in-parent values for it's affected children. In addition, - * the call must generate reflow commands that will incrementally - * reflow and repair the damaged portion of the frame tree. - * - * @param aIndexInParent the index in the content container where - * the new content was deleted. - */ - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) = 0; - /** * This call is invoked when content is changed in the content tree. * The first frame that maps that content is asked to deal with the diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 25cc288f53fb..af12e562636e 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -89,6 +89,9 @@ public: nsresult FrameAppendedReflow(nsInlineReflowState& aState, nsInlineReflow& aInlineReflow); + nsresult FrameDeletedReflow(nsInlineReflowState& aState, + nsInlineReflow& aInlineReflow); + nsresult ChildIncrementalReflow(nsInlineReflowState& aState, nsInlineReflow& aInlineReflow); @@ -369,7 +372,13 @@ nsInlineFrame::InlineReflow(nsLineLayout& aLineLayout, state.reflowCommand->GetChildFrame(newFrame); state.reflowCommand->GetPrevSiblingFrame(prevSibling); InsertNewFrame(newFrame, prevSibling); - // fall thru... + // XXX For now map into full reflow... + rv = ResizeReflow(state, inlineReflow); + break; + + case nsIReflowCommand::FrameDeleted: + rv = FrameDeletedReflow(state, inlineReflow); + break; default: // XXX For now map the other incremental operations into full reflows @@ -532,6 +541,62 @@ nsInlineFrame::FrameAppendedReflow(nsInlineReflowState& aState, return rs; } +nsInlineReflowStatus +nsInlineFrame::FrameDeletedReflow(nsInlineReflowState& aState, + nsInlineReflow& aInlineReflow) +{ + // Get the deleted frame + nsIFrame* deletedFrame; + aState.reflowCommand->GetChildFrame(deletedFrame); + + // Find the previous sibling frame + nsIFrame* prevSibling = nsnull; + for (nsIFrame* f = mFirstChild; f != deletedFrame; f->GetNextSibling(f)) { + if (nsnull == f) { + // We didn't find the deleted frame in our child list + NS_WARNING("Can't find deleted frame"); + return NS_OK; + } + + prevSibling = f; + } + + // Take the frame away; Note that we also have to take away any + // continuations so we loop here until deadFrame is nsnull. + nsInlineFrame* flow = this; + while (nsnull != deletedFrame) { + // Remove frame from sibling list + nsIFrame* nextSib; + deletedFrame->GetNextSibling(nextSib); + if (nsnull != prevSibling) { + prevSibling->SetNextSibling(nextSib); + } + else { + flow->mFirstChild = nextSib; + } + + // Break frame out of its flow and then destroy it + nsIFrame* nextInFlow; + deletedFrame->GetNextInFlow(nextInFlow); + deletedFrame->BreakFromNextFlow(); + deletedFrame->DeleteFrame(aState.mPresContext); + deletedFrame = nextInFlow; + + if (nsnull != deletedFrame) { + // Get the parent of deadFrame's continuation + deletedFrame->GetGeometricParent((nsIFrame*&) flow); + + // When we move to a next-in-flow then the deadFrame will be the + // first child of the new parent. Therefore we know that + // prevSibling will be null. + prevSibling = nsnull; + } + } + + // XXX For now map into full reflow... + return ResizeReflow(aState, aInlineReflow); +} + nsInlineReflowStatus nsInlineFrame::ChildIncrementalReflow(nsInlineReflowState& aState, nsInlineReflow& aInlineReflow) diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp index 547ab1ba9c1f..d89c420aeec8 100644 --- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -157,23 +157,6 @@ NS_IMETHODIMP nsPlaceholderFrame::ContentReplaced(nsIPresShell* aShell, return NS_OK; } -NS_IMETHODIMP nsPlaceholderFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - NS_ASSERTION(mContent == aContainer, "bad content-deleted target"); - - // Forward the notification to the floater - if (nsnull != mAnchoredItem) { - return mAnchoredItem->ContentDeleted(aShell, aPresContext, aContainer, - aChild, aIndexInParent); - } - - return NS_OK; -} - NS_IMETHODIMP nsPlaceholderFrame::ContentChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/generic/nsPlaceholderFrame.h b/layout/generic/nsPlaceholderFrame.h index afe55cff38ff..4e44c6a75859 100644 --- a/layout/generic/nsPlaceholderFrame.h +++ b/layout/generic/nsPlaceholderFrame.h @@ -56,11 +56,6 @@ public: nsIContent* aOldChild, nsIContent* aNewChild, PRInt32 aIndexInParent); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); NS_IMETHOD ContentChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/html/base/src/nsAbsoluteFrame.cpp b/layout/html/base/src/nsAbsoluteFrame.cpp index 7be241d7db19..0498833a20e5 100644 --- a/layout/html/base/src/nsAbsoluteFrame.cpp +++ b/layout/html/base/src/nsAbsoluteFrame.cpp @@ -97,26 +97,6 @@ NS_IMETHODIMP nsAbsoluteFrame::Reflow(nsIPresContext& aPresContext, return nsFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); } -// XXX CONSTRUCTION -#if 0 -NS_IMETHODIMP nsAbsoluteFrame::ContentInserted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - NS_ASSERTION(mContent == aContainer, "bad content-inserted target"); - - // Forward the notification to the absolutely positioned frame - if (nsnull != mFrame) { - return mFrame->ContentInserted(aShell, aPresContext, aContainer, aChild, - aIndexInParent); - } - - return NS_OK; -} -#endif - NS_IMETHODIMP nsAbsoluteFrame::ContentReplaced(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aContainer, @@ -135,23 +115,6 @@ NS_IMETHODIMP nsAbsoluteFrame::ContentReplaced(nsIPresShell* aShell, return NS_OK; } -NS_IMETHODIMP nsAbsoluteFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - NS_ASSERTION(mContent == aContainer, "bad content-deleted target"); - - // Forward the notification to the absolutely positioned frame - if (nsnull != mFrame) { - return mFrame->ContentDeleted(aShell, aPresContext, aContainer, aChild, - aIndexInParent); - } - - return NS_OK; -} - NS_IMETHODIMP nsAbsoluteFrame::ContentChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/html/base/src/nsAbsoluteFrame.h b/layout/html/base/src/nsAbsoluteFrame.h index a6b20eee4a2b..3fe5b0a3f05e 100644 --- a/layout/html/base/src/nsAbsoluteFrame.h +++ b/layout/html/base/src/nsAbsoluteFrame.h @@ -43,28 +43,12 @@ public: const nsReflowState& aReflowState, nsReflowStatus& aStatus); -// XXX CONSTRUCTION -#if 0 - NS_IMETHOD ContentAppended(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer); - NS_IMETHOD ContentInserted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); -#endif NS_IMETHOD ContentReplaced(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aContainer, nsIContent* aOldChild, nsIContent* aNewChild, PRInt32 aIndexInParent); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); NS_IMETHOD ContentChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/html/base/src/nsBlockFrame.cpp b/layout/html/base/src/nsBlockFrame.cpp index d8cdf87d366f..a76afe42bd12 100644 --- a/layout/html/base/src/nsBlockFrame.cpp +++ b/layout/html/base/src/nsBlockFrame.cpp @@ -243,12 +243,6 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); - NS_IMETHOD List(FILE* out, PRInt32 aIndent, nsIListFilter *aFilter) const; NS_IMETHOD ListTag(FILE* out) const; NS_IMETHOD VerifyTree() const; @@ -2332,7 +2326,101 @@ nsBlockFrame::FrameDeletedReflow(nsBlockReflowState& aState) if (nsnull == mLines) { return NS_OK; } - LineData* line = mLines; + + // Get the deleted frame + nsIFrame* deletedFrame; + aState.reflowCommand->GetChildFrame(deletedFrame); + + // Find the previous sibling frame + nsIFrame* prevSibling = nsnull; + for (nsIFrame* f = mLines->mFirstChild; f != deletedFrame; f->GetNextSibling(f)) { + if (nsnull == f) { + // We didn't find the deleted frame in our child list + NS_WARNING("Can't find deleted frame"); + return NS_OK; + } + + prevSibling = f; + } + + // Find the line that contains deletedFrame; we also find the pointer to + // the line. + nsBlockFrame* flow = this; + LineData** linep = &flow->mLines; + LineData* line = flow->mLines; + while (nsnull != line) { + if (line->Contains(deletedFrame)) { + break; + } + linep = &line->mNext; + line = line->mNext; + } + + // Remove frame and its continuations + while (nsnull != deletedFrame) { + while ((nsnull != line) && (nsnull != deletedFrame)) { +#ifdef NS_DEBUG + nsIFrame* parent; + deletedFrame->GetGeometricParent(parent); + NS_ASSERTION(flow == parent, "messed up delete code"); +#endif + NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, + ("nsBlockFrame::ContentDeleted: deadFrame=%p", deletedFrame)); + + // Remove deletedFrame from the line + if (line->mFirstChild == deletedFrame) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + line->mFirstChild = nextFrame; + } + else { + nsIFrame* lastFrame = line->LastChild(); + if (lastFrame == deletedFrame) { + line->SetLastContentIsComplete(); + } + } + + // Take deletedFrame out of the sibling list + if (nsnull != prevSibling) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + prevSibling->SetNextSibling(nextFrame); + } + + // Destroy frame; capture its next-in-flow first in case we need + // to destroy that too. + nsIFrame* nextInFlow; + deletedFrame->GetNextInFlow(nextInFlow); + if (nsnull != nextInFlow) { + deletedFrame->BreakFromNextFlow(); + } + deletedFrame->DeleteFrame(aState.mPresContext); + deletedFrame = nextInFlow; + + // If line is empty, remove it now + LineData* next = line->mNext; + if (0 == --line->mChildCount) { + *linep = next; + line->mNext = nsnull; + delete line; + } + else { + linep = &line->mNext; + } + line = next; + } + + // Advance to next flow block if the frame has more continuations + if (nsnull != deletedFrame) { + flow = (nsBlockFrame*) flow->mNextInFlow; + NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); + line = flow->mLines; + prevSibling = nsnull; + } + } + + // Find the first dirty line. That's where we start to reflow + line = mLines; while (nsnull != line->mNext) { if (line->IsDirty()) { break; @@ -3467,167 +3555,6 @@ nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame, return NS_OK; } -NS_IMETHODIMP -nsBlockFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - // Find the frame that precedes the frame to destroy and the frame - // to destroy (the first-in-flow if the frame is continued). We also - // find which of our next-in-flows contain the dead frame. - nsBlockFrame* flow; - nsIFrame* deadFrame; - nsIFrame* prevSibling; - if (aIndexInParent > 0) { - nsIContent* precedingContent; - aContainer->ChildAt(aIndexInParent - 1, precedingContent); - prevSibling = aShell->FindFrameWithContent(precedingContent); - NS_RELEASE(precedingContent); - - // The frame may have a next-in-flow. Get the last-in-flow; we do - // it the hard way because we can't assume that prevSibling is a - // subclass of nsSplittableFrame. - nsIFrame* nextInFlow; - do { - prevSibling->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - prevSibling = nextInFlow; - } - } while (nsnull != nextInFlow); - - // Get the dead frame (maybe) - prevSibling->GetGeometricParent((nsIFrame*&)flow); - prevSibling->GetNextSibling(deadFrame); - if (nsnull == deadFrame) { - // The deadFrame must be prevSibling's parent's next-in-flows - // first frame. Therefore it doesn't have a prevSibling. - flow = (nsBlockFrame*) flow->mNextInFlow; - if (nsnull != flow) { - deadFrame = flow->mLines->mFirstChild; - } - prevSibling = nsnull; - } - } - else { - prevSibling = nsnull; - flow = this; - deadFrame = mLines->mFirstChild; - } - NS_ASSERTION(nsnull != deadFrame, "yikes! couldn't find frame"); - if (nsnull == deadFrame) { - return NS_OK; - } - - // Generate a reflow command for the appropriate flow frame - nsIReflowCommand* cmd; - nsresult rv = NS_NewHTMLReflowCommand(&cmd, flow, - nsIReflowCommand::FrameDeleted); - if (NS_OK != rv) { - return rv; - } - aShell->AppendReflowCommand(cmd); - NS_RELEASE(cmd); - - // Find line that contains deadFrame; we also find the pointer to - // the line. - LineData** linep = &flow->mLines; - LineData* line = flow->mLines; - while (nsnull != line) { - if (line->Contains(deadFrame)) { - break; - } - linep = &line->mNext; - line = line->mNext; - } - - // Remove frame and its continuations - PRBool pseudos = flow->IsPseudoFrame(); - while (nsnull != deadFrame) { - while ((nsnull != line) && (nsnull != deadFrame)) { -#ifdef NS_DEBUG - nsIFrame* parent; - deadFrame->GetGeometricParent(parent); - NS_ASSERTION(flow == parent, "messed up delete code"); -#endif - NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, - ("nsBlockFrame::ContentDeleted: deadFrame=%p", - deadFrame)); - - // Remove deadFrame from the line - if (line->mFirstChild == deadFrame) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - line->mFirstChild = nextFrame; - } - else { - nsIFrame* lastFrame = line->LastChild(); - if (lastFrame == deadFrame) { - line->SetLastContentIsComplete(); - } - } - - // Take deadFrame out of the sibling list - if (nsnull != prevSibling) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - prevSibling->SetNextSibling(nextFrame); - } - - // Destroy frame; capture its next-in-flow first in case we need - // to destroy that too. - nsIFrame* nextInFlow; - deadFrame->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - deadFrame->BreakFromNextFlow(); - } - deadFrame->DeleteFrame(*aPresContext); - deadFrame = nextInFlow; - - // If line is empty, remove it now - LineData* next = line->mNext; - if (0 == --line->mChildCount) { - *linep = next; - line->mNext = nsnull; - delete line; - } - else { - linep = &line->mNext; - } - line = next; - } - - // Advance to next flow block if the frame has more continuations - if (nsnull != deadFrame) { - flow = (nsBlockFrame*) flow->mNextInFlow; - NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); - line = flow->mLines; - prevSibling = nsnull; - } - } - -#ifdef NS_DEBUG - if (GetVerifyTreeEnable()) { - // Verify that the above delete code actually deleted the frames! - flow = this; - while (nsnull != flow) { - nsIFrame* frame = flow->mLines->mFirstChild; - while (nsnull != frame) { - nsIContent* content; - frame->GetContent(content); - NS_ASSERTION(content != aChild, "delete failed"); - NS_RELEASE(content); - frame->GetNextSibling(frame); - } - flow = (nsBlockFrame*) flow->mNextInFlow; - } - } -#endif - - return rv; -} - PRBool nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext, nsIFrame* aChild) diff --git a/layout/html/base/src/nsBlockReflowState.cpp b/layout/html/base/src/nsBlockReflowState.cpp index d8cdf87d366f..a76afe42bd12 100644 --- a/layout/html/base/src/nsBlockReflowState.cpp +++ b/layout/html/base/src/nsBlockReflowState.cpp @@ -243,12 +243,6 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); - NS_IMETHOD List(FILE* out, PRInt32 aIndent, nsIListFilter *aFilter) const; NS_IMETHOD ListTag(FILE* out) const; NS_IMETHOD VerifyTree() const; @@ -2332,7 +2326,101 @@ nsBlockFrame::FrameDeletedReflow(nsBlockReflowState& aState) if (nsnull == mLines) { return NS_OK; } - LineData* line = mLines; + + // Get the deleted frame + nsIFrame* deletedFrame; + aState.reflowCommand->GetChildFrame(deletedFrame); + + // Find the previous sibling frame + nsIFrame* prevSibling = nsnull; + for (nsIFrame* f = mLines->mFirstChild; f != deletedFrame; f->GetNextSibling(f)) { + if (nsnull == f) { + // We didn't find the deleted frame in our child list + NS_WARNING("Can't find deleted frame"); + return NS_OK; + } + + prevSibling = f; + } + + // Find the line that contains deletedFrame; we also find the pointer to + // the line. + nsBlockFrame* flow = this; + LineData** linep = &flow->mLines; + LineData* line = flow->mLines; + while (nsnull != line) { + if (line->Contains(deletedFrame)) { + break; + } + linep = &line->mNext; + line = line->mNext; + } + + // Remove frame and its continuations + while (nsnull != deletedFrame) { + while ((nsnull != line) && (nsnull != deletedFrame)) { +#ifdef NS_DEBUG + nsIFrame* parent; + deletedFrame->GetGeometricParent(parent); + NS_ASSERTION(flow == parent, "messed up delete code"); +#endif + NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, + ("nsBlockFrame::ContentDeleted: deadFrame=%p", deletedFrame)); + + // Remove deletedFrame from the line + if (line->mFirstChild == deletedFrame) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + line->mFirstChild = nextFrame; + } + else { + nsIFrame* lastFrame = line->LastChild(); + if (lastFrame == deletedFrame) { + line->SetLastContentIsComplete(); + } + } + + // Take deletedFrame out of the sibling list + if (nsnull != prevSibling) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + prevSibling->SetNextSibling(nextFrame); + } + + // Destroy frame; capture its next-in-flow first in case we need + // to destroy that too. + nsIFrame* nextInFlow; + deletedFrame->GetNextInFlow(nextInFlow); + if (nsnull != nextInFlow) { + deletedFrame->BreakFromNextFlow(); + } + deletedFrame->DeleteFrame(aState.mPresContext); + deletedFrame = nextInFlow; + + // If line is empty, remove it now + LineData* next = line->mNext; + if (0 == --line->mChildCount) { + *linep = next; + line->mNext = nsnull; + delete line; + } + else { + linep = &line->mNext; + } + line = next; + } + + // Advance to next flow block if the frame has more continuations + if (nsnull != deletedFrame) { + flow = (nsBlockFrame*) flow->mNextInFlow; + NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); + line = flow->mLines; + prevSibling = nsnull; + } + } + + // Find the first dirty line. That's where we start to reflow + line = mLines; while (nsnull != line->mNext) { if (line->IsDirty()) { break; @@ -3467,167 +3555,6 @@ nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame, return NS_OK; } -NS_IMETHODIMP -nsBlockFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - // Find the frame that precedes the frame to destroy and the frame - // to destroy (the first-in-flow if the frame is continued). We also - // find which of our next-in-flows contain the dead frame. - nsBlockFrame* flow; - nsIFrame* deadFrame; - nsIFrame* prevSibling; - if (aIndexInParent > 0) { - nsIContent* precedingContent; - aContainer->ChildAt(aIndexInParent - 1, precedingContent); - prevSibling = aShell->FindFrameWithContent(precedingContent); - NS_RELEASE(precedingContent); - - // The frame may have a next-in-flow. Get the last-in-flow; we do - // it the hard way because we can't assume that prevSibling is a - // subclass of nsSplittableFrame. - nsIFrame* nextInFlow; - do { - prevSibling->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - prevSibling = nextInFlow; - } - } while (nsnull != nextInFlow); - - // Get the dead frame (maybe) - prevSibling->GetGeometricParent((nsIFrame*&)flow); - prevSibling->GetNextSibling(deadFrame); - if (nsnull == deadFrame) { - // The deadFrame must be prevSibling's parent's next-in-flows - // first frame. Therefore it doesn't have a prevSibling. - flow = (nsBlockFrame*) flow->mNextInFlow; - if (nsnull != flow) { - deadFrame = flow->mLines->mFirstChild; - } - prevSibling = nsnull; - } - } - else { - prevSibling = nsnull; - flow = this; - deadFrame = mLines->mFirstChild; - } - NS_ASSERTION(nsnull != deadFrame, "yikes! couldn't find frame"); - if (nsnull == deadFrame) { - return NS_OK; - } - - // Generate a reflow command for the appropriate flow frame - nsIReflowCommand* cmd; - nsresult rv = NS_NewHTMLReflowCommand(&cmd, flow, - nsIReflowCommand::FrameDeleted); - if (NS_OK != rv) { - return rv; - } - aShell->AppendReflowCommand(cmd); - NS_RELEASE(cmd); - - // Find line that contains deadFrame; we also find the pointer to - // the line. - LineData** linep = &flow->mLines; - LineData* line = flow->mLines; - while (nsnull != line) { - if (line->Contains(deadFrame)) { - break; - } - linep = &line->mNext; - line = line->mNext; - } - - // Remove frame and its continuations - PRBool pseudos = flow->IsPseudoFrame(); - while (nsnull != deadFrame) { - while ((nsnull != line) && (nsnull != deadFrame)) { -#ifdef NS_DEBUG - nsIFrame* parent; - deadFrame->GetGeometricParent(parent); - NS_ASSERTION(flow == parent, "messed up delete code"); -#endif - NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, - ("nsBlockFrame::ContentDeleted: deadFrame=%p", - deadFrame)); - - // Remove deadFrame from the line - if (line->mFirstChild == deadFrame) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - line->mFirstChild = nextFrame; - } - else { - nsIFrame* lastFrame = line->LastChild(); - if (lastFrame == deadFrame) { - line->SetLastContentIsComplete(); - } - } - - // Take deadFrame out of the sibling list - if (nsnull != prevSibling) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - prevSibling->SetNextSibling(nextFrame); - } - - // Destroy frame; capture its next-in-flow first in case we need - // to destroy that too. - nsIFrame* nextInFlow; - deadFrame->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - deadFrame->BreakFromNextFlow(); - } - deadFrame->DeleteFrame(*aPresContext); - deadFrame = nextInFlow; - - // If line is empty, remove it now - LineData* next = line->mNext; - if (0 == --line->mChildCount) { - *linep = next; - line->mNext = nsnull; - delete line; - } - else { - linep = &line->mNext; - } - line = next; - } - - // Advance to next flow block if the frame has more continuations - if (nsnull != deadFrame) { - flow = (nsBlockFrame*) flow->mNextInFlow; - NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); - line = flow->mLines; - prevSibling = nsnull; - } - } - -#ifdef NS_DEBUG - if (GetVerifyTreeEnable()) { - // Verify that the above delete code actually deleted the frames! - flow = this; - while (nsnull != flow) { - nsIFrame* frame = flow->mLines->mFirstChild; - while (nsnull != frame) { - nsIContent* content; - frame->GetContent(content); - NS_ASSERTION(content != aChild, "delete failed"); - NS_RELEASE(content); - frame->GetNextSibling(frame); - } - flow = (nsBlockFrame*) flow->mNextInFlow; - } - } -#endif - - return rv; -} - PRBool nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext, nsIFrame* aChild) diff --git a/layout/html/base/src/nsBlockReflowState.h b/layout/html/base/src/nsBlockReflowState.h index d8cdf87d366f..a76afe42bd12 100644 --- a/layout/html/base/src/nsBlockReflowState.h +++ b/layout/html/base/src/nsBlockReflowState.h @@ -243,12 +243,6 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); - NS_IMETHOD List(FILE* out, PRInt32 aIndent, nsIListFilter *aFilter) const; NS_IMETHOD ListTag(FILE* out) const; NS_IMETHOD VerifyTree() const; @@ -2332,7 +2326,101 @@ nsBlockFrame::FrameDeletedReflow(nsBlockReflowState& aState) if (nsnull == mLines) { return NS_OK; } - LineData* line = mLines; + + // Get the deleted frame + nsIFrame* deletedFrame; + aState.reflowCommand->GetChildFrame(deletedFrame); + + // Find the previous sibling frame + nsIFrame* prevSibling = nsnull; + for (nsIFrame* f = mLines->mFirstChild; f != deletedFrame; f->GetNextSibling(f)) { + if (nsnull == f) { + // We didn't find the deleted frame in our child list + NS_WARNING("Can't find deleted frame"); + return NS_OK; + } + + prevSibling = f; + } + + // Find the line that contains deletedFrame; we also find the pointer to + // the line. + nsBlockFrame* flow = this; + LineData** linep = &flow->mLines; + LineData* line = flow->mLines; + while (nsnull != line) { + if (line->Contains(deletedFrame)) { + break; + } + linep = &line->mNext; + line = line->mNext; + } + + // Remove frame and its continuations + while (nsnull != deletedFrame) { + while ((nsnull != line) && (nsnull != deletedFrame)) { +#ifdef NS_DEBUG + nsIFrame* parent; + deletedFrame->GetGeometricParent(parent); + NS_ASSERTION(flow == parent, "messed up delete code"); +#endif + NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, + ("nsBlockFrame::ContentDeleted: deadFrame=%p", deletedFrame)); + + // Remove deletedFrame from the line + if (line->mFirstChild == deletedFrame) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + line->mFirstChild = nextFrame; + } + else { + nsIFrame* lastFrame = line->LastChild(); + if (lastFrame == deletedFrame) { + line->SetLastContentIsComplete(); + } + } + + // Take deletedFrame out of the sibling list + if (nsnull != prevSibling) { + nsIFrame* nextFrame; + deletedFrame->GetNextSibling(nextFrame); + prevSibling->SetNextSibling(nextFrame); + } + + // Destroy frame; capture its next-in-flow first in case we need + // to destroy that too. + nsIFrame* nextInFlow; + deletedFrame->GetNextInFlow(nextInFlow); + if (nsnull != nextInFlow) { + deletedFrame->BreakFromNextFlow(); + } + deletedFrame->DeleteFrame(aState.mPresContext); + deletedFrame = nextInFlow; + + // If line is empty, remove it now + LineData* next = line->mNext; + if (0 == --line->mChildCount) { + *linep = next; + line->mNext = nsnull; + delete line; + } + else { + linep = &line->mNext; + } + line = next; + } + + // Advance to next flow block if the frame has more continuations + if (nsnull != deletedFrame) { + flow = (nsBlockFrame*) flow->mNextInFlow; + NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); + line = flow->mLines; + prevSibling = nsnull; + } + } + + // Find the first dirty line. That's where we start to reflow + line = mLines; while (nsnull != line->mNext) { if (line->IsDirty()) { break; @@ -3467,167 +3555,6 @@ nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame, return NS_OK; } -NS_IMETHODIMP -nsBlockFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - // Find the frame that precedes the frame to destroy and the frame - // to destroy (the first-in-flow if the frame is continued). We also - // find which of our next-in-flows contain the dead frame. - nsBlockFrame* flow; - nsIFrame* deadFrame; - nsIFrame* prevSibling; - if (aIndexInParent > 0) { - nsIContent* precedingContent; - aContainer->ChildAt(aIndexInParent - 1, precedingContent); - prevSibling = aShell->FindFrameWithContent(precedingContent); - NS_RELEASE(precedingContent); - - // The frame may have a next-in-flow. Get the last-in-flow; we do - // it the hard way because we can't assume that prevSibling is a - // subclass of nsSplittableFrame. - nsIFrame* nextInFlow; - do { - prevSibling->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - prevSibling = nextInFlow; - } - } while (nsnull != nextInFlow); - - // Get the dead frame (maybe) - prevSibling->GetGeometricParent((nsIFrame*&)flow); - prevSibling->GetNextSibling(deadFrame); - if (nsnull == deadFrame) { - // The deadFrame must be prevSibling's parent's next-in-flows - // first frame. Therefore it doesn't have a prevSibling. - flow = (nsBlockFrame*) flow->mNextInFlow; - if (nsnull != flow) { - deadFrame = flow->mLines->mFirstChild; - } - prevSibling = nsnull; - } - } - else { - prevSibling = nsnull; - flow = this; - deadFrame = mLines->mFirstChild; - } - NS_ASSERTION(nsnull != deadFrame, "yikes! couldn't find frame"); - if (nsnull == deadFrame) { - return NS_OK; - } - - // Generate a reflow command for the appropriate flow frame - nsIReflowCommand* cmd; - nsresult rv = NS_NewHTMLReflowCommand(&cmd, flow, - nsIReflowCommand::FrameDeleted); - if (NS_OK != rv) { - return rv; - } - aShell->AppendReflowCommand(cmd); - NS_RELEASE(cmd); - - // Find line that contains deadFrame; we also find the pointer to - // the line. - LineData** linep = &flow->mLines; - LineData* line = flow->mLines; - while (nsnull != line) { - if (line->Contains(deadFrame)) { - break; - } - linep = &line->mNext; - line = line->mNext; - } - - // Remove frame and its continuations - PRBool pseudos = flow->IsPseudoFrame(); - while (nsnull != deadFrame) { - while ((nsnull != line) && (nsnull != deadFrame)) { -#ifdef NS_DEBUG - nsIFrame* parent; - deadFrame->GetGeometricParent(parent); - NS_ASSERTION(flow == parent, "messed up delete code"); -#endif - NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW, - ("nsBlockFrame::ContentDeleted: deadFrame=%p", - deadFrame)); - - // Remove deadFrame from the line - if (line->mFirstChild == deadFrame) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - line->mFirstChild = nextFrame; - } - else { - nsIFrame* lastFrame = line->LastChild(); - if (lastFrame == deadFrame) { - line->SetLastContentIsComplete(); - } - } - - // Take deadFrame out of the sibling list - if (nsnull != prevSibling) { - nsIFrame* nextFrame; - deadFrame->GetNextSibling(nextFrame); - prevSibling->SetNextSibling(nextFrame); - } - - // Destroy frame; capture its next-in-flow first in case we need - // to destroy that too. - nsIFrame* nextInFlow; - deadFrame->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - deadFrame->BreakFromNextFlow(); - } - deadFrame->DeleteFrame(*aPresContext); - deadFrame = nextInFlow; - - // If line is empty, remove it now - LineData* next = line->mNext; - if (0 == --line->mChildCount) { - *linep = next; - line->mNext = nsnull; - delete line; - } - else { - linep = &line->mNext; - } - line = next; - } - - // Advance to next flow block if the frame has more continuations - if (nsnull != deadFrame) { - flow = (nsBlockFrame*) flow->mNextInFlow; - NS_ASSERTION(nsnull != flow, "whoops, continuation without a parent"); - line = flow->mLines; - prevSibling = nsnull; - } - } - -#ifdef NS_DEBUG - if (GetVerifyTreeEnable()) { - // Verify that the above delete code actually deleted the frames! - flow = this; - while (nsnull != flow) { - nsIFrame* frame = flow->mLines->mFirstChild; - while (nsnull != frame) { - nsIContent* content; - frame->GetContent(content); - NS_ASSERTION(content != aChild, "delete failed"); - NS_RELEASE(content); - frame->GetNextSibling(frame); - } - flow = (nsBlockFrame*) flow->mNextInFlow; - } - } -#endif - - return rv; -} - PRBool nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext, nsIFrame* aChild) diff --git a/layout/html/base/src/nsBodyFrame.cpp b/layout/html/base/src/nsBodyFrame.cpp index 737d30005789..64bc7ddcc457 100644 --- a/layout/html/base/src/nsBodyFrame.cpp +++ b/layout/html/base/src/nsBodyFrame.cpp @@ -360,19 +360,6 @@ nsBodyFrame::Reflow(nsIPresContext& aPresContext, return NS_OK; } -NS_METHOD nsBodyFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - NS_ASSERTION(mContent == aContainer, "bad content-deleted target"); - - // Pass along the notification to our pseudo frame that maps all the content - return mFirstChild->ContentDeleted(aShell, aPresContext, aContainer, - aChild, aIndexInParent); -} - NS_METHOD nsBodyFrame::CreateContinuingFrame(nsIPresContext& aPresContext, nsIFrame* aParent, diff --git a/layout/html/base/src/nsBodyFrame.h b/layout/html/base/src/nsBodyFrame.h index 8161d36a3c79..ccd0cf423289 100644 --- a/layout/html/base/src/nsBodyFrame.h +++ b/layout/html/base/src/nsBodyFrame.h @@ -45,12 +45,6 @@ public: const nsReflowState& aReflowState, nsReflowStatus& aStatus); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); - NS_IMETHOD CreateContinuingFrame(nsIPresContext& aPresContext, nsIFrame* aParent, nsIStyleContext* aStyleContext, diff --git a/layout/html/base/src/nsHTMLContainerFrame.cpp b/layout/html/base/src/nsHTMLContainerFrame.cpp index 00223a7a54cc..8ef0a52e205a 100644 --- a/layout/html/base/src/nsHTMLContainerFrame.cpp +++ b/layout/html/base/src/nsHTMLContainerFrame.cpp @@ -140,99 +140,6 @@ NS_METHOD nsHTMLContainerFrame::GetCursorAndContentAt(nsIPresContext& aPresConte return NS_OK; } -NS_IMETHODIMP -nsHTMLContainerFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - // Find the frame that precedes the deletion point - nsHTMLContainerFrame* flow; - nsIFrame* deadFrame; - nsIFrame* prevSibling; - if (aIndexInParent > 0) { - nsIContent* precedingContent; - aContainer->ChildAt(aIndexInParent - 1, precedingContent); - prevSibling = aShell->FindFrameWithContent(precedingContent); - NS_RELEASE(precedingContent); - - // The frame may have a next-in-flow. Get the last-in-flow - nsIFrame* nextInFlow; - do { - prevSibling->GetNextInFlow(nextInFlow); - if (nsnull != nextInFlow) { - prevSibling = nextInFlow; - } - } while (nsnull != nextInFlow); - - // Get the dead frame (maybe) - prevSibling->GetGeometricParent((nsIFrame*&)flow); - prevSibling->GetNextSibling(deadFrame); - if (nsnull == deadFrame) { - // The deadFrame must be prevSibling's parent's next-in-flows - // first frame. Therefore it doesn't have a prevSibling. - flow = (nsHTMLContainerFrame*) flow->mNextInFlow; - if (nsnull != flow) { - deadFrame = flow->mFirstChild; - } - prevSibling = nsnull; - } - } - else { - prevSibling = nsnull; - flow = this; - deadFrame = flow->mFirstChild; - } - NS_ASSERTION(nsnull != deadFrame, "yikes! couldn't find frame"); - if (nsnull == deadFrame) { - return NS_OK; - } - - // Generate a reflow command - nsIReflowCommand* cmd; - nsresult rv = NS_NewHTMLReflowCommand(&cmd, flow, - nsIReflowCommand::FrameDeleted); - if (NS_OK != rv) { - return rv; - } - aShell->AppendReflowCommand(cmd); - NS_RELEASE(cmd); - - // Take the frame away; Note that we also have to take away any - // continuations so we loop here until deadFrame is nsnull. - while (nsnull != deadFrame) { - // Remove frame from sibling list - nsIFrame* nextSib; - deadFrame->GetNextSibling(nextSib); - if (nsnull != prevSibling) { - prevSibling->SetNextSibling(nextSib); - } - else { - flow->mFirstChild = nextSib; - } - - // Break frame out of its flow and then destroy it - nsIFrame* nextInFlow; - deadFrame->GetNextInFlow(nextInFlow); - deadFrame->BreakFromNextFlow(); - deadFrame->DeleteFrame(*aPresContext); - deadFrame = nextInFlow; - - if (nsnull != deadFrame) { - // Get the parent of deadFrame's continuation - deadFrame->GetGeometricParent((nsIFrame*&) flow); - - // When we move to a next-in-flow then the deadFrame will be the - // first child of the new parent. Therefore we know that - // prevSibling will be null. - prevSibling = nsnull; - } - } - - return rv; -} - nsPlaceholderFrame* nsHTMLContainerFrame::CreatePlaceholderFrame(nsIPresContext& aPresContext, nsIFrame* aFloatedFrame) diff --git a/layout/html/base/src/nsHTMLContainerFrame.h b/layout/html/base/src/nsHTMLContainerFrame.h index 5ee163d1dfe3..56c4564c13c7 100644 --- a/layout/html/base/src/nsHTMLContainerFrame.h +++ b/layout/html/base/src/nsHTMLContainerFrame.h @@ -41,12 +41,6 @@ public: nsIContent** aContent, PRInt32& aCursor); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); - NS_IMETHOD AttributeChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/html/base/src/nsInlineFrame.cpp b/layout/html/base/src/nsInlineFrame.cpp index 25cc288f53fb..af12e562636e 100644 --- a/layout/html/base/src/nsInlineFrame.cpp +++ b/layout/html/base/src/nsInlineFrame.cpp @@ -89,6 +89,9 @@ public: nsresult FrameAppendedReflow(nsInlineReflowState& aState, nsInlineReflow& aInlineReflow); + nsresult FrameDeletedReflow(nsInlineReflowState& aState, + nsInlineReflow& aInlineReflow); + nsresult ChildIncrementalReflow(nsInlineReflowState& aState, nsInlineReflow& aInlineReflow); @@ -369,7 +372,13 @@ nsInlineFrame::InlineReflow(nsLineLayout& aLineLayout, state.reflowCommand->GetChildFrame(newFrame); state.reflowCommand->GetPrevSiblingFrame(prevSibling); InsertNewFrame(newFrame, prevSibling); - // fall thru... + // XXX For now map into full reflow... + rv = ResizeReflow(state, inlineReflow); + break; + + case nsIReflowCommand::FrameDeleted: + rv = FrameDeletedReflow(state, inlineReflow); + break; default: // XXX For now map the other incremental operations into full reflows @@ -532,6 +541,62 @@ nsInlineFrame::FrameAppendedReflow(nsInlineReflowState& aState, return rs; } +nsInlineReflowStatus +nsInlineFrame::FrameDeletedReflow(nsInlineReflowState& aState, + nsInlineReflow& aInlineReflow) +{ + // Get the deleted frame + nsIFrame* deletedFrame; + aState.reflowCommand->GetChildFrame(deletedFrame); + + // Find the previous sibling frame + nsIFrame* prevSibling = nsnull; + for (nsIFrame* f = mFirstChild; f != deletedFrame; f->GetNextSibling(f)) { + if (nsnull == f) { + // We didn't find the deleted frame in our child list + NS_WARNING("Can't find deleted frame"); + return NS_OK; + } + + prevSibling = f; + } + + // Take the frame away; Note that we also have to take away any + // continuations so we loop here until deadFrame is nsnull. + nsInlineFrame* flow = this; + while (nsnull != deletedFrame) { + // Remove frame from sibling list + nsIFrame* nextSib; + deletedFrame->GetNextSibling(nextSib); + if (nsnull != prevSibling) { + prevSibling->SetNextSibling(nextSib); + } + else { + flow->mFirstChild = nextSib; + } + + // Break frame out of its flow and then destroy it + nsIFrame* nextInFlow; + deletedFrame->GetNextInFlow(nextInFlow); + deletedFrame->BreakFromNextFlow(); + deletedFrame->DeleteFrame(aState.mPresContext); + deletedFrame = nextInFlow; + + if (nsnull != deletedFrame) { + // Get the parent of deadFrame's continuation + deletedFrame->GetGeometricParent((nsIFrame*&) flow); + + // When we move to a next-in-flow then the deadFrame will be the + // first child of the new parent. Therefore we know that + // prevSibling will be null. + prevSibling = nsnull; + } + } + + // XXX For now map into full reflow... + return ResizeReflow(aState, aInlineReflow); +} + nsInlineReflowStatus nsInlineFrame::ChildIncrementalReflow(nsInlineReflowState& aState, nsInlineReflow& aInlineReflow) diff --git a/layout/html/base/src/nsPlaceholderFrame.cpp b/layout/html/base/src/nsPlaceholderFrame.cpp index 547ab1ba9c1f..d89c420aeec8 100644 --- a/layout/html/base/src/nsPlaceholderFrame.cpp +++ b/layout/html/base/src/nsPlaceholderFrame.cpp @@ -157,23 +157,6 @@ NS_IMETHODIMP nsPlaceholderFrame::ContentReplaced(nsIPresShell* aShell, return NS_OK; } -NS_IMETHODIMP nsPlaceholderFrame::ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent) -{ - NS_ASSERTION(mContent == aContainer, "bad content-deleted target"); - - // Forward the notification to the floater - if (nsnull != mAnchoredItem) { - return mAnchoredItem->ContentDeleted(aShell, aPresContext, aContainer, - aChild, aIndexInParent); - } - - return NS_OK; -} - NS_IMETHODIMP nsPlaceholderFrame::ContentChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/html/base/src/nsPlaceholderFrame.h b/layout/html/base/src/nsPlaceholderFrame.h index afe55cff38ff..4e44c6a75859 100644 --- a/layout/html/base/src/nsPlaceholderFrame.h +++ b/layout/html/base/src/nsPlaceholderFrame.h @@ -56,11 +56,6 @@ public: nsIContent* aOldChild, nsIContent* aNewChild, PRInt32 aIndexInParent); - NS_IMETHOD ContentDeleted(nsIPresShell* aShell, - nsIPresContext* aPresContext, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInParent); NS_IMETHOD ContentChanged(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aChild, diff --git a/layout/html/style/src/nsHTMLStyleSheet.cpp b/layout/html/style/src/nsHTMLStyleSheet.cpp index 2613d7ec625d..e3d116b87f3b 100644 --- a/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -252,6 +252,12 @@ public: nsIContent* aChild, PRInt32 aIndexInContainer); + NS_IMETHOD ContentRemoved(nsIPresContext* aPresContext, + nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer); + // XXX style rule enumerations virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; @@ -1565,6 +1571,42 @@ HTMLStyleSheetImpl::ContentInserted(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +HTMLStyleSheetImpl::ContentRemoved(nsIPresContext* aPresContext, + nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) +{ + nsIPresShell* shell = aPresContext->GetShell(); + nsresult rv = NS_OK; + + // Find the child frame + nsIFrame* childFrame = shell->FindFrameWithContent(aChild); + + if (nsnull != childFrame) { + // Get the parent frame. + // Note that we use the content parent, and not the geometric parent, + // in case the frame has been moved out of the flow... + nsIFrame* parentFrame; + childFrame->GetContentParent(parentFrame); + NS_ASSERTION(nsnull != parentFrame, "null content parent frame"); + + // Notify the parent frame with a reflow command. + nsIReflowCommand* reflowCmd; + rv = NS_NewHTMLReflowCommand(&reflowCmd, parentFrame, + nsIReflowCommand::FrameDeleted, childFrame); + + if (NS_SUCCEEDED(rv)) { + shell->AppendReflowCommand(reflowCmd); + NS_RELEASE(reflowCmd); + } + } + + NS_RELEASE(shell); + return rv; +} + void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const { nsAutoString buffer; diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 2613d7ec625d..e3d116b87f3b 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -252,6 +252,12 @@ public: nsIContent* aChild, PRInt32 aIndexInContainer); + NS_IMETHOD ContentRemoved(nsIPresContext* aPresContext, + nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer); + // XXX style rule enumerations virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; @@ -1565,6 +1571,42 @@ HTMLStyleSheetImpl::ContentInserted(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +HTMLStyleSheetImpl::ContentRemoved(nsIPresContext* aPresContext, + nsIDocument* aDocument, + nsIContent* aContainer, + nsIContent* aChild, + PRInt32 aIndexInContainer) +{ + nsIPresShell* shell = aPresContext->GetShell(); + nsresult rv = NS_OK; + + // Find the child frame + nsIFrame* childFrame = shell->FindFrameWithContent(aChild); + + if (nsnull != childFrame) { + // Get the parent frame. + // Note that we use the content parent, and not the geometric parent, + // in case the frame has been moved out of the flow... + nsIFrame* parentFrame; + childFrame->GetContentParent(parentFrame); + NS_ASSERTION(nsnull != parentFrame, "null content parent frame"); + + // Notify the parent frame with a reflow command. + nsIReflowCommand* reflowCmd; + rv = NS_NewHTMLReflowCommand(&reflowCmd, parentFrame, + nsIReflowCommand::FrameDeleted, childFrame); + + if (NS_SUCCEEDED(rv)) { + shell->AppendReflowCommand(reflowCmd); + NS_RELEASE(reflowCmd); + } + } + + NS_RELEASE(shell); + return rv; +} + void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const { nsAutoString buffer; diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 4bceb4f28e46..c96e86b6d647 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -788,12 +788,8 @@ NS_IMETHODIMP StyleSetImpl::ContentRemoved(nsIPresContext* aPresContext, nsIContent* aChild, PRInt32 aIndexInContainer) { -#if 0 return mFrameConstructor->ContentRemoved(aPresContext, aDocument, aContainer, aChild, aIndexInContainer); -#else - return NS_OK; -#endif } // xxx style rules enumeration