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"
10 #include "nsContainerFrame.h"
11 #include "nsTableRowGroupFrame.h"
12 #include "mozilla/WritingModes.h"
14 class nsTableCellFrame
;
17 struct TableCellReflowInput
;
18 } // namespace mozilla
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.
27 * @see nsTableRowGroupFrame
28 * @see nsTableCellFrame
30 class nsTableRowFrame
: public nsContainerFrame
{
31 using TableCellReflowInput
= mozilla::TableCellReflowInput
;
35 NS_DECL_FRAMEARENA_HELPERS(nsTableRowFrame
)
37 virtual ~nsTableRowFrame();
39 void Init(nsIContent
* aContent
, nsContainerFrame
* aParent
,
40 nsIFrame
* aPrevInFlow
) override
;
42 void Destroy(DestroyContext
&) override
;
44 void DidSetComputedStyle(ComputedStyle
* aOldComputedStyle
) override
;
46 void AppendFrames(ChildListID aListID
, nsFrameList
&& aFrameList
) override
;
47 void InsertFrames(ChildListID aListID
, nsIFrame
* aPrevFrame
,
48 const nsLineList::iterator
* aPrevFrameLine
,
49 nsFrameList
&& aFrameList
) override
;
50 void RemoveFrame(DestroyContext
&, ChildListID
, nsIFrame
*) override
;
52 /** instantiate a new instance of nsTableRowFrame.
53 * @param aPresShell the pres shell for this frame
55 * @return the frame that was created
57 friend nsTableRowFrame
* NS_NewTableRowFrame(mozilla::PresShell
* aPresShell
,
58 ComputedStyle
* aStyle
);
60 nsTableRowGroupFrame
* GetTableRowGroupFrame() const {
61 nsIFrame
* parent
= GetParent();
62 MOZ_ASSERT(parent
&& parent
->IsTableRowGroupFrame());
63 return static_cast<nsTableRowGroupFrame
*>(parent
);
66 nsTableFrame
* GetTableFrame() const {
67 return GetTableRowGroupFrame()->GetTableFrame();
70 nsMargin
GetUsedMargin() const override
;
71 nsMargin
GetUsedBorder() const override
;
72 nsMargin
GetUsedPadding() const override
;
74 void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
75 const nsDisplayListSet
& aLists
) override
;
77 void PaintCellBackgroundsForFrame(nsIFrame
* aFrame
,
78 nsDisplayListBuilder
* aBuilder
,
79 const nsDisplayListSet
& aLists
,
80 const nsPoint
& aOffset
= nsPoint());
82 // Implemented in nsTableCellFrame.h, because it needs to know about the
83 // nsTableCellFrame class, but we can't include nsTableCellFrame.h here.
84 inline nsTableCellFrame
* GetFirstCell() const;
86 /** calls Reflow for all of its child cells.
88 * Cells with rowspan=1 are all set to the same height and stacked
91 * Cells are not split unless absolutely necessary.
93 * Cells are resized in nsTableFrame::BalanceColumnWidths and
94 * nsTableFrame::ShrinkWrapChildren
96 * @param aDesiredSize width set to width of the sum of the cells,
97 * height set to height of cells with rowspan=1.
99 * @see nsIFrame::Reflow
100 * @see nsTableFrame::BalanceColumnWidths
101 * @see nsTableFrame::ShrinkWrapChildren
103 void Reflow(nsPresContext
* aPresContext
, ReflowOutput
& aDesiredSize
,
104 const ReflowInput
& aReflowInput
,
105 nsReflowStatus
& aStatus
) override
;
109 #ifdef DEBUG_FRAME_DUMP
110 nsresult
GetFrameName(nsAString
& aResult
) const override
;
113 void UpdateBSize(nscoord aBSize
, nscoord aAscent
, nscoord aDescent
,
114 nsTableFrame
* aTableFrame
= nullptr,
115 nsTableCellFrame
* aCellFrame
= nullptr);
119 // calculate the bsize, considering content bsize of the
120 // cells and the style bsize of the row and cells, excluding pct bsizes
121 nscoord
CalcBSize(const ReflowInput
& aReflowInput
);
123 // Support for cells with 'vertical-align: baseline'.
126 * returns the max-ascent amongst all the cells that have
127 * 'vertical-align: baseline', *including* cells with rowspans.
128 * returns 0 if we don't have any cell with 'vertical-align: baseline'
130 nscoord
GetMaxCellAscent() const;
132 /* return the row ascent
134 Maybe
<nscoord
> GetRowBaseline(mozilla::WritingMode aWM
);
136 /** returns the ordinal position of this row in its table */
137 virtual int32_t GetRowIndex() const;
139 /** set this row's starting row index */
140 void SetRowIndex(int aRowIndex
);
142 // See nsTableFrame.h
143 int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex
) const;
145 // See nsTableFrame.h
146 void AddDeletedRowIndex();
148 /** used by row group frame code */
149 nscoord
ReflowCellFrame(nsPresContext
* aPresContext
,
150 const ReflowInput
& aReflowInput
, bool aIsTopOfPage
,
151 nsTableCellFrame
* aCellFrame
, nscoord aAvailableBSize
,
152 nsReflowStatus
& aStatus
);
154 * Collapse the row if required, apply col and colgroup visibility: collapse
155 * info to the cells in the row.
156 * @return the amount to shift bstart-wards all following rows
157 * @param aRowOffset - shift the row bstart-wards by this amount
158 * @param aISize - new isize of the row
159 * @param aCollapseGroup - parent rowgroup is collapsed so this row needs
161 * @param aDidCollapse - the row has been collapsed
163 nscoord
CollapseRowIfNecessary(nscoord aRowOffset
, nscoord aISize
,
164 bool aCollapseGroup
, bool& aDidCollapse
);
167 * Insert a cell frame after the last cell frame that has a col index
168 * that is less than aColIndex. If no such cell frame is found the
169 * frame to insert is prepended to the child list.
170 * @param aFrame the cell frame to insert
171 * @param aColIndex the col index
173 void InsertCellFrame(nsTableCellFrame
* aFrame
, int32_t aColIndex
);
176 * Calculate the cell frame's actual block-size given its desired block-size
177 * (the border-box block-size in the last reflow). This method takes into
178 * account the specified bsize (in the style).
180 * @return the specified block-size if it is larger than the desired
181 * block-size. Otherwise, the desired block-size.
183 nscoord
CalcCellActualBSize(nsTableCellFrame
* aCellFrame
,
184 const nscoord
& aDesiredBSize
,
185 mozilla::WritingMode aWM
);
187 bool IsFirstInserted() const;
188 void SetFirstInserted(bool aValue
);
190 nscoord
GetContentBSize() const;
191 void SetContentBSize(nscoord aTwipValue
);
193 bool HasStyleBSize() const;
195 bool HasFixedBSize() const;
196 void SetHasFixedBSize(bool aValue
);
198 bool HasPctBSize() const;
199 void SetHasPctBSize(bool aValue
);
201 nscoord
GetFixedBSize() const;
202 void SetFixedBSize(nscoord aValue
);
204 float GetPctBSize() const;
205 void SetPctBSize(float aPctValue
, bool aForce
= false);
207 nscoord
GetInitialBSize(nscoord aBasis
= 0) const;
209 nsTableRowFrame
* GetPrevRow() const;
210 nsTableRowFrame
* GetNextRow() const;
212 bool HasUnpaginatedBSize() const {
213 return HasAnyStateBits(NS_TABLE_ROW_HAS_UNPAGINATED_BSIZE
);
215 nscoord
GetUnpaginatedBSize() const;
216 void SetUnpaginatedBSize(nscoord aValue
);
218 BCPixelSize
GetBStartBCBorderWidth() const { return mBStartBorderWidth
; }
219 BCPixelSize
GetBEndBCBorderWidth() const { return mBEndBorderWidth
; }
220 void SetBStartBCBorderWidth(BCPixelSize aWidth
) {
221 mBStartBorderWidth
= aWidth
;
223 void SetBEndBCBorderWidth(BCPixelSize aWidth
) { mBEndBorderWidth
= aWidth
; }
224 mozilla::LogicalMargin
GetBCBorderWidth(mozilla::WritingMode aWM
);
226 void InvalidateFrame(uint32_t aDisplayItemKey
= 0,
227 bool aRebuildDisplayItems
= true) override
;
228 void InvalidateFrameWithRect(const nsRect
& aRect
,
229 uint32_t aDisplayItemKey
= 0,
230 bool aRebuildDisplayItems
= true) override
;
231 void InvalidateFrameForRemoval() override
{ InvalidateFrameSubtree(); }
234 mozilla::a11y::AccType
AccessibleType() override
;
238 /** protected constructor.
241 explicit nsTableRowFrame(ComputedStyle
* aStyle
, nsPresContext
* aPresContext
,
242 ClassID aID
= kClassID
);
244 void InitChildReflowInput(nsPresContext
& aPresContext
,
245 const mozilla::LogicalSize
& aAvailSize
,
246 bool aBorderCollapse
,
247 TableCellReflowInput
& aReflowInput
);
249 LogicalSides
GetLogicalSkipSides() const override
;
251 // row-specific methods
253 nscoord
ComputeCellXOffset(const ReflowInput
& aState
, nsIFrame
* aKidFrame
,
254 const nsMargin
& aKidMargin
) const;
256 * Called for incremental/dirty and resize reflows. If aDirtyOnly is true then
257 * only reflow dirty cells.
259 void ReflowChildren(nsPresContext
* aPresContext
, ReflowOutput
& aDesiredSize
,
260 const ReflowInput
& aReflowInput
,
261 nsTableFrame
& aTableFrame
, nsReflowStatus
& aStatus
);
265 unsigned mRowIndex
: 29;
266 unsigned mHasFixedBSize
: 1; // set if the dominating style bsize on the
267 // row or any cell is pixel based
268 unsigned mHasPctBSize
: 1; // set if the dominating style bsize on the row
269 // or any cell is pct based
270 unsigned mFirstInserted
: 1; // if true, then it was the bstart-most newly
274 // the desired bsize based on the content of the tallest cell in the row
275 nscoord mContentBSize
= 0;
276 // the bsize based on a style percentage bsize on either the row or any cell
277 // if mHasPctBSize is set
278 nscoord mStylePctBSize
= 0;
279 // the bsize based on a style pixel bsize on the row or any
280 // cell if mHasFixedBSize is set
281 nscoord mStyleFixedBSize
= 0;
283 // max-ascent and max-descent amongst all cells that have
284 // 'vertical-align: baseline'
285 nscoord mMaxCellAscent
= 0; // does include cells with rowspan > 1
286 nscoord mMaxCellDescent
= 0; // does *not* include cells with rowspan > 1
288 // border widths in pixels in the collapsing border model of the *inner*
289 // half of the border only
290 BCPixelSize mBStartBorderWidth
= 0;
291 BCPixelSize mBEndBorderWidth
= 0;
294 * Sets the NS_ROW_HAS_CELL_WITH_STYLE_BSIZE bit to indicate whether
295 * this row has any cells that have non-auto-bsize. (Row-spanning
296 * cells are ignored.)
298 void InitHasCellWithStyleBSize(nsTableFrame
* aTableFrame
);
301 inline int32_t nsTableRowFrame::GetAdjustmentForStoredIndex(
302 int32_t aStoredIndex
) const {
303 nsTableRowGroupFrame
* parentFrame
= GetTableRowGroupFrame();
304 return parentFrame
->GetAdjustmentForStoredIndex(aStoredIndex
);
307 inline void nsTableRowFrame::AddDeletedRowIndex() {
308 nsTableRowGroupFrame
* parentFrame
= GetTableRowGroupFrame();
309 parentFrame
->AddDeletedRowIndex(int32_t(mBits
.mRowIndex
));
312 inline int32_t nsTableRowFrame::GetRowIndex() const {
313 int32_t storedRowIndex
= int32_t(mBits
.mRowIndex
);
314 int32_t rowIndexAdjustment
= GetAdjustmentForStoredIndex(storedRowIndex
);
315 return (storedRowIndex
- rowIndexAdjustment
);
318 inline void nsTableRowFrame::SetRowIndex(int aRowIndex
) {
319 // Note: Setting the index of a row (as in the case of adding new rows) should
320 // be preceded by a call to nsTableFrame::RecalculateRowIndices()
321 // so as to correctly clear mDeletedRowIndexRanges.
323 GetTableRowGroupFrame()->GetTableFrame()->IsDeletedRowIndexRangesEmpty(),
324 "mDeletedRowIndexRanges should be empty here!");
325 mBits
.mRowIndex
= aRowIndex
;
328 inline bool nsTableRowFrame::IsFirstInserted() const {
329 return bool(mBits
.mFirstInserted
);
332 inline void nsTableRowFrame::SetFirstInserted(bool aValue
) {
333 mBits
.mFirstInserted
= aValue
;
336 inline bool nsTableRowFrame::HasStyleBSize() const {
337 return (bool)mBits
.mHasFixedBSize
|| (bool)mBits
.mHasPctBSize
;
340 inline bool nsTableRowFrame::HasFixedBSize() const {
341 return (bool)mBits
.mHasFixedBSize
;
344 inline void nsTableRowFrame::SetHasFixedBSize(bool aValue
) {
345 mBits
.mHasFixedBSize
= aValue
;
348 inline bool nsTableRowFrame::HasPctBSize() const {
349 return (bool)mBits
.mHasPctBSize
;
352 inline void nsTableRowFrame::SetHasPctBSize(bool aValue
) {
353 mBits
.mHasPctBSize
= aValue
;
356 inline nscoord
nsTableRowFrame::GetContentBSize() const {
357 return mContentBSize
;
360 inline void nsTableRowFrame::SetContentBSize(nscoord aValue
) {
361 mContentBSize
= aValue
;
364 inline nscoord
nsTableRowFrame::GetFixedBSize() const {
365 if (mBits
.mHasFixedBSize
) {
366 return mStyleFixedBSize
;
371 inline float nsTableRowFrame::GetPctBSize() const {
372 if (mBits
.mHasPctBSize
) {
373 return (float)mStylePctBSize
/ 100.0f
;
378 inline mozilla::LogicalMargin
nsTableRowFrame::GetBCBorderWidth(
379 mozilla::WritingMode aWM
) {
380 nsPresContext
* presContext
= PresContext();
381 return mozilla::LogicalMargin(
382 aWM
, presContext
->DevPixelsToAppUnits(mBStartBorderWidth
), 0,
383 presContext
->DevPixelsToAppUnits(mBEndBorderWidth
), 0);