зеркало из https://github.com/mozilla/gecko-dev.git
Moved ContentDeleted() document notification code to the style system which
generates the reflow command
This commit is contained in:
Родитель
ad7714484d
Коммит
50795d8516
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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___ */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче