diff --git a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp index fe4d5eda0e1..40a52f42689 100644 --- a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp @@ -23,18 +23,16 @@ #include "nsIStyleContext.h" #include "nsIViewManager.h" #include "nsLayoutAtoms.h" +#include "nsIReflowCommand.h" +#include "nsIPresShell.h" +#include "nsHTMLParts.h" static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID); -void -nsAbsoluteContainingBlock::DestroyFrames(nsIPresContext& aPresContext) -{ - mAbsoluteFrames.DestroyFrames(aPresContext); -} - nsresult -nsAbsoluteContainingBlock::FirstChild(nsIAtom* aListName, - nsIFrame** aFirstChild) const +nsAbsoluteContainingBlock::FirstChild(const nsIFrame* aDelegatingFrame, + nsIAtom* aListName, + nsIFrame** aFirstChild) const { NS_PRECONDITION(nsLayoutAtoms::absoluteList == aListName, "unexpected child list name"); *aFirstChild = mAbsoluteFrames.FirstChild(); @@ -42,17 +40,92 @@ nsAbsoluteContainingBlock::FirstChild(nsIAtom* aListName, } nsresult -nsAbsoluteContainingBlock::SetInitialChildList(nsIPresContext& aPresContext, +nsAbsoluteContainingBlock::SetInitialChildList(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, nsIAtom* aListName, nsIFrame* aChildList) { NS_PRECONDITION(nsLayoutAtoms::absoluteList == aListName, "unexpected child list name"); +#ifdef NS_DEBUG + nsFrame::VerifyDirtyBitSet(aChildList); +#endif mAbsoluteFrames.SetFrames(aChildList); return NS_OK; } nsresult -nsAbsoluteContainingBlock::Reflow(nsIPresContext& aPresContext, +nsAbsoluteContainingBlock::AppendFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList) +{ + nsresult rv = NS_OK; + + // Append the frames to our list of absolutely positioned frames +#ifdef NS_DEBUG + nsFrame::VerifyDirtyBitSet(aFrameList); +#endif + mAbsoluteFrames.AppendFrames(nsnull, aFrameList); + + // Generate a reflow command to reflow the dirty frames + nsIReflowCommand* reflowCmd; + rv = NS_NewHTMLReflowCommand(&reflowCmd, aDelegatingFrame, nsIReflowCommand::ReflowDirty); + if (NS_SUCCEEDED(rv)) { + reflowCmd->SetChildListName(nsLayoutAtoms::absoluteList); + aPresShell.AppendReflowCommand(reflowCmd); + NS_RELEASE(reflowCmd); + } + + return rv; +} + +nsresult +nsAbsoluteContainingBlock::InsertFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList) +{ + nsresult rv = NS_OK; + + // Insert the new frames +#ifdef NS_DEBUG + nsFrame::VerifyDirtyBitSet(aFrameList); +#endif + mAbsoluteFrames.InsertFrames(nsnull, aPrevFrame, aFrameList); + + // Generate a reflow command to reflow the dirty frames + nsIReflowCommand* reflowCmd; + rv = NS_NewHTMLReflowCommand(&reflowCmd, aDelegatingFrame, nsIReflowCommand::ReflowDirty); + if (NS_SUCCEEDED(rv)) { + reflowCmd->SetChildListName(nsLayoutAtoms::absoluteList); + aPresShell.AppendReflowCommand(reflowCmd); + NS_RELEASE(reflowCmd); + } + + return rv; +} + +nsresult +nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame) +{ + PRBool result = mAbsoluteFrames.DestroyFrame(aPresContext, aOldFrame); + NS_ASSERTION(result, "didn't find frame to delete"); + // Because positioned frames aren't part of a flow, there's no additional + // work to do, e.g. reflowing sibling frames. And because positioned frames + // have a view, we don't need to repaint + return NS_OK; +} + +nsresult +nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState) { // Make a copy of the reflow state. If the reason is eReflowReason_Incremental, @@ -66,14 +139,15 @@ nsAbsoluteContainingBlock::Reflow(nsIPresContext& aPresContext, for (kidFrame = mAbsoluteFrames.FirstChild(); nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) { // Reflow the frame nsReflowStatus kidStatus; - ReflowAbsoluteFrame(aPresContext, reflowState, kidFrame, PR_FALSE, - kidStatus); + ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, reflowState, kidFrame, + PR_FALSE, kidStatus); } return NS_OK; } nsresult -nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresContext, +nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, PRBool& aWasHandled) { @@ -88,7 +162,7 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresConte nsIAtom* listName; PRBool isAbsoluteChild; - // It's targeted at us. See if the child frame is absolutely positioned + // It's targeted at us. See if it's for the positioned child frames aReflowState.reflowCommand->GetChildListName(listName); isAbsoluteChild = nsLayoutAtoms::absoluteList == listName; NS_IF_RELEASE(listName); @@ -101,47 +175,19 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresConte // Get the type of reflow command aReflowState.reflowCommand->GetType(type); - // Handle each specific type - if (nsIReflowCommand::FrameAppended == type) { - // Add the frames to our list of absolutely position frames - aReflowState.reflowCommand->GetChildFrame(newFrames); - NS_ASSERTION(nsnull != newFrames, "null child list"); - numFrames = nsContainerFrame::LengthOf(newFrames); - mAbsoluteFrames.AppendFrames(nsnull, newFrames); + // The only type of reflow command we expect is that we have dirty + // child frames to reflow + NS_ASSERTION(nsIReflowCommand::ReflowDirty, "unexpected reflow type"); - } else if (nsIReflowCommand::FrameRemoved == type) { - // Get the new frame - nsIFrame* childFrame; - aReflowState.reflowCommand->GetChildFrame(childFrame); + // Walk the positioned frames and reflow the dirty frames + for (nsIFrame* f = mAbsoluteFrames.FirstChild(); f; f->GetNextSibling(&f)) { + nsFrameState frameState; - PRBool result = mAbsoluteFrames.DestroyFrame(aPresContext, childFrame); - NS_ASSERTION(result, "didn't find frame to delete"); - - } else if (nsIReflowCommand::FrameInserted == type) { - // Get the previous sibling - nsIFrame* prevSibling; - aReflowState.reflowCommand->GetPrevSiblingFrame(prevSibling); - - // Insert the new frames - aReflowState.reflowCommand->GetChildFrame(newFrames); - NS_ASSERTION(nsnull != newFrames, "null child list"); - numFrames = nsContainerFrame::LengthOf(newFrames); - mAbsoluteFrames.InsertFrames(nsnull, prevSibling, newFrames); - - } else { - NS_ASSERTION(PR_FALSE, "unexpected reflow type"); - } - - // For inserted and appended reflow commands we need to reflow the - // newly added frames - if ((nsIReflowCommand::FrameAppended == type) || - (nsIReflowCommand::FrameInserted == type)) { - - while (numFrames-- > 0) { + f->GetFrameState(&frameState); + if (frameState & NS_FRAME_IS_DIRTY) { nsReflowStatus status; - - ReflowAbsoluteFrame(aPresContext, aReflowState, newFrames, PR_TRUE, status); - newFrames->GetNextSibling(&newFrames); + ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowState, + newFrames, PR_TRUE, status); } } @@ -161,19 +207,12 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresConte aReflowState.reflowCommand->GetNext(nextFrame, PR_TRUE); nsReflowStatus kidStatus; - ReflowAbsoluteFrame(aPresContext, aReflowState, nextFrame, PR_FALSE, kidStatus); - // XXX Make sure the frame is repainted. For the time being, since we - // have no idea what actually changed repaint it all... - nsIView* view; - nextFrame->GetView(&view); - if (nsnull != view) { - nsIViewManager* viewMgr; - view->GetViewManager(viewMgr); - if (nsnull != viewMgr) { - viewMgr->UpdateView(view, (nsIRegion*)nsnull, NS_VMREFRESH_NO_SYNC); - NS_RELEASE(viewMgr); - } - } + ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowState, + nextFrame, PR_FALSE, kidStatus); + // We don't need to invalidate anything because the frame should + // invalidate any area within its frame that needs repainting, and + // because it has a view if it changes size the view manager will + // damage the dirty area aWasHandled = PR_TRUE; } } @@ -181,11 +220,19 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresConte return NS_OK; } +void +nsAbsoluteContainingBlock::DestroyFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext) +{ + mAbsoluteFrames.DestroyFrames(aPresContext); +} + // XXX Optimize the case where it's a resize reflow and the absolutely // positioned child has the exact same size and position and skip the // reflow... nsresult -nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIPresContext& aPresContext, +nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsIFrame* aKidFrame, PRBool aInitialReflow, @@ -299,7 +346,9 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIPresContext& aPresCon } nsresult -nsAbsoluteContainingBlock::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const +nsAbsoluteContainingBlock::GetPositionedInfo(const nsIFrame* aDelegatingFrame, + nscoord& aXMost, + nscoord& aYMost) const { aXMost = aYMost = 0; for (nsIFrame* f = mAbsoluteFrames.FirstChild(); nsnull != f; f->GetNextSibling(&f)) { diff --git a/mozilla/layout/generic/nsAbsoluteContainingBlock.h b/mozilla/layout/generic/nsAbsoluteContainingBlock.h index 9167b97c36b..5839d46022a 100644 --- a/mozilla/layout/generic/nsAbsoluteContainingBlock.h +++ b/mozilla/layout/generic/nsAbsoluteContainingBlock.h @@ -27,43 +27,71 @@ class nsIFrame; class nsIPresContext; /** - * This class contains the logic for being an absolutely containing block. + * This class contains the logic for being an absolute containing block. * * There is no principal child list, just a named child list which contains * the absolutely positioned frames * + * All functions include as the first argument the frame that is delegating + * the request + * * @see nsLayoutAtoms::absoluteList */ class nsAbsoluteContainingBlock { public: - nsresult FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const; + nsresult FirstChild(const nsIFrame* aDelegatingFrame, + nsIAtom* aListName, + nsIFrame** aFirstChild) const; - nsresult SetInitialChildList(nsIPresContext& aPresContext, + nsresult SetInitialChildList(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, nsIAtom* aListName, nsIFrame* aChildList); + nsresult AppendFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList); + nsresult InsertFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList); + nsresult RemoveFrame(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame); // Called by the delegating frame after it has done its reflow first. This // function will reflow any absolutely positioned child frames that need to // be reflowed, e.g., because the absolutely positioned child frame has // 'auto' for an offset, or a percentage based width or height - nsresult Reflow(nsIPresContext& aPresContext, + nsresult Reflow(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState); // Called only for a reflow reason of eReflowReason_Incremental. The // aWasHandled return value indicates whether the reflow command was // handled (i.e., the reflow command involved an absolutely positioned // child element), or whether the caller should handle it - nsresult IncrementalReflow(nsIPresContext& aPresContext, + nsresult IncrementalReflow(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, PRBool& aWasHandled); - void DestroyFrames(nsIPresContext& aPresContext); + void DestroyFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext); - nsresult GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const; + nsresult GetPositionedInfo(const nsIFrame* aDelegatingFrame, + nscoord& aXMost, + nscoord& aYMost) const; protected: - nsresult ReflowAbsoluteFrame(nsIPresContext& aPresContext, + nsresult ReflowAbsoluteFrame(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsIFrame* aKidFrame, PRBool aInitialReflow, diff --git a/mozilla/layout/generic/nsAreaFrame.cpp b/mozilla/layout/generic/nsAreaFrame.cpp index 5694d6964e6..f2a9b269433 100644 --- a/mozilla/layout/generic/nsAreaFrame.cpp +++ b/mozilla/layout/generic/nsAreaFrame.cpp @@ -106,7 +106,7 @@ nsAreaFrame::Init(nsIPresContext& aPresContext, NS_IMETHODIMP nsAreaFrame::Destroy(nsIPresContext& aPresContext) { - mAbsoluteContainer.DestroyFrames(aPresContext); + mAbsoluteContainer.DestroyFrames(this, aPresContext); return nsBlockFrame::Destroy(aPresContext); } @@ -118,7 +118,7 @@ nsAreaFrame::SetInitialChildList(nsIPresContext& aPresContext, nsresult rv; if (nsLayoutAtoms::absoluteList == aListName) { - rv = mAbsoluteContainer.SetInitialChildList(aPresContext, aListName, aChildList); + rv = mAbsoluteContainer.SetInitialChildList(this, aPresContext, aListName, aChildList); } else { rv = nsBlockFrame::SetInitialChildList(aPresContext, aListName, aChildList); } @@ -126,6 +126,62 @@ nsAreaFrame::SetInitialChildList(nsIPresContext& aPresContext, return rv; } +NS_IMETHODIMP +nsAreaFrame::AppendFrames(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList) +{ + nsresult rv; + + if (nsLayoutAtoms::absoluteList == aListName) { + rv = mAbsoluteContainer.AppendFrames(this, aPresContext, aPresShell, aListName, + aFrameList); + } else { + rv = nsBlockFrame::AppendFrames(aPresContext, aPresShell, aListName, + aFrameList); + } + + return rv; +} + +NS_IMETHODIMP +nsAreaFrame::InsertFrames(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList) +{ + nsresult rv; + + if (nsLayoutAtoms::absoluteList == aListName) { + rv = mAbsoluteContainer.InsertFrames(this, aPresContext, aPresShell, aListName, + aPrevFrame, aFrameList); + } else { + rv = nsBlockFrame::InsertFrames(aPresContext, aPresShell, aListName, + aPrevFrame, aFrameList); + } + + return rv; +} + +NS_IMETHODIMP +nsAreaFrame::RemoveFrame(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame) +{ + nsresult rv; + + if (nsLayoutAtoms::absoluteList == aListName) { + rv = mAbsoluteContainer.RemoveFrame(this, aPresContext, aPresShell, aListName, aOldFrame); + } else { + rv = nsBlockFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame); + } + + return rv; +} + NS_IMETHODIMP nsAreaFrame::GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const @@ -148,7 +204,7 @@ nsAreaFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const { NS_PRECONDITION(nsnull != aFirstChild, "null OUT parameter pointer"); if (aListName == nsLayoutAtoms::absoluteList) { - return mAbsoluteContainer.FirstChild(aListName, aFirstChild); + return mAbsoluteContainer.FirstChild(this, aListName, aFirstChild); } return nsBlockFrame::FirstChild(aListName, aFirstChild); @@ -217,7 +273,7 @@ nsAreaFrame::Paint(nsIPresContext& aPresContext, NS_IMETHODIMP nsAreaFrame::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const { - nsresult rv = mAbsoluteContainer.GetPositionedInfo(aXMost, aYMost); + nsresult rv = mAbsoluteContainer.GetPositionedInfo(this, aXMost, aYMost); // If we have child frames that stick outside of our box, and they should // be visible, then include them too so the total size is correct @@ -257,7 +313,7 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext, // Give the absolute positioning code a chance to handle it PRBool handled; - mAbsoluteContainer.IncrementalReflow(aPresContext, aReflowState, handled); + mAbsoluteContainer.IncrementalReflow(this, aPresContext, aReflowState, handled); // If the incremental reflow command was handled by the absolute positioning // code, then we're all done @@ -276,7 +332,7 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext, // If we have a space manager, then set it in the reflow state if (nsnull != mSpaceManager) { - // Modify the reflow state and set the space manager + // Modify the existing reflow state nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState; reflowState.mSpaceManager = mSpaceManager; @@ -288,9 +344,10 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext, rv = nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); // Let the absolutely positioned container reflow any absolutely positioned - // child frames that need to be reflowed + // child frames that need to be reflowed, e.g., elements with a percentage + // based width/height if (NS_SUCCEEDED(rv)) { - rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState); + rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState); } if (mFlags & NS_AREA_WRAP_SIZE) { diff --git a/mozilla/layout/generic/nsAreaFrame.h b/mozilla/layout/generic/nsAreaFrame.h index bd9da173054..e7de9b6b787 100644 --- a/mozilla/layout/generic/nsAreaFrame.h +++ b/mozilla/layout/generic/nsAreaFrame.h @@ -61,6 +61,19 @@ public: NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext, nsIAtom* aListName, nsIFrame* aChildList); + NS_IMETHOD AppendFrames(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList); + NS_IMETHOD InsertFrames(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList); + NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame); NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const; diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index a294a6e04cf..d97336737cd 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -3843,11 +3843,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame is updated - return nsFrame::AppendFrames(aPresContext, aPresShell, aListName, - aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -3907,11 +3902,6 @@ nsBlockFrame::InsertFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame and floater code is updated - return nsFrame::InsertFrames(aPresContext, aPresShell, aListName, - aPrevFrame, aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -4270,11 +4260,6 @@ nsBlockFrame::RemoveFrame(nsIPresContext& aPresContext, // We will reflow *after* removing the placeholder (which is done 2nd) return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame code is updated - return nsFrame::RemoveFrame(aPresContext, aPresShell, aListName, - aOldFrame); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index a294a6e04cf..d97336737cd 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -3843,11 +3843,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame is updated - return nsFrame::AppendFrames(aPresContext, aPresShell, aListName, - aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -3907,11 +3902,6 @@ nsBlockFrame::InsertFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame and floater code is updated - return nsFrame::InsertFrames(aPresContext, aPresShell, aListName, - aPrevFrame, aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -4270,11 +4260,6 @@ nsBlockFrame::RemoveFrame(nsIPresContext& aPresContext, // We will reflow *after* removing the placeholder (which is done 2nd) return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame code is updated - return nsFrame::RemoveFrame(aPresContext, aPresShell, aListName, - aOldFrame); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index a294a6e04cf..d97336737cd 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -3843,11 +3843,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame is updated - return nsFrame::AppendFrames(aPresContext, aPresShell, aListName, - aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -3907,11 +3902,6 @@ nsBlockFrame::InsertFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame and floater code is updated - return nsFrame::InsertFrames(aPresContext, aPresShell, aListName, - aPrevFrame, aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -4270,11 +4260,6 @@ nsBlockFrame::RemoveFrame(nsIPresContext& aPresContext, // We will reflow *after* removing the placeholder (which is done 2nd) return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame code is updated - return nsFrame::RemoveFrame(aPresContext, aPresShell, aListName, - aOldFrame); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } diff --git a/mozilla/layout/generic/nsInlineFrame.cpp b/mozilla/layout/generic/nsInlineFrame.cpp index ec770ec5732..a9b51ed4a90 100644 --- a/mozilla/layout/generic/nsInlineFrame.cpp +++ b/mozilla/layout/generic/nsInlineFrame.cpp @@ -67,7 +67,7 @@ NS_NewPositionedInlineFrame(nsIFrame** aNewFrame) NS_IMETHODIMP nsPositionedInlineFrame::Destroy(nsIPresContext& aPresContext) { - mAbsoluteContainer.DestroyFrames(aPresContext); + mAbsoluteContainer.DestroyFrames(this, aPresContext); return nsInlineFrame::Destroy(aPresContext); } @@ -79,7 +79,7 @@ nsPositionedInlineFrame::SetInitialChildList(nsIPresContext& aPresContext, nsresult rv; if (nsLayoutAtoms::absoluteList == aListName) { - rv = mAbsoluteContainer.SetInitialChildList(aPresContext, aListName, aChildList); + rv = mAbsoluteContainer.SetInitialChildList(this, aPresContext, aListName, aChildList); } else { rv = nsInlineFrame::SetInitialChildList(aPresContext, aListName, aChildList); } @@ -151,7 +151,7 @@ nsPositionedInlineFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) { NS_PRECONDITION(nsnull != aFirstChild, "null OUT parameter pointer"); if (aListName == nsLayoutAtoms::absoluteList) { - return mAbsoluteContainer.FirstChild(aListName, aFirstChild); + return mAbsoluteContainer.FirstChild(this, aListName, aFirstChild); } return nsInlineFrame::FirstChild(aListName, aFirstChild); @@ -179,7 +179,7 @@ nsPositionedInlineFrame::Reflow(nsIPresContext& aPresContext, // Give the absolute positioning code a chance to handle it PRBool handled; - mAbsoluteContainer.IncrementalReflow(aPresContext, aReflowState, handled); + mAbsoluteContainer.IncrementalReflow(this, aPresContext, aReflowState, handled); // If the incremental reflow command was handled by the absolute positioning // code, then we're all done @@ -200,7 +200,7 @@ nsPositionedInlineFrame::Reflow(nsIPresContext& aPresContext, // Let the absolutely positioned container reflow any absolutely positioned // child frames that need to be reflowed if (NS_SUCCEEDED(rv)) { - rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState); + rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState); } return rv; diff --git a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp index fe4d5eda0e1..40a52f42689 100644 --- a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp +++ b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp @@ -23,18 +23,16 @@ #include "nsIStyleContext.h" #include "nsIViewManager.h" #include "nsLayoutAtoms.h" +#include "nsIReflowCommand.h" +#include "nsIPresShell.h" +#include "nsHTMLParts.h" static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID); -void -nsAbsoluteContainingBlock::DestroyFrames(nsIPresContext& aPresContext) -{ - mAbsoluteFrames.DestroyFrames(aPresContext); -} - nsresult -nsAbsoluteContainingBlock::FirstChild(nsIAtom* aListName, - nsIFrame** aFirstChild) const +nsAbsoluteContainingBlock::FirstChild(const nsIFrame* aDelegatingFrame, + nsIAtom* aListName, + nsIFrame** aFirstChild) const { NS_PRECONDITION(nsLayoutAtoms::absoluteList == aListName, "unexpected child list name"); *aFirstChild = mAbsoluteFrames.FirstChild(); @@ -42,17 +40,92 @@ nsAbsoluteContainingBlock::FirstChild(nsIAtom* aListName, } nsresult -nsAbsoluteContainingBlock::SetInitialChildList(nsIPresContext& aPresContext, +nsAbsoluteContainingBlock::SetInitialChildList(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, nsIAtom* aListName, nsIFrame* aChildList) { NS_PRECONDITION(nsLayoutAtoms::absoluteList == aListName, "unexpected child list name"); +#ifdef NS_DEBUG + nsFrame::VerifyDirtyBitSet(aChildList); +#endif mAbsoluteFrames.SetFrames(aChildList); return NS_OK; } nsresult -nsAbsoluteContainingBlock::Reflow(nsIPresContext& aPresContext, +nsAbsoluteContainingBlock::AppendFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList) +{ + nsresult rv = NS_OK; + + // Append the frames to our list of absolutely positioned frames +#ifdef NS_DEBUG + nsFrame::VerifyDirtyBitSet(aFrameList); +#endif + mAbsoluteFrames.AppendFrames(nsnull, aFrameList); + + // Generate a reflow command to reflow the dirty frames + nsIReflowCommand* reflowCmd; + rv = NS_NewHTMLReflowCommand(&reflowCmd, aDelegatingFrame, nsIReflowCommand::ReflowDirty); + if (NS_SUCCEEDED(rv)) { + reflowCmd->SetChildListName(nsLayoutAtoms::absoluteList); + aPresShell.AppendReflowCommand(reflowCmd); + NS_RELEASE(reflowCmd); + } + + return rv; +} + +nsresult +nsAbsoluteContainingBlock::InsertFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList) +{ + nsresult rv = NS_OK; + + // Insert the new frames +#ifdef NS_DEBUG + nsFrame::VerifyDirtyBitSet(aFrameList); +#endif + mAbsoluteFrames.InsertFrames(nsnull, aPrevFrame, aFrameList); + + // Generate a reflow command to reflow the dirty frames + nsIReflowCommand* reflowCmd; + rv = NS_NewHTMLReflowCommand(&reflowCmd, aDelegatingFrame, nsIReflowCommand::ReflowDirty); + if (NS_SUCCEEDED(rv)) { + reflowCmd->SetChildListName(nsLayoutAtoms::absoluteList); + aPresShell.AppendReflowCommand(reflowCmd); + NS_RELEASE(reflowCmd); + } + + return rv; +} + +nsresult +nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame) +{ + PRBool result = mAbsoluteFrames.DestroyFrame(aPresContext, aOldFrame); + NS_ASSERTION(result, "didn't find frame to delete"); + // Because positioned frames aren't part of a flow, there's no additional + // work to do, e.g. reflowing sibling frames. And because positioned frames + // have a view, we don't need to repaint + return NS_OK; +} + +nsresult +nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState) { // Make a copy of the reflow state. If the reason is eReflowReason_Incremental, @@ -66,14 +139,15 @@ nsAbsoluteContainingBlock::Reflow(nsIPresContext& aPresContext, for (kidFrame = mAbsoluteFrames.FirstChild(); nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame)) { // Reflow the frame nsReflowStatus kidStatus; - ReflowAbsoluteFrame(aPresContext, reflowState, kidFrame, PR_FALSE, - kidStatus); + ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, reflowState, kidFrame, + PR_FALSE, kidStatus); } return NS_OK; } nsresult -nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresContext, +nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, PRBool& aWasHandled) { @@ -88,7 +162,7 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresConte nsIAtom* listName; PRBool isAbsoluteChild; - // It's targeted at us. See if the child frame is absolutely positioned + // It's targeted at us. See if it's for the positioned child frames aReflowState.reflowCommand->GetChildListName(listName); isAbsoluteChild = nsLayoutAtoms::absoluteList == listName; NS_IF_RELEASE(listName); @@ -101,47 +175,19 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresConte // Get the type of reflow command aReflowState.reflowCommand->GetType(type); - // Handle each specific type - if (nsIReflowCommand::FrameAppended == type) { - // Add the frames to our list of absolutely position frames - aReflowState.reflowCommand->GetChildFrame(newFrames); - NS_ASSERTION(nsnull != newFrames, "null child list"); - numFrames = nsContainerFrame::LengthOf(newFrames); - mAbsoluteFrames.AppendFrames(nsnull, newFrames); + // The only type of reflow command we expect is that we have dirty + // child frames to reflow + NS_ASSERTION(nsIReflowCommand::ReflowDirty, "unexpected reflow type"); - } else if (nsIReflowCommand::FrameRemoved == type) { - // Get the new frame - nsIFrame* childFrame; - aReflowState.reflowCommand->GetChildFrame(childFrame); + // Walk the positioned frames and reflow the dirty frames + for (nsIFrame* f = mAbsoluteFrames.FirstChild(); f; f->GetNextSibling(&f)) { + nsFrameState frameState; - PRBool result = mAbsoluteFrames.DestroyFrame(aPresContext, childFrame); - NS_ASSERTION(result, "didn't find frame to delete"); - - } else if (nsIReflowCommand::FrameInserted == type) { - // Get the previous sibling - nsIFrame* prevSibling; - aReflowState.reflowCommand->GetPrevSiblingFrame(prevSibling); - - // Insert the new frames - aReflowState.reflowCommand->GetChildFrame(newFrames); - NS_ASSERTION(nsnull != newFrames, "null child list"); - numFrames = nsContainerFrame::LengthOf(newFrames); - mAbsoluteFrames.InsertFrames(nsnull, prevSibling, newFrames); - - } else { - NS_ASSERTION(PR_FALSE, "unexpected reflow type"); - } - - // For inserted and appended reflow commands we need to reflow the - // newly added frames - if ((nsIReflowCommand::FrameAppended == type) || - (nsIReflowCommand::FrameInserted == type)) { - - while (numFrames-- > 0) { + f->GetFrameState(&frameState); + if (frameState & NS_FRAME_IS_DIRTY) { nsReflowStatus status; - - ReflowAbsoluteFrame(aPresContext, aReflowState, newFrames, PR_TRUE, status); - newFrames->GetNextSibling(&newFrames); + ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowState, + newFrames, PR_TRUE, status); } } @@ -161,19 +207,12 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresConte aReflowState.reflowCommand->GetNext(nextFrame, PR_TRUE); nsReflowStatus kidStatus; - ReflowAbsoluteFrame(aPresContext, aReflowState, nextFrame, PR_FALSE, kidStatus); - // XXX Make sure the frame is repainted. For the time being, since we - // have no idea what actually changed repaint it all... - nsIView* view; - nextFrame->GetView(&view); - if (nsnull != view) { - nsIViewManager* viewMgr; - view->GetViewManager(viewMgr); - if (nsnull != viewMgr) { - viewMgr->UpdateView(view, (nsIRegion*)nsnull, NS_VMREFRESH_NO_SYNC); - NS_RELEASE(viewMgr); - } - } + ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowState, + nextFrame, PR_FALSE, kidStatus); + // We don't need to invalidate anything because the frame should + // invalidate any area within its frame that needs repainting, and + // because it has a view if it changes size the view manager will + // damage the dirty area aWasHandled = PR_TRUE; } } @@ -181,11 +220,19 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIPresContext& aPresConte return NS_OK; } +void +nsAbsoluteContainingBlock::DestroyFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext) +{ + mAbsoluteFrames.DestroyFrames(aPresContext); +} + // XXX Optimize the case where it's a resize reflow and the absolutely // positioned child has the exact same size and position and skip the // reflow... nsresult -nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIPresContext& aPresContext, +nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsIFrame* aKidFrame, PRBool aInitialReflow, @@ -299,7 +346,9 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIPresContext& aPresCon } nsresult -nsAbsoluteContainingBlock::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const +nsAbsoluteContainingBlock::GetPositionedInfo(const nsIFrame* aDelegatingFrame, + nscoord& aXMost, + nscoord& aYMost) const { aXMost = aYMost = 0; for (nsIFrame* f = mAbsoluteFrames.FirstChild(); nsnull != f; f->GetNextSibling(&f)) { diff --git a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.h b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.h index 9167b97c36b..5839d46022a 100644 --- a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.h +++ b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.h @@ -27,43 +27,71 @@ class nsIFrame; class nsIPresContext; /** - * This class contains the logic for being an absolutely containing block. + * This class contains the logic for being an absolute containing block. * * There is no principal child list, just a named child list which contains * the absolutely positioned frames * + * All functions include as the first argument the frame that is delegating + * the request + * * @see nsLayoutAtoms::absoluteList */ class nsAbsoluteContainingBlock { public: - nsresult FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const; + nsresult FirstChild(const nsIFrame* aDelegatingFrame, + nsIAtom* aListName, + nsIFrame** aFirstChild) const; - nsresult SetInitialChildList(nsIPresContext& aPresContext, + nsresult SetInitialChildList(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, nsIAtom* aListName, nsIFrame* aChildList); + nsresult AppendFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList); + nsresult InsertFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList); + nsresult RemoveFrame(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame); // Called by the delegating frame after it has done its reflow first. This // function will reflow any absolutely positioned child frames that need to // be reflowed, e.g., because the absolutely positioned child frame has // 'auto' for an offset, or a percentage based width or height - nsresult Reflow(nsIPresContext& aPresContext, + nsresult Reflow(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState); // Called only for a reflow reason of eReflowReason_Incremental. The // aWasHandled return value indicates whether the reflow command was // handled (i.e., the reflow command involved an absolutely positioned // child element), or whether the caller should handle it - nsresult IncrementalReflow(nsIPresContext& aPresContext, + nsresult IncrementalReflow(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, PRBool& aWasHandled); - void DestroyFrames(nsIPresContext& aPresContext); + void DestroyFrames(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext); - nsresult GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const; + nsresult GetPositionedInfo(const nsIFrame* aDelegatingFrame, + nscoord& aXMost, + nscoord& aYMost) const; protected: - nsresult ReflowAbsoluteFrame(nsIPresContext& aPresContext, + nsresult ReflowAbsoluteFrame(nsIFrame* aDelegatingFrame, + nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsIFrame* aKidFrame, PRBool aInitialReflow, diff --git a/mozilla/layout/html/base/src/nsAreaFrame.cpp b/mozilla/layout/html/base/src/nsAreaFrame.cpp index 5694d6964e6..f2a9b269433 100644 --- a/mozilla/layout/html/base/src/nsAreaFrame.cpp +++ b/mozilla/layout/html/base/src/nsAreaFrame.cpp @@ -106,7 +106,7 @@ nsAreaFrame::Init(nsIPresContext& aPresContext, NS_IMETHODIMP nsAreaFrame::Destroy(nsIPresContext& aPresContext) { - mAbsoluteContainer.DestroyFrames(aPresContext); + mAbsoluteContainer.DestroyFrames(this, aPresContext); return nsBlockFrame::Destroy(aPresContext); } @@ -118,7 +118,7 @@ nsAreaFrame::SetInitialChildList(nsIPresContext& aPresContext, nsresult rv; if (nsLayoutAtoms::absoluteList == aListName) { - rv = mAbsoluteContainer.SetInitialChildList(aPresContext, aListName, aChildList); + rv = mAbsoluteContainer.SetInitialChildList(this, aPresContext, aListName, aChildList); } else { rv = nsBlockFrame::SetInitialChildList(aPresContext, aListName, aChildList); } @@ -126,6 +126,62 @@ nsAreaFrame::SetInitialChildList(nsIPresContext& aPresContext, return rv; } +NS_IMETHODIMP +nsAreaFrame::AppendFrames(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList) +{ + nsresult rv; + + if (nsLayoutAtoms::absoluteList == aListName) { + rv = mAbsoluteContainer.AppendFrames(this, aPresContext, aPresShell, aListName, + aFrameList); + } else { + rv = nsBlockFrame::AppendFrames(aPresContext, aPresShell, aListName, + aFrameList); + } + + return rv; +} + +NS_IMETHODIMP +nsAreaFrame::InsertFrames(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList) +{ + nsresult rv; + + if (nsLayoutAtoms::absoluteList == aListName) { + rv = mAbsoluteContainer.InsertFrames(this, aPresContext, aPresShell, aListName, + aPrevFrame, aFrameList); + } else { + rv = nsBlockFrame::InsertFrames(aPresContext, aPresShell, aListName, + aPrevFrame, aFrameList); + } + + return rv; +} + +NS_IMETHODIMP +nsAreaFrame::RemoveFrame(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame) +{ + nsresult rv; + + if (nsLayoutAtoms::absoluteList == aListName) { + rv = mAbsoluteContainer.RemoveFrame(this, aPresContext, aPresShell, aListName, aOldFrame); + } else { + rv = nsBlockFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame); + } + + return rv; +} + NS_IMETHODIMP nsAreaFrame::GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const @@ -148,7 +204,7 @@ nsAreaFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const { NS_PRECONDITION(nsnull != aFirstChild, "null OUT parameter pointer"); if (aListName == nsLayoutAtoms::absoluteList) { - return mAbsoluteContainer.FirstChild(aListName, aFirstChild); + return mAbsoluteContainer.FirstChild(this, aListName, aFirstChild); } return nsBlockFrame::FirstChild(aListName, aFirstChild); @@ -217,7 +273,7 @@ nsAreaFrame::Paint(nsIPresContext& aPresContext, NS_IMETHODIMP nsAreaFrame::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const { - nsresult rv = mAbsoluteContainer.GetPositionedInfo(aXMost, aYMost); + nsresult rv = mAbsoluteContainer.GetPositionedInfo(this, aXMost, aYMost); // If we have child frames that stick outside of our box, and they should // be visible, then include them too so the total size is correct @@ -257,7 +313,7 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext, // Give the absolute positioning code a chance to handle it PRBool handled; - mAbsoluteContainer.IncrementalReflow(aPresContext, aReflowState, handled); + mAbsoluteContainer.IncrementalReflow(this, aPresContext, aReflowState, handled); // If the incremental reflow command was handled by the absolute positioning // code, then we're all done @@ -276,7 +332,7 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext, // If we have a space manager, then set it in the reflow state if (nsnull != mSpaceManager) { - // Modify the reflow state and set the space manager + // Modify the existing reflow state nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState; reflowState.mSpaceManager = mSpaceManager; @@ -288,9 +344,10 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext, rv = nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); // Let the absolutely positioned container reflow any absolutely positioned - // child frames that need to be reflowed + // child frames that need to be reflowed, e.g., elements with a percentage + // based width/height if (NS_SUCCEEDED(rv)) { - rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState); + rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState); } if (mFlags & NS_AREA_WRAP_SIZE) { diff --git a/mozilla/layout/html/base/src/nsAreaFrame.h b/mozilla/layout/html/base/src/nsAreaFrame.h index bd9da173054..e7de9b6b787 100644 --- a/mozilla/layout/html/base/src/nsAreaFrame.h +++ b/mozilla/layout/html/base/src/nsAreaFrame.h @@ -61,6 +61,19 @@ public: NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext, nsIAtom* aListName, nsIFrame* aChildList); + NS_IMETHOD AppendFrames(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aFrameList); + NS_IMETHOD InsertFrames(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aPrevFrame, + nsIFrame* aFrameList); + NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext, + nsIPresShell& aPresShell, + nsIAtom* aListName, + nsIFrame* aOldFrame); NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const; diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index a294a6e04cf..d97336737cd 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -3843,11 +3843,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame is updated - return nsFrame::AppendFrames(aPresContext, aPresShell, aListName, - aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -3907,11 +3902,6 @@ nsBlockFrame::InsertFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame and floater code is updated - return nsFrame::InsertFrames(aPresContext, aPresShell, aListName, - aPrevFrame, aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -4270,11 +4260,6 @@ nsBlockFrame::RemoveFrame(nsIPresContext& aPresContext, // We will reflow *after* removing the placeholder (which is done 2nd) return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame code is updated - return nsFrame::RemoveFrame(aPresContext, aPresShell, aListName, - aOldFrame); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index a294a6e04cf..d97336737cd 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -3843,11 +3843,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame is updated - return nsFrame::AppendFrames(aPresContext, aPresShell, aListName, - aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -3907,11 +3902,6 @@ nsBlockFrame::InsertFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame and floater code is updated - return nsFrame::InsertFrames(aPresContext, aPresShell, aListName, - aPrevFrame, aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -4270,11 +4260,6 @@ nsBlockFrame::RemoveFrame(nsIPresContext& aPresContext, // We will reflow *after* removing the placeholder (which is done 2nd) return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame code is updated - return nsFrame::RemoveFrame(aPresContext, aPresShell, aListName, - aOldFrame); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.h b/mozilla/layout/html/base/src/nsBlockReflowState.h index a294a6e04cf..d97336737cd 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.h +++ b/mozilla/layout/html/base/src/nsBlockReflowState.h @@ -3843,11 +3843,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame is updated - return nsFrame::AppendFrames(aPresContext, aPresShell, aListName, - aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -3907,11 +3902,6 @@ nsBlockFrame::InsertFrames(nsIPresContext& aPresContext, mFloaters.AppendFrames(nsnull, aFrameList); return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame and floater code is updated - return nsFrame::InsertFrames(aPresContext, aPresShell, aListName, - aPrevFrame, aFrameList); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } @@ -4270,11 +4260,6 @@ nsBlockFrame::RemoveFrame(nsIPresContext& aPresContext, // We will reflow *after* removing the placeholder (which is done 2nd) return NS_OK; } - else if (nsLayoutAtoms::absoluteList == aListName) { - // XXX temporary until area frame code is updated - return nsFrame::RemoveFrame(aPresContext, aPresShell, aListName, - aOldFrame); - } else if (nsnull != aListName) { return NS_ERROR_INVALID_ARG; } diff --git a/mozilla/layout/html/base/src/nsInlineFrame.cpp b/mozilla/layout/html/base/src/nsInlineFrame.cpp index ec770ec5732..a9b51ed4a90 100644 --- a/mozilla/layout/html/base/src/nsInlineFrame.cpp +++ b/mozilla/layout/html/base/src/nsInlineFrame.cpp @@ -67,7 +67,7 @@ NS_NewPositionedInlineFrame(nsIFrame** aNewFrame) NS_IMETHODIMP nsPositionedInlineFrame::Destroy(nsIPresContext& aPresContext) { - mAbsoluteContainer.DestroyFrames(aPresContext); + mAbsoluteContainer.DestroyFrames(this, aPresContext); return nsInlineFrame::Destroy(aPresContext); } @@ -79,7 +79,7 @@ nsPositionedInlineFrame::SetInitialChildList(nsIPresContext& aPresContext, nsresult rv; if (nsLayoutAtoms::absoluteList == aListName) { - rv = mAbsoluteContainer.SetInitialChildList(aPresContext, aListName, aChildList); + rv = mAbsoluteContainer.SetInitialChildList(this, aPresContext, aListName, aChildList); } else { rv = nsInlineFrame::SetInitialChildList(aPresContext, aListName, aChildList); } @@ -151,7 +151,7 @@ nsPositionedInlineFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) { NS_PRECONDITION(nsnull != aFirstChild, "null OUT parameter pointer"); if (aListName == nsLayoutAtoms::absoluteList) { - return mAbsoluteContainer.FirstChild(aListName, aFirstChild); + return mAbsoluteContainer.FirstChild(this, aListName, aFirstChild); } return nsInlineFrame::FirstChild(aListName, aFirstChild); @@ -179,7 +179,7 @@ nsPositionedInlineFrame::Reflow(nsIPresContext& aPresContext, // Give the absolute positioning code a chance to handle it PRBool handled; - mAbsoluteContainer.IncrementalReflow(aPresContext, aReflowState, handled); + mAbsoluteContainer.IncrementalReflow(this, aPresContext, aReflowState, handled); // If the incremental reflow command was handled by the absolute positioning // code, then we're all done @@ -200,7 +200,7 @@ nsPositionedInlineFrame::Reflow(nsIPresContext& aPresContext, // Let the absolutely positioned container reflow any absolutely positioned // child frames that need to be reflowed if (NS_SUCCEEDED(rv)) { - rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState); + rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState); } return rv;