Bug 1821144 - remove old windows worker definitions. r=aryx
[gecko.git] / layout / tables / nsTableRowGroupFrame.h
blob8f904df0b20d0db58f3f3ef39859fca7d83465ea
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 nsTableRowGroupFrame_h__
6 #define nsTableRowGroupFrame_h__
8 #include "mozilla/Attributes.h"
9 #include "nscore.h"
10 #include "nsContainerFrame.h"
11 #include "nsAtom.h"
12 #include "nsILineIterator.h"
13 #include "nsTArray.h"
14 #include "nsTableFrame.h"
15 #include "mozilla/WritingModes.h"
17 class nsTableRowFrame;
18 namespace mozilla {
19 class PresShell;
20 struct TableRowGroupReflowInput;
21 } // namespace mozilla
23 #define MIN_ROWS_NEEDING_CURSOR 20
25 /**
26 * nsTableRowGroupFrame is the frame that maps row groups
27 * (HTML tags THEAD, TFOOT, and TBODY). This class cannot be reused
28 * outside of an nsTableFrame. It assumes that its parent is an nsTableFrame,
29 * and its children are nsTableRowFrames.
31 * @see nsTableFrame
32 * @see nsTableRowFrame
34 class nsTableRowGroupFrame final : public nsContainerFrame,
35 public nsILineIterator {
36 using TableRowGroupReflowInput = mozilla::TableRowGroupReflowInput;
38 public:
39 NS_DECL_QUERYFRAME
40 NS_DECL_FRAMEARENA_HELPERS(nsTableRowGroupFrame)
42 /** instantiate a new instance of nsTableRowFrame.
43 * @param aPresShell the pres shell for this frame
45 * @return the frame that was created
47 friend nsTableRowGroupFrame* NS_NewTableRowGroupFrame(
48 mozilla::PresShell* aPresShell, ComputedStyle* aStyle);
49 virtual ~nsTableRowGroupFrame();
51 // nsIFrame overrides
52 void Init(nsIContent* aContent, nsContainerFrame* aParent,
53 nsIFrame* aPrevInFlow) override {
54 nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
55 if (!aPrevInFlow) {
56 mWritingMode = GetTableFrame()->GetWritingMode();
60 void DestroyFrom(nsIFrame* aDestructRoot,
61 PostDestroyData& aPostDestroyData) override;
63 /** @see nsIFrame::DidSetComputedStyle */
64 void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
66 void AppendFrames(ChildListID aListID, nsFrameList&& aFrameList) override;
67 void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
68 const nsLineList::iterator* aPrevFrameLine,
69 nsFrameList&& aFrameList) override;
70 void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
72 nsMargin GetUsedMargin() const override;
73 nsMargin GetUsedBorder() const override;
74 nsMargin GetUsedPadding() const override;
76 void BuildDisplayList(nsDisplayListBuilder* aBuilder,
77 const nsDisplayListSet& aLists) override;
79 /**
80 * Calls Reflow for all of its child rows.
82 * Rows are all set to the same isize and stacked in the block direction.
84 * Rows are not split unless absolutely necessary.
86 * @param aDesiredSize isize set to isize of rows, bsize set to
87 * sum of bsize of rows that fit in AvailableBSize.
89 * @see nsIFrame::Reflow
91 void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
92 const ReflowInput& aReflowInput,
93 nsReflowStatus& aStatus) override;
95 bool ComputeCustomOverflow(mozilla::OverflowAreas& aOverflowAreas) override;
97 #ifdef DEBUG_FRAME_DUMP
98 nsresult GetFrameName(nsAString& aResult) const override;
99 #endif
101 nsTableRowFrame* GetFirstRow();
102 nsTableRowFrame* GetLastRow();
104 nsTableFrame* GetTableFrame() const {
105 nsIFrame* parent = GetParent();
106 MOZ_ASSERT(parent && parent->IsTableFrame());
107 return static_cast<nsTableFrame*>(parent);
110 /** return the number of child rows (not necessarily == number of child
111 * frames) */
112 int32_t GetRowCount() const;
114 /** return the table-relative row index of the first row in this rowgroup.
115 * if there are no rows, -1 is returned.
117 int32_t GetStartRowIndex() const;
119 /** Adjust the row indices of all rows whose index is >= aRowIndex.
120 * @param aRowIndex - start adjusting with this index
121 * @param aAdjustment - shift the row index by this amount
123 void AdjustRowIndices(int32_t aRowIndex, int32_t anAdjustment);
125 // See nsTableFrame.h
126 int32_t GetAdjustmentForStoredIndex(int32_t aStoredIndex);
128 /* mark rows starting from aStartRowFrame to the next 'aNumRowsToRemove-1'
129 * number of rows as deleted
131 void MarkRowsAsDeleted(nsTableRowFrame& aStartRowFrame,
132 int32_t aNumRowsToDelete);
134 // See nsTableFrame.h
135 void AddDeletedRowIndex(int32_t aDeletedRowStoredIndex);
138 * Used for header and footer row group frames that are repeated when
139 * splitting a table frame.
141 * Performs any table specific initialization
143 * @param aHeaderFooterFrame the original header or footer row group frame
144 * that was repeated
146 nsresult InitRepeatedFrame(nsTableRowGroupFrame* aHeaderFooterFrame);
149 * Get the total bsize of all the row rects
151 nscoord GetBSizeBasis(const ReflowInput& aReflowInput);
153 mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
156 * Gets inner border widths before collapsing with cell borders
157 * Caller must get bstart border from previous row group or from table
158 * GetContinuousBCBorderWidth will not overwrite aBorder.BStart()
159 * see nsTablePainter about continuous borders
161 void GetContinuousBCBorderWidth(mozilla::WritingMode aWM,
162 mozilla::LogicalMargin& aBorder);
165 * Sets full border widths before collapsing with cell borders
166 * @param aForSide - side to set; only IEnd, IStart, BEnd are valid
168 void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide,
169 BCPixelSize aPixelValue);
171 * Adjust to the effect of visibility:collapse on the row group and
172 * its children
173 * @return additional shift bstart-wards that should be applied
174 * to subsequent rowgroups due to rows and this
175 * rowgroup being collapsed
176 * @param aBTotalOffset the total amount that the rowgroup is shifted
177 * @param aISize new isize of the rowgroup
178 * @param aWM the table's writing mode
180 nscoord CollapseRowGroupIfNecessary(nscoord aBTotalOffset, nscoord aISize,
181 mozilla::WritingMode aWM);
183 // nsILineIterator methods
184 public:
185 // The table row is the equivalent to a line in block layout.
186 // The nsILineIterator assumes that a line resides in a block, this role is
187 // fullfilled by the row group. Rows in table are counted relative to the
188 // table. The row index of row corresponds to the cellmap coordinates. The
189 // line index with respect to a row group can be computed by substracting the
190 // row index of the first row in the row group.
192 /** Get the number of rows in a row group
193 * @return the number of lines in a row group
195 int32_t GetNumLines() const final;
197 /** @see nsILineIterator.h IsLineIteratorFlowRTL */
198 bool IsLineIteratorFlowRTL() final;
200 /** Return structural information about a line. */
201 Result<LineInfo, nsresult> GetLine(int32_t aLineNumber) final;
203 /** Given a frame that's a child of the rowgroup, find which line its on.
204 * @param aFrame - frame, should be a row
205 * @param aStartLine - minimal index to return
206 * @return row index relative to the row group if this a row
207 * frame and the index is at least aStartLine.
208 * -1 if the frame cannot be found.
210 int32_t FindLineContaining(nsIFrame* aFrame, int32_t aStartLine = 0) final;
212 /** Find the orginating cell frame on a row that is the nearest to the
213 * inline-dir coordinate of aPos.
214 * @param aLineNumber - the index of the row relative to the row group
215 * @param aPos - coordinate in twips relative to the
216 * origin of the row group
217 * @param aFrameFound - pointer to the cellframe
218 * @param aPosIsBeforeFirstFrame - the point is before the first originating
219 * cellframe
220 * @param aPosIsAfterLastFrame - the point is after the last originating
221 * cellframe
223 NS_IMETHOD FindFrameAt(int32_t aLineNumber, nsPoint aPos,
224 nsIFrame** aFrameFound, bool* aPosIsBeforeFirstFrame,
225 bool* aPosIsAfterLastFrame) final;
227 /** Check whether visual and logical order of cell frames within a line are
228 * identical. As the layout will reorder them this is always the case
229 * @param aLine - the index of the row relative to the table
230 * @param aIsReordered - returns false
231 * @param aFirstVisual - if the table is rtl first originating cell frame
232 * @param aLastVisual - if the table is rtl last originating cell frame
235 NS_IMETHOD CheckLineOrder(int32_t aLine, bool* aIsReordered,
236 nsIFrame** aFirstVisual,
237 nsIFrame** aLastVisual) final;
239 // row cursor methods to speed up searching for the row(s)
240 // containing a point. The basic idea is that we set the cursor
241 // property if the rows' y and yMosts are non-decreasing (considering only
242 // rows with nonempty overflowAreas --- empty overflowAreas never participate
243 // in event handling or painting), and the rowgroup has sufficient number of
244 // rows. The cursor property points to a "recently used" row. If we get a
245 // series of requests that work on rows "near" the cursor, then we can find
246 // those nearby rows quickly by starting our search at the cursor.
247 // This code is based on the line cursor code in nsBlockFrame. It's more
248 // general though, and could be extracted and used elsewhere.
249 struct FrameCursorData {
250 nsTArray<nsIFrame*> mFrames;
251 uint32_t mCursorIndex;
252 nscoord mOverflowAbove;
253 nscoord mOverflowBelow;
255 FrameCursorData()
256 : mFrames(MIN_ROWS_NEEDING_CURSOR),
257 mCursorIndex(0),
258 mOverflowAbove(0),
259 mOverflowBelow(0) {}
261 bool AppendFrame(nsIFrame* aFrame);
263 void FinishBuildingCursor() { mFrames.Compact(); }
266 // Clear out row cursor because we're disturbing the rows (e.g., Reflow)
267 void ClearRowCursor();
270 * Get the first row that might contain y-coord 'aY', or nullptr if you must
271 * search all rows.
272 * The actual row returned might not contain 'aY', but if not, it is
273 * guaranteed to be before any row which does contain 'aY'.
274 * aOverflowAbove is the maximum over all rows of -row.GetOverflowRect().y.
275 * To find all rows that intersect the vertical interval aY/aYMost, call
276 * GetFirstRowContaining(aY, &overflowAbove), and then iterate through all
277 * rows until reaching a row where row->GetRect().y - overflowAbove >= aYMost.
278 * That row and all subsequent rows cannot intersect the interval.
280 nsIFrame* GetFirstRowContaining(nscoord aY, nscoord* aOverflowAbove);
283 * Set up the row cursor. After this, call AppendFrame for every
284 * child frame in sibling order. Ensure that the child frame y and YMost
285 * values form non-decreasing sequences (should always be true for table
286 * rows); if this is violated, call ClearRowCursor(). If we return nullptr,
287 * then we decided not to use a cursor or we already have one set up.
289 FrameCursorData* SetupRowCursor();
291 bool CanProvideLineIterator() const final { return true; }
292 nsILineIterator* GetLineIterator() final { return this; }
294 bool IsFrameOfType(uint32_t aFlags) const override {
295 if (aFlags & (eSupportsContainLayoutAndPaint | eSupportsAspectRatio)) {
296 return false;
299 return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
302 void InvalidateFrame(uint32_t aDisplayItemKey = 0,
303 bool aRebuildDisplayItems = true) override;
304 void InvalidateFrameWithRect(const nsRect& aRect,
305 uint32_t aDisplayItemKey = 0,
306 bool aRebuildDisplayItems = true) override;
307 void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
309 protected:
310 explicit nsTableRowGroupFrame(ComputedStyle* aStyle,
311 nsPresContext* aPresContext);
313 void InitChildReflowInput(nsPresContext& aPresContext, bool aBorderCollapse,
314 ReflowInput& aReflowInput);
316 LogicalSides GetLogicalSkipSides() const override;
318 void PlaceChild(nsPresContext* aPresContext,
319 TableRowGroupReflowInput& aReflowInput, nsIFrame* aKidFrame,
320 const ReflowInput& aKidReflowInput, mozilla::WritingMode aWM,
321 const mozilla::LogicalPoint& aKidPosition,
322 const nsSize& aContainerSize, ReflowOutput& aDesiredSize,
323 const nsRect& aOriginalKidRect,
324 const nsRect& aOriginalKidInkOverflow);
326 void CalculateRowBSizes(nsPresContext* aPresContext,
327 ReflowOutput& aDesiredSize,
328 const ReflowInput& aReflowInput);
330 void DidResizeRows(ReflowOutput& aDesiredSize);
333 * Reflow the frames we've already created
335 * @param aPresContext presentation context to use
336 * @param aReflowInput current inline state
338 void ReflowChildren(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
339 TableRowGroupReflowInput& aReflowInput,
340 nsReflowStatus& aStatus,
341 bool* aPageBreakBeforeEnd = nullptr);
343 nsresult SplitRowGroup(nsPresContext* aPresContext,
344 ReflowOutput& aDesiredSize,
345 const ReflowInput& aReflowInput,
346 nsTableFrame* aTableFrame, nsReflowStatus& aStatus,
347 bool aRowForcedPageBreak);
349 void SplitSpanningCells(nsPresContext& aPresContext,
350 const ReflowInput& aReflowInput,
351 nsTableFrame& aTableFrame, nsTableRowFrame& aFirstRow,
352 nsTableRowFrame& aLastRow, bool aFirstRowIsTopOfPage,
353 nscoord aSpanningRowBottom,
354 nsTableRowFrame*& aContRowFrame,
355 nsTableRowFrame*& aFirstTruncatedRow,
356 nscoord& aDesiredHeight);
358 void CreateContinuingRowFrame(nsIFrame& aRowFrame, nsIFrame** aContRowFrame);
360 bool IsSimpleRowFrame(nsTableFrame* aTableFrame, nsTableRowFrame* aRowFrame);
362 void GetNextRowSibling(nsIFrame** aRowFrame);
364 void UndoContinuedRow(nsPresContext* aPresContext, nsTableRowFrame* aRow);
366 private:
367 // border widths in pixels in the collapsing border model
368 BCPixelSize mIEndContBorderWidth = 0;
369 BCPixelSize mBEndContBorderWidth = 0;
370 BCPixelSize mIStartContBorderWidth = 0;
372 public:
373 bool IsRepeatable() const;
374 void SetRepeatable(bool aRepeatable);
375 bool HasStyleBSize() const;
376 void SetHasStyleBSize(bool aValue);
377 bool HasInternalBreakBefore() const;
378 bool HasInternalBreakAfter() const;
381 inline bool nsTableRowGroupFrame::IsRepeatable() const {
382 return HasAnyStateBits(NS_ROWGROUP_REPEATABLE);
385 inline void nsTableRowGroupFrame::SetRepeatable(bool aRepeatable) {
386 if (aRepeatable) {
387 AddStateBits(NS_ROWGROUP_REPEATABLE);
388 } else {
389 RemoveStateBits(NS_ROWGROUP_REPEATABLE);
393 inline bool nsTableRowGroupFrame::HasStyleBSize() const {
394 return HasAnyStateBits(NS_ROWGROUP_HAS_STYLE_BSIZE);
397 inline void nsTableRowGroupFrame::SetHasStyleBSize(bool aValue) {
398 if (aValue) {
399 AddStateBits(NS_ROWGROUP_HAS_STYLE_BSIZE);
400 } else {
401 RemoveStateBits(NS_ROWGROUP_HAS_STYLE_BSIZE);
405 inline void nsTableRowGroupFrame::GetContinuousBCBorderWidth(
406 mozilla::WritingMode aWM, mozilla::LogicalMargin& aBorder) {
407 int32_t d2a = PresContext()->AppUnitsPerDevPixel();
408 aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, mIEndContBorderWidth);
409 aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, mBEndContBorderWidth);
410 aBorder.IStart(aWM) = BC_BORDER_END_HALF_COORD(d2a, mIStartContBorderWidth);
412 #endif