From 9e702bf0fa01c56fe39fa9f6b37a2662734e70c6 Mon Sep 17 00:00:00 2001 From: troy Date: Wed, 10 Jun 1998 05:33:38 +0000 Subject: [PATCH] Changed block to do the initial reflow of a floater. Also fixed a problem with floated tables crashing git-svn-id: svn://10.0.0.236/trunk@3591 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsBlockFrame.cpp | 38 +++++++++ mozilla/layout/generic/nsBlockFrame.h | 4 + mozilla/layout/generic/nsBlockReflowState.cpp | 38 +++++++++ mozilla/layout/generic/nsBlockReflowState.h | 38 +++++++++ mozilla/layout/generic/nsPlaceholderFrame.cpp | 78 +++++-------------- mozilla/layout/generic/nsPlaceholderFrame.h | 14 ++-- mozilla/layout/html/base/src/nsBlockFrame.cpp | 38 +++++++++ mozilla/layout/html/base/src/nsBlockFrame.h | 4 + .../html/base/src/nsBlockReflowState.cpp | 38 +++++++++ .../layout/html/base/src/nsBlockReflowState.h | 38 +++++++++ .../html/base/src/nsPlaceholderFrame.cpp | 78 +++++-------------- .../layout/html/base/src/nsPlaceholderFrame.h | 14 ++-- 12 files changed, 288 insertions(+), 132 deletions(-) diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index bd291ed7280..bf4fc11255c 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -1711,6 +1711,40 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState, //---------------------------------------------------------------------- +void nsBlockFrame::ReflowFloater(nsIPresContext* aPresContext, + nsBlockReflowState& aState, + nsIFrame* aFloaterFrame) +{ + // Compute the available space for the floater. Use the default + // 'auto' width and height values + nsSize kidAvailSize(0, NS_UNCONSTRAINEDSIZE); + nsSize styleSize; + PRIntn styleSizeFlags = nsCSSLayout::GetStyleSize(aPresContext, *aState.reflowState, + styleSize); + + // XXX The width and height are for the content area only. Add in space for + // border and padding + if (styleSizeFlags & NS_SIZE_HAS_WIDTH) { + kidAvailSize.width = styleSize.width; + } + if (styleSizeFlags & NS_SIZE_HAS_HEIGHT) { + kidAvailSize.height = styleSize.height; + } + + // Resize reflow the anchored item into the available space + // XXX Check for complete? + nsReflowMetrics desiredSize(nsnull); + nsReflowState reflowState(aFloaterFrame, *aState.reflowState, kidAvailSize, + eReflowReason_Initial); + nsReflowStatus status; + + aFloaterFrame->WillReflow(*aPresContext); + aFloaterFrame->Reflow(aPresContext, desiredSize, reflowState, status); + aFloaterFrame->SizeTo(desiredSize.width, desiredSize.height); + + aFloaterFrame->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); +} + PRBool nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIFrame* aFloater, @@ -1733,6 +1767,9 @@ nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIAnchoredItems::anHTMLFloater, this); + // Reflow the floater + ReflowFloater(aPresContext, *state, aFloater); + // Determine whether we place it at the top or we place it below the // current line if (IsLeftMostChild(aPlaceholder)) { @@ -1897,6 +1934,7 @@ nsBlockFrame::PlaceBelowCurrentLineFloaters(nsBlockReflowState& aState, // Pass on updated available space to the current line if (nsnull != aState.mCurrentLine) { nsLineLayout& lineLayout = *aState.mCurrentLine; + GetAvailableSpace(aState, aY); lineLayout.SetReflowSpace(aState.mCurrentBand.availSpace); } } diff --git a/mozilla/layout/generic/nsBlockFrame.h b/mozilla/layout/generic/nsBlockFrame.h index eaf3fbf3452..77b3e0ee8ff 100644 --- a/mozilla/layout/generic/nsBlockFrame.h +++ b/mozilla/layout/generic/nsBlockFrame.h @@ -293,6 +293,10 @@ protected: nsLineData* GetFirstLine(); + void ReflowFloater(nsIPresContext* aPresContext, + nsBlockReflowState& aState, + nsIFrame* aFloaterFrame); + void SetFirstChild(nsIFrame* aFirstChild) { if (nsnull == mFirstChild) { mFirstChild = aFirstChild; diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index bd291ed7280..bf4fc11255c 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -1711,6 +1711,40 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState, //---------------------------------------------------------------------- +void nsBlockFrame::ReflowFloater(nsIPresContext* aPresContext, + nsBlockReflowState& aState, + nsIFrame* aFloaterFrame) +{ + // Compute the available space for the floater. Use the default + // 'auto' width and height values + nsSize kidAvailSize(0, NS_UNCONSTRAINEDSIZE); + nsSize styleSize; + PRIntn styleSizeFlags = nsCSSLayout::GetStyleSize(aPresContext, *aState.reflowState, + styleSize); + + // XXX The width and height are for the content area only. Add in space for + // border and padding + if (styleSizeFlags & NS_SIZE_HAS_WIDTH) { + kidAvailSize.width = styleSize.width; + } + if (styleSizeFlags & NS_SIZE_HAS_HEIGHT) { + kidAvailSize.height = styleSize.height; + } + + // Resize reflow the anchored item into the available space + // XXX Check for complete? + nsReflowMetrics desiredSize(nsnull); + nsReflowState reflowState(aFloaterFrame, *aState.reflowState, kidAvailSize, + eReflowReason_Initial); + nsReflowStatus status; + + aFloaterFrame->WillReflow(*aPresContext); + aFloaterFrame->Reflow(aPresContext, desiredSize, reflowState, status); + aFloaterFrame->SizeTo(desiredSize.width, desiredSize.height); + + aFloaterFrame->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); +} + PRBool nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIFrame* aFloater, @@ -1733,6 +1767,9 @@ nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIAnchoredItems::anHTMLFloater, this); + // Reflow the floater + ReflowFloater(aPresContext, *state, aFloater); + // Determine whether we place it at the top or we place it below the // current line if (IsLeftMostChild(aPlaceholder)) { @@ -1897,6 +1934,7 @@ nsBlockFrame::PlaceBelowCurrentLineFloaters(nsBlockReflowState& aState, // Pass on updated available space to the current line if (nsnull != aState.mCurrentLine) { nsLineLayout& lineLayout = *aState.mCurrentLine; + GetAvailableSpace(aState, aY); lineLayout.SetReflowSpace(aState.mCurrentBand.availSpace); } } diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index bd291ed7280..bf4fc11255c 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -1711,6 +1711,40 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState, //---------------------------------------------------------------------- +void nsBlockFrame::ReflowFloater(nsIPresContext* aPresContext, + nsBlockReflowState& aState, + nsIFrame* aFloaterFrame) +{ + // Compute the available space for the floater. Use the default + // 'auto' width and height values + nsSize kidAvailSize(0, NS_UNCONSTRAINEDSIZE); + nsSize styleSize; + PRIntn styleSizeFlags = nsCSSLayout::GetStyleSize(aPresContext, *aState.reflowState, + styleSize); + + // XXX The width and height are for the content area only. Add in space for + // border and padding + if (styleSizeFlags & NS_SIZE_HAS_WIDTH) { + kidAvailSize.width = styleSize.width; + } + if (styleSizeFlags & NS_SIZE_HAS_HEIGHT) { + kidAvailSize.height = styleSize.height; + } + + // Resize reflow the anchored item into the available space + // XXX Check for complete? + nsReflowMetrics desiredSize(nsnull); + nsReflowState reflowState(aFloaterFrame, *aState.reflowState, kidAvailSize, + eReflowReason_Initial); + nsReflowStatus status; + + aFloaterFrame->WillReflow(*aPresContext); + aFloaterFrame->Reflow(aPresContext, desiredSize, reflowState, status); + aFloaterFrame->SizeTo(desiredSize.width, desiredSize.height); + + aFloaterFrame->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); +} + PRBool nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIFrame* aFloater, @@ -1733,6 +1767,9 @@ nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIAnchoredItems::anHTMLFloater, this); + // Reflow the floater + ReflowFloater(aPresContext, *state, aFloater); + // Determine whether we place it at the top or we place it below the // current line if (IsLeftMostChild(aPlaceholder)) { @@ -1897,6 +1934,7 @@ nsBlockFrame::PlaceBelowCurrentLineFloaters(nsBlockReflowState& aState, // Pass on updated available space to the current line if (nsnull != aState.mCurrentLine) { nsLineLayout& lineLayout = *aState.mCurrentLine; + GetAvailableSpace(aState, aY); lineLayout.SetReflowSpace(aState.mCurrentBand.availSpace); } } diff --git a/mozilla/layout/generic/nsPlaceholderFrame.cpp b/mozilla/layout/generic/nsPlaceholderFrame.cpp index e5741eef20a..5ce07ccbb92 100644 --- a/mozilla/layout/generic/nsPlaceholderFrame.cpp +++ b/mozilla/layout/generic/nsPlaceholderFrame.cpp @@ -44,7 +44,7 @@ nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult, } nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent) - : nsContainerFrame(aContent, aParent) + : nsFrame(aContent, aParent) { } @@ -52,24 +52,6 @@ nsPlaceholderFrame::~nsPlaceholderFrame() { } -NS_IMETHODIMP -nsPlaceholderFrame::DeleteFrame() -{ - // XXX This is sick, but because the frame that we wrap is *also* - // added to the body as a direct child, we must not delete the child - // twice. - mFirstChild = nsnull; - - return nsContainerFrame::DeleteFrame(); -} - -NS_IMETHODIMP -nsPlaceholderFrame::IsSplittable(nsSplittableType& aIsSplittable) const -{ - aIsSplittable = NS_FRAME_NOT_SPLITTABLE; - return NS_OK; -} - NS_IMETHODIMP nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, @@ -91,16 +73,21 @@ nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, NS_ASSERTION(nsnull != container, "no floater container"); // Have we created the anchored item yet? - if (nsnull == mFirstChild) { + if (nsnull == mAnchoredItem) { // If the content object is a container then wrap it in a body pseudo-frame // XXX begin hack + // XXX More hack. We don't want to blindly wrap a body pseudo-frame around + // a table content object, because the body pseudo-frame will map the table's + // content children rather than create a table frame and let it map the + // children... PRBool select = PR_FALSE; nsIAtom* atom = mContent->GetTag(); nsAutoString tmp; if (nsnull != atom) { atom->ToString(tmp); - if (tmp.EqualsIgnoreCase("select")) { + if (tmp.EqualsIgnoreCase("select") || + tmp.EqualsIgnoreCase("table")) { select = PR_TRUE; } NS_RELEASE(atom); @@ -108,51 +95,24 @@ nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, // XXX end hack if (mContent->CanContainChildren() && !select) { - nsBodyFrame::NewFrame(&mFirstChild, mContent, this); + nsBodyFrame::NewFrame(&mAnchoredItem, mContent, this); // Use our style context for the pseudo-frame - mFirstChild->SetStyleContext(aPresContext, mStyleContext); + mAnchoredItem->SetStyleContext(aPresContext, mStyleContext); } else { // Create the anchored item nsIContentDelegate* delegate = mContent->GetDelegate(aPresContext); nsresult rv = delegate->CreateFrame(aPresContext, mContent, mGeometricParent, mStyleContext, - mFirstChild); + mAnchoredItem); NS_RELEASE(delegate); if (NS_OK != rv) { return rv; } } - mChildCount = 1; - // Compute the available space for the floater. Use the default - // 'auto' width and height values - nsSize kidAvailSize(0, NS_UNCONSTRAINEDSIZE); - nsSize styleSize; - PRIntn styleSizeFlags = nsCSSLayout::GetStyleSize(aPresContext, aReflowState, - styleSize); - - // XXX The width and height are for the content area only. Add in space for - // border and padding - if (styleSizeFlags & NS_SIZE_HAS_WIDTH) { - kidAvailSize.width = styleSize.width; - } - if (styleSizeFlags & NS_SIZE_HAS_HEIGHT) { - kidAvailSize.height = styleSize.height; - } - - // Resize reflow the anchored item into the available space - // XXX Check for complete? - nsReflowMetrics desiredSize(nsnull); - nsReflowState reflowState(mFirstChild, aReflowState, kidAvailSize, - eReflowReason_Initial); - mFirstChild->WillReflow(*aPresContext); - mFirstChild->Reflow(aPresContext, desiredSize, reflowState, aStatus); - mFirstChild->SizeTo(desiredSize.width, desiredSize.height); - - // Now notify our containing block that there's a new floater - container->AddFloater(aPresContext, mFirstChild, this); - mFirstChild->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); + // Notify our containing block that there's a new floater + container->AddFloater(aPresContext, mAnchoredItem, this); } else { // XXX This causes anchored-items sizes to get fixed up; this is @@ -160,13 +120,13 @@ nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, // of the incremental reflow methods and propagating things down // properly to the contained frame. nsReflowMetrics desiredSize(nsnull); - nsReflowState reflowState(mFirstChild, aReflowState, aReflowState.maxSize, + nsReflowState reflowState(mAnchoredItem, aReflowState, aReflowState.maxSize, eReflowReason_Resize); - mFirstChild->WillReflow(*aPresContext); - mFirstChild->Reflow(aPresContext, desiredSize, reflowState, aStatus); - mFirstChild->SizeTo(desiredSize.width, desiredSize.height); - container->PlaceFloater(aPresContext, mFirstChild, this); - mFirstChild->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); + mAnchoredItem->WillReflow(*aPresContext); + mAnchoredItem->Reflow(aPresContext, desiredSize, reflowState, aStatus); + mAnchoredItem->SizeTo(desiredSize.width, desiredSize.height); + container->PlaceFloater(aPresContext, mAnchoredItem, this); + mAnchoredItem->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); } return nsFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); diff --git a/mozilla/layout/generic/nsPlaceholderFrame.h b/mozilla/layout/generic/nsPlaceholderFrame.h index 62a3376cd19..d2e15f797ac 100644 --- a/mozilla/layout/generic/nsPlaceholderFrame.h +++ b/mozilla/layout/generic/nsPlaceholderFrame.h @@ -18,10 +18,10 @@ #ifndef nsPlaceholderFrame_h___ #define nsPlaceholderFrame_h___ -#include "nsContainerFrame.h" +#include "nsFrame.h" // Implementation of a frame that's used as a placeholder for an anchored item -class nsPlaceholderFrame : public nsContainerFrame { +class nsPlaceholderFrame : public nsFrame { public: /** * Create a new placeholder frame @@ -31,11 +31,9 @@ public: nsIFrame* aParent); // Returns the associated anchored item - nsIFrame* GetAnchoredItem() const { return mFirstChild; } + nsIFrame* GetAnchoredItem() const {return mAnchoredItem;} // nsIFrame overrides - NS_IMETHOD DeleteFrame(); - NS_IMETHOD IsSplittable(nsSplittableType& aIsSplittable) const; NS_IMETHOD Reflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, const nsReflowState& aReflowState, @@ -43,8 +41,10 @@ public: NS_IMETHOD ListTag(FILE* out = stdout) const; protected: - // Constructor. Takes as arguments the content object, the index in parent, - // and the Frame for the content parent + nsIFrame* mAnchoredItem; + + // Constructor. Takes as arguments the content object and the Frame for + // the content parent nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent); virtual ~nsPlaceholderFrame(); }; diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index bd291ed7280..bf4fc11255c 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -1711,6 +1711,40 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState, //---------------------------------------------------------------------- +void nsBlockFrame::ReflowFloater(nsIPresContext* aPresContext, + nsBlockReflowState& aState, + nsIFrame* aFloaterFrame) +{ + // Compute the available space for the floater. Use the default + // 'auto' width and height values + nsSize kidAvailSize(0, NS_UNCONSTRAINEDSIZE); + nsSize styleSize; + PRIntn styleSizeFlags = nsCSSLayout::GetStyleSize(aPresContext, *aState.reflowState, + styleSize); + + // XXX The width and height are for the content area only. Add in space for + // border and padding + if (styleSizeFlags & NS_SIZE_HAS_WIDTH) { + kidAvailSize.width = styleSize.width; + } + if (styleSizeFlags & NS_SIZE_HAS_HEIGHT) { + kidAvailSize.height = styleSize.height; + } + + // Resize reflow the anchored item into the available space + // XXX Check for complete? + nsReflowMetrics desiredSize(nsnull); + nsReflowState reflowState(aFloaterFrame, *aState.reflowState, kidAvailSize, + eReflowReason_Initial); + nsReflowStatus status; + + aFloaterFrame->WillReflow(*aPresContext); + aFloaterFrame->Reflow(aPresContext, desiredSize, reflowState, status); + aFloaterFrame->SizeTo(desiredSize.width, desiredSize.height); + + aFloaterFrame->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); +} + PRBool nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIFrame* aFloater, @@ -1733,6 +1767,9 @@ nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIAnchoredItems::anHTMLFloater, this); + // Reflow the floater + ReflowFloater(aPresContext, *state, aFloater); + // Determine whether we place it at the top or we place it below the // current line if (IsLeftMostChild(aPlaceholder)) { @@ -1897,6 +1934,7 @@ nsBlockFrame::PlaceBelowCurrentLineFloaters(nsBlockReflowState& aState, // Pass on updated available space to the current line if (nsnull != aState.mCurrentLine) { nsLineLayout& lineLayout = *aState.mCurrentLine; + GetAvailableSpace(aState, aY); lineLayout.SetReflowSpace(aState.mCurrentBand.availSpace); } } diff --git a/mozilla/layout/html/base/src/nsBlockFrame.h b/mozilla/layout/html/base/src/nsBlockFrame.h index eaf3fbf3452..77b3e0ee8ff 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.h +++ b/mozilla/layout/html/base/src/nsBlockFrame.h @@ -293,6 +293,10 @@ protected: nsLineData* GetFirstLine(); + void ReflowFloater(nsIPresContext* aPresContext, + nsBlockReflowState& aState, + nsIFrame* aFloaterFrame); + void SetFirstChild(nsIFrame* aFirstChild) { if (nsnull == mFirstChild) { mFirstChild = aFirstChild; diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index bd291ed7280..bf4fc11255c 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -1711,6 +1711,40 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState, //---------------------------------------------------------------------- +void nsBlockFrame::ReflowFloater(nsIPresContext* aPresContext, + nsBlockReflowState& aState, + nsIFrame* aFloaterFrame) +{ + // Compute the available space for the floater. Use the default + // 'auto' width and height values + nsSize kidAvailSize(0, NS_UNCONSTRAINEDSIZE); + nsSize styleSize; + PRIntn styleSizeFlags = nsCSSLayout::GetStyleSize(aPresContext, *aState.reflowState, + styleSize); + + // XXX The width and height are for the content area only. Add in space for + // border and padding + if (styleSizeFlags & NS_SIZE_HAS_WIDTH) { + kidAvailSize.width = styleSize.width; + } + if (styleSizeFlags & NS_SIZE_HAS_HEIGHT) { + kidAvailSize.height = styleSize.height; + } + + // Resize reflow the anchored item into the available space + // XXX Check for complete? + nsReflowMetrics desiredSize(nsnull); + nsReflowState reflowState(aFloaterFrame, *aState.reflowState, kidAvailSize, + eReflowReason_Initial); + nsReflowStatus status; + + aFloaterFrame->WillReflow(*aPresContext); + aFloaterFrame->Reflow(aPresContext, desiredSize, reflowState, status); + aFloaterFrame->SizeTo(desiredSize.width, desiredSize.height); + + aFloaterFrame->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); +} + PRBool nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIFrame* aFloater, @@ -1733,6 +1767,9 @@ nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIAnchoredItems::anHTMLFloater, this); + // Reflow the floater + ReflowFloater(aPresContext, *state, aFloater); + // Determine whether we place it at the top or we place it below the // current line if (IsLeftMostChild(aPlaceholder)) { @@ -1897,6 +1934,7 @@ nsBlockFrame::PlaceBelowCurrentLineFloaters(nsBlockReflowState& aState, // Pass on updated available space to the current line if (nsnull != aState.mCurrentLine) { nsLineLayout& lineLayout = *aState.mCurrentLine; + GetAvailableSpace(aState, aY); lineLayout.SetReflowSpace(aState.mCurrentBand.availSpace); } } diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.h b/mozilla/layout/html/base/src/nsBlockReflowState.h index bd291ed7280..bf4fc11255c 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.h +++ b/mozilla/layout/html/base/src/nsBlockReflowState.h @@ -1711,6 +1711,40 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState, //---------------------------------------------------------------------- +void nsBlockFrame::ReflowFloater(nsIPresContext* aPresContext, + nsBlockReflowState& aState, + nsIFrame* aFloaterFrame) +{ + // Compute the available space for the floater. Use the default + // 'auto' width and height values + nsSize kidAvailSize(0, NS_UNCONSTRAINEDSIZE); + nsSize styleSize; + PRIntn styleSizeFlags = nsCSSLayout::GetStyleSize(aPresContext, *aState.reflowState, + styleSize); + + // XXX The width and height are for the content area only. Add in space for + // border and padding + if (styleSizeFlags & NS_SIZE_HAS_WIDTH) { + kidAvailSize.width = styleSize.width; + } + if (styleSizeFlags & NS_SIZE_HAS_HEIGHT) { + kidAvailSize.height = styleSize.height; + } + + // Resize reflow the anchored item into the available space + // XXX Check for complete? + nsReflowMetrics desiredSize(nsnull); + nsReflowState reflowState(aFloaterFrame, *aState.reflowState, kidAvailSize, + eReflowReason_Initial); + nsReflowStatus status; + + aFloaterFrame->WillReflow(*aPresContext); + aFloaterFrame->Reflow(aPresContext, desiredSize, reflowState, status); + aFloaterFrame->SizeTo(desiredSize.width, desiredSize.height); + + aFloaterFrame->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); +} + PRBool nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIFrame* aFloater, @@ -1733,6 +1767,9 @@ nsBlockFrame::AddFloater(nsIPresContext* aPresContext, nsIAnchoredItems::anHTMLFloater, this); + // Reflow the floater + ReflowFloater(aPresContext, *state, aFloater); + // Determine whether we place it at the top or we place it below the // current line if (IsLeftMostChild(aPlaceholder)) { @@ -1897,6 +1934,7 @@ nsBlockFrame::PlaceBelowCurrentLineFloaters(nsBlockReflowState& aState, // Pass on updated available space to the current line if (nsnull != aState.mCurrentLine) { nsLineLayout& lineLayout = *aState.mCurrentLine; + GetAvailableSpace(aState, aY); lineLayout.SetReflowSpace(aState.mCurrentBand.availSpace); } } diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp index e5741eef20a..5ce07ccbb92 100644 --- a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp +++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp @@ -44,7 +44,7 @@ nsPlaceholderFrame::NewFrame(nsIFrame** aInstancePtrResult, } nsPlaceholderFrame::nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent) - : nsContainerFrame(aContent, aParent) + : nsFrame(aContent, aParent) { } @@ -52,24 +52,6 @@ nsPlaceholderFrame::~nsPlaceholderFrame() { } -NS_IMETHODIMP -nsPlaceholderFrame::DeleteFrame() -{ - // XXX This is sick, but because the frame that we wrap is *also* - // added to the body as a direct child, we must not delete the child - // twice. - mFirstChild = nsnull; - - return nsContainerFrame::DeleteFrame(); -} - -NS_IMETHODIMP -nsPlaceholderFrame::IsSplittable(nsSplittableType& aIsSplittable) const -{ - aIsSplittable = NS_FRAME_NOT_SPLITTABLE; - return NS_OK; -} - NS_IMETHODIMP nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, @@ -91,16 +73,21 @@ nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, NS_ASSERTION(nsnull != container, "no floater container"); // Have we created the anchored item yet? - if (nsnull == mFirstChild) { + if (nsnull == mAnchoredItem) { // If the content object is a container then wrap it in a body pseudo-frame // XXX begin hack + // XXX More hack. We don't want to blindly wrap a body pseudo-frame around + // a table content object, because the body pseudo-frame will map the table's + // content children rather than create a table frame and let it map the + // children... PRBool select = PR_FALSE; nsIAtom* atom = mContent->GetTag(); nsAutoString tmp; if (nsnull != atom) { atom->ToString(tmp); - if (tmp.EqualsIgnoreCase("select")) { + if (tmp.EqualsIgnoreCase("select") || + tmp.EqualsIgnoreCase("table")) { select = PR_TRUE; } NS_RELEASE(atom); @@ -108,51 +95,24 @@ nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, // XXX end hack if (mContent->CanContainChildren() && !select) { - nsBodyFrame::NewFrame(&mFirstChild, mContent, this); + nsBodyFrame::NewFrame(&mAnchoredItem, mContent, this); // Use our style context for the pseudo-frame - mFirstChild->SetStyleContext(aPresContext, mStyleContext); + mAnchoredItem->SetStyleContext(aPresContext, mStyleContext); } else { // Create the anchored item nsIContentDelegate* delegate = mContent->GetDelegate(aPresContext); nsresult rv = delegate->CreateFrame(aPresContext, mContent, mGeometricParent, mStyleContext, - mFirstChild); + mAnchoredItem); NS_RELEASE(delegate); if (NS_OK != rv) { return rv; } } - mChildCount = 1; - // Compute the available space for the floater. Use the default - // 'auto' width and height values - nsSize kidAvailSize(0, NS_UNCONSTRAINEDSIZE); - nsSize styleSize; - PRIntn styleSizeFlags = nsCSSLayout::GetStyleSize(aPresContext, aReflowState, - styleSize); - - // XXX The width and height are for the content area only. Add in space for - // border and padding - if (styleSizeFlags & NS_SIZE_HAS_WIDTH) { - kidAvailSize.width = styleSize.width; - } - if (styleSizeFlags & NS_SIZE_HAS_HEIGHT) { - kidAvailSize.height = styleSize.height; - } - - // Resize reflow the anchored item into the available space - // XXX Check for complete? - nsReflowMetrics desiredSize(nsnull); - nsReflowState reflowState(mFirstChild, aReflowState, kidAvailSize, - eReflowReason_Initial); - mFirstChild->WillReflow(*aPresContext); - mFirstChild->Reflow(aPresContext, desiredSize, reflowState, aStatus); - mFirstChild->SizeTo(desiredSize.width, desiredSize.height); - - // Now notify our containing block that there's a new floater - container->AddFloater(aPresContext, mFirstChild, this); - mFirstChild->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); + // Notify our containing block that there's a new floater + container->AddFloater(aPresContext, mAnchoredItem, this); } else { // XXX This causes anchored-items sizes to get fixed up; this is @@ -160,13 +120,13 @@ nsPlaceholderFrame::Reflow(nsIPresContext* aPresContext, // of the incremental reflow methods and propagating things down // properly to the contained frame. nsReflowMetrics desiredSize(nsnull); - nsReflowState reflowState(mFirstChild, aReflowState, aReflowState.maxSize, + nsReflowState reflowState(mAnchoredItem, aReflowState, aReflowState.maxSize, eReflowReason_Resize); - mFirstChild->WillReflow(*aPresContext); - mFirstChild->Reflow(aPresContext, desiredSize, reflowState, aStatus); - mFirstChild->SizeTo(desiredSize.width, desiredSize.height); - container->PlaceFloater(aPresContext, mFirstChild, this); - mFirstChild->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); + mAnchoredItem->WillReflow(*aPresContext); + mAnchoredItem->Reflow(aPresContext, desiredSize, reflowState, aStatus); + mAnchoredItem->SizeTo(desiredSize.width, desiredSize.height); + container->PlaceFloater(aPresContext, mAnchoredItem, this); + mAnchoredItem->DidReflow(*aPresContext, NS_FRAME_REFLOW_FINISHED); } return nsFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.h b/mozilla/layout/html/base/src/nsPlaceholderFrame.h index 62a3376cd19..d2e15f797ac 100644 --- a/mozilla/layout/html/base/src/nsPlaceholderFrame.h +++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.h @@ -18,10 +18,10 @@ #ifndef nsPlaceholderFrame_h___ #define nsPlaceholderFrame_h___ -#include "nsContainerFrame.h" +#include "nsFrame.h" // Implementation of a frame that's used as a placeholder for an anchored item -class nsPlaceholderFrame : public nsContainerFrame { +class nsPlaceholderFrame : public nsFrame { public: /** * Create a new placeholder frame @@ -31,11 +31,9 @@ public: nsIFrame* aParent); // Returns the associated anchored item - nsIFrame* GetAnchoredItem() const { return mFirstChild; } + nsIFrame* GetAnchoredItem() const {return mAnchoredItem;} // nsIFrame overrides - NS_IMETHOD DeleteFrame(); - NS_IMETHOD IsSplittable(nsSplittableType& aIsSplittable) const; NS_IMETHOD Reflow(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, const nsReflowState& aReflowState, @@ -43,8 +41,10 @@ public: NS_IMETHOD ListTag(FILE* out = stdout) const; protected: - // Constructor. Takes as arguments the content object, the index in parent, - // and the Frame for the content parent + nsIFrame* mAnchoredItem; + + // Constructor. Takes as arguments the content object and the Frame for + // the content parent nsPlaceholderFrame(nsIContent* aContent, nsIFrame* aParent); virtual ~nsPlaceholderFrame(); };