Bumping manifests a=b2g-bump
[gecko.git] / layout / tables / nsTableFrame.h
blobda918d32d8a5f1443cf4f3158127946b912a3192
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"
9 #include "celldata.h"
10 #include "nscore.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;
21 class nsTableCellMap;
22 class nsTableColFrame;
23 class nsColGroupFrame;
24 class nsTableRowGroupFrame;
25 class nsTableRowFrame;
26 class nsTableColGroupFrame;
27 class nsITableLayoutStrategy;
28 class nsStyleContext;
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
48 public:
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);
61 private:
62 bool mPartHasFixedBackground;
65 class nsAutoPushCurrentTableItem
67 public:
68 nsAutoPushCurrentTableItem() : mBuilder(nullptr) {}
70 void Push(nsDisplayListBuilder* aBuilder, nsDisplayTableItem* aPushItem)
72 mBuilder = aBuilder;
73 mOldCurrentItem = aBuilder->GetCurrentTableItem();
74 aBuilder->SetCurrentTableItem(aPushItem);
75 #ifdef DEBUG
76 mPushedItem = aPushItem;
77 #endif
79 ~nsAutoPushCurrentTableItem() {
80 if (!mBuilder)
81 return;
82 #ifdef DEBUG
83 NS_ASSERTION(mBuilder->GetCurrentTableItem() == mPushedItem,
84 "Someone messed with the current table item behind our back!");
85 #endif
86 mBuilder->SetCurrentTableItem(mOldCurrentItem);
89 private:
90 nsDisplayListBuilder* mBuilder;
91 nsDisplayTableItem* mOldCurrentItem;
92 #ifdef DEBUG
93 nsDisplayTableItem* mPushedItem;
94 #endif
97 /* ============================================================================ */
99 /**
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
109 public:
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
216 * display list set.
218 static void DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
219 nsFrame* aFrame,
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);
230 bool IsAutoHeight();
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,
258 nsIFrame* aEnd);
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
267 * of the table.
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,
331 nscoord aWidthInCB);
333 // XXXldb REWRITE THIS COMMENT!
334 /** inner tables are reflowed in two steps.
335 * <pre>
336 * if mFirstPassValid is false, this is our first time through since content was last changed
337 * set pass to 1
338 * do pass 1
339 * get min/max info for all cells in an infinite space
340 * do column balancing
341 * set mFirstPassValid to true
342 * do pass 2
343 * use column widths to Reflow cells
344 * </pre>
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) {
373 return false;
375 return nsContainerFrame::IsFrameOfType(aFlags);
378 #ifdef DEBUG_FRAME_DUMP
379 /** @see nsIFrame::GetFrameName */
380 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
381 #endif
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);
408 * return result;
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);
435 * return result;
437 virtual nscoord GetCellSpacingY(int32_t aStartRowIndex,
438 int32_t aEndRowIndex);
440 private:
441 /* For the base implementation of nsTableFrame, cell spacing does not depend
442 * on row/column indexing.
444 nscoord GetCellSpacingX();
445 nscoord GetCellSpacingY();
447 public:
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
458 * of the table.
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
466 * of a table.
468 * @param aCell the cell
470 * @return the col span, correcting for col spans that extend beyond the edge
471 * of the table.
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
490 * colframe cache
492 void InsertCol(nsTableColFrame& aColFrame,
493 int32_t aColIndex);
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
501 // create one.
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
506 // new cols.
507 void AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
508 int32_t aNumColsToAdd,
509 nsTableColType aColType,
510 bool aAddToTable);
512 void MatchCellMapToColCache(nsTableCellMap* aCellMap);
513 /** empty the column frame cache */
514 void ClearColCache();
516 void DidResizeColumns();
518 void AppendCell(nsTableCellFrame& aCellFrame,
519 int32_t aRowIndex);
521 void InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
522 int32_t aRowIndex,
523 int32_t aColIndexBefore);
525 void RemoveCell(nsTableCellFrame* aCellFrame,
526 int32_t aRowIndex);
528 void AppendRows(nsTableRowGroupFrame* aRowGroupFrame,
529 int32_t aRowIndex,
530 nsTArray<nsTableRowFrame*>& aRowFrames);
532 int32_t InsertRows(nsTableRowGroupFrame* aRowGroupFrame,
533 nsTArray<nsTableRowFrame*>& aFrames,
534 int32_t aRowIndex,
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,
550 int32_t aColIndex,
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;
581 protected:
583 /** protected constructor.
584 * @see NewFrame
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;
595 public:
596 bool IsRowInserted() const;
597 void SetRowInserted(bool aValue);
599 protected:
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
603 // height.
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,
626 * colgroups and cols
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);
654 private:
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
661 public:
663 // calculate the computed height of aFrame including its border and padding given
664 // its reflow state.
665 nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
667 protected:
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,
677 nscoord aAmount);
679 void PlaceChild(nsTableReflowState& aReflowState,
680 nsIFrame* aKidFrame,
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();
689 public:
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.
696 protected:
697 void PushChildren(const RowGroupArray& aRowGroups, int32_t aPushFrom);
699 public:
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);
726 protected:
728 bool HaveReflowedColGroups() const;
729 void SetHaveReflowedColGroups(bool aValue);
731 public:
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
773 * to exclude.
775 void ResetRowIndices(const nsFrameList::Slice& aRowGroupsToExclude);
777 nsTArray<nsTableColFrame*>& GetColCache();
780 protected:
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 */
821 bool IsAutoLayout();
823 public:
825 #ifdef DEBUG
826 void Dump(bool aDumpRows,
827 bool aDumpCols,
828 bool aDumpCellMap);
829 #endif
831 protected:
833 * Helper method for RemoveFrame.
835 void DoRemoveFrame(ChildListID aListID, nsIFrame* aOldFrame);
836 #ifdef DEBUG
837 void DumpRowGroup(nsIFrame* aChildFrame);
838 #endif
839 // DATA MEMBERS
840 nsAutoTArray<nsTableColFrame*, 8> mColFrames;
842 struct TableBits {
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?
855 } mBits;
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()
948 return mColFrames;
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;
971 inline nscoord
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
985 public:
986 explicit nsTableIterator(nsIFrame& aSource);
987 explicit nsTableIterator(nsFrameList& aSource);
988 nsIFrame* First();
989 nsIFrame* Next();
990 bool IsLeftToRight();
991 int32_t Count();
993 protected:
994 void Init(nsIFrame* aFirstChild);
995 bool mLeftToRight;
996 nsIFrame* mFirstListChild;
997 nsIFrame* mFirstChild;
998 nsIFrame* mCurrentChild;
999 int32_t mCount;
1002 #define ABORT0() \
1003 {NS_ASSERTION(false, "CellIterator program error"); \
1004 return;}
1006 #define ABORT1(aReturn) \
1007 {NS_ASSERTION(false, "CellIterator program error"); \
1008 return aReturn;}
1010 #endif