From c6e290213d653b304903c2a86b389f220369a6c6 Mon Sep 17 00:00:00 2001 From: troy Date: Tue, 5 May 1998 04:47:53 +0000 Subject: [PATCH] Work in progress for inserted incremental reflow git-svn-id: svn://10.0.0.236/trunk@1124 18797224-902f-48f8-a5cc-f745e15eee43 --- .../layout/generic/nsHTMLContainerFrame.cpp | 103 ++++++++++++++++++ mozilla/layout/generic/nsHTMLContainerFrame.h | 4 + mozilla/layout/generic/nsPlaceholderFrame.cpp | 9 ++ mozilla/layout/generic/nsPlaceholderFrame.h | 2 + .../layout/html/base/src/nsAbsoluteFrame.cpp | 12 +- .../layout/html/base/src/nsAbsoluteFrame.h | 2 + mozilla/layout/html/base/src/nsBodyFrame.cpp | 10 +- .../html/base/src/nsHTMLContainerFrame.cpp | 103 ++++++++++++++++++ .../html/base/src/nsHTMLContainerFrame.h | 4 + .../html/base/src/nsPlaceholderFrame.cpp | 9 ++ .../layout/html/base/src/nsPlaceholderFrame.h | 2 + 11 files changed, 253 insertions(+), 7 deletions(-) diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.cpp b/mozilla/layout/generic/nsHTMLContainerFrame.cpp index bf2877f5c30..e000ca9ea7a 100644 --- a/mozilla/layout/generic/nsHTMLContainerFrame.cpp +++ b/mozilla/layout/generic/nsHTMLContainerFrame.cpp @@ -31,9 +31,17 @@ #include "nsIDocument.h" #include "nsIURL.h" #include "nsReflowCommand.h" +#include "nsIPtr.h" +#include "nsAbsoluteFrame.h" +#include "nsPlaceholderFrame.h" +#include "nsIContentDelegate.h" static NS_DEFINE_IID(kStyleBorderSID, NS_STYLEBORDER_SID); static NS_DEFINE_IID(kStyleColorSID, NS_STYLECOLOR_SID); +static NS_DEFINE_IID(kStylePositionSID, NS_STYLEPOSITION_SID); +static NS_DEFINE_IID(kStyleDisplaySID, NS_STYLEDISPLAY_SID); + +NS_DEF_PTR(nsIStyleContext); nsHTMLContainerFrame::nsHTMLContainerFrame(nsIContent* aContent, PRInt32 aIndexInParent, @@ -235,6 +243,38 @@ static void AdjustIndexInParents(nsIFrame* aContainerFrame, } } +nsIFrame* nsHTMLContainerFrame::CreateFrameFor(nsIPresContext* aPresContext, + nsIContent* aContent, + PRInt32 aIndexInParent) +{ + // Get the style content for the frame + nsIStyleContextPtr styleContext = aPresContext->ResolveStyleContextFor(aContent, this); + nsStylePosition* position = (nsStylePosition*)styleContext->GetData(kStylePositionSID); + nsStyleDisplay* display = (nsStyleDisplay*)styleContext->GetData(kStyleDisplaySID); + nsIFrame* result; + + // See whether it wants any special handling + if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) { + AbsoluteFrame::NewFrame(&result, aContent, aIndexInParent, this); + } else if (display->mFloats != NS_STYLE_FLOAT_NONE) { + PlaceholderFrame::NewFrame(&result, aContent, aIndexInParent, this); + } else if (NS_STYLE_DISPLAY_NONE == display->mDisplay) { + nsFrame::NewFrame(&result, aContent, aIndexInParent, this); + } else { + nsIContentDelegate* delegate; + + // Ask the content delegate to create the frame + // XXX The delegate will also resolve the style context... + delegate = aContent->GetDelegate(aPresContext); + result = delegate->CreateFrame(aPresContext, aContent, aIndexInParent, this); + NS_RELEASE(delegate); + } + + // Set the frame's style context + result->SetStyleContext(aPresContext, styleContext); + return result; +} + NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aContainer, @@ -263,6 +303,69 @@ NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell, frame->GetNextInFlow((nsIFrame*&)frame); } + // Find the frame that precedes this frame + nsIFrame* prevSibling = nsnull; + + if (aIndexInParent > 0) { + nsIContent* precedingContent = aContainer->ChildAt(aIndexInParent - 1); + 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 geometric parent. We expect it to be this frame or one of its + // next-in-flow(s). It could be a pseudo-frame, but then it better also be + // a nsHTMLContainerFrame... + nsHTMLContainerFrame* parent = this; + + if (nsnull != prevSibling) { + prevSibling->GetGeometricParent((nsIFrame*&)parent); + } + + // Create the new frame + nsIFrame* newFrame = parent->CreateFrameFor(aPresContext, aChild, aIndexInParent); + + // Insert the frame + if (nsnull == prevSibling) { + // If there's no preceding frame, then this is the first content child + NS_ASSERTION(0 == aIndexInParent, "unexpected index-in-parent"); + NS_ASSERTION(0 == parent->mFirstContentOffset, "unexpected first content offset"); + newFrame->SetNextSibling(parent->mFirstChild); + parent->mFirstChild = newFrame; + + } else { + nsIFrame* nextSibling; + + // Link the new frame into + prevSibling->GetNextSibling(nextSibling); + newFrame->SetNextSibling(nextSibling); + prevSibling->SetNextSibling(newFrame); + + if (nsnull == nextSibling) { + // The new frame is the last child frame + parent->SetLastContentOffset(newFrame); + + if (parent->IsPseudoFrame()) { + parent->PropagateContentOffsets(); + } + } + } + parent->mChildCount++; + + // Generate a reflow command + nsReflowCommand* cmd = new nsReflowCommand(aPresContext, parent, + nsReflowCommand::FrameAppended, + newFrame); + aShell->AppendReflowCommand(cmd); + return NS_OK; } diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.h b/mozilla/layout/generic/nsHTMLContainerFrame.h index 627803cd997..c126f8711f7 100644 --- a/mozilla/layout/generic/nsHTMLContainerFrame.h +++ b/mozilla/layout/generic/nsHTMLContainerFrame.h @@ -61,6 +61,10 @@ protected: const nsString& aBase, const nsString& aURLSpec, const nsString& aTargetSpec); + + nsIFrame* CreateFrameFor(nsIPresContext* aPresContext, + nsIContent* aContent, + PRInt32 aIndexInParent); }; #endif /* nsHTMLContainerFrame_h___ */ diff --git a/mozilla/layout/generic/nsPlaceholderFrame.cpp b/mozilla/layout/generic/nsPlaceholderFrame.cpp index bd545e2068a..8a056b9c8c5 100644 --- a/mozilla/layout/generic/nsPlaceholderFrame.cpp +++ b/mozilla/layout/generic/nsPlaceholderFrame.cpp @@ -52,6 +52,15 @@ PlaceholderFrame::~PlaceholderFrame() { } +NS_METHOD PlaceholderFrame::SetIndexInParent(PRInt32 aIndexInParent) +{ + if (nsnull != mAnchoredItem) { + mAnchoredItem->SetIndexInParent(aIndexInParent); + } + + return nsFrame::SetIndexInParent(aIndexInParent); +} + NS_METHOD PlaceholderFrame::ResizeReflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, const nsSize& aMaxSize, diff --git a/mozilla/layout/generic/nsPlaceholderFrame.h b/mozilla/layout/generic/nsPlaceholderFrame.h index 6cae7e1c546..9f4d5a68a51 100644 --- a/mozilla/layout/generic/nsPlaceholderFrame.h +++ b/mozilla/layout/generic/nsPlaceholderFrame.h @@ -35,6 +35,8 @@ public: // Returns the associated anchored item nsIFrame* GetAnchoredItem() const {return mAnchoredItem;} + NS_IMETHOD SetIndexInParent(PRInt32 aIndexInParent); + // Resize reflow methods NS_IMETHOD ResizeReflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, diff --git a/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp b/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp index b9db91ad097..fbb9d22fc14 100644 --- a/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp +++ b/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp @@ -63,6 +63,15 @@ AbsoluteFrame::~AbsoluteFrame() { } +NS_METHOD AbsoluteFrame::SetIndexInParent(PRInt32 aIndexInParent) +{ + if (nsnull != mFrame) { + mFrame->SetIndexInParent(aIndexInParent); + } + + return nsFrame::SetIndexInParent(aIndexInParent); +} + nsIView* AbsoluteFrame::CreateView(nsIView* aContainingView, const nsRect& aRect, nsStylePosition* aPosition) @@ -101,8 +110,7 @@ nsIView* AbsoluteFrame::CreateView(nsIView* aContainingView, if (aPosition->mZIndex.GetUnit() == eStyleUnit_Integer) { zIndex = aPosition->mZIndex.GetIntValue(); } else if (aPosition->mZIndex.GetUnit() == eStyleUnit_Auto) { - // XXX need to handle z-index "auto" - NS_NOTYETIMPLEMENTED("zIndex: auto"); + zIndex = 0; } else if (aPosition->mZIndex.GetUnit() == eStyleUnit_Inherit) { // XXX need to handle z-index "inherit" NS_NOTYETIMPLEMENTED("zIndex: inherit"); diff --git a/mozilla/layout/html/base/src/nsAbsoluteFrame.h b/mozilla/layout/html/base/src/nsAbsoluteFrame.h index 7046de8b6b3..2f410a11ce5 100644 --- a/mozilla/layout/html/base/src/nsAbsoluteFrame.h +++ b/mozilla/layout/html/base/src/nsAbsoluteFrame.h @@ -33,6 +33,8 @@ public: PRInt32 aIndexInParent, nsIFrame* aParent); + NS_IMETHOD SetIndexInParent(PRInt32 aIndexInParent); + // Resize reflow methods NS_IMETHOD ResizeReflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, diff --git a/mozilla/layout/html/base/src/nsBodyFrame.cpp b/mozilla/layout/html/base/src/nsBodyFrame.cpp index 1051b08b8ef..a5ea8976987 100644 --- a/mozilla/layout/html/base/src/nsBodyFrame.cpp +++ b/mozilla/layout/html/base/src/nsBodyFrame.cpp @@ -200,8 +200,7 @@ NS_METHOD nsBodyFrame::ResizeReflow(nsIPresContext* aPresContext, aDesiredSize.height = PR_MAX(desiredRect.YMost(), mSpaceManager->YMost()); if (isPseudoFrame) { aDesiredSize.width = desiredRect.XMost(); - } - else { + } else { aDesiredSize.width = aMaxSize.width; aDesiredSize.height += mySpacing->mBorderPadding.top + mySpacing->mBorderPadding.bottom; @@ -275,7 +274,9 @@ NS_METHOD nsBodyFrame::IncrementalReflow(nsIPresContext* aPresContext, // XXX Clear the list of regions. This fixes a problem with the way reflow // appended is currently working (we're reflowing some framems twice) - mSpaceManager->ClearRegions(); + if (nsReflowCommand::FrameAppended == aReflowCommand.GetType()) { + mSpaceManager->ClearRegions(); + } mSpaceManager->Translate(leftInset, topInset); // The reflow command should never be target for us @@ -307,8 +308,7 @@ NS_METHOD nsBodyFrame::IncrementalReflow(nsIPresContext* aPresContext, aDesiredSize.height = PR_MAX(aDesiredRect.YMost(), mSpaceManager->YMost()); if (isPseudoFrame) { aDesiredSize.width = aDesiredRect.XMost(); - } - else { + } else { aDesiredSize.width = aMaxSize.width; aDesiredSize.height += mySpacing->mBorderPadding.top + mySpacing->mBorderPadding.bottom; diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp index bf2877f5c30..e000ca9ea7a 100644 --- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp +++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp @@ -31,9 +31,17 @@ #include "nsIDocument.h" #include "nsIURL.h" #include "nsReflowCommand.h" +#include "nsIPtr.h" +#include "nsAbsoluteFrame.h" +#include "nsPlaceholderFrame.h" +#include "nsIContentDelegate.h" static NS_DEFINE_IID(kStyleBorderSID, NS_STYLEBORDER_SID); static NS_DEFINE_IID(kStyleColorSID, NS_STYLECOLOR_SID); +static NS_DEFINE_IID(kStylePositionSID, NS_STYLEPOSITION_SID); +static NS_DEFINE_IID(kStyleDisplaySID, NS_STYLEDISPLAY_SID); + +NS_DEF_PTR(nsIStyleContext); nsHTMLContainerFrame::nsHTMLContainerFrame(nsIContent* aContent, PRInt32 aIndexInParent, @@ -235,6 +243,38 @@ static void AdjustIndexInParents(nsIFrame* aContainerFrame, } } +nsIFrame* nsHTMLContainerFrame::CreateFrameFor(nsIPresContext* aPresContext, + nsIContent* aContent, + PRInt32 aIndexInParent) +{ + // Get the style content for the frame + nsIStyleContextPtr styleContext = aPresContext->ResolveStyleContextFor(aContent, this); + nsStylePosition* position = (nsStylePosition*)styleContext->GetData(kStylePositionSID); + nsStyleDisplay* display = (nsStyleDisplay*)styleContext->GetData(kStyleDisplaySID); + nsIFrame* result; + + // See whether it wants any special handling + if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) { + AbsoluteFrame::NewFrame(&result, aContent, aIndexInParent, this); + } else if (display->mFloats != NS_STYLE_FLOAT_NONE) { + PlaceholderFrame::NewFrame(&result, aContent, aIndexInParent, this); + } else if (NS_STYLE_DISPLAY_NONE == display->mDisplay) { + nsFrame::NewFrame(&result, aContent, aIndexInParent, this); + } else { + nsIContentDelegate* delegate; + + // Ask the content delegate to create the frame + // XXX The delegate will also resolve the style context... + delegate = aContent->GetDelegate(aPresContext); + result = delegate->CreateFrame(aPresContext, aContent, aIndexInParent, this); + NS_RELEASE(delegate); + } + + // Set the frame's style context + result->SetStyleContext(aPresContext, styleContext); + return result; +} + NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell, nsIPresContext* aPresContext, nsIContent* aContainer, @@ -263,6 +303,69 @@ NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell, frame->GetNextInFlow((nsIFrame*&)frame); } + // Find the frame that precedes this frame + nsIFrame* prevSibling = nsnull; + + if (aIndexInParent > 0) { + nsIContent* precedingContent = aContainer->ChildAt(aIndexInParent - 1); + 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 geometric parent. We expect it to be this frame or one of its + // next-in-flow(s). It could be a pseudo-frame, but then it better also be + // a nsHTMLContainerFrame... + nsHTMLContainerFrame* parent = this; + + if (nsnull != prevSibling) { + prevSibling->GetGeometricParent((nsIFrame*&)parent); + } + + // Create the new frame + nsIFrame* newFrame = parent->CreateFrameFor(aPresContext, aChild, aIndexInParent); + + // Insert the frame + if (nsnull == prevSibling) { + // If there's no preceding frame, then this is the first content child + NS_ASSERTION(0 == aIndexInParent, "unexpected index-in-parent"); + NS_ASSERTION(0 == parent->mFirstContentOffset, "unexpected first content offset"); + newFrame->SetNextSibling(parent->mFirstChild); + parent->mFirstChild = newFrame; + + } else { + nsIFrame* nextSibling; + + // Link the new frame into + prevSibling->GetNextSibling(nextSibling); + newFrame->SetNextSibling(nextSibling); + prevSibling->SetNextSibling(newFrame); + + if (nsnull == nextSibling) { + // The new frame is the last child frame + parent->SetLastContentOffset(newFrame); + + if (parent->IsPseudoFrame()) { + parent->PropagateContentOffsets(); + } + } + } + parent->mChildCount++; + + // Generate a reflow command + nsReflowCommand* cmd = new nsReflowCommand(aPresContext, parent, + nsReflowCommand::FrameAppended, + newFrame); + aShell->AppendReflowCommand(cmd); + return NS_OK; } diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h index 627803cd997..c126f8711f7 100644 --- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h +++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h @@ -61,6 +61,10 @@ protected: const nsString& aBase, const nsString& aURLSpec, const nsString& aTargetSpec); + + nsIFrame* CreateFrameFor(nsIPresContext* aPresContext, + nsIContent* aContent, + PRInt32 aIndexInParent); }; #endif /* nsHTMLContainerFrame_h___ */ diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp index bd545e2068a..8a056b9c8c5 100644 --- a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp +++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp @@ -52,6 +52,15 @@ PlaceholderFrame::~PlaceholderFrame() { } +NS_METHOD PlaceholderFrame::SetIndexInParent(PRInt32 aIndexInParent) +{ + if (nsnull != mAnchoredItem) { + mAnchoredItem->SetIndexInParent(aIndexInParent); + } + + return nsFrame::SetIndexInParent(aIndexInParent); +} + NS_METHOD PlaceholderFrame::ResizeReflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, const nsSize& aMaxSize, diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.h b/mozilla/layout/html/base/src/nsPlaceholderFrame.h index 6cae7e1c546..9f4d5a68a51 100644 --- a/mozilla/layout/html/base/src/nsPlaceholderFrame.h +++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.h @@ -35,6 +35,8 @@ public: // Returns the associated anchored item nsIFrame* GetAnchoredItem() const {return mAnchoredItem;} + NS_IMETHOD SetIndexInParent(PRInt32 aIndexInParent); + // Resize reflow methods NS_IMETHOD ResizeReflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize,