Bug 1637697 [wpt PR 23571] - De-flaky some pointerevents wpt tests - Part 1, a=testonly
[gecko.git] / layout / tables / nsTableRowFrame.h
blobe622a81cfb70e48721a41ae1cb78461df2231f97
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;
18 } // namespace mozilla
20 /**
21 * nsTableRowFrame is the frame that maps table rows
22 * (HTML tag TR). This class cannot be reused
23 * outside of an nsTableRowGroupFrame. It assumes that its parent is an
24 * nsTableRowGroupFrame, and its children are nsTableCellFrames.
26 * @see nsTableFrame
27 * @see nsTableRowGroupFrame
28 * @see nsTableCellFrame
30 class nsTableRowFrame : public nsContainerFrame {
31 using TableCellReflowInput = mozilla::TableCellReflowInput;
33 public:
34 NS_DECL_QUERYFRAME
35 NS_DECL_FRAMEARENA_HELPERS(nsTableRowFrame)
37 virtual ~nsTableRowFrame();
39 virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
40 nsIFrame* aPrevInFlow) override;
42 virtual void DestroyFrom(nsIFrame* aDestructRoot,
43 PostDestroyData& aPostDestroyData) override;
45 /** @see nsIFrame::DidSetComputedStyle */
46 virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
48 virtual void AppendFrames(ChildListID aListID,
49 nsFrameList& aFrameList) override;
50 virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
51 const nsLineList::iterator* aPrevFrameLine,
52 nsFrameList& aFrameList) override;
53 virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
55 /** instantiate a new instance of nsTableRowFrame.
56 * @param aPresShell the pres shell for this frame
58 * @return the frame that was created
60 friend nsTableRowFrame* NS_NewTableRowFrame(mozilla::PresShell* aPresShell,
61 ComputedStyle* aStyle);
63 nsTableRowGroupFrame* GetTableRowGroupFrame() const {
64 nsIFrame* parent = GetParent();
65 MOZ_ASSERT(parent && parent->IsTableRowGroupFrame());
66 return static_cast<nsTableRowGroupFrame*>(parent);
69 nsTableFrame* GetTableFrame() const {
70 return GetTableRowGroupFrame()->GetTableFrame();
73 virtual nsMargin GetUsedMargin() const override;
74 virtual nsMargin GetUsedBorder() const override;
75 virtual nsMargin GetUsedPadding() const override;
77 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
78 const nsDisplayListSet& aLists) override;
80 void PaintCellBackgroundsForFrame(nsIFrame* aFrame,
81 nsDisplayListBuilder* aBuilder,
82 const nsDisplayListSet& aLists,
83 const nsPoint& aOffset = nsPoint());
85 // Implemented in nsTableCellFrame.h, because it needs to know about the
86 // nsTableCellFrame class, but we can't include nsTableCellFrame.h here.
87 inline nsTableCellFrame* GetFirstCell() const;
89 /** calls Reflow for all of its child cells.
91 * Cells with rowspan=1 are all set to the same height and stacked
92 * horizontally.
94 * Cells are not split unless absolutely necessary.
96 * Cells are resized in nsTableFrame::BalanceColumnWidths and
97 * nsTableFrame::ShrinkWrapChildren
99 * @param aDesiredSize width set to width of the sum of the cells,
100 * height set to height of cells with rowspan=1.
102 * @see nsIFrame::Reflow
103 * @see nsTableFrame::BalanceColumnWidths
104 * @see nsTableFrame::ShrinkWrapChildren
106 virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
107 const ReflowInput& aReflowInput,
108 nsReflowStatus& aStatus) override;
110 void DidResize();
112 #ifdef DEBUG_FRAME_DUMP
113 virtual nsresult GetFrameName(nsAString& aResult) const override;
114 #endif
116 void UpdateBSize(nscoord aBSize, nscoord aAscent, nscoord aDescent,
117 nsTableFrame* aTableFrame = nullptr,
118 nsTableCellFrame* aCellFrame = nullptr);
120 void ResetBSize(nscoord aRowStyleBSize);
122 // calculate the bsize, considering content bsize of the
123 // cells and the style bsize of the row and cells, excluding pct bsizes
124 nscoord CalcBSize(const ReflowInput& aReflowInput);
126 // Support for cells with 'vertical-align: baseline'.
129 * returns the max-ascent amongst all the cells that have
130 * 'vertical-align: baseline', *including* cells with rowspans.
131 * returns 0 if we don't have any cell with 'vertical-align: baseline'
133 nscoord GetMaxCellAscent() const;
135 /* return the row ascent
137 nscoord GetRowBaseline(mozilla::WritingMode aWritingMode);
139 /** returns the ordinal position of this row in its table */
140 virtual int32_t GetRowIndex() const;
142 /** set this row's starting row index */
143 void SetRowIndex(int aRowIndex);
145 // See nsTableFrame.h
146 int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex) const;
148 // See nsTableFrame.h
149 void AddDeletedRowIndex();
151 /** used by row group frame code */
152 nscoord ReflowCellFrame(nsPresContext* aPresContext,
153 const ReflowInput& aReflowInput, bool aIsTopOfPage,
154 nsTableCellFrame* aCellFrame, nscoord aAvailableBSize,
155 nsReflowStatus& aStatus);
157 * Collapse the row if required, apply col and colgroup visibility: collapse
158 * info to the cells in the row.
159 * @return the amount to shift bstart-wards all following rows
160 * @param aRowOffset - shift the row bstart-wards by this amount
161 * @param aISize - new isize of the row
162 * @param aCollapseGroup - parent rowgroup is collapsed so this row needs
163 * to be collapsed
164 * @param aDidCollapse - the row has been collapsed
166 nscoord CollapseRowIfNecessary(nscoord aRowOffset, nscoord aISize,
167 bool aCollapseGroup, bool& aDidCollapse);
170 * Insert a cell frame after the last cell frame that has a col index
171 * that is less than aColIndex. If no such cell frame is found the
172 * frame to insert is prepended to the child list.
173 * @param aFrame the cell frame to insert
174 * @param aColIndex the col index
176 void InsertCellFrame(nsTableCellFrame* aFrame, int32_t aColIndex);
178 nsresult CalculateCellActualBSize(nsTableCellFrame* aCellFrame,
179 nscoord& aDesiredBSize,
180 mozilla::WritingMode aWM);
182 bool IsFirstInserted() const;
183 void SetFirstInserted(bool aValue);
185 nscoord GetContentBSize() const;
186 void SetContentBSize(nscoord aTwipValue);
188 bool HasStyleBSize() const;
190 bool HasFixedBSize() const;
191 void SetHasFixedBSize(bool aValue);
193 bool HasPctBSize() const;
194 void SetHasPctBSize(bool aValue);
196 nscoord GetFixedBSize() const;
197 void SetFixedBSize(nscoord aValue);
199 float GetPctBSize() const;
200 void SetPctBSize(float aPctValue, bool aForce = false);
202 nscoord GetInitialBSize(nscoord aBasis = 0) const;
204 nsTableRowFrame* GetNextRow() const;
206 bool HasUnpaginatedBSize();
207 void SetHasUnpaginatedBSize(bool aValue);
208 nscoord GetUnpaginatedBSize();
209 void SetUnpaginatedBSize(nsPresContext* aPresContext, nscoord aValue);
211 BCPixelSize GetBStartBCBorderWidth() const { return mBStartBorderWidth; }
212 BCPixelSize GetBEndBCBorderWidth() const { return mBEndBorderWidth; }
213 void SetBStartBCBorderWidth(BCPixelSize aWidth) {
214 mBStartBorderWidth = aWidth;
216 void SetBEndBCBorderWidth(BCPixelSize aWidth) { mBEndBorderWidth = aWidth; }
217 mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
220 * Gets inner border widths before collapsing with cell borders
221 * Caller must get block-end border from next row or from table
222 * GetContinuousBCBorderWidth will not overwrite that border
223 * see nsTablePainter about continuous borders
225 void GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
226 mozilla::LogicalMargin& aBorder);
229 * @returns outer block-start bc border == prev row's block-end inner
231 nscoord GetOuterBStartContBCBorderWidth();
233 * Sets full border widths before collapsing with cell borders
234 * @param aForSide - side to set; only accepts iend, istart, and bstart
236 void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide,
237 BCPixelSize aPixelValue);
239 virtual bool IsFrameOfType(uint32_t aFlags) const override {
240 if (aFlags & eSupportsContainLayoutAndPaint) {
241 return false;
244 return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
247 virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0,
248 bool aRebuildDisplayItems = true) override;
249 virtual void InvalidateFrameWithRect(
250 const nsRect& aRect, uint32_t aDisplayItemKey = 0,
251 bool aRebuildDisplayItems = true) override;
252 virtual void InvalidateFrameForRemoval() override {
253 InvalidateFrameSubtree();
256 #ifdef ACCESSIBILITY
257 virtual mozilla::a11y::AccType AccessibleType() override;
258 #endif
260 protected:
261 /** protected constructor.
262 * @see NewFrame
264 explicit nsTableRowFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
265 ClassID aID = kClassID);
267 void InitChildReflowInput(nsPresContext& aPresContext,
268 const mozilla::LogicalSize& aAvailSize,
269 bool aBorderCollapse,
270 TableCellReflowInput& aReflowInput);
272 virtual LogicalSides GetLogicalSkipSides(
273 const ReflowInput* aReflowInput = nullptr) const override;
275 // row-specific methods
277 nscoord ComputeCellXOffset(const ReflowInput& aState, nsIFrame* aKidFrame,
278 const nsMargin& aKidMargin) const;
280 * Called for incremental/dirty and resize reflows. If aDirtyOnly is true then
281 * only reflow dirty cells.
283 void ReflowChildren(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
284 const ReflowInput& aReflowInput,
285 nsTableFrame& aTableFrame, nsReflowStatus& aStatus);
287 private:
288 struct RowBits {
289 unsigned mRowIndex : 29;
290 unsigned mHasFixedBSize : 1; // set if the dominating style bsize on the
291 // row or any cell is pixel based
292 unsigned mHasPctBSize : 1; // set if the dominating style bsize on the row
293 // or any cell is pct based
294 unsigned mFirstInserted : 1; // if true, then it was the bstart-most newly
295 // inserted row
296 } mBits;
298 // the desired bsize based on the content of the tallest cell in the row
299 nscoord mContentBSize;
300 // the bsize based on a style percentage bsize on either the row or any cell
301 // if mHasPctBSize is set
302 nscoord mStylePctBSize;
303 // the bsize based on a style pixel bsize on the row or any
304 // cell if mHasFixedBSize is set
305 nscoord mStyleFixedBSize;
307 // max-ascent and max-descent amongst all cells that have
308 // 'vertical-align: baseline'
309 nscoord mMaxCellAscent; // does include cells with rowspan > 1
310 nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1
312 // border widths in pixels in the collapsing border model of the *inner*
313 // half of the border only
314 BCPixelSize mBStartBorderWidth;
315 BCPixelSize mBEndBorderWidth;
316 BCPixelSize mIEndContBorderWidth;
317 BCPixelSize mBStartContBorderWidth;
318 BCPixelSize mIStartContBorderWidth;
321 * Sets the NS_ROW_HAS_CELL_WITH_STYLE_BSIZE bit to indicate whether
322 * this row has any cells that have non-auto-bsize. (Row-spanning
323 * cells are ignored.)
325 void InitHasCellWithStyleBSize(nsTableFrame* aTableFrame);
328 inline int32_t nsTableRowFrame::GetAdjustmentForStoredIndex(
329 int32_t aStoredIndex) const {
330 nsTableRowGroupFrame* parentFrame = GetTableRowGroupFrame();
331 return parentFrame->GetAdjustmentForStoredIndex(aStoredIndex);
334 inline void nsTableRowFrame::AddDeletedRowIndex() {
335 nsTableRowGroupFrame* parentFrame = GetTableRowGroupFrame();
336 parentFrame->AddDeletedRowIndex(int32_t(mBits.mRowIndex));
339 inline int32_t nsTableRowFrame::GetRowIndex() const {
340 int32_t storedRowIndex = int32_t(mBits.mRowIndex);
341 int32_t rowIndexAdjustment = GetAdjustmentForStoredIndex(storedRowIndex);
342 return (storedRowIndex - rowIndexAdjustment);
345 inline void nsTableRowFrame::SetRowIndex(int aRowIndex) {
346 // Note: Setting the index of a row (as in the case of adding new rows) should
347 // be preceded by a call to nsTableFrame::RecalculateRowIndices()
348 // so as to correctly clear mDeletedRowIndexRanges.
349 MOZ_ASSERT(
350 GetTableRowGroupFrame()->GetTableFrame()->IsDeletedRowIndexRangesEmpty(),
351 "mDeletedRowIndexRanges should be empty here!");
352 mBits.mRowIndex = aRowIndex;
355 inline bool nsTableRowFrame::IsFirstInserted() const {
356 return bool(mBits.mFirstInserted);
359 inline void nsTableRowFrame::SetFirstInserted(bool aValue) {
360 mBits.mFirstInserted = aValue;
363 inline bool nsTableRowFrame::HasStyleBSize() const {
364 return (bool)mBits.mHasFixedBSize || (bool)mBits.mHasPctBSize;
367 inline bool nsTableRowFrame::HasFixedBSize() const {
368 return (bool)mBits.mHasFixedBSize;
371 inline void nsTableRowFrame::SetHasFixedBSize(bool aValue) {
372 mBits.mHasFixedBSize = aValue;
375 inline bool nsTableRowFrame::HasPctBSize() const {
376 return (bool)mBits.mHasPctBSize;
379 inline void nsTableRowFrame::SetHasPctBSize(bool aValue) {
380 mBits.mHasPctBSize = aValue;
383 inline nscoord nsTableRowFrame::GetContentBSize() const {
384 return mContentBSize;
387 inline void nsTableRowFrame::SetContentBSize(nscoord aValue) {
388 mContentBSize = aValue;
391 inline nscoord nsTableRowFrame::GetFixedBSize() const {
392 if (mBits.mHasFixedBSize) {
393 return mStyleFixedBSize;
395 return 0;
398 inline float nsTableRowFrame::GetPctBSize() const {
399 if (mBits.mHasPctBSize) {
400 return (float)mStylePctBSize / 100.0f;
402 return 0.0f;
405 inline bool nsTableRowFrame::HasUnpaginatedBSize() {
406 return HasAnyStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
409 inline void nsTableRowFrame::SetHasUnpaginatedBSize(bool aValue) {
410 if (aValue) {
411 AddStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
412 } else {
413 RemoveStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE);
417 inline mozilla::LogicalMargin nsTableRowFrame::GetBCBorderWidth(
418 mozilla::WritingMode aWM) {
419 nsPresContext* presContext = PresContext();
420 return mozilla::LogicalMargin(
421 aWM, presContext->DevPixelsToAppUnits(mBStartBorderWidth), 0,
422 presContext->DevPixelsToAppUnits(mBEndBorderWidth), 0);
425 inline void nsTableRowFrame::GetContinuousBCBorderWidth(
426 mozilla::WritingMode aWM, mozilla::LogicalMargin& aBorder) {
427 int32_t d2a = PresContext()->AppUnitsPerDevPixel();
428 aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, mIStartContBorderWidth);
429 aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(d2a, mBStartContBorderWidth);
430 aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(d2a, mIEndContBorderWidth);
433 inline nscoord nsTableRowFrame::GetOuterBStartContBCBorderWidth() {
434 int32_t aPixelsToTwips = mozilla::AppUnitsPerCSSPixel();
435 return BC_BORDER_START_HALF_COORD(aPixelsToTwips, mBStartContBorderWidth);
438 #endif