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 nsTableFrame_h__
6 #define nsTableFrame_h__
8 #include "mozilla/Attributes.h"
11 #include "nsContainerFrame.h"
12 #include "nsStyleCoord.h"
13 #include "nsStyleConsts.h"
14 #include "nsTableColFrame.h"
15 #include "nsTableColGroupFrame.h"
16 #include "nsCellMap.h"
17 #include "nsGkAtoms.h"
18 #include "nsDisplayList.h"
20 class nsTableCellFrame
;
22 class nsTableColFrame
;
23 class nsColGroupFrame
;
24 class nsTableRowGroupFrame
;
25 class nsTableRowFrame
;
26 class nsTableColGroupFrame
;
27 class nsITableLayoutStrategy
;
30 struct nsTableReflowState
;
31 struct nsStylePosition
;
32 struct BCPropertyData
;
34 static inline bool IS_TABLE_CELL(nsIAtom
* frameType
) {
35 return nsGkAtoms::tableCellFrame
== frameType
||
36 nsGkAtoms::bcTableCellFrame
== frameType
;
39 static inline bool FrameHasBorderOrBackground(nsIFrame
* f
) {
40 return (f
->StyleVisibility()->IsVisible() &&
41 (!f
->StyleBackground()->IsTransparent() ||
42 f
->StyleDisplay()->mAppearance
||
43 f
->StyleBorder()->HasBorder()));
46 class nsDisplayTableItem
: public nsDisplayItem
49 nsDisplayTableItem(nsDisplayListBuilder
* aBuilder
, nsIFrame
* aFrame
) :
50 nsDisplayItem(aBuilder
, aFrame
),
51 mPartHasFixedBackground(false) {}
53 // With collapsed borders, parts of the collapsed border can extend outside
54 // the table part frames, so allow this display element to blow out to our
55 // overflow rect. This is also useful for row frames that have spanning
56 // cells extending outside them.
57 virtual nsRect
GetBounds(nsDisplayListBuilder
* aBuilder
, bool* aSnap
) MOZ_OVERRIDE
;
59 void UpdateForFrameBackground(nsIFrame
* aFrame
);
62 bool mPartHasFixedBackground
;
65 class nsAutoPushCurrentTableItem
68 nsAutoPushCurrentTableItem() : mBuilder(nullptr) {}
70 void Push(nsDisplayListBuilder
* aBuilder
, nsDisplayTableItem
* aPushItem
)
73 mOldCurrentItem
= aBuilder
->GetCurrentTableItem();
74 aBuilder
->SetCurrentTableItem(aPushItem
);
76 mPushedItem
= aPushItem
;
79 ~nsAutoPushCurrentTableItem() {
83 NS_ASSERTION(mBuilder
->GetCurrentTableItem() == mPushedItem
,
84 "Someone messed with the current table item behind our back!");
86 mBuilder
->SetCurrentTableItem(mOldCurrentItem
);
90 nsDisplayListBuilder
* mBuilder
;
91 nsDisplayTableItem
* mOldCurrentItem
;
93 nsDisplayTableItem
* mPushedItem
;
97 /* ============================================================================ */
100 * nsTableFrame maps the inner portion of a table (everything except captions.)
101 * Used as a pseudo-frame within nsTableOuterFrame, it may also be used
102 * stand-alone as the top-level frame.
104 * The principal child list contains row group frames. There is also an
105 * additional child list, kColGroupList, which contains the col group frames.
107 class nsTableFrame
: public nsContainerFrame
110 NS_DECL_FRAMEARENA_HELPERS
112 static void DestroyPositionedTablePartArray(void* aPropertyValue
);
113 NS_DECLARE_FRAME_PROPERTY(PositionedTablePartArray
, DestroyPositionedTablePartArray
)
115 /** nsTableOuterFrame has intimate knowledge of the inner table frame */
116 friend class nsTableOuterFrame
;
118 /** instantiate a new instance of nsTableRowFrame.
119 * @param aPresShell the pres shell for this frame
121 * @return the frame that was created
123 friend nsTableFrame
* NS_NewTableFrame(nsIPresShell
* aPresShell
,
124 nsStyleContext
* aContext
);
126 /** sets defaults for table-specific style.
127 * @see nsIFrame::Init
129 virtual void Init(nsIContent
* aContent
,
130 nsContainerFrame
* aParent
,
131 nsIFrame
* aPrevInFlow
) MOZ_OVERRIDE
;
133 static float GetTwipsToPixels(nsPresContext
* aPresContext
);
135 // Return true if aParentReflowState.frame or any of its ancestors within
136 // the containing table have non-auto height. (e.g. pct or fixed height)
137 static bool AncestorsHaveStyleHeight(const nsHTMLReflowState
& aParentReflowState
);
139 // See if a special height reflow will occur due to having a pct height when
140 // the pct height basis may not yet be valid.
141 static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState
& aReflowState
);
143 // Notify the frame and its ancestors (up to the containing table) that a special
144 // height reflow will occur.
145 static void RequestSpecialHeightReflow(const nsHTMLReflowState
& aReflowState
);
147 static void RePositionViews(nsIFrame
* aFrame
);
149 static bool PageBreakAfter(nsIFrame
* aSourceFrame
,
150 nsIFrame
* aNextFrame
);
152 // Register a positioned table part with its nsTableFrame. These objects will
153 // be visited by FixupPositionedTableParts after reflow is complete. (See that
154 // function for more explanation.) Should be called during frame construction.
155 static void RegisterPositionedTablePart(nsIFrame
* aFrame
);
157 // Unregister a positioned table part with its nsTableFrame.
158 static void UnregisterPositionedTablePart(nsIFrame
* aFrame
,
159 nsIFrame
* aDestructRoot
);
161 nsPoint
GetFirstSectionOrigin(const nsHTMLReflowState
& aReflowState
) const;
163 * Notification that aAttribute has changed for content inside a table (cell, row, etc)
165 void AttributeChangedFor(nsIFrame
* aFrame
,
166 nsIContent
* aContent
,
167 nsIAtom
* aAttribute
);
169 /** @see nsIFrame::DestroyFrom */
170 virtual void DestroyFrom(nsIFrame
* aDestructRoot
) MOZ_OVERRIDE
;
172 /** @see nsIFrame::DidSetStyleContext */
173 virtual void DidSetStyleContext(nsStyleContext
* aOldStyleContext
) MOZ_OVERRIDE
;
175 virtual void SetInitialChildList(ChildListID aListID
,
176 nsFrameList
& aChildList
) MOZ_OVERRIDE
;
177 virtual void AppendFrames(ChildListID aListID
,
178 nsFrameList
& aFrameList
) MOZ_OVERRIDE
;
179 virtual void InsertFrames(ChildListID aListID
,
180 nsIFrame
* aPrevFrame
,
181 nsFrameList
& aFrameList
) MOZ_OVERRIDE
;
182 virtual void RemoveFrame(ChildListID aListID
,
183 nsIFrame
* aOldFrame
) MOZ_OVERRIDE
;
185 virtual nsMargin
GetUsedBorder() const MOZ_OVERRIDE
;
186 virtual nsMargin
GetUsedPadding() const MOZ_OVERRIDE
;
187 virtual nsMargin
GetUsedMargin() const MOZ_OVERRIDE
;
189 // Get the offset from the border box to the area where the row groups fit
190 nsMargin
GetChildAreaOffset(const nsHTMLReflowState
* aReflowState
) const;
192 /** helper method to find the table parent of any table frame object */
193 static nsTableFrame
* GetTableFrame(nsIFrame
* aSourceFrame
);
195 /* Like GetTableFrame, but will return nullptr if we don't pass through
196 * aMustPassThrough on the way to the table.
198 static nsTableFrame
* GetTableFramePassingThrough(nsIFrame
* aMustPassThrough
,
199 nsIFrame
* aSourceFrame
);
201 typedef void (* DisplayGenericTablePartTraversal
)
202 (nsDisplayListBuilder
* aBuilder
, nsFrame
* aFrame
,
203 const nsRect
& aDirtyRect
, const nsDisplayListSet
& aLists
);
204 static void GenericTraversal(nsDisplayListBuilder
* aBuilder
, nsFrame
* aFrame
,
205 const nsRect
& aDirtyRect
, const nsDisplayListSet
& aLists
);
208 * Helper method to handle display common to table frames, rowgroup frames
209 * and row frames. It creates a background display item for handling events
210 * if necessary, an outline display item if necessary, and displays
211 * all the the frame's children.
212 * @param aDisplayItem the display item created for this part, or null
213 * if this part's border/background painting is delegated to an ancestor
214 * @param aTraversal a function that gets called to traverse the table
215 * part's child frames and add their display list items to a
218 static void DisplayGenericTablePart(nsDisplayListBuilder
* aBuilder
,
220 const nsRect
& aDirtyRect
,
221 const nsDisplayListSet
& aLists
,
222 nsDisplayTableItem
* aDisplayItem
,
223 DisplayGenericTablePartTraversal aTraversal
= GenericTraversal
);
225 // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
226 // of type aChildType.
227 static nsIFrame
* GetFrameAtOrBefore(nsIFrame
* aParentFrame
,
228 nsIFrame
* aPriorChildFrame
,
229 nsIAtom
* aChildType
);
232 /** @return true if aDisplayType represents a rowgroup of any sort
233 * (header, footer, or body)
235 bool IsRowGroup(int32_t aDisplayType
) const;
237 virtual const nsFrameList
& GetChildList(ChildListID aListID
) const MOZ_OVERRIDE
;
238 virtual void GetChildLists(nsTArray
<ChildList
>* aLists
) const MOZ_OVERRIDE
;
240 virtual void BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
241 const nsRect
& aDirtyRect
,
242 const nsDisplayListSet
& aLists
) MOZ_OVERRIDE
;
245 * Paint the background of the table and its parts (column groups,
246 * columns, row groups, rows, and cells), and the table border, and all
247 * internal borders if border-collapse is on.
249 void PaintTableBorderBackground(nsRenderingContext
& aRenderingContext
,
250 const nsRect
& aDirtyRect
,
251 nsPoint aPt
, uint32_t aBGPaintFlags
);
254 * Determines if any table part has a background image that is currently not
255 * decoded. Does not look into cell contents (ie only table parts).
257 static bool AnyTablePartHasUndecodedBackgroundImage(nsIFrame
* aStart
,
260 /** Get the outer half (i.e., the part outside the height and width of
261 * the table) of the largest segment (?) of border-collapsed border on
262 * the table on each side, or 0 for non border-collapsed tables.
264 nsMargin
GetOuterBCBorder() const;
266 /** Same as above, but only if it's included from the border-box width
269 nsMargin
GetIncludedOuterBCBorder() const;
271 /** Same as above, but only if it's excluded from the border-box width
272 * of the table. This is the area that leaks out into the margin
273 * (or potentially past it, if there is no margin).
275 nsMargin
GetExcludedOuterBCBorder() const;
278 * In quirks mode, the size of the table background is reduced
279 * by the outer BC border. Compute the reduction needed.
281 nsMargin
GetDeflationForBackground(nsPresContext
* aPresContext
) const;
283 /** Get width of table + colgroup + col collapse: elements that
284 * continue along the length of the whole left side.
285 * see nsTablePainter about continuous borders
287 nscoord
GetContinuousLeftBCBorderWidth() const;
288 void SetContinuousLeftBCBorderWidth(nscoord aValue
);
290 friend class nsDelayedCalcBCBorders
;
292 void AddBCDamageArea(const nsIntRect
& aValue
);
293 bool BCRecalcNeeded(nsStyleContext
* aOldStyleContext
,
294 nsStyleContext
* aNewStyleContext
);
295 void PaintBCBorders(nsRenderingContext
& aRenderingContext
,
296 const nsRect
& aDirtyRect
);
298 virtual void MarkIntrinsicISizesDirty() MOZ_OVERRIDE
;
299 // For border-collapse tables, the caller must not add padding and
300 // border to the results of these functions.
301 virtual nscoord
GetMinISize(nsRenderingContext
*aRenderingContext
) MOZ_OVERRIDE
;
302 virtual nscoord
GetPrefISize(nsRenderingContext
*aRenderingContext
) MOZ_OVERRIDE
;
303 virtual IntrinsicISizeOffsetData
304 IntrinsicISizeOffsets(nsRenderingContext
* aRenderingContext
) MOZ_OVERRIDE
;
306 virtual mozilla::LogicalSize
307 ComputeSize(nsRenderingContext
*aRenderingContext
,
308 mozilla::WritingMode aWritingMode
,
309 const mozilla::LogicalSize
& aCBSize
,
310 nscoord aAvailableISize
,
311 const mozilla::LogicalSize
& aMargin
,
312 const mozilla::LogicalSize
& aBorder
,
313 const mozilla::LogicalSize
& aPadding
,
314 uint32_t aFlags
) MOZ_OVERRIDE
;
316 virtual mozilla::LogicalSize
317 ComputeAutoSize(nsRenderingContext
*aRenderingContext
,
318 mozilla::WritingMode aWritingMode
,
319 const mozilla::LogicalSize
& aCBSize
,
320 nscoord aAvailableISize
,
321 const mozilla::LogicalSize
& aMargin
,
322 const mozilla::LogicalSize
& aBorder
,
323 const mozilla::LogicalSize
& aPadding
,
324 bool aShrinkWrap
) MOZ_OVERRIDE
;
327 * A copy of nsFrame::ShrinkWidthToFit that calls a different
328 * GetPrefISize, since tables have two different ones.
330 nscoord
TableShrinkWidthToFit(nsRenderingContext
*aRenderingContext
,
333 // XXXldb REWRITE THIS COMMENT!
334 /** inner tables are reflowed in two steps.
336 * if mFirstPassValid is false, this is our first time through since content was last changed
339 * get min/max info for all cells in an infinite space
340 * do column balancing
341 * set mFirstPassValid to true
343 * use column widths to Reflow cells
346 * @see nsIFrame::Reflow
348 virtual void Reflow(nsPresContext
* aPresContext
,
349 nsHTMLReflowMetrics
& aDesiredSize
,
350 const nsHTMLReflowState
& aReflowState
,
351 nsReflowStatus
& aStatus
) MOZ_OVERRIDE
;
353 void ReflowTable(nsHTMLReflowMetrics
& aDesiredSize
,
354 const nsHTMLReflowState
& aReflowState
,
355 nscoord aAvailHeight
,
356 nsIFrame
*& aLastChildReflowed
,
357 nsReflowStatus
& aStatus
);
359 nsFrameList
& GetColGroups();
361 virtual nsIFrame
* GetParentStyleContextFrame() const MOZ_OVERRIDE
;
364 * Get the "type" of the frame
366 * @see nsGkAtoms::tableFrame
368 virtual nsIAtom
* GetType() const MOZ_OVERRIDE
;
370 virtual bool IsFrameOfType(uint32_t aFlags
) const MOZ_OVERRIDE
372 if (aFlags
& eSupportsCSSTransforms
) {
375 return nsContainerFrame::IsFrameOfType(aFlags
);
378 #ifdef DEBUG_FRAME_DUMP
379 /** @see nsIFrame::GetFrameName */
380 virtual nsresult
GetFrameName(nsAString
& aResult
) const MOZ_OVERRIDE
;
383 /** return the width of the column at aColIndex */
384 int32_t GetColumnWidth(int32_t aColIndex
);
386 /** Helper to get the cell spacing X style value.
387 * The argument refers to the space between column aColIndex and column
388 * aColIndex + 1. An index of -1 indicates the padding between the table
389 * and the left border, an index equal to the number of columns indicates
390 * the padding between the table and the right border.
392 * Although in this class cell spacing does not depend on the index, it
393 * may be important for overriding classes.
395 virtual nscoord
GetCellSpacingX(int32_t aColIndex
);
397 /** Helper to find the sum of the cell spacing between arbitrary columns.
398 * The argument refers to the space between column aColIndex and column
399 * aColIndex + 1. An index of -1 indicates the padding between the table
400 * and the left border, an index equal to the number of columns indicates
401 * the padding between the table and the right border.
403 * This method is equivalent to
404 * nscoord result = 0;
405 * for (i = aStartColIndex; i < aEndColIndex; i++) {
406 * result += GetCellSpacingX(i);
410 virtual nscoord
GetCellSpacingX(int32_t aStartColIndex
,
411 int32_t aEndColIndex
);
413 /** Helper to get the cell spacing Y style value.
414 * The argument refers to the space between row aRowIndex and row
415 * aRowIndex + 1. An index of -1 indicates the padding between the table
416 * and the top border, an index equal to the number of rows indicates
417 * the padding between the table and the bottom border.
419 * Although in this class cell spacing does not depend on the index, it
420 * may be important for overriding classes.
422 virtual nscoord
GetCellSpacingY(int32_t aRowIndex
);
424 /** Helper to find the sum of the cell spacing between arbitrary rows.
425 * The argument refers to the space between row aRowIndex and row
426 * aRowIndex + 1. An index of -1 indicates the padding between the table
427 * and the top border, an index equal to the number of rows indicates
428 * the padding between the table and the bottom border.
430 * This method is equivalent to
431 * nscoord result = 0;
432 * for (i = aStartRowIndex; i < aEndRowIndex; i++) {
433 * result += GetCellSpacingY(i);
437 virtual nscoord
GetCellSpacingY(int32_t aStartRowIndex
,
438 int32_t aEndRowIndex
);
441 /* For the base implementation of nsTableFrame, cell spacing does not depend
442 * on row/column indexing.
444 nscoord
GetCellSpacingX();
445 nscoord
GetCellSpacingY();
448 virtual nscoord
GetLogicalBaseline(mozilla::WritingMode aWritingMode
) const MOZ_OVERRIDE
;
449 /** return the row span of a cell, taking into account row span magic at the bottom
450 * of a table. The row span equals the number of rows spanned by aCell starting at
451 * aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
452 * index in which aCell originates.
454 * @param aStartRowIndex the cell
455 * @param aCell the cell
457 * @return the row span, correcting for row spans that extend beyond the bottom
460 int32_t GetEffectiveRowSpan(int32_t aStartRowIndex
,
461 const nsTableCellFrame
& aCell
) const;
462 int32_t GetEffectiveRowSpan(const nsTableCellFrame
& aCell
,
463 nsCellMap
* aCellMap
= nullptr);
465 /** return the col span of a cell, taking into account col span magic at the edge
468 * @param aCell the cell
470 * @return the col span, correcting for col spans that extend beyond the edge
473 int32_t GetEffectiveColSpan(const nsTableCellFrame
& aCell
,
474 nsCellMap
* aCellMap
= nullptr) const;
476 /** indicate whether the row has more than one cell that either originates
477 * or is spanned from the rows above
479 bool HasMoreThanOneCell(int32_t aRowIndex
) const;
481 /** return the column frame associated with aColIndex
482 * returns nullptr if the col frame has not yet been allocated, or if
483 * aColIndex is out of range
485 nsTableColFrame
* GetColFrame(int32_t aColIndex
) const;
487 /** Insert a col frame reference into the colframe cache and adapt the cellmap
488 * @param aColFrame - the column frame
489 * @param aColIndex - index where the column should be inserted into the
492 void InsertCol(nsTableColFrame
& aColFrame
,
495 nsTableColGroupFrame
* CreateAnonymousColGroupFrame(nsTableColGroupType aType
);
497 int32_t DestroyAnonymousColFrames(int32_t aNumFrames
);
499 // Append aNumColsToAdd anonymous col frames of type eColAnonymousCell to our
500 // last eColGroupAnonymousCell colgroup. If we have no such colgroup, then
502 void AppendAnonymousColFrames(int32_t aNumColsToAdd
);
504 // Append aNumColsToAdd anonymous col frames of type aColType to
505 // aColGroupFrame. If aAddToTable is true, also call AddColsToTable on the
507 void AppendAnonymousColFrames(nsTableColGroupFrame
* aColGroupFrame
,
508 int32_t aNumColsToAdd
,
509 nsTableColType aColType
,
512 void MatchCellMapToColCache(nsTableCellMap
* aCellMap
);
513 /** empty the column frame cache */
514 void ClearColCache();
516 void DidResizeColumns();
518 void AppendCell(nsTableCellFrame
& aCellFrame
,
521 void InsertCells(nsTArray
<nsTableCellFrame
*>& aCellFrames
,
523 int32_t aColIndexBefore
);
525 void RemoveCell(nsTableCellFrame
* aCellFrame
,
528 void AppendRows(nsTableRowGroupFrame
* aRowGroupFrame
,
530 nsTArray
<nsTableRowFrame
*>& aRowFrames
);
532 int32_t InsertRows(nsTableRowGroupFrame
* aRowGroupFrame
,
533 nsTArray
<nsTableRowFrame
*>& aFrames
,
535 bool aConsiderSpans
);
537 void RemoveRows(nsTableRowFrame
& aFirstRowFrame
,
538 int32_t aNumRowsToRemove
,
539 bool aConsiderSpans
);
541 /** Insert multiple rowgroups into the table cellmap handling
542 * @param aRowGroups - iterator that iterates over the rowgroups to insert
544 void InsertRowGroups(const nsFrameList::Slice
& aRowGroups
);
546 void InsertColGroups(int32_t aStartColIndex
,
547 const nsFrameList::Slice
& aColgroups
);
549 void RemoveCol(nsTableColGroupFrame
* aColGroupFrame
,
551 bool aRemoveFromCache
,
552 bool aRemoveFromCellMap
);
554 bool ColumnHasCellSpacingBefore(int32_t aColIndex
) const;
556 bool HasPctCol() const;
557 void SetHasPctCol(bool aValue
);
559 bool HasCellSpanningPctCol() const;
560 void SetHasCellSpanningPctCol(bool aValue
);
563 * To be called on a frame by its parent after setting its size/position and
564 * calling DidReflow (possibly via FinishReflowChild()). This can also be
565 * used for child frames which are not being reflowed but did have their size
566 * or position changed.
568 * @param aFrame The frame to invalidate
569 * @param aOrigRect The original rect of aFrame (before the change).
570 * @param aOrigVisualOverflow The original overflow rect of aFrame.
571 * @param aIsFirstReflow True if the size/position change is due to the
572 * first reflow of aFrame.
574 static void InvalidateTableFrame(nsIFrame
* aFrame
,
575 const nsRect
& aOrigRect
,
576 const nsRect
& aOrigVisualOverflow
,
577 bool aIsFirstReflow
);
579 virtual bool UpdateOverflow() MOZ_OVERRIDE
;
583 /** protected constructor.
586 explicit nsTableFrame(nsStyleContext
* aContext
);
588 /** destructor, responsible for mColumnLayoutData */
589 virtual ~nsTableFrame();
591 void InitChildReflowState(nsHTMLReflowState
& aReflowState
);
593 virtual LogicalSides
GetLogicalSkipSides(const nsHTMLReflowState
* aReflowState
= nullptr) const MOZ_OVERRIDE
;
596 bool IsRowInserted() const;
597 void SetRowInserted(bool aValue
);
601 // A helper function to reflow a header or footer with unconstrained height
602 // to see if it should be made repeatable and also to determine its desired
604 nsresult
SetupHeaderFooterChild(const nsTableReflowState
& aReflowState
,
605 nsTableRowGroupFrame
* aFrame
,
606 nscoord
* aDesiredHeight
);
608 void ReflowChildren(nsTableReflowState
& aReflowState
,
609 nsReflowStatus
& aStatus
,
610 nsIFrame
*& aLastChildReflowed
,
611 nsOverflowAreas
& aOverflowAreas
);
613 // This calls the col group and column reflow methods, which do two things:
614 // (1) set all the dimensions to 0
615 // (2) notify the table about colgroups or columns with hidden visibility
616 void ReflowColGroups(nsRenderingContext
* aRenderingContext
);
618 /** return the width of the table taking into account visibility collapse
619 * on columns and colgroups
620 * @param aBorderPadding the border and padding of the table
622 nscoord
GetCollapsedWidth(nsMargin aBorderPadding
);
625 /** Adjust the table for visibility.collapse set on rowgroups, rows,
627 * @param aDesiredSize the metrics of the table
628 * @param aBorderPadding the border and padding of the table
630 void AdjustForCollapsingRowsCols(nsHTMLReflowMetrics
& aDesiredSize
,
631 nsMargin aBorderPadding
);
633 /** FixupPositionedTableParts is called at the end of table reflow to reflow
634 * the absolutely positioned descendants of positioned table parts. This is
635 * necessary because the dimensions of table parts may change after they've
636 * been reflowed (e.g. in AdjustForCollapsingRowsCols).
638 void FixupPositionedTableParts(nsPresContext
* aPresContext
,
639 nsHTMLReflowMetrics
& aDesiredSize
,
640 const nsHTMLReflowState
& aReflowState
);
642 // Clears the list of positioned table parts.
643 void ClearAllPositionedTableParts();
645 nsITableLayoutStrategy
* LayoutStrategy() const {
646 return static_cast<nsTableFrame
*>(FirstInFlow())->
647 mTableLayoutStrategy
;
650 // Helper for InsertFrames.
651 void HomogenousInsertFrames(ChildListID aListID
,
652 nsIFrame
* aPrevFrame
,
653 nsFrameList
& aFrameList
);
655 /* Handle a row that got inserted during reflow. aNewHeight is the
656 new height of the table after reflow. */
657 void ProcessRowInserted(nscoord aNewHeight
);
659 // WIDTH AND HEIGHT CALCULATION
663 // calculate the computed height of aFrame including its border and padding given
665 nscoord
CalcBorderBoxHeight(const nsHTMLReflowState
& aReflowState
);
669 // update the desired height of this table taking into account the current
670 // reflow state, the table attributes and the content driven rowgroup heights
671 // this function can change the overflow area
672 void CalcDesiredHeight(const nsHTMLReflowState
& aReflowState
, nsHTMLReflowMetrics
& aDesiredSize
);
674 // The following is a helper for CalcDesiredHeight
676 void DistributeHeightToRows(const nsHTMLReflowState
& aReflowState
,
679 void PlaceChild(nsTableReflowState
& aReflowState
,
681 nsHTMLReflowMetrics
& aKidDesiredSize
,
682 const nsRect
& aOriginalKidRect
,
683 const nsRect
& aOriginalKidVisualOverflow
);
684 void PlaceRepeatedFooter(nsTableReflowState
& aReflowState
,
685 nsTableRowGroupFrame
*aTfoot
,
686 nscoord aFooterHeight
);
688 nsIFrame
* GetFirstBodyRowGroupFrame();
690 typedef nsAutoTArray
<nsTableRowGroupFrame
*, 8> RowGroupArray
;
692 * Push all our child frames from the aRowGroups array, in order, starting
693 * from the frame at aPushFrom to the end of the array. The frames are put on
694 * our overflow list or moved directly to our next-in-flow if one exists.
697 void PushChildren(const RowGroupArray
& aRowGroups
, int32_t aPushFrom
);
700 // put the children frames in the display order (e.g. thead before tbodies
701 // before tfoot). This will handle calling GetRowGroupFrame() on the
702 // children, and not append nulls, so the array is guaranteed to contain
703 // nsTableRowGroupFrames. If there are multiple theads or tfoots, all but
704 // the first one are treated as tbodies instead.
706 void OrderRowGroups(RowGroupArray
& aChildren
,
707 nsTableRowGroupFrame
** aHead
= nullptr,
708 nsTableRowGroupFrame
** aFoot
= nullptr) const;
710 // Return the thead, if any
711 nsTableRowGroupFrame
* GetTHead() const;
713 // Return the tfoot, if any
714 nsTableRowGroupFrame
* GetTFoot() const;
716 // Returns true if there are any cells above the row at
717 // aRowIndex and spanning into the row at aRowIndex, the number of
718 // effective columns limits the search up to that column
719 bool RowIsSpannedInto(int32_t aRowIndex
, int32_t aNumEffCols
);
721 // Returns true if there is a cell originating in aRowIndex
722 // which spans into the next row, the number of effective
723 // columns limits the search up to that column
724 bool RowHasSpanningCells(int32_t aRowIndex
, int32_t aNumEffCols
);
728 bool HaveReflowedColGroups() const;
729 void SetHaveReflowedColGroups(bool aValue
);
732 bool IsBorderCollapse() const;
734 bool NeedToCalcBCBorders() const;
735 void SetNeedToCalcBCBorders(bool aValue
);
737 bool NeedToCollapse() const;
738 void SetNeedToCollapse(bool aValue
);
740 bool HasZeroColSpans() const;
741 void SetHasZeroColSpans(bool aValue
);
743 bool NeedColSpanExpansion() const;
744 void SetNeedColSpanExpansion(bool aValue
);
746 /** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame
747 * state bit, which implies that all descendants are dirty. The
748 * GeometryDirty still implies that all the parts of the table are
749 * dirty, but resizing optimizations should still apply to the
750 * contents of the individual cells.
752 void SetGeometryDirty() { mBits
.mGeometryDirty
= true; }
753 void ClearGeometryDirty() { mBits
.mGeometryDirty
= false; }
754 bool IsGeometryDirty() const { return mBits
.mGeometryDirty
; }
756 /** Get the cell map for this table frame. It is not always mCellMap.
757 * Only the firstInFlow has a legit cell map
759 nsTableCellMap
* GetCellMap() const;
761 /** Iterate over the row groups and adjust the row indices of all rows
762 * whose index is >= aRowIndex.
763 * @param aRowIndex - start adjusting with this index
764 * @param aAdjustment - shift the row index by this amount
766 void AdjustRowIndices(int32_t aRowIndex
,
767 int32_t aAdjustment
);
769 /** Reset the rowindices of all rows as they might have changed due to
770 * rowgroup reordering, exclude new row group frames that show in the
771 * reordering but are not yet inserted into the cellmap
772 * @param aRowGroupsToExclude - an iterator that will produce the row groups
775 void ResetRowIndices(const nsFrameList::Slice
& aRowGroupsToExclude
);
777 nsTArray
<nsTableColFrame
*>& GetColCache();
782 void SetBorderCollapse(bool aValue
);
784 BCPropertyData
* GetBCProperty(bool aCreateIfNecessary
= false) const;
785 void SetFullBCDamageArea();
786 void CalcBCBorders();
788 void ExpandBCDamageArea(nsIntRect
& aRect
) const;
790 void SetColumnDimensions(nscoord aHeight
,
791 const nsMargin
& aReflowState
);
793 int32_t CollectRows(nsIFrame
* aFrame
,
794 nsTArray
<nsTableRowFrame
*>& aCollection
);
796 public: /* ----- Cell Map public methods ----- */
798 int32_t GetStartRowIndex(nsTableRowGroupFrame
* aRowGroupFrame
);
800 /** returns the number of rows in this table.
802 int32_t GetRowCount () const
804 return GetCellMap()->GetRowCount();
807 /** returns the number of columns in this table after redundant columns have been removed
809 int32_t GetEffectiveColCount() const;
811 /* return the col count including dead cols */
812 int32_t GetColCount () const
814 return GetCellMap()->GetColCount();
817 // return the last col index which isn't of type eColAnonymousCell
818 int32_t GetIndexOfLastRealCol();
820 /** returns true if table-layout:auto */
826 void Dump(bool aDumpRows
,
833 * Helper method for RemoveFrame.
835 void DoRemoveFrame(ChildListID aListID
, nsIFrame
* aOldFrame
);
837 void DumpRowGroup(nsIFrame
* aChildFrame
);
840 nsAutoTArray
<nsTableColFrame
*, 8> mColFrames
;
843 uint32_t mHaveReflowedColGroups
:1; // have the col groups gotten their initial reflow
844 uint32_t mHasPctCol
:1; // does any cell or col have a pct width
845 uint32_t mCellSpansPctCol
:1; // does any cell span a col with a pct width (or containing a cell with a pct width)
846 uint32_t mIsBorderCollapse
:1; // border collapsing model vs. separate model
847 uint32_t mRowInserted
:1;
848 uint32_t mNeedToCalcBCBorders
:1;
849 uint32_t mGeometryDirty
:1;
850 uint32_t mLeftContBCBorder
:8;
851 uint32_t mNeedToCollapse
:1; // rows, cols that have visibility:collapse need to be collapsed
852 uint32_t mHasZeroColSpans
:1;
853 uint32_t mNeedColSpanExpansion
:1;
854 uint32_t mResizedColumns
:1; // have we resized columns since last reflow?
857 nsTableCellMap
* mCellMap
; // maintains the relationships between rows, cols, and cells
858 nsITableLayoutStrategy
* mTableLayoutStrategy
;// the layout strategy for this frame
859 nsFrameList mColGroups
; // the list of colgroup frames
863 inline bool nsTableFrame::IsRowGroup(int32_t aDisplayType
) const
865 return bool((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP
== aDisplayType
) ||
866 (NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP
== aDisplayType
) ||
867 (NS_STYLE_DISPLAY_TABLE_ROW_GROUP
== aDisplayType
));
870 inline void nsTableFrame::SetHaveReflowedColGroups(bool aValue
)
872 mBits
.mHaveReflowedColGroups
= aValue
;
875 inline bool nsTableFrame::HaveReflowedColGroups() const
877 return (bool)mBits
.mHaveReflowedColGroups
;
880 inline bool nsTableFrame::HasPctCol() const
882 return (bool)mBits
.mHasPctCol
;
885 inline void nsTableFrame::SetHasPctCol(bool aValue
)
887 mBits
.mHasPctCol
= (unsigned)aValue
;
890 inline bool nsTableFrame::HasCellSpanningPctCol() const
892 return (bool)mBits
.mCellSpansPctCol
;
895 inline void nsTableFrame::SetHasCellSpanningPctCol(bool aValue
)
897 mBits
.mCellSpansPctCol
= (unsigned)aValue
;
900 inline bool nsTableFrame::IsRowInserted() const
902 return (bool)mBits
.mRowInserted
;
905 inline void nsTableFrame::SetRowInserted(bool aValue
)
907 mBits
.mRowInserted
= (unsigned)aValue
;
910 inline void nsTableFrame::SetNeedToCollapse(bool aValue
)
912 static_cast<nsTableFrame
*>(FirstInFlow())->mBits
.mNeedToCollapse
= (unsigned)aValue
;
915 inline bool nsTableFrame::NeedToCollapse() const
917 return (bool) static_cast<nsTableFrame
*>(FirstInFlow())->mBits
.mNeedToCollapse
;
920 inline void nsTableFrame::SetHasZeroColSpans(bool aValue
)
922 mBits
.mHasZeroColSpans
= (unsigned)aValue
;
925 inline bool nsTableFrame::HasZeroColSpans() const
927 return (bool)mBits
.mHasZeroColSpans
;
930 inline void nsTableFrame::SetNeedColSpanExpansion(bool aValue
)
932 mBits
.mNeedColSpanExpansion
= (unsigned)aValue
;
935 inline bool nsTableFrame::NeedColSpanExpansion() const
937 return (bool)mBits
.mNeedColSpanExpansion
;
941 inline nsFrameList
& nsTableFrame::GetColGroups()
943 return static_cast<nsTableFrame
*>(FirstInFlow())->mColGroups
;
946 inline nsTArray
<nsTableColFrame
*>& nsTableFrame::GetColCache()
951 inline bool nsTableFrame::IsBorderCollapse() const
953 return (bool)mBits
.mIsBorderCollapse
;
956 inline void nsTableFrame::SetBorderCollapse(bool aValue
)
958 mBits
.mIsBorderCollapse
= aValue
;
961 inline bool nsTableFrame::NeedToCalcBCBorders() const
963 return (bool)mBits
.mNeedToCalcBCBorders
;
966 inline void nsTableFrame::SetNeedToCalcBCBorders(bool aValue
)
968 mBits
.mNeedToCalcBCBorders
= (unsigned)aValue
;
972 nsTableFrame::GetContinuousLeftBCBorderWidth() const
974 int32_t aPixelsToTwips
= nsPresContext::AppUnitsPerCSSPixel();
975 return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips
, mBits
.mLeftContBCBorder
);
978 inline void nsTableFrame::SetContinuousLeftBCBorderWidth(nscoord aValue
)
980 mBits
.mLeftContBCBorder
= (unsigned) aValue
;
983 class nsTableIterator
986 explicit nsTableIterator(nsIFrame
& aSource
);
987 explicit nsTableIterator(nsFrameList
& aSource
);
990 bool IsLeftToRight();
994 void Init(nsIFrame
* aFirstChild
);
996 nsIFrame
* mFirstListChild
;
997 nsIFrame
* mFirstChild
;
998 nsIFrame
* mCurrentChild
;
1003 {NS_ASSERTION(false, "CellIterator program error"); \
1006 #define ABORT1(aReturn) \
1007 {NS_ASSERTION(false, "CellIterator program error"); \