Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
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;
37 }
39 static inline bool FrameHasBorderOrBackground(nsIFrame* f) {
40 return (f->StyleVisibility()->IsVisible() &&
41 (!f->StyleBackground()->IsTransparent() ||
42 f->StyleDisplay()->mAppearance ||
43 f->StyleBorder()->HasBorder()));
44 }
46 class nsDisplayTableItem : public nsDisplayItem
47 {
48 public:
49 nsDisplayTableItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
50 nsDisplayItem(aBuilder, aFrame),
51 mPartHasFixedBackground(false) {}
53 virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
54 nsIFrame* aFrame) MOZ_OVERRIDE;
55 // With collapsed borders, parts of the collapsed border can extend outside
56 // the table part frames, so allow this display element to blow out to our
57 // overflow rect. This is also useful for row frames that have spanning
58 // cells extending outside them.
59 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
61 void UpdateForFrameBackground(nsIFrame* aFrame);
63 private:
64 bool mPartHasFixedBackground;
65 };
67 class nsAutoPushCurrentTableItem
68 {
69 public:
70 nsAutoPushCurrentTableItem() : mBuilder(nullptr) {}
72 void Push(nsDisplayListBuilder* aBuilder, nsDisplayTableItem* aPushItem)
73 {
74 mBuilder = aBuilder;
75 mOldCurrentItem = aBuilder->GetCurrentTableItem();
76 aBuilder->SetCurrentTableItem(aPushItem);
77 #ifdef DEBUG
78 mPushedItem = aPushItem;
79 #endif
80 }
81 ~nsAutoPushCurrentTableItem() {
82 if (!mBuilder)
83 return;
84 #ifdef DEBUG
85 NS_ASSERTION(mBuilder->GetCurrentTableItem() == mPushedItem,
86 "Someone messed with the current table item behind our back!");
87 #endif
88 mBuilder->SetCurrentTableItem(mOldCurrentItem);
89 }
91 private:
92 nsDisplayListBuilder* mBuilder;
93 nsDisplayTableItem* mOldCurrentItem;
94 #ifdef DEBUG
95 nsDisplayTableItem* mPushedItem;
96 #endif
97 };
99 /* ============================================================================ */
101 /**
102 * nsTableFrame maps the inner portion of a table (everything except captions.)
103 * Used as a pseudo-frame within nsTableOuterFrame, it may also be used
104 * stand-alone as the top-level frame.
105 *
106 * The principal child list contains row group frames. There is also an
107 * additional child list, kColGroupList, which contains the col group frames.
108 */
109 class nsTableFrame : public nsContainerFrame
110 {
111 public:
112 NS_DECL_FRAMEARENA_HELPERS
114 static void DestroyPositionedTablePartArray(void* aPropertyValue);
115 NS_DECLARE_FRAME_PROPERTY(PositionedTablePartArray, DestroyPositionedTablePartArray)
117 /** nsTableOuterFrame has intimate knowledge of the inner table frame */
118 friend class nsTableOuterFrame;
120 /** instantiate a new instance of nsTableRowFrame.
121 * @param aPresShell the pres shell for this frame
122 *
123 * @return the frame that was created
124 */
125 friend nsIFrame* NS_NewTableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
127 /** sets defaults for table-specific style.
128 * @see nsIFrame::Init
129 */
130 virtual void Init(nsIContent* aContent,
131 nsIFrame* aParent,
132 nsIFrame* aPrevInFlow) MOZ_OVERRIDE;
134 static float GetTwipsToPixels(nsPresContext* aPresContext);
136 // Return true if aParentReflowState.frame or any of its ancestors within
137 // the containing table have non-auto height. (e.g. pct or fixed height)
138 static bool AncestorsHaveStyleHeight(const nsHTMLReflowState& aParentReflowState);
140 // See if a special height reflow will occur due to having a pct height when
141 // the pct height basis may not yet be valid.
142 static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
144 // Notify the frame and its ancestors (up to the containing table) that a special
145 // height reflow will occur.
146 static void RequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
148 static void RePositionViews(nsIFrame* aFrame);
150 static bool PageBreakAfter(nsIFrame* aSourceFrame,
151 nsIFrame* aNextFrame);
153 // Register a positioned table part with its nsTableFrame. These objects will
154 // be visited by FixupPositionedTableParts after reflow is complete. (See that
155 // function for more explanation.) Should be called during frame construction.
156 static void RegisterPositionedTablePart(nsIFrame* aFrame);
158 // Unregister a positioned table part with its nsTableFrame.
159 static void UnregisterPositionedTablePart(nsIFrame* aFrame,
160 nsIFrame* aDestructRoot);
162 nsPoint GetFirstSectionOrigin(const nsHTMLReflowState& aReflowState) const;
163 /*
164 * Notification that aAttribute has changed for content inside a table (cell, row, etc)
165 */
166 void AttributeChangedFor(nsIFrame* aFrame,
167 nsIContent* aContent,
168 nsIAtom* aAttribute);
170 /** @see nsIFrame::DestroyFrom */
171 virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
173 /** @see nsIFrame::DidSetStyleContext */
174 virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
176 virtual nsresult AppendFrames(ChildListID aListID,
177 nsFrameList& aFrameList) MOZ_OVERRIDE;
178 virtual nsresult InsertFrames(ChildListID aListID,
179 nsIFrame* aPrevFrame,
180 nsFrameList& aFrameList) MOZ_OVERRIDE;
181 virtual nsresult RemoveFrame(ChildListID aListID,
182 nsIFrame* aOldFrame) MOZ_OVERRIDE;
184 virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE;
185 virtual nsMargin GetUsedPadding() const MOZ_OVERRIDE;
186 virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE;
188 // Get the offset from the border box to the area where the row groups fit
189 nsMargin GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const;
191 /** helper method to find the table parent of any table frame object */
192 static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame);
194 /* Like GetTableFrame, but will return nullptr if we don't pass through
195 * aMustPassThrough on the way to the table.
196 */
197 static nsTableFrame* GetTableFramePassingThrough(nsIFrame* aMustPassThrough,
198 nsIFrame* aSourceFrame);
200 typedef void (* DisplayGenericTablePartTraversal)
201 (nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
202 const nsRect& aDirtyRect, const nsDisplayListSet& aLists);
203 static void GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
204 const nsRect& aDirtyRect, const nsDisplayListSet& aLists);
206 /**
207 * Helper method to handle display common to table frames, rowgroup frames
208 * and row frames. It creates a background display item for handling events
209 * if necessary, an outline display item if necessary, and displays
210 * all the the frame's children.
211 * @param aDisplayItem the display item created for this part, or null
212 * if this part's border/background painting is delegated to an ancestor
213 * @param aTraversal a function that gets called to traverse the table
214 * part's child frames and add their display list items to a
215 * display list set.
216 */
217 static void DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
218 nsFrame* aFrame,
219 const nsRect& aDirtyRect,
220 const nsDisplayListSet& aLists,
221 nsDisplayTableItem* aDisplayItem,
222 DisplayGenericTablePartTraversal aTraversal = GenericTraversal);
224 // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
225 // of type aChildType.
226 static nsIFrame* GetFrameAtOrBefore(nsIFrame* aParentFrame,
227 nsIFrame* aPriorChildFrame,
228 nsIAtom* aChildType);
229 bool IsAutoHeight();
231 /** @return true if aDisplayType represents a rowgroup of any sort
232 * (header, footer, or body)
233 */
234 bool IsRowGroup(int32_t aDisplayType) const;
236 /** Initialize the table frame with a set of children.
237 * @see nsIFrame::SetInitialChildList
238 */
239 virtual nsresult SetInitialChildList(ChildListID aListID,
240 nsFrameList& aChildList) MOZ_OVERRIDE;
242 virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
243 virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
245 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
246 const nsRect& aDirtyRect,
247 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
249 /**
250 * Paint the background of the table and its parts (column groups,
251 * columns, row groups, rows, and cells), and the table border, and all
252 * internal borders if border-collapse is on.
253 */
254 void PaintTableBorderBackground(nsRenderingContext& aRenderingContext,
255 const nsRect& aDirtyRect,
256 nsPoint aPt, uint32_t aBGPaintFlags);
258 /**
259 * Determines if any table part has a background image that is currently not
260 * decoded. Does not look into cell contents (ie only table parts).
261 */
262 static bool AnyTablePartHasUndecodedBackgroundImage(nsIFrame* aStart,
263 nsIFrame* aEnd);
265 /** Get the outer half (i.e., the part outside the height and width of
266 * the table) of the largest segment (?) of border-collapsed border on
267 * the table on each side, or 0 for non border-collapsed tables.
268 */
269 nsMargin GetOuterBCBorder() const;
271 /** Same as above, but only if it's included from the border-box width
272 * of the table.
273 */
274 nsMargin GetIncludedOuterBCBorder() const;
276 /** Same as above, but only if it's excluded from the border-box width
277 * of the table. This is the area that leaks out into the margin
278 * (or potentially past it, if there is no margin).
279 */
280 nsMargin GetExcludedOuterBCBorder() const;
282 /**
283 * In quirks mode, the size of the table background is reduced
284 * by the outer BC border. Compute the reduction needed.
285 */
286 nsMargin GetDeflationForBackground(nsPresContext* aPresContext) const;
288 /** Get width of table + colgroup + col collapse: elements that
289 * continue along the length of the whole left side.
290 * see nsTablePainter about continuous borders
291 */
292 nscoord GetContinuousLeftBCBorderWidth() const;
293 void SetContinuousLeftBCBorderWidth(nscoord aValue);
295 friend class nsDelayedCalcBCBorders;
297 void AddBCDamageArea(const nsIntRect& aValue);
298 bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
299 nsStyleContext* aNewStyleContext);
300 void PaintBCBorders(nsRenderingContext& aRenderingContext,
301 const nsRect& aDirtyRect);
303 virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
304 // For border-collapse tables, the caller must not add padding and
305 // border to the results of these functions.
306 virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
307 virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
308 virtual IntrinsicWidthOffsetData
309 IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
311 virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
312 nsSize aCBSize, nscoord aAvailableWidth,
313 nsSize aMargin, nsSize aBorder, nsSize aPadding,
314 uint32_t aFlags) MOZ_OVERRIDE;
315 virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
316 nsSize aCBSize, nscoord aAvailableWidth,
317 nsSize aMargin, nsSize aBorder,
318 nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
319 /**
320 * A copy of nsFrame::ShrinkWidthToFit that calls a different
321 * GetPrefWidth, since tables have two different ones.
322 */
323 nscoord TableShrinkWidthToFit(nsRenderingContext *aRenderingContext,
324 nscoord aWidthInCB);
326 // XXXldb REWRITE THIS COMMENT!
327 /** inner tables are reflowed in two steps.
328 * <pre>
329 * if mFirstPassValid is false, this is our first time through since content was last changed
330 * set pass to 1
331 * do pass 1
332 * get min/max info for all cells in an infinite space
333 * do column balancing
334 * set mFirstPassValid to true
335 * do pass 2
336 * use column widths to Reflow cells
337 * </pre>
338 *
339 * @see nsIFrame::Reflow
340 */
341 virtual nsresult Reflow(nsPresContext* aPresContext,
342 nsHTMLReflowMetrics& aDesiredSize,
343 const nsHTMLReflowState& aReflowState,
344 nsReflowStatus& aStatus) MOZ_OVERRIDE;
346 nsresult ReflowTable(nsHTMLReflowMetrics& aDesiredSize,
347 const nsHTMLReflowState& aReflowState,
348 nscoord aAvailHeight,
349 nsIFrame*& aLastChildReflowed,
350 nsReflowStatus& aStatus);
352 nsFrameList& GetColGroups();
354 virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
356 /**
357 * Get the "type" of the frame
358 *
359 * @see nsGkAtoms::tableFrame
360 */
361 virtual nsIAtom* GetType() const MOZ_OVERRIDE;
363 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
364 {
365 if (aFlags & eSupportsCSSTransforms) {
366 return false;
367 }
368 return nsContainerFrame::IsFrameOfType(aFlags);
369 }
371 #ifdef DEBUG_FRAME_DUMP
372 /** @see nsIFrame::GetFrameName */
373 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
374 #endif
376 /** return the width of the column at aColIndex */
377 int32_t GetColumnWidth(int32_t aColIndex);
379 /** helper to get the cell spacing X style value */
380 nscoord GetCellSpacingX();
382 /** helper to get the cell spacing Y style value */
383 nscoord GetCellSpacingY();
385 virtual nscoord GetBaseline() const MOZ_OVERRIDE;
386 /** return the row span of a cell, taking into account row span magic at the bottom
387 * of a table. The row span equals the number of rows spanned by aCell starting at
388 * aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
389 * index in which aCell originates.
390 *
391 * @param aStartRowIndex the cell
392 * @param aCell the cell
393 *
394 * @return the row span, correcting for row spans that extend beyond the bottom
395 * of the table.
396 */
397 int32_t GetEffectiveRowSpan(int32_t aStartRowIndex,
398 const nsTableCellFrame& aCell) const;
399 int32_t GetEffectiveRowSpan(const nsTableCellFrame& aCell,
400 nsCellMap* aCellMap = nullptr);
402 /** return the col span of a cell, taking into account col span magic at the edge
403 * of a table.
404 *
405 * @param aCell the cell
406 *
407 * @return the col span, correcting for col spans that extend beyond the edge
408 * of the table.
409 */
410 int32_t GetEffectiveColSpan(const nsTableCellFrame& aCell,
411 nsCellMap* aCellMap = nullptr) const;
413 /** indicate whether the row has more than one cell that either originates
414 * or is spanned from the rows above
415 */
416 bool HasMoreThanOneCell(int32_t aRowIndex) const;
418 /** return the column frame associated with aColIndex
419 * returns nullptr if the col frame has not yet been allocated, or if
420 * aColIndex is out of range
421 */
422 nsTableColFrame* GetColFrame(int32_t aColIndex) const;
424 /** Insert a col frame reference into the colframe cache and adapt the cellmap
425 * @param aColFrame - the column frame
426 * @param aColIndex - index where the column should be inserted into the
427 * colframe cache
428 */
429 void InsertCol(nsTableColFrame& aColFrame,
430 int32_t aColIndex);
432 nsTableColGroupFrame* CreateAnonymousColGroupFrame(nsTableColGroupType aType);
434 int32_t DestroyAnonymousColFrames(int32_t aNumFrames);
436 // Append aNumColsToAdd anonymous col frames of type eColAnonymousCell to our
437 // last eColGroupAnonymousCell colgroup. If we have no such colgroup, then
438 // create one.
439 void AppendAnonymousColFrames(int32_t aNumColsToAdd);
441 // Append aNumColsToAdd anonymous col frames of type aColType to
442 // aColGroupFrame. If aAddToTable is true, also call AddColsToTable on the
443 // new cols.
444 void AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
445 int32_t aNumColsToAdd,
446 nsTableColType aColType,
447 bool aAddToTable);
449 void MatchCellMapToColCache(nsTableCellMap* aCellMap);
450 /** empty the column frame cache */
451 void ClearColCache();
453 void DidResizeColumns();
455 void AppendCell(nsTableCellFrame& aCellFrame,
456 int32_t aRowIndex);
458 void InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
459 int32_t aRowIndex,
460 int32_t aColIndexBefore);
462 void RemoveCell(nsTableCellFrame* aCellFrame,
463 int32_t aRowIndex);
465 void AppendRows(nsTableRowGroupFrame* aRowGroupFrame,
466 int32_t aRowIndex,
467 nsTArray<nsTableRowFrame*>& aRowFrames);
469 int32_t InsertRows(nsTableRowGroupFrame* aRowGroupFrame,
470 nsTArray<nsTableRowFrame*>& aFrames,
471 int32_t aRowIndex,
472 bool aConsiderSpans);
474 void RemoveRows(nsTableRowFrame& aFirstRowFrame,
475 int32_t aNumRowsToRemove,
476 bool aConsiderSpans);
478 /** Insert multiple rowgroups into the table cellmap handling
479 * @param aRowGroups - iterator that iterates over the rowgroups to insert
480 */
481 void InsertRowGroups(const nsFrameList::Slice& aRowGroups);
483 void InsertColGroups(int32_t aStartColIndex,
484 const nsFrameList::Slice& aColgroups);
486 void RemoveCol(nsTableColGroupFrame* aColGroupFrame,
487 int32_t aColIndex,
488 bool aRemoveFromCache,
489 bool aRemoveFromCellMap);
491 bool ColumnHasCellSpacingBefore(int32_t aColIndex) const;
493 bool HasPctCol() const;
494 void SetHasPctCol(bool aValue);
496 bool HasCellSpanningPctCol() const;
497 void SetHasCellSpanningPctCol(bool aValue);
499 /**
500 * To be called on a frame by its parent after setting its size/position and
501 * calling DidReflow (possibly via FinishReflowChild()). This can also be
502 * used for child frames which are not being reflowed but did have their size
503 * or position changed.
504 *
505 * @param aFrame The frame to invalidate
506 * @param aOrigRect The original rect of aFrame (before the change).
507 * @param aOrigVisualOverflow The original overflow rect of aFrame.
508 * @param aIsFirstReflow True if the size/position change is due to the
509 * first reflow of aFrame.
510 */
511 static void InvalidateTableFrame(nsIFrame* aFrame,
512 const nsRect& aOrigRect,
513 const nsRect& aOrigVisualOverflow,
514 bool aIsFirstReflow);
516 virtual bool UpdateOverflow() MOZ_OVERRIDE;
518 protected:
520 /** protected constructor.
521 * @see NewFrame
522 */
523 nsTableFrame(nsStyleContext* aContext);
525 /** destructor, responsible for mColumnLayoutData */
526 virtual ~nsTableFrame();
528 void InitChildReflowState(nsHTMLReflowState& aReflowState);
530 virtual int GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
532 public:
533 bool IsRowInserted() const;
534 void SetRowInserted(bool aValue);
536 protected:
538 // A helper function to reflow a header or footer with unconstrained height
539 // to see if it should be made repeatable and also to determine its desired
540 // height.
541 nsresult SetupHeaderFooterChild(const nsTableReflowState& aReflowState,
542 nsTableRowGroupFrame* aFrame,
543 nscoord* aDesiredHeight);
545 nsresult ReflowChildren(nsTableReflowState& aReflowState,
546 nsReflowStatus& aStatus,
547 nsIFrame*& aLastChildReflowed,
548 nsOverflowAreas& aOverflowAreas);
550 // This calls the col group and column reflow methods, which do two things:
551 // (1) set all the dimensions to 0
552 // (2) notify the table about colgroups or columns with hidden visibility
553 void ReflowColGroups(nsRenderingContext* aRenderingContext);
555 /** return the width of the table taking into account visibility collapse
556 * on columns and colgroups
557 * @param aBorderPadding the border and padding of the table
558 */
559 nscoord GetCollapsedWidth(nsMargin aBorderPadding);
562 /** Adjust the table for visibility.collapse set on rowgroups, rows,
563 * colgroups and cols
564 * @param aDesiredSize the metrics of the table
565 * @param aBorderPadding the border and padding of the table
566 */
567 void AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
568 nsMargin aBorderPadding);
570 /** FixupPositionedTableParts is called at the end of table reflow to reflow
571 * the absolutely positioned descendants of positioned table parts. This is
572 * necessary because the dimensions of table parts may change after they've
573 * been reflowed (e.g. in AdjustForCollapsingRowsCols).
574 */
575 void FixupPositionedTableParts(nsPresContext* aPresContext,
576 nsHTMLReflowMetrics& aDesiredSize,
577 const nsHTMLReflowState& aReflowState);
579 // Clears the list of positioned table parts.
580 void ClearAllPositionedTableParts();
582 nsITableLayoutStrategy* LayoutStrategy() const {
583 return static_cast<nsTableFrame*>(FirstInFlow())->
584 mTableLayoutStrategy;
585 }
587 // Helper for InsertFrames.
588 void HomogenousInsertFrames(ChildListID aListID,
589 nsIFrame* aPrevFrame,
590 nsFrameList& aFrameList);
591 private:
592 /* Handle a row that got inserted during reflow. aNewHeight is the
593 new height of the table after reflow. */
594 void ProcessRowInserted(nscoord aNewHeight);
596 // WIDTH AND HEIGHT CALCULATION
598 public:
600 // calculate the computed height of aFrame including its border and padding given
601 // its reflow state.
602 nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
604 protected:
606 // update the desired height of this table taking into account the current
607 // reflow state, the table attributes and the content driven rowgroup heights
608 // this function can change the overflow area
609 void CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize);
611 // The following is a helper for CalcDesiredHeight
613 void DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
614 nscoord aAmount);
616 void PlaceChild(nsTableReflowState& aReflowState,
617 nsIFrame* aKidFrame,
618 nsHTMLReflowMetrics& aKidDesiredSize,
619 const nsRect& aOriginalKidRect,
620 const nsRect& aOriginalKidVisualOverflow);
621 void PlaceRepeatedFooter(nsTableReflowState& aReflowState,
622 nsTableRowGroupFrame *aTfoot,
623 nscoord aFooterHeight);
625 nsIFrame* GetFirstBodyRowGroupFrame();
626 public:
627 typedef nsAutoTArray<nsTableRowGroupFrame*, 8> RowGroupArray;
628 /**
629 * Push all our child frames from the aRowGroups array, in order, starting
630 * from the frame at aPushFrom to the end of the array. The frames are put on
631 * our overflow list or moved directly to our next-in-flow if one exists.
632 */
633 protected:
634 void PushChildren(const RowGroupArray& aRowGroups, int32_t aPushFrom);
636 public:
637 // put the children frames in the display order (e.g. thead before tbodies
638 // before tfoot). This will handle calling GetRowGroupFrame() on the
639 // children, and not append nulls, so the array is guaranteed to contain
640 // nsTableRowGroupFrames. If there are multiple theads or tfoots, all but
641 // the first one are treated as tbodies instead.
643 void OrderRowGroups(RowGroupArray& aChildren,
644 nsTableRowGroupFrame** aHead = nullptr,
645 nsTableRowGroupFrame** aFoot = nullptr) const;
647 // Return the thead, if any
648 nsTableRowGroupFrame* GetTHead() const;
650 // Return the tfoot, if any
651 nsTableRowGroupFrame* GetTFoot() const;
653 // Returns true if there are any cells above the row at
654 // aRowIndex and spanning into the row at aRowIndex, the number of
655 // effective columns limits the search up to that column
656 bool RowIsSpannedInto(int32_t aRowIndex, int32_t aNumEffCols);
658 // Returns true if there is a cell originating in aRowIndex
659 // which spans into the next row, the number of effective
660 // columns limits the search up to that column
661 bool RowHasSpanningCells(int32_t aRowIndex, int32_t aNumEffCols);
663 protected:
665 bool HaveReflowedColGroups() const;
666 void SetHaveReflowedColGroups(bool aValue);
668 public:
669 bool IsBorderCollapse() const;
671 bool NeedToCalcBCBorders() const;
672 void SetNeedToCalcBCBorders(bool aValue);
674 bool NeedToCollapse() const;
675 void SetNeedToCollapse(bool aValue);
677 bool HasZeroColSpans() const;
678 void SetHasZeroColSpans(bool aValue);
680 bool NeedColSpanExpansion() const;
681 void SetNeedColSpanExpansion(bool aValue);
683 /** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame
684 * state bit, which implies that all descendants are dirty. The
685 * GeometryDirty still implies that all the parts of the table are
686 * dirty, but resizing optimizations should still apply to the
687 * contents of the individual cells.
688 */
689 void SetGeometryDirty() { mBits.mGeometryDirty = true; }
690 void ClearGeometryDirty() { mBits.mGeometryDirty = false; }
691 bool IsGeometryDirty() const { return mBits.mGeometryDirty; }
693 /** Get the cell map for this table frame. It is not always mCellMap.
694 * Only the firstInFlow has a legit cell map
695 */
696 nsTableCellMap* GetCellMap() const;
698 /** Iterate over the row groups and adjust the row indices of all rows
699 * whose index is >= aRowIndex.
700 * @param aRowIndex - start adjusting with this index
701 * @param aAdjustment - shift the row index by this amount
702 */
703 void AdjustRowIndices(int32_t aRowIndex,
704 int32_t aAdjustment);
706 /** Reset the rowindices of all rows as they might have changed due to
707 * rowgroup reordering, exclude new row group frames that show in the
708 * reordering but are not yet inserted into the cellmap
709 * @param aRowGroupsToExclude - an iterator that will produce the row groups
710 * to exclude.
711 */
712 void ResetRowIndices(const nsFrameList::Slice& aRowGroupsToExclude);
714 nsTArray<nsTableColFrame*>& GetColCache();
717 protected:
719 void SetBorderCollapse(bool aValue);
721 BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const;
722 void SetFullBCDamageArea();
723 void CalcBCBorders();
725 void ExpandBCDamageArea(nsIntRect& aRect) const;
727 void SetColumnDimensions(nscoord aHeight,
728 const nsMargin& aReflowState);
730 int32_t CollectRows(nsIFrame* aFrame,
731 nsTArray<nsTableRowFrame*>& aCollection);
733 public: /* ----- Cell Map public methods ----- */
735 int32_t GetStartRowIndex(nsTableRowGroupFrame* aRowGroupFrame);
737 /** returns the number of rows in this table.
738 */
739 int32_t GetRowCount () const
740 {
741 return GetCellMap()->GetRowCount();
742 }
744 /** returns the number of columns in this table after redundant columns have been removed
745 */
746 int32_t GetEffectiveColCount() const;
748 /* return the col count including dead cols */
749 int32_t GetColCount () const
750 {
751 return GetCellMap()->GetColCount();
752 }
754 // return the last col index which isn't of type eColAnonymousCell
755 int32_t GetIndexOfLastRealCol();
757 /** returns true if table-layout:auto */
758 bool IsAutoLayout();
760 public:
762 #ifdef DEBUG
763 void Dump(bool aDumpRows,
764 bool aDumpCols,
765 bool aDumpCellMap);
766 #endif
768 protected:
769 /**
770 * Helper method for RemoveFrame.
771 */
772 void DoRemoveFrame(ChildListID aListID, nsIFrame* aOldFrame);
773 #ifdef DEBUG
774 void DumpRowGroup(nsIFrame* aChildFrame);
775 #endif
776 // DATA MEMBERS
777 nsAutoTArray<nsTableColFrame*, 8> mColFrames;
779 struct TableBits {
780 uint32_t mHaveReflowedColGroups:1; // have the col groups gotten their initial reflow
781 uint32_t mHasPctCol:1; // does any cell or col have a pct width
782 uint32_t mCellSpansPctCol:1; // does any cell span a col with a pct width (or containing a cell with a pct width)
783 uint32_t mIsBorderCollapse:1; // border collapsing model vs. separate model
784 uint32_t mRowInserted:1;
785 uint32_t mNeedToCalcBCBorders:1;
786 uint32_t mGeometryDirty:1;
787 uint32_t mLeftContBCBorder:8;
788 uint32_t mNeedToCollapse:1; // rows, cols that have visibility:collapse need to be collapsed
789 uint32_t mHasZeroColSpans:1;
790 uint32_t mNeedColSpanExpansion:1;
791 uint32_t mResizedColumns:1; // have we resized columns since last reflow?
792 } mBits;
794 nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
795 nsITableLayoutStrategy* mTableLayoutStrategy;// the layout strategy for this frame
796 nsFrameList mColGroups; // the list of colgroup frames
797 };
800 inline bool nsTableFrame::IsRowGroup(int32_t aDisplayType) const
801 {
802 return bool((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == aDisplayType) ||
803 (NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == aDisplayType) ||
804 (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == aDisplayType));
805 }
807 inline void nsTableFrame::SetHaveReflowedColGroups(bool aValue)
808 {
809 mBits.mHaveReflowedColGroups = aValue;
810 }
812 inline bool nsTableFrame::HaveReflowedColGroups() const
813 {
814 return (bool)mBits.mHaveReflowedColGroups;
815 }
817 inline bool nsTableFrame::HasPctCol() const
818 {
819 return (bool)mBits.mHasPctCol;
820 }
822 inline void nsTableFrame::SetHasPctCol(bool aValue)
823 {
824 mBits.mHasPctCol = (unsigned)aValue;
825 }
827 inline bool nsTableFrame::HasCellSpanningPctCol() const
828 {
829 return (bool)mBits.mCellSpansPctCol;
830 }
832 inline void nsTableFrame::SetHasCellSpanningPctCol(bool aValue)
833 {
834 mBits.mCellSpansPctCol = (unsigned)aValue;
835 }
837 inline bool nsTableFrame::IsRowInserted() const
838 {
839 return (bool)mBits.mRowInserted;
840 }
842 inline void nsTableFrame::SetRowInserted(bool aValue)
843 {
844 mBits.mRowInserted = (unsigned)aValue;
845 }
847 inline void nsTableFrame::SetNeedToCollapse(bool aValue)
848 {
849 static_cast<nsTableFrame*>(FirstInFlow())->mBits.mNeedToCollapse = (unsigned)aValue;
850 }
852 inline bool nsTableFrame::NeedToCollapse() const
853 {
854 return (bool) static_cast<nsTableFrame*>(FirstInFlow())->mBits.mNeedToCollapse;
855 }
857 inline void nsTableFrame::SetHasZeroColSpans(bool aValue)
858 {
859 mBits.mHasZeroColSpans = (unsigned)aValue;
860 }
862 inline bool nsTableFrame::HasZeroColSpans() const
863 {
864 return (bool)mBits.mHasZeroColSpans;
865 }
867 inline void nsTableFrame::SetNeedColSpanExpansion(bool aValue)
868 {
869 mBits.mNeedColSpanExpansion = (unsigned)aValue;
870 }
872 inline bool nsTableFrame::NeedColSpanExpansion() const
873 {
874 return (bool)mBits.mNeedColSpanExpansion;
875 }
878 inline nsFrameList& nsTableFrame::GetColGroups()
879 {
880 return static_cast<nsTableFrame*>(FirstInFlow())->mColGroups;
881 }
883 inline nsTArray<nsTableColFrame*>& nsTableFrame::GetColCache()
884 {
885 return mColFrames;
886 }
888 inline bool nsTableFrame::IsBorderCollapse() const
889 {
890 return (bool)mBits.mIsBorderCollapse;
891 }
893 inline void nsTableFrame::SetBorderCollapse(bool aValue)
894 {
895 mBits.mIsBorderCollapse = aValue;
896 }
898 inline bool nsTableFrame::NeedToCalcBCBorders() const
899 {
900 return (bool)mBits.mNeedToCalcBCBorders;
901 }
903 inline void nsTableFrame::SetNeedToCalcBCBorders(bool aValue)
904 {
905 mBits.mNeedToCalcBCBorders = (unsigned)aValue;
906 }
908 inline nscoord
909 nsTableFrame::GetContinuousLeftBCBorderWidth() const
910 {
911 int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
912 return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, mBits.mLeftContBCBorder);
913 }
915 inline void nsTableFrame::SetContinuousLeftBCBorderWidth(nscoord aValue)
916 {
917 mBits.mLeftContBCBorder = (unsigned) aValue;
918 }
920 class nsTableIterator
921 {
922 public:
923 nsTableIterator(nsIFrame& aSource);
924 nsTableIterator(nsFrameList& aSource);
925 nsIFrame* First();
926 nsIFrame* Next();
927 bool IsLeftToRight();
928 int32_t Count();
930 protected:
931 void Init(nsIFrame* aFirstChild);
932 bool mLeftToRight;
933 nsIFrame* mFirstListChild;
934 nsIFrame* mFirstChild;
935 nsIFrame* mCurrentChild;
936 int32_t mCount;
937 };
939 #define ABORT0() \
940 {NS_ASSERTION(false, "CellIterator program error"); \
941 return;}
943 #define ABORT1(aReturn) \
944 {NS_ASSERTION(false, "CellIterator program error"); \
945 return aReturn;}
947 #endif