/src/mozilla-central/layout/tables/nsTableWrapperFrame.h
Line | Count | Source (jump to first uncovered line) |
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 | | #ifndef nsTableWrapperFrame_h__ |
6 | | #define nsTableWrapperFrame_h__ |
7 | | |
8 | | #include "mozilla/Attributes.h" |
9 | | #include "mozilla/Maybe.h" |
10 | | #include "nscore.h" |
11 | | #include "nsContainerFrame.h" |
12 | | #include "nsCellMap.h" |
13 | | #include "nsTableFrame.h" |
14 | | |
15 | | /** |
16 | | * Primary frame for a table element, |
17 | | * the nsTableWrapperFrame contains 0 or one caption frame, and a nsTableFrame |
18 | | * pseudo-frame (referred to as the "inner frame'). |
19 | | */ |
20 | | class nsTableWrapperFrame : public nsContainerFrame |
21 | | { |
22 | | public: |
23 | | NS_DECL_QUERYFRAME |
24 | | NS_DECL_FRAMEARENA_HELPERS(nsTableWrapperFrame) |
25 | | |
26 | | /** instantiate a new instance of nsTableRowFrame. |
27 | | * @param aPresShell the pres shell for this frame |
28 | | * |
29 | | * @return the frame that was created |
30 | | */ |
31 | | friend nsTableWrapperFrame* NS_NewTableWrapperFrame(nsIPresShell* aPresShell, |
32 | | ComputedStyle* aStyle); |
33 | | |
34 | | // nsIFrame overrides - see there for a description |
35 | | |
36 | | virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override; |
37 | | |
38 | | virtual const nsFrameList& GetChildList(ChildListID aListID) const override; |
39 | | virtual void GetChildLists(nsTArray<ChildList>* aLists) const override; |
40 | | |
41 | | virtual void SetInitialChildList(ChildListID aListID, |
42 | | nsFrameList& aChildList) override; |
43 | | virtual void AppendFrames(ChildListID aListID, |
44 | | nsFrameList& aFrameList) override; |
45 | | virtual void InsertFrames(ChildListID aListID, |
46 | | nsIFrame* aPrevFrame, |
47 | | nsFrameList& aFrameList) override; |
48 | | virtual void RemoveFrame(ChildListID aListID, |
49 | | nsIFrame* aOldFrame) override; |
50 | | |
51 | 0 | virtual nsContainerFrame* GetContentInsertionFrame() override { |
52 | 0 | return PrincipalChildList().FirstChild()->GetContentInsertionFrame(); |
53 | 0 | } |
54 | | |
55 | | #ifdef ACCESSIBILITY |
56 | | virtual mozilla::a11y::AccType AccessibleType() override; |
57 | | #endif |
58 | | |
59 | | virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, |
60 | | const nsDisplayListSet& aLists) override; |
61 | | |
62 | | void BuildDisplayListForInnerTable(nsDisplayListBuilder* aBuilder, |
63 | | const nsDisplayListSet& aLists); |
64 | | |
65 | | virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override; |
66 | | |
67 | | bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, |
68 | | BaselineSharingGroup aBaselineGroup, |
69 | | nscoord* aBaseline) const override |
70 | 0 | { |
71 | 0 | auto innerTable = InnerTableFrame(); |
72 | 0 | nscoord offset; |
73 | 0 | if (innerTable->GetNaturalBaselineBOffset(aWM, aBaselineGroup, &offset)) { |
74 | 0 | auto bStart = innerTable->BStart(aWM, mRect.Size()); |
75 | 0 | if (aBaselineGroup == BaselineSharingGroup::eFirst) { |
76 | 0 | *aBaseline = offset + bStart; |
77 | 0 | } else { |
78 | 0 | auto bEnd = bStart + innerTable->BSize(aWM); |
79 | 0 | *aBaseline = BSize(aWM) - (bEnd - offset); |
80 | 0 | } |
81 | 0 | return true; |
82 | 0 | } |
83 | 0 | return false; |
84 | 0 | } |
85 | | |
86 | | virtual nscoord GetMinISize(gfxContext *aRenderingContext) override; |
87 | | virtual nscoord GetPrefISize(gfxContext *aRenderingContext) override; |
88 | | |
89 | | virtual mozilla::LogicalSize |
90 | | ComputeAutoSize(gfxContext* aRenderingContext, |
91 | | mozilla::WritingMode aWM, |
92 | | const mozilla::LogicalSize& aCBSize, |
93 | | nscoord aAvailableISize, |
94 | | const mozilla::LogicalSize& aMargin, |
95 | | const mozilla::LogicalSize& aBorder, |
96 | | const mozilla::LogicalSize& aPadding, |
97 | | ComputeSizeFlags aFlags) override; |
98 | | |
99 | | /** process a reflow command for the table. |
100 | | * This involves reflowing the caption and the inner table. |
101 | | * @see nsIFrame::Reflow */ |
102 | | virtual void Reflow(nsPresContext* aPresContext, |
103 | | ReflowOutput& aDesiredSize, |
104 | | const ReflowInput& aReflowInput, |
105 | | nsReflowStatus& aStatus) override; |
106 | | |
107 | | #ifdef DEBUG_FRAME_DUMP |
108 | | virtual nsresult GetFrameName(nsAString& aResult) const override; |
109 | | #endif |
110 | | |
111 | | virtual ComputedStyle* GetParentComputedStyle(nsIFrame** aProviderFrame) const override; |
112 | | |
113 | | /** |
114 | | * Return the content for the cell at the given row and column. |
115 | | */ |
116 | | nsIContent* GetCellAt(uint32_t aRowIdx, uint32_t aColIdx) const; |
117 | | |
118 | | /** |
119 | | * Return the number of rows in the table. |
120 | | */ |
121 | | int32_t GetRowCount() const |
122 | 0 | { |
123 | 0 | return InnerTableFrame()->GetRowCount(); |
124 | 0 | } |
125 | | |
126 | | /** |
127 | | * Return the number of columns in the table. |
128 | | */ |
129 | | int32_t GetColCount() const |
130 | 0 | { |
131 | 0 | return InnerTableFrame()->GetColCount(); |
132 | 0 | } |
133 | | |
134 | | /** |
135 | | * Return the index of the cell at the given row and column. |
136 | | */ |
137 | | int32_t GetIndexByRowAndColumn(int32_t aRowIdx, int32_t aColIdx) const |
138 | 0 | { |
139 | 0 | nsTableCellMap* cellMap = InnerTableFrame()->GetCellMap(); |
140 | 0 | if (!cellMap) |
141 | 0 | return -1; |
142 | 0 | |
143 | 0 | return cellMap->GetIndexByRowAndColumn(aRowIdx, aColIdx); |
144 | 0 | } |
145 | | |
146 | | /** |
147 | | * Get the row and column indices for the cell at the given index. |
148 | | */ |
149 | | void GetRowAndColumnByIndex(int32_t aCellIdx, int32_t* aRowIdx, |
150 | | int32_t* aColIdx) const |
151 | 0 | { |
152 | 0 | *aRowIdx = *aColIdx = 0; |
153 | 0 | nsTableCellMap* cellMap = InnerTableFrame()->GetCellMap(); |
154 | 0 | if (cellMap) { |
155 | 0 | cellMap->GetRowAndColumnByIndex(aCellIdx, aRowIdx, aColIdx); |
156 | 0 | } |
157 | 0 | } |
158 | | |
159 | | /** |
160 | | * return the frame for the cell at the given row and column. |
161 | | */ |
162 | | nsTableCellFrame* GetCellFrameAt(uint32_t aRowIdx, uint32_t aColIdx) const |
163 | 0 | { |
164 | 0 | nsTableCellMap* map = InnerTableFrame()->GetCellMap(); |
165 | 0 | if (!map) { |
166 | 0 | return nullptr; |
167 | 0 | } |
168 | 0 | |
169 | 0 | return map->GetCellInfoAt(aRowIdx, aColIdx); |
170 | 0 | } |
171 | | |
172 | | /** |
173 | | * Return the col span of the cell at the given row and column indices. |
174 | | */ |
175 | | uint32_t GetEffectiveColSpanAt(uint32_t aRowIdx, uint32_t aColIdx) const |
176 | 0 | { |
177 | 0 | nsTableCellMap* map = InnerTableFrame()->GetCellMap(); |
178 | 0 | return map->GetEffectiveColSpan(aRowIdx, aColIdx); |
179 | 0 | } |
180 | | |
181 | | /** |
182 | | * Return the effective row span of the cell at the given row and column. |
183 | | */ |
184 | | uint32_t GetEffectiveRowSpanAt(uint32_t aRowIdx, uint32_t aColIdx) const |
185 | 0 | { |
186 | 0 | nsTableCellMap* map = InnerTableFrame()->GetCellMap(); |
187 | 0 | return map->GetEffectiveRowSpan(aRowIdx, aColIdx); |
188 | 0 | } |
189 | | |
190 | | /** |
191 | | * The CB size to use for the inner table frame if we're a grid item. |
192 | | */ |
193 | | NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridItemCBSizeProperty, mozilla::LogicalSize); |
194 | | |
195 | | protected: |
196 | | |
197 | | explicit nsTableWrapperFrame(ComputedStyle* aStyle, ClassID aID = kClassID); |
198 | | virtual ~nsTableWrapperFrame(); |
199 | | |
200 | | void InitChildReflowInput(nsPresContext& aPresContext, |
201 | | const ReflowInput& aOuterRS, |
202 | | ReflowInput& aReflowInput); |
203 | | |
204 | | // Get a NS_STYLE_CAPTION_SIDE_* value, or NO_SIDE if no caption is present. |
205 | | // (Remember that caption-side values are interpreted logically, despite |
206 | | // having "physical" names.) |
207 | | uint8_t GetCaptionSide(); |
208 | | |
209 | 0 | bool HasSideCaption() { |
210 | 0 | uint8_t captionSide = GetCaptionSide(); |
211 | 0 | return captionSide == NS_STYLE_CAPTION_SIDE_LEFT || |
212 | 0 | captionSide == NS_STYLE_CAPTION_SIDE_RIGHT; |
213 | 0 | } |
214 | | |
215 | | uint8_t GetCaptionVerticalAlign(); |
216 | | |
217 | | void SetDesiredSize(uint8_t aCaptionSide, |
218 | | const mozilla::LogicalSize& aInnerSize, |
219 | | const mozilla::LogicalSize& aCaptionSize, |
220 | | const mozilla::LogicalMargin& aInnerMargin, |
221 | | const mozilla::LogicalMargin& aCaptionMargin, |
222 | | nscoord& aISize, |
223 | | nscoord& aBSize, |
224 | | mozilla::WritingMode aWM); |
225 | | |
226 | | nsresult GetCaptionOrigin(uint32_t aCaptionSide, |
227 | | const mozilla::LogicalSize& aContainBlockSize, |
228 | | const mozilla::LogicalSize& aInnerSize, |
229 | | const mozilla::LogicalMargin& aInnerMargin, |
230 | | const mozilla::LogicalSize& aCaptionSize, |
231 | | mozilla::LogicalMargin& aCaptionMargin, |
232 | | mozilla::LogicalPoint& aOrigin, |
233 | | mozilla::WritingMode aWM); |
234 | | |
235 | | nsresult GetInnerOrigin(uint32_t aCaptionSide, |
236 | | const mozilla::LogicalSize& aContainBlockSize, |
237 | | const mozilla::LogicalSize& aCaptionSize, |
238 | | const mozilla::LogicalMargin& aCaptionMargin, |
239 | | const mozilla::LogicalSize& aInnerSize, |
240 | | mozilla::LogicalMargin& aInnerMargin, |
241 | | mozilla::LogicalPoint& aOrigin, |
242 | | mozilla::WritingMode aWM); |
243 | | |
244 | | // reflow the child (caption or innertable frame) |
245 | | void OuterBeginReflowChild(nsPresContext* aPresContext, |
246 | | nsIFrame* aChildFrame, |
247 | | const ReflowInput& aOuterRI, |
248 | | mozilla::Maybe<ReflowInput>& aChildRI, |
249 | | nscoord aAvailISize); |
250 | | |
251 | | void OuterDoReflowChild(nsPresContext* aPresContext, |
252 | | nsIFrame* aChildFrame, |
253 | | const ReflowInput& aChildRI, |
254 | | ReflowOutput& aMetrics, |
255 | | nsReflowStatus& aStatus); |
256 | | |
257 | | // Set the overflow areas in our reflow metrics |
258 | | void UpdateOverflowAreas(ReflowOutput& aMet); |
259 | | |
260 | | // Get the margin. |
261 | | void GetChildMargin(nsPresContext* aPresContext, |
262 | | const ReflowInput& aOuterRI, |
263 | | nsIFrame* aChildFrame, |
264 | | nscoord aAvailableWidth, |
265 | | mozilla::LogicalMargin& aMargin); |
266 | | |
267 | | virtual bool IsFrameOfType(uint32_t aFlags) const override |
268 | 0 | { |
269 | 0 | return nsContainerFrame::IsFrameOfType(aFlags & |
270 | 0 | (~eCanContainOverflowContainers)); |
271 | 0 | } |
272 | | |
273 | | nsTableFrame* InnerTableFrame() const |
274 | 0 | { |
275 | 0 | return static_cast<nsTableFrame*>(mFrames.FirstChild()); |
276 | 0 | } |
277 | | |
278 | | /** |
279 | | * Helper for ComputeAutoSize. |
280 | | * Compute the margin-box inline size of aChildFrame given the inputs. |
281 | | * If aMarginResult is non-null, fill it with the part of the |
282 | | * margin-isize that was contributed by the margin. |
283 | | */ |
284 | | nscoord ChildShrinkWrapISize(gfxContext* aRenderingContext, |
285 | | nsIFrame* aChildFrame, |
286 | | mozilla::WritingMode aWM, |
287 | | mozilla::LogicalSize aCBSize, |
288 | | nscoord aAvailableISize, |
289 | | nscoord* aMarginResult = nullptr) const; |
290 | | |
291 | | private: |
292 | | nsFrameList mCaptionFrames; |
293 | | }; |
294 | | |
295 | | #endif |