Bug 1919083 - [ci] Enable os-integration variant for more suites, r=jmaher
[gecko.git] / layout / tables / nsTableRowFrame.h
blob4fe175c0e2cbdbdf8417f5df62d49ebcf36b2060
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 nsTableRowFrame_h__
6 #define nsTableRowFrame_h__
8 #include "mozilla/Attributes.h"
9 #include "nscore.h"
10 #include "nsContainerFrame.h"
11 #include "nsTableRowGroupFrame.h"
12 #include "mozilla/WritingModes.h"
14 class nsTableCellFrame;
15 namespace mozilla {
16 class PresShell;
17 struct TableCellReflowInput;
19 // Yes if table-cells should use 'vertical-align:top' in
20 // nsTableCellFrame::BlockDirAlignChild(). This is a hack to workaround our
21 // current table row group fragmentation to avoid data loss.
22 enum class ForceAlignTopForTableCell : uint8_t { No, Yes };
23 } // namespace mozilla
25 /**
26 * nsTableRowFrame is the frame that maps table rows
27 * (HTML tag TR). This class cannot be reused
28 * outside of an nsTableRowGroupFrame. It assumes that its parent is an
29 * nsTableRowGroupFrame, and its children are nsTableCellFrames.
31 * @see nsTableFrame
32 * @see nsTableRowGroupFrame
33 * @see nsTableCellFrame
35 class nsTableRowFrame : public nsContainerFrame {
36 using TableCellReflowInput = mozilla::TableCellReflowInput;
38 public:
39 NS_DECL_QUERYFRAME
40 NS_DECL_FRAMEARENA_HELPERS(nsTableRowFrame)
42 virtual ~nsTableRowFrame();
44 void Init(nsIContent* aContent, nsContainerFrame* aParent,
45 nsIFrame* aPrevInFlow) override;
47 void Destroy(DestroyContext&) override;
49 void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
51 void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override;
52 void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
53 const nsLineList::iterator* aPrevFrameLine,
54 nsFrameList&& aFrameList) override;
55 void RemoveFrame(DestroyContext&, ChildListID, nsIFrame*) override;
57 /** instantiate a new instance of nsTableRowFrame.
58 * @param aPresShell the pres shell for this frame
60 * @return the frame that was created
62 friend nsTableRowFrame* NS_NewTableRowFrame(mozilla::PresShell* aPresShell,
63 ComputedStyle* aStyle);
65 nsTableRowGroupFrame* GetTableRowGroupFrame() const {
66 nsIFrame* parent = GetParent();
67 MOZ_ASSERT(parent && parent->IsTableRowGroupFrame());
68 return static_cast<nsTableRowGroupFrame*>(parent);
71 nsTableFrame* GetTableFrame() const {
72 return GetTableRowGroupFrame()->GetTableFrame();
75 nsMargin GetUsedMargin() const override;
76 nsMargin GetUsedBorder() const override;
77 nsMargin GetUsedPadding() const override;
79 void BuildDisplayList(nsDisplayListBuilder* aBuilder,
80 const nsDisplayListSet& aLists) override;
82 void PaintCellBackgroundsForFrame(nsIFrame* aFrame,
83 nsDisplayListBuilder* aBuilder,
84 const nsDisplayListSet& aLists,
85 const nsPoint& aOffset = nsPoint());
87 // Implemented in nsTableCellFrame.h, because it needs to know about the
88 // nsTableCellFrame class, but we can't include nsTableCellFrame.h here.
89 inline nsTableCellFrame* GetFirstCell() const;
91 /** calls Reflow for all of its child cells.
93 * Cells with rowspan=1 are all set to the same height and stacked
94 * horizontally.
96 * Cells are not split unless absolutely necessary.
98 * Cells are resized in nsTableFrame::BalanceColumnWidths and
99 * nsTableFrame::ShrinkWrapChildren
101 * @param aDesiredSize width set to width of the sum of the cells,
102 * height set to height of cells with rowspan=1.
104 * @see nsIFrame::Reflow
105 * @see nsTableFrame::BalanceColumnWidths
106 * @see nsTableFrame::ShrinkWrapChildren
108 void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
109 const ReflowInput& aReflowInput,
110 nsReflowStatus& aStatus) override;
112 void DidResize(mozilla::ForceAlignTopForTableCell aForceAlignTop =
113 mozilla::ForceAlignTopForTableCell::No);
115 #ifdef DEBUG_FRAME_DUMP
116 nsresult GetFrameName(nsAString& aResult) const override;
117 #endif
119 void UpdateBSize(nscoord aBSize, nscoord aAscent, nscoord aDescent,
120 nsTableFrame* aTableFrame = nullptr,
121 nsTableCellFrame* aCellFrame = nullptr);
123 void ResetBSize();
125 // calculate the bsize, considering content bsize of the
126 // cells and the style bsize of the row and cells, excluding pct bsizes
127 nscoord CalcBSize(const ReflowInput& aReflowInput);
129 // Support for cells with 'vertical-align: baseline'.
132 * returns the max-ascent amongst all the cells that have
133 * 'vertical-align: baseline', *including* cells with rowspans.
134 * returns 0 if we don't have any cell with 'vertical-align: baseline'
136 nscoord GetMaxCellAscent() const;
138 /* return the row ascent
140 Maybe<nscoord> GetRowBaseline(mozilla::WritingMode aWM);
142 /** returns the ordinal position of this row in its table */
143 virtual int32_t GetRowIndex() const;
145 /** set this row's starting row index */
146 void SetRowIndex(int aRowIndex);
148 // See nsTableFrame.h
149 int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex) const;
151 // See nsTableFrame.h
152 void AddDeletedRowIndex();
155 * This function is called by the row group frame's SplitRowGroup() code when
156 * pushing a row frame that has cell frames that span into it. The cell frame
157 * should be reflowed with the specified available block-size.
159 nscoord ReflowCellFrame(nsPresContext* aPresContext,
160 const ReflowInput& aReflowInput, bool aIsTopOfPage,
161 nsTableCellFrame* aCellFrame, nscoord aAvailableBSize,
162 nsReflowStatus& aStatus);
164 * Collapse the row if required, apply col and colgroup visibility: collapse
165 * info to the cells in the row.
166 * @return the amount to shift bstart-wards all following rows
167 * @param aRowOffset - shift the row bstart-wards by this amount
168 * @param aISize - new isize of the row
169 * @param aCollapseGroup - parent rowgroup is collapsed so this row needs
170 * to be collapsed
171 * @param aDidCollapse - the row has been collapsed
173 nscoord CollapseRowIfNecessary(nscoord aRowOffset, nscoord aISize,
174 bool aCollapseGroup, bool& aDidCollapse);
177 * Insert a cell frame after the last cell frame that has a col index
178 * that is less than aColIndex. If no such cell frame is found the
179 * frame to insert is prepended to the child list.
180 * @param aFrame the cell frame to insert
181 * @param aColIndex the col index
183 void InsertCellFrame(nsTableCellFrame* aFrame, int32_t aColIndex);
186 * Calculate the cell frame's actual block-size given its desired block-size
187 * (the border-box block-size in the last reflow). This method takes into
188 * account the specified bsize (in the style).
190 * @return the specified block-size if it is larger than the desired
191 * block-size. Otherwise, the desired block-size.
193 nscoord CalcCellActualBSize(nsTableCellFrame* aCellFrame,
194 const nscoord& aDesiredBSize,
195 mozilla::WritingMode aWM);
197 bool IsFirstInserted() const;
198 void SetFirstInserted(bool aValue);
200 nscoord GetContentBSize() const;
201 void SetContentBSize(nscoord aTwipValue);
203 bool HasStyleBSize() const;
205 bool HasFixedBSize() const;
206 void SetHasFixedBSize(bool aValue);
208 bool HasPctBSize() const;
209 void SetHasPctBSize(bool aValue);
211 nscoord GetFixedBSize() const;
212 void SetFixedBSize(nscoord aValue);
214 float GetPctBSize() const;
215 void SetPctBSize(float aPctValue, bool aForce = false);
217 nscoord GetInitialBSize(nscoord aBasis = 0) const;
219 nsTableRowFrame* GetPrevRow() const;
220 nsTableRowFrame* GetNextRow() const;
222 bool HasUnpaginatedBSize() const {
223 return HasAnyStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
225 nscoord GetUnpaginatedBSize() const;
226 void SetUnpaginatedBSize(nscoord aValue);
228 nscoord GetBStartBCBorderWidth() const { return mBStartBorderWidth; }
229 nscoord GetBEndBCBorderWidth() const { return mBEndBorderWidth; }
230 void SetBStartBCBorderWidth(nscoord aWidth) { mBStartBorderWidth = aWidth; }
231 void SetBEndBCBorderWidth(nscoord aWidth) { mBEndBorderWidth = aWidth; }
232 mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
234 void InvalidateFrame(uint32_t aDisplayItemKey = 0,
235 bool aRebuildDisplayItems = true) override;
236 void InvalidateFrameWithRect(const nsRect& aRect,
237 uint32_t aDisplayItemKey = 0,
238 bool aRebuildDisplayItems = true) override;
239 void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
241 #ifdef ACCESSIBILITY
242 mozilla::a11y::AccType AccessibleType() override;
243 #endif
245 protected:
246 /** protected constructor.
247 * @see NewFrame
249 explicit nsTableRowFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
250 ClassID aID = kClassID);
252 void InitChildReflowInput(nsPresContext& aPresContext,
253 const mozilla::LogicalSize& aAvailSize,
254 bool aBorderCollapse,
255 TableCellReflowInput& aReflowInput);
257 LogicalSides GetLogicalSkipSides() const override;
259 // row-specific methods
261 nscoord ComputeCellXOffset(const ReflowInput& aState, nsIFrame* aKidFrame,
262 const nsMargin& aKidMargin) const;
264 * Called for incremental/dirty and resize reflows. If aDirtyOnly is true then
265 * only reflow dirty cells.
267 void ReflowChildren(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
268 const ReflowInput& aReflowInput,
269 nsTableFrame& aTableFrame, nsReflowStatus& aStatus);
271 private:
272 struct RowBits {
273 unsigned mRowIndex : 29;
274 unsigned mHasFixedBSize : 1; // set if the dominating style bsize on the
275 // row or any cell is pixel based
276 unsigned mHasPctBSize : 1; // set if the dominating style bsize on the row
277 // or any cell is pct based
278 unsigned mFirstInserted : 1; // if true, then it was the bstart-most newly
279 // inserted row
280 } mBits;
282 // the desired bsize based on the content of the tallest cell in the row
283 nscoord mContentBSize = 0;
284 // the bsize based on a style percentage bsize on either the row or any cell
285 // if mHasPctBSize is set
286 nscoord mStylePctBSize = 0;
287 // the bsize based on a style pixel bsize on the row or any
288 // cell if mHasFixedBSize is set
289 nscoord mStyleFixedBSize = 0;
291 // max-ascent and max-descent amongst all cells that have
292 // 'vertical-align: baseline'
293 nscoord mMaxCellAscent = 0; // does include cells with rowspan > 1
294 nscoord mMaxCellDescent = 0; // does *not* include cells with rowspan > 1
296 // border widths in the collapsing border model of the *inner*
297 // half of the border only
298 nscoord mBStartBorderWidth = 0;
299 nscoord mBEndBorderWidth = 0;
300 nscoord mIEndContBorderWidth = 0;
301 nscoord mBStartContBorderWidth = 0;
302 nscoord mIStartContBorderWidth = 0;
305 * Sets the NS_ROW_HAS_CELL_WITH_STYLE_BSIZE bit to indicate whether
306 * this row has any cells that have non-auto-bsize. (Row-spanning
307 * cells are ignored.)
309 void InitHasCellWithStyleBSize(nsTableFrame* aTableFrame);
312 inline int32_t nsTableRowFrame::GetAdjustmentForStoredIndex(
313 int32_t aStoredIndex) const {
314 nsTableRowGroupFrame* parentFrame = GetTableRowGroupFrame();
315 return parentFrame->GetAdjustmentForStoredIndex(aStoredIndex);
318 inline void nsTableRowFrame::AddDeletedRowIndex() {
319 nsTableRowGroupFrame* parentFrame = GetTableRowGroupFrame();
320 parentFrame->AddDeletedRowIndex(int32_t(mBits.mRowIndex));
323 inline int32_t nsTableRowFrame::GetRowIndex() const {
324 int32_t storedRowIndex = int32_t(mBits.mRowIndex);
325 int32_t rowIndexAdjustment = GetAdjustmentForStoredIndex(storedRowIndex);
326 return (storedRowIndex - rowIndexAdjustment);
329 inline void nsTableRowFrame::SetRowIndex(int aRowIndex) {
330 // Note: Setting the index of a row (as in the case of adding new rows) should
331 // be preceded by a call to nsTableFrame::RecalculateRowIndices()
332 // so as to correctly clear mDeletedRowIndexRanges.
333 MOZ_ASSERT(
334 GetTableRowGroupFrame()->GetTableFrame()->IsDeletedRowIndexRangesEmpty(),
335 "mDeletedRowIndexRanges should be empty here!");
336 mBits.mRowIndex = aRowIndex;
339 inline bool nsTableRowFrame::IsFirstInserted() const {
340 return bool(mBits.mFirstInserted);
343 inline void nsTableRowFrame::SetFirstInserted(bool aValue) {
344 mBits.mFirstInserted = aValue;
347 inline bool nsTableRowFrame::HasStyleBSize() const {
348 return (bool)mBits.mHasFixedBSize || (bool)mBits.mHasPctBSize;
351 inline bool nsTableRowFrame::HasFixedBSize() const {
352 return (bool)mBits.mHasFixedBSize;
355 inline void nsTableRowFrame::SetHasFixedBSize(bool aValue) {
356 mBits.mHasFixedBSize = aValue;
359 inline bool nsTableRowFrame::HasPctBSize() const {
360 return (bool)mBits.mHasPctBSize;
363 inline void nsTableRowFrame::SetHasPctBSize(bool aValue) {
364 mBits.mHasPctBSize = aValue;
367 inline nscoord nsTableRowFrame::GetContentBSize() const {
368 return mContentBSize;
371 inline void nsTableRowFrame::SetContentBSize(nscoord aValue) {
372 mContentBSize = aValue;
375 inline nscoord nsTableRowFrame::GetFixedBSize() const {
376 if (mBits.mHasFixedBSize) {
377 return mStyleFixedBSize;
379 return 0;
382 inline float nsTableRowFrame::GetPctBSize() const {
383 if (mBits.mHasPctBSize) {
384 return (float)mStylePctBSize / 100.0f;
386 return 0.0f;
389 inline mozilla::LogicalMargin nsTableRowFrame::GetBCBorderWidth(
390 mozilla::WritingMode aWM) {
391 return mozilla::LogicalMargin(aWM, mBStartBorderWidth, 0, mBEndBorderWidth,
395 #endif