Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : /*
7 : * code for managing absolutely positioned children of a rendering
8 : * object that is a containing block for them
9 : */
10 :
11 : #ifndef nsAbsoluteContainingBlock_h___
12 : #define nsAbsoluteContainingBlock_h___
13 :
14 : #include "nsFrameList.h"
15 : #include "nsIFrame.h"
16 : #include "mozilla/TypedEnumBits.h"
17 :
18 : class nsContainerFrame;
19 : class nsPresContext;
20 :
21 : /**
22 : * This class contains the logic for being an absolute containing block. This
23 : * class is used within viewport frames (for frames representing content with
24 : * fixed position) and blocks (for frames representing absolutely positioned
25 : * content), since each set of frames is absolutely positioned with respect to
26 : * its parent.
27 : *
28 : * There is no principal child list, just a named child list which contains
29 : * the absolutely positioned frames (kAbsoluteList or kFixedList).
30 : *
31 : * All functions include as the first argument the frame that is delegating
32 : * the request.
33 : */
34 : class nsAbsoluteContainingBlock
35 : {
36 : using ReflowInput = mozilla::ReflowInput;
37 :
38 : public:
39 : typedef nsIFrame::ChildListID ChildListID;
40 :
41 64 : explicit nsAbsoluteContainingBlock(ChildListID aChildListID)
42 : #ifdef DEBUG
43 64 : : mChildListID(aChildListID)
44 : #endif
45 : {
46 64 : MOZ_ASSERT(mChildListID == nsIFrame::kAbsoluteList ||
47 : mChildListID == nsIFrame::kFixedList,
48 : "should either represent position:fixed or absolute content");
49 64 : }
50 :
51 984 : const nsFrameList& GetChildList() const { return mAbsoluteFrames; }
52 : void AppendChildList(nsTArray<nsIFrame::ChildList>* aLists,
53 : ChildListID aListID) const
54 : {
55 : NS_ASSERTION(aListID == mChildListID, "wrong list ID");
56 : GetChildList().AppendIfNonempty(aLists, aListID);
57 : }
58 :
59 : void SetInitialChildList(nsIFrame* aDelegatingFrame,
60 : ChildListID aListID,
61 : nsFrameList& aChildList);
62 : void AppendFrames(nsIFrame* aDelegatingFrame,
63 : ChildListID aListID,
64 : nsFrameList& aFrameList);
65 : void InsertFrames(nsIFrame* aDelegatingFrame,
66 : ChildListID aListID,
67 : nsIFrame* aPrevFrame,
68 : nsFrameList& aFrameList);
69 : void RemoveFrame(nsIFrame* aDelegatingFrame,
70 : ChildListID aListID,
71 : nsIFrame* aOldFrame);
72 :
73 : enum class AbsPosReflowFlags {
74 : eConstrainHeight = 0x1,
75 : eCBWidthChanged = 0x2,
76 : eCBHeightChanged = 0x4,
77 : eCBWidthAndHeightChanged = eCBWidthChanged | eCBHeightChanged,
78 : eIsGridContainerCB = 0x8,
79 : };
80 :
81 : /**
82 : * Called by the delegating frame after it has done its reflow first. This
83 : * function will reflow any absolutely positioned child frames that need to
84 : * be reflowed, e.g., because the absolutely positioned child frame has
85 : * 'auto' for an offset, or a percentage based width or height.
86 : *
87 : * @param aOverflowAreas, if non-null, is unioned with (in the local
88 : * coordinate space) the overflow areas of the absolutely positioned
89 : * children.
90 : *
91 : * @param aReflowStatus is assumed to be already-initialized, e.g. with the
92 : * status of the delegating frame's main reflow. This function merges in the
93 : * statuses of the absolutely positioned children's reflows.
94 : *
95 : * @param aFlags zero or more AbsPosReflowFlags
96 : */
97 : void Reflow(nsContainerFrame* aDelegatingFrame,
98 : nsPresContext* aPresContext,
99 : const ReflowInput& aReflowInput,
100 : nsReflowStatus& aReflowStatus,
101 : const nsRect& aContainingBlock,
102 : AbsPosReflowFlags aFlags,
103 : nsOverflowAreas* aOverflowAreas);
104 :
105 : void DestroyFrames(nsIFrame* aDelegatingFrame,
106 : nsIFrame* aDestructRoot);
107 :
108 237 : bool HasAbsoluteFrames() const { return mAbsoluteFrames.NotEmpty(); }
109 :
110 : /**
111 : * Mark our size-dependent absolute frames with NS_FRAME_HAS_DIRTY_CHILDREN
112 : * so that we'll make sure to reflow them.
113 : */
114 : void MarkSizeDependentFramesDirty();
115 :
116 : /**
117 : * Mark all our absolute frames with NS_FRAME_IS_DIRTY.
118 : */
119 : void MarkAllFramesDirty();
120 :
121 : protected:
122 : /**
123 : * Returns true if the position of aFrame depends on the position of
124 : * its placeholder or if the position or size of aFrame depends on a
125 : * containing block dimension that changed.
126 : */
127 : bool FrameDependsOnContainer(nsIFrame* aFrame, bool aCBWidthChanged,
128 : bool aCBHeightChanged);
129 :
130 : /**
131 : * After an abspos child's size is known, this method can be used to
132 : * resolve size-dependent values in the ComputedLogicalOffsets on its
133 : * reflow state. (This may involve resolving the inline dimension of
134 : * aLogicalCBSize, too; hence, that variable is an in/outparam.)
135 : *
136 : * aKidSize, aMargin, aOffsets, and aLogicalCBSize are all expected to be
137 : * represented in terms of the absolute containing block's writing-mode.
138 : */
139 : void ResolveSizeDependentOffsets(nsPresContext* aPresContext,
140 : ReflowInput& aKidReflowInput,
141 : const mozilla::LogicalSize& aKidSize,
142 : const mozilla::LogicalMargin& aMargin,
143 : mozilla::LogicalMargin* aOffsets,
144 : mozilla::LogicalSize* aLogicalCBSize);
145 :
146 : void ReflowAbsoluteFrame(nsIFrame* aDelegatingFrame,
147 : nsPresContext* aPresContext,
148 : const ReflowInput& aReflowInput,
149 : const nsRect& aContainingBlockRect,
150 : AbsPosReflowFlags aFlags,
151 : nsIFrame* aKidFrame,
152 : nsReflowStatus& aStatus,
153 : nsOverflowAreas* aOverflowAreas);
154 :
155 : /**
156 : * Mark our absolute frames dirty.
157 : * @param aMarkAllDirty if true, all will be marked with NS_FRAME_IS_DIRTY.
158 : * Otherwise, the size-dependant ones will be marked with
159 : * NS_FRAME_HAS_DIRTY_CHILDREN.
160 : */
161 : void DoMarkFramesDirty(bool aMarkAllDirty);
162 :
163 : protected:
164 : nsFrameList mAbsoluteFrames; // additional named child list
165 :
166 : #ifdef DEBUG
167 : ChildListID const mChildListID; // kFixedList or kAbsoluteList
168 : #endif
169 : };
170 :
171 : namespace mozilla {
172 297 : MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsAbsoluteContainingBlock::AbsPosReflowFlags)
173 : }
174 : #endif /* nsnsAbsoluteContainingBlock_h___ */
|