michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * code for managing absolutely positioned children of a rendering michael@0: * object that is a containing block for them michael@0: */ michael@0: michael@0: #ifndef nsAbsoluteContainingBlock_h___ michael@0: #define nsAbsoluteContainingBlock_h___ michael@0: michael@0: #include "nsFrameList.h" michael@0: #include "nsIFrame.h" michael@0: michael@0: class nsContainerFrame; michael@0: class nsHTMLReflowState; michael@0: class nsPresContext; michael@0: michael@0: /** michael@0: * This class contains the logic for being an absolute containing block. This michael@0: * class is used within viewport frames (for frames representing content with michael@0: * fixed position) and blocks (for frames representing absolutely positioned michael@0: * content), since each set of frames is absolutely positioned with respect to michael@0: * its parent. michael@0: * michael@0: * There is no principal child list, just a named child list which contains michael@0: * the absolutely positioned frames (kAbsoluteList or kFixedList). michael@0: * michael@0: * All functions include as the first argument the frame that is delegating michael@0: * the request. michael@0: */ michael@0: class nsAbsoluteContainingBlock michael@0: { michael@0: public: michael@0: typedef nsIFrame::ChildListID ChildListID; michael@0: michael@0: nsAbsoluteContainingBlock(ChildListID aChildListID) michael@0: #ifdef DEBUG michael@0: : mChildListID(aChildListID) michael@0: #endif michael@0: { michael@0: MOZ_ASSERT(mChildListID == nsIFrame::kAbsoluteList || michael@0: mChildListID == nsIFrame::kFixedList, michael@0: "should either represent position:fixed or absolute content"); michael@0: } michael@0: michael@0: const nsFrameList& GetChildList() const { return mAbsoluteFrames; } michael@0: void AppendChildList(nsTArray* aLists, michael@0: ChildListID aListID) const michael@0: { michael@0: NS_ASSERTION(aListID == mChildListID, "wrong list ID"); michael@0: GetChildList().AppendIfNonempty(aLists, aListID); michael@0: } michael@0: michael@0: nsresult SetInitialChildList(nsIFrame* aDelegatingFrame, michael@0: ChildListID aListID, michael@0: nsFrameList& aChildList); michael@0: nsresult AppendFrames(nsIFrame* aDelegatingFrame, michael@0: ChildListID aListID, michael@0: nsFrameList& aFrameList); michael@0: nsresult InsertFrames(nsIFrame* aDelegatingFrame, michael@0: ChildListID aListID, michael@0: nsIFrame* aPrevFrame, michael@0: nsFrameList& aFrameList); michael@0: void RemoveFrame(nsIFrame* aDelegatingFrame, michael@0: ChildListID aListID, michael@0: nsIFrame* aOldFrame); michael@0: michael@0: /** michael@0: * Called by the delegating frame after it has done its reflow first. This michael@0: * function will reflow any absolutely positioned child frames that need to michael@0: * be reflowed, e.g., because the absolutely positioned child frame has michael@0: * 'auto' for an offset, or a percentage based width or height. michael@0: * michael@0: * @param aOverflowAreas, if non-null, is unioned with (in the local michael@0: * coordinate space) the overflow areas of the absolutely positioned michael@0: * children. michael@0: * michael@0: * @param aReflowStatus is assumed to be already-initialized, e.g. with the michael@0: * status of the delegating frame's main reflow. This function merges in the michael@0: * statuses of the absolutely positioned children's reflows. michael@0: */ michael@0: nsresult Reflow(nsContainerFrame* aDelegatingFrame, michael@0: nsPresContext* aPresContext, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aReflowStatus, michael@0: const nsRect& aContainingBlock, michael@0: bool aConstrainHeight, michael@0: bool aCBWidthChanged, michael@0: bool aCBHeightChanged, michael@0: nsOverflowAreas* aOverflowAreas); michael@0: michael@0: void DestroyFrames(nsIFrame* aDelegatingFrame, michael@0: nsIFrame* aDestructRoot); michael@0: michael@0: bool HasAbsoluteFrames() const { return mAbsoluteFrames.NotEmpty(); } michael@0: michael@0: /** michael@0: * Mark our size-dependent absolute frames with NS_FRAME_HAS_DIRTY_CHILDREN michael@0: * so that we'll make sure to reflow them. michael@0: */ michael@0: void MarkSizeDependentFramesDirty(); michael@0: michael@0: /** michael@0: * Mark all our absolute frames with NS_FRAME_IS_DIRTY. michael@0: */ michael@0: void MarkAllFramesDirty(); michael@0: michael@0: protected: michael@0: /** michael@0: * Returns true if the position of aFrame depends on the position of michael@0: * its placeholder or if the position or size of aFrame depends on a michael@0: * containing block dimension that changed. michael@0: */ michael@0: bool FrameDependsOnContainer(nsIFrame* aFrame, bool aCBWidthChanged, michael@0: bool aCBHeightChanged); michael@0: michael@0: nsresult ReflowAbsoluteFrame(nsIFrame* aDelegatingFrame, michael@0: nsPresContext* aPresContext, michael@0: const nsHTMLReflowState& aReflowState, michael@0: const nsRect& aContainingBlockRect, michael@0: bool aConstrainHeight, michael@0: nsIFrame* aKidFrame, michael@0: nsReflowStatus& aStatus, michael@0: nsOverflowAreas* aOverflowAreas); michael@0: michael@0: /** michael@0: * Mark our absolute frames dirty. michael@0: * @param aMarkAllDirty if true, all will be marked with NS_FRAME_IS_DIRTY. michael@0: * Otherwise, the size-dependant ones will be marked with michael@0: * NS_FRAME_HAS_DIRTY_CHILDREN. michael@0: */ michael@0: void DoMarkFramesDirty(bool aMarkAllDirty); michael@0: michael@0: protected: michael@0: nsFrameList mAbsoluteFrames; // additional named child list michael@0: michael@0: #ifdef DEBUG michael@0: ChildListID const mChildListID; // kFixedList or kAbsoluteList michael@0: #endif michael@0: }; michael@0: michael@0: #endif /* nsnsAbsoluteContainingBlock_h___ */