1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
37 #ifndef nsTableFrame_h__
38 #define nsTableFrame_h__
41 #include "nsVoidArray.h"
42 #include "nsHTMLContainerFrame.h"
43 #include "nsStyleCoord.h"
44 #include "nsStyleConsts.h"
45 #include "nsITableLayout.h"
46 #include "nsTableColFrame.h"
47 #include "nsTableColGroupFrame.h"
48 #include "nsCellMap.h"
49 #include "nsGkAtoms.h"
50 #include "nsDisplayList.h"
52 class nsTableCellFrame
;
53 class nsTableColFrame
;
54 class nsTableRowGroupFrame
;
55 class nsTableRowFrame
;
56 class nsTableColGroupFrame
;
57 class nsITableLayoutStrategy
;
60 struct nsTableReflowState
;
61 struct nsStylePosition
;
64 * Child list name indices
65 * @see #GetAdditionalChildListName()
67 #define NS_TABLE_FRAME_COLGROUP_LIST_INDEX 0
68 #define NS_TABLE_FRAME_OVERFLOW_LIST_INDEX 1
69 #define NS_TABLE_FRAME_LAST_LIST_INDEX NS_TABLE_FRAME_OVERFLOW_LIST_INDEX
71 static inline PRBool
IS_TABLE_CELL(nsIAtom
* frameType
) {
72 return nsGkAtoms::tableCellFrame
== frameType
||
73 nsGkAtoms::bcTableCellFrame
== frameType
;
76 class nsDisplayTableItem
: public nsDisplayItem
79 nsDisplayTableItem(nsIFrame
* aFrame
) : nsDisplayItem(aFrame
),
80 mPartHasFixedBackground(PR_FALSE
) {}
82 virtual PRBool
IsVaryingRelativeToMovingFrame(nsDisplayListBuilder
* aBuilder
);
83 // With collapsed borders, parts of the collapsed border can extend outside
84 // the table part frames, so allow this display element to blow out to our
85 // overflow rect. This is also useful for row frames that have spanning
86 // cells extending outside them.
87 virtual nsRect
GetBounds(nsDisplayListBuilder
* aBuilder
);
89 void UpdateForFrameBackground(nsIFrame
* aFrame
);
92 PRPackedBool mPartHasFixedBackground
;
95 class nsAutoPushCurrentTableItem
98 nsAutoPushCurrentTableItem() : mBuilder(nsnull
) {}
100 void Push(nsDisplayListBuilder
* aBuilder
, nsDisplayTableItem
* aPushItem
)
103 mOldCurrentItem
= aBuilder
->GetCurrentTableItem();
104 aBuilder
->SetCurrentTableItem(aPushItem
);
106 mPushedItem
= aPushItem
;
109 ~nsAutoPushCurrentTableItem() {
113 NS_ASSERTION(mBuilder
->GetCurrentTableItem() == mPushedItem
,
114 "Someone messed with the current table item behind our back!");
116 mBuilder
->SetCurrentTableItem(mOldCurrentItem
);
120 nsDisplayListBuilder
* mBuilder
;
121 nsDisplayTableItem
* mOldCurrentItem
;
123 nsDisplayTableItem
* mPushedItem
;
127 /* ============================================================================ */
129 /** nsTableFrame maps the inner portion of a table (everything except captions.)
130 * Used as a pseudo-frame within nsTableOuterFrame, it may also be used
131 * stand-alone as the top-level frame.
133 * The flowed child list contains row group frames. There is also an additional
135 * - "ColGroup-list" which contains the col group frames
137 * @see nsGkAtoms::colGroupList
139 class nsTableFrame
: public nsHTMLContainerFrame
, public nsITableLayout
144 NS_DECL_ISUPPORTS_INHERITED
146 /** nsTableOuterFrame has intimate knowledge of the inner table frame */
147 friend class nsTableOuterFrame
;
149 /** instantiate a new instance of nsTableRowFrame.
150 * @param aPresShell the pres shell for this frame
152 * @return the frame that was created
154 friend nsIFrame
* NS_NewTableFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
);
156 /** sets defaults for table-specific style.
157 * @see nsIFrame::Init
159 NS_IMETHOD
Init(nsIContent
* aContent
,
161 nsIFrame
* aPrevInFlow
);
164 static void* GetProperty(nsIFrame
* aFrame
,
165 nsIAtom
* aPropertyName
,
166 PRBool aCreateIfNecessary
= PR_FALSE
);
168 static float GetTwipsToPixels(nsPresContext
* aPresContext
);
170 // Return true if aParentReflowState.frame or any of its ancestors within
171 // the containing table have non-auto height. (e.g. pct or fixed height)
172 static PRBool
AncestorsHaveStyleHeight(const nsHTMLReflowState
& aParentReflowState
);
174 // See if a special height reflow will occur due to having a pct height when
175 // the pct height basis may not yet be valid.
176 static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState
& aReflowState
);
178 // Notify the frame and its ancestors (up to the containing table) that a special
179 // height reflow will occur.
180 static void RequestSpecialHeightReflow(const nsHTMLReflowState
& aReflowState
);
182 virtual PRBool
IsContainingBlock() const;
184 static void RePositionViews(nsIFrame
* aFrame
);
186 static PRBool
PageBreakAfter(nsIFrame
& aSourceFrame
,
187 nsIFrame
* aNextFrame
);
189 nsPoint
GetFirstSectionOrigin(const nsHTMLReflowState
& aReflowState
) const;
191 * Notification that aAttribute has changed for content inside a table (cell, row, etc)
193 void AttributeChangedFor(nsIFrame
* aFrame
,
194 nsIContent
* aContent
,
195 nsIAtom
* aAttribute
);
197 /** @see nsIFrame::Destroy */
198 virtual void Destroy();
200 /** @see nsIFrame::DidSetStyleContext */
201 virtual void DidSetStyleContext(nsStyleContext
* aOldStyleContext
);
203 NS_IMETHOD
AppendFrames(nsIAtom
* aListName
,
204 nsIFrame
* aFrameList
);
205 NS_IMETHOD
InsertFrames(nsIAtom
* aListName
,
206 nsIFrame
* aPrevFrame
,
207 nsIFrame
* aFrameList
);
208 NS_IMETHOD
RemoveFrame(nsIAtom
* aListName
,
209 nsIFrame
* aOldFrame
);
211 virtual nsMargin
GetUsedBorder() const;
212 virtual nsMargin
GetUsedPadding() const;
214 // Get the offset from the border box to the area where the row groups fit
215 nsMargin
GetChildAreaOffset(const nsHTMLReflowState
* aReflowState
) const;
217 // Get the offset from the border box to the area where the content fits
218 nsMargin
GetContentAreaOffset(const nsHTMLReflowState
* aReflowState
) const;
220 /** helper method to find the table parent of any table frame object */
221 static nsTableFrame
* GetTableFrame(nsIFrame
* aSourceFrame
);
223 typedef nsresult (* DisplayGenericTablePartTraversal
)
224 (nsDisplayListBuilder
* aBuilder
, nsFrame
* aFrame
,
225 const nsRect
& aDirtyRect
, const nsDisplayListSet
& aLists
);
226 static nsresult
GenericTraversal(nsDisplayListBuilder
* aBuilder
, nsFrame
* aFrame
,
227 const nsRect
& aDirtyRect
, const nsDisplayListSet
& aLists
);
230 * Helper method to handle display common to table frames, rowgroup frames
231 * and row frames. It creates a background display item for handling events
232 * if necessary, an outline display item if necessary, and displays
233 * all the the frame's children.
234 * @param aDisplayItem the display item created for this part, or null
235 * if this part's border/background painting is delegated to an ancestor
236 * @param aTraversal a function that gets called to traverse the table
237 * part's child frames and add their display list items to a
240 static nsresult
DisplayGenericTablePart(nsDisplayListBuilder
* aBuilder
,
242 const nsRect
& aDirtyRect
,
243 const nsDisplayListSet
& aLists
,
244 nsDisplayTableItem
* aDisplayItem
,
245 DisplayGenericTablePartTraversal aTraversal
= GenericTraversal
);
247 // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
248 // of type aChildType.
249 static nsIFrame
* GetFrameAtOrBefore(nsIFrame
* aParentFrame
,
250 nsIFrame
* aPriorChildFrame
,
251 nsIAtom
* aChildType
);
252 PRBool
IsAutoWidth(PRBool
* aIsPctWidth
= nsnull
);
253 PRBool
IsAutoHeight();
254 static PRBool
IsPctHeight(nsStyleContext
* aStyleContext
);
256 /** @return PR_TRUE if aDisplayType represents a rowgroup of any sort
257 * (header, footer, or body)
259 PRBool
IsRowGroup(PRInt32 aDisplayType
) const;
261 /** Initialize the table frame with a set of children.
262 * @see nsIFrame::SetInitialChildList
264 NS_IMETHOD
SetInitialChildList(nsIAtom
* aListName
,
265 nsIFrame
* aChildList
);
267 /** return the first child belonging to the list aListName.
268 * @see nsIFrame::GetFirstChild
270 virtual nsIFrame
* GetFirstChild(nsIAtom
* aListName
) const;
272 /** @see nsIFrame::GetAdditionalChildListName */
273 virtual nsIAtom
* GetAdditionalChildListName(PRInt32 aIndex
) const;
275 NS_IMETHOD
BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
276 const nsRect
& aDirtyRect
,
277 const nsDisplayListSet
& aLists
);
280 * Paint the background of the table and its parts (column groups,
281 * columns, row groups, rows, and cells), and the table border, and all
282 * internal borders if border-collapse is on.
284 void PaintTableBorderBackground(nsIRenderingContext
& aRenderingContext
,
285 const nsRect
& aDirtyRect
,
288 // Get the outer half (i.e., the part outside the height and width of
289 // the table) of the largest segment (?) of border-collapsed border on
290 // the table on each side, or 0 for non border-collapsed tables.
291 nsMargin
GetOuterBCBorder() const;
293 // Same as above, but only if it's included from the border-box width
294 // of the table (nonzero only in quirks mode).
295 nsMargin
GetIncludedOuterBCBorder() const;
297 // Same as above, but only if it's excluded from the border-box width
298 // of the table (nonzero only in standards mode). This is the area
299 // that leaks out into the margin (or potentially past it, if there is
301 nsMargin
GetExcludedOuterBCBorder() const;
303 /** Get width of table + colgroup + col collapse: elements that
304 * continue along the length of the whole left side.
305 * see nsTablePainter about continuous borders
306 * @param aPixelsToTwips - conversion factor
307 * @param aGetInner - get only inner half of border width
309 nscoord
GetContinuousLeftBCBorderWidth() const;
310 friend class nsDelayedCalcBCBorders
;
312 void SetBCDamageArea(const nsRect
& aValue
);
313 PRBool
BCRecalcNeeded(nsStyleContext
* aOldStyleContext
,
314 nsStyleContext
* aNewStyleContext
);
315 void PaintBCBorders(nsIRenderingContext
& aRenderingContext
,
316 const nsRect
& aDirtyRect
);
318 /** nsIFrame method overridden to handle table specifics
320 NS_IMETHOD
SetSelected(nsPresContext
* aPresContext
,
324 SelectionType aType
);
326 virtual void MarkIntrinsicWidthsDirty();
327 // For border-collapse tables, the caller must not add padding and
328 // border to the results of these functions.
329 virtual nscoord
GetMinWidth(nsIRenderingContext
*aRenderingContext
);
330 virtual nscoord
GetPrefWidth(nsIRenderingContext
*aRenderingContext
);
331 virtual IntrinsicWidthOffsetData
332 IntrinsicWidthOffsets(nsIRenderingContext
* aRenderingContext
);
334 virtual nsSize
ComputeSize(nsIRenderingContext
*aRenderingContext
,
335 nsSize aCBSize
, nscoord aAvailableWidth
,
336 nsSize aMargin
, nsSize aBorder
, nsSize aPadding
,
338 virtual nsSize
ComputeAutoSize(nsIRenderingContext
*aRenderingContext
,
339 nsSize aCBSize
, nscoord aAvailableWidth
,
340 nsSize aMargin
, nsSize aBorder
,
341 nsSize aPadding
, PRBool aShrinkWrap
);
343 * A copy of nsFrame::ShrinkWidthToFit that calls a different
344 * GetPrefWidth, since tables have two different ones.
346 nscoord
TableShrinkWidthToFit(nsIRenderingContext
*aRenderingContext
,
349 // XXXldb REWRITE THIS COMMENT!
350 /** inner tables are reflowed in two steps.
352 * if mFirstPassValid is false, this is our first time through since content was last changed
355 * get min/max info for all cells in an infinite space
356 * do column balancing
357 * set mFirstPassValid to true
359 * use column widths to Reflow cells
362 * @see nsIFrame::Reflow
364 NS_IMETHOD
Reflow(nsPresContext
* aPresContext
,
365 nsHTMLReflowMetrics
& aDesiredSize
,
366 const nsHTMLReflowState
& aReflowState
,
367 nsReflowStatus
& aStatus
);
369 nsresult
ReflowTable(nsHTMLReflowMetrics
& aDesiredSize
,
370 const nsHTMLReflowState
& aReflowState
,
371 nscoord aAvailHeight
,
372 nsIFrame
*& aLastChildReflowed
,
373 nsReflowStatus
& aStatus
);
375 nsFrameList
& GetColGroups();
377 NS_IMETHOD
GetParentStyleContextFrame(nsPresContext
* aPresContext
,
378 nsIFrame
** aProviderFrame
,
381 virtual PRBool
IsFrameOfType(PRUint32 aFlags
) const
383 return nsHTMLContainerFrame::IsFrameOfType(aFlags
&
384 ~nsIFrame::eExcludesIgnorableWhitespace
);
388 * Get the "type" of the frame
390 * @see nsGkAtoms::tableFrame
392 virtual nsIAtom
* GetType() const;
395 /** @see nsIFrame::GetFrameName */
396 NS_IMETHOD
GetFrameName(nsAString
& aResult
) const;
399 /** return the width of the column at aColIndex */
400 virtual PRInt32
GetColumnWidth(PRInt32 aColIndex
);
402 /** set the width of the column at aColIndex to aWidth */
403 virtual void SetColumnWidth(PRInt32 aColIndex
, nscoord aWidth
);
405 /** helper to get the cell spacing X style value */
406 virtual nscoord
GetCellSpacingX();
408 /** helper to get the cell spacing Y style value */
409 virtual nscoord
GetCellSpacingY();
411 virtual nscoord
GetBaseline() const;
412 /** return the row span of a cell, taking into account row span magic at the bottom
413 * of a table. The row span equals the number of rows spanned by aCell starting at
414 * aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
415 * index in which aCell originates.
417 * @param aStartRowIndex the cell
418 * @param aCell the cell
420 * @return the row span, correcting for row spans that extend beyond the bottom
423 virtual PRInt32
GetEffectiveRowSpan(PRInt32 aStartRowIndex
,
424 const nsTableCellFrame
& aCell
) const;
425 virtual PRInt32
GetEffectiveRowSpan(const nsTableCellFrame
& aCell
,
426 nsCellMap
* aCellMap
= nsnull
);
428 /** return the col span of a cell, taking into account col span magic at the edge
431 * @param aCell the cell
433 * @return the col span, correcting for col spans that extend beyond the edge
436 virtual PRInt32
GetEffectiveColSpan(const nsTableCellFrame
& aCell
,
437 nsCellMap
* aCellMap
= nsnull
) const;
439 /** indicate whether the row has more than one cell that either originates
440 * or is spanned from the rows above
442 PRBool
HasMoreThanOneCell(PRInt32 aRowIndex
) const;
444 /** return the value of the COLS attribute, adjusted for the
445 * actual number of columns in the table
447 PRInt32
GetEffectiveCOLSAttribute();
449 /** return the column frame associated with aColIndex
450 * returns nsnull if the col frame has not yet been allocated, or if
451 * aColIndex is out of range
453 nsTableColFrame
* GetColFrame(PRInt32 aColIndex
) const;
455 /** Insert a col frame reference into the colframe cache and adapt the cellmap
456 * @param aColFrame - the column frame
457 * @param aColIndex - index where the column should be inserted into the
460 void InsertCol(nsTableColFrame
& aColFrame
,
463 nsTableColGroupFrame
* CreateAnonymousColGroupFrame(nsTableColGroupType aType
);
465 PRInt32
DestroyAnonymousColFrames(PRInt32 aNumFrames
);
467 void CreateAnonymousColFrames(PRInt32 aNumColsToAdd
,
468 nsTableColType aColType
,
470 nsIFrame
* aPrevCol
= nsnull
);
472 void CreateAnonymousColFrames(nsTableColGroupFrame
* aColGroupFrame
,
473 PRInt32 aNumColsToAdd
,
474 nsTableColType aColType
,
475 PRBool aAddToColGroupAndTable
,
477 nsIFrame
** aFirstNewFrame
);
479 void MatchCellMapToColCache(nsTableCellMap
* aCellMap
);
480 /** empty the column frame cache */
481 void ClearColCache();
483 void DidResizeColumns();
485 virtual void AppendCell(nsTableCellFrame
& aCellFrame
,
488 virtual void InsertCells(nsVoidArray
& aCellFrames
,
490 PRInt32 aColIndexBefore
);
492 virtual void RemoveCell(nsTableCellFrame
* aCellFrame
,
495 void AppendRows(nsTableRowGroupFrame
& aRowGroupFrame
,
497 nsVoidArray
& aRowFrames
);
499 PRInt32
InsertRow(nsTableRowGroupFrame
& aRowGroupFrame
,
502 PRBool aConsiderSpans
);
504 PRInt32
InsertRows(nsTableRowGroupFrame
& aRowGroupFrame
,
505 nsVoidArray
& aFrames
,
507 PRBool aConsiderSpans
);
509 virtual void RemoveRows(nsTableRowFrame
& aFirstRowFrame
,
510 PRInt32 aNumRowsToRemove
,
511 PRBool aConsiderSpans
);
513 /** Insert multiple rowgroups into the table cellmap handling
514 * @param aFirstRowGroupFrame - first row group to be inserted all siblings
515 * will be appended too.
517 void AppendRowGroups(nsIFrame
* aFirstRowGroupFrame
);
519 /** Insert multiple rowgroups into the table cellmap handling
520 * @param aFirstRowGroupFrame - first row group to be inserted
521 * @param aLastRowGroupFrame - when inserting the siblings of
522 * aFirstRowGroupFrame stop at this row group
524 void InsertRowGroups(nsIFrame
* aFirstRowGroupFrame
,
525 nsIFrame
* aLastRowGroupFrame
);
527 void InsertColGroups(PRInt32 aColIndex
,
528 nsIFrame
* aFirstFrame
,
529 nsIFrame
* aLastFrame
= nsnull
);
531 virtual void RemoveCol(nsTableColGroupFrame
* aColGroupFrame
,
533 PRBool aRemoveFromCache
,
534 PRBool aRemoveFromCellMap
);
536 NS_IMETHOD
GetIndexByRowAndColumn(PRInt32 aRow
, PRInt32 aColumn
, PRInt32
*aIndex
);
537 NS_IMETHOD
GetRowAndColumnByIndex(PRInt32 aIndex
, PRInt32
*aRow
, PRInt32
*aColumn
);
539 PRBool
ColumnHasCellSpacingBefore(PRInt32 aColIndex
) const;
541 PRBool
HasPctCol() const;
542 void SetHasPctCol(PRBool aValue
);
544 PRBool
HasCellSpanningPctCol() const;
545 void SetHasCellSpanningPctCol(PRBool aValue
);
548 * To be called on a frame by its parent after setting its size/position and
549 * calling DidReflow (possibly via FinishReflowChild()). This can also be
550 * used for child frames which are not being reflown but did have their size
551 * or position changed.
553 * @param aFrame The frame to invalidate
554 * @param aOrigRect The original rect of aFrame (before the change).
555 * @param aOrigOverflowRect The original overflow rect of aFrame.
556 * @param aIsFirstReflow True if the size/position change is due to the
557 * first reflow of aFrame.
559 static void InvalidateFrame(nsIFrame
* aFrame
,
560 const nsRect
& aOrigRect
,
561 const nsRect
& aOrigOverflowRect
,
562 PRBool aIsFirstReflow
);
566 /** protected constructor.
569 nsTableFrame(nsStyleContext
* aContext
);
571 /** destructor, responsible for mColumnLayoutData */
572 virtual ~nsTableFrame();
574 void InitChildReflowState(nsHTMLReflowState
& aReflowState
);
576 /** implement abstract method on nsHTMLContainerFrame */
577 virtual PRIntn
GetSkipSides() const;
579 virtual PRBool
ParentDisablesSelection() const; //override default behavior
582 PRBool
IsRowInserted() const;
583 void SetRowInserted(PRBool aValue
);
587 // A helper function to reflow a header or footer with unconstrained height
588 // to see if it should be made repeatable and also to determine its desired
590 nsresult
SetupHeaderFooterChild(const nsTableReflowState
& aReflowState
,
591 nsTableRowGroupFrame
* aFrame
,
592 nscoord
* aDesiredHeight
);
594 NS_METHOD
ReflowChildren(nsTableReflowState
& aReflowState
,
595 nsReflowStatus
& aStatus
,
596 nsIFrame
*& aLastChildReflowed
,
597 nsRect
& aOverflowArea
);
599 // This calls the col group and column reflow methods, which do two things:
600 // (1) set all the dimensions to 0
601 // (2) notify the table about colgroups or columns with hidden visibility
602 void ReflowColGroups(nsIRenderingContext
* aRenderingContext
);
604 /** return the width of the table taking into account visibility collapse
605 * on columns and colgroups
606 * @param aBorderPadding the border and padding of the table
608 nscoord
GetCollapsedWidth(nsMargin aBorderPadding
);
611 /** Adjust the table for visibilty.collapse set on rowgroups, rows, colgroups
613 * @param aDesiredSize the metrics of the table
614 * @param aBorderPadding the border and padding of the table
616 void AdjustForCollapsingRowsCols(nsHTMLReflowMetrics
& aDesiredSize
,
617 nsMargin aBorderPadding
);
619 nsITableLayoutStrategy
* LayoutStrategy() const {
620 return static_cast<nsTableFrame
*>(GetFirstInFlow())->
621 mTableLayoutStrategy
;
625 /* Handle a row that got inserted during reflow. aNewHeight is the
626 new height of the table after reflow. */
627 void ProcessRowInserted(nscoord aNewHeight
);
629 // WIDTH AND HEIGHT CALCULATION
633 // calculate the computed height of aFrame including its border and padding given
635 nscoord
CalcBorderBoxHeight(const nsHTMLReflowState
& aReflowState
);
639 // update the desired height of this table taking into account the current
640 // reflow state, the table attributes and the content driven rowgroup heights
641 // this function can change the overflow area
642 void CalcDesiredHeight(const nsHTMLReflowState
& aReflowState
, nsHTMLReflowMetrics
& aDesiredSize
);
644 // The following is a helper for CalcDesiredHeight
646 void DistributeHeightToRows(const nsHTMLReflowState
& aReflowState
,
649 void PlaceChild(nsTableReflowState
& aReflowState
,
651 nsHTMLReflowMetrics
& aKidDesiredSize
,
652 const nsRect
& aOriginalKidRect
,
653 const nsRect
& aOriginalKidOverflowRect
);
655 nsIFrame
* GetFirstBodyRowGroupFrame();
656 PRBool
MoveOverflowToChildList(nsPresContext
* aPresContext
);
658 * Push all our child frames from the aFrames array, in order, starting from the
659 * frame at aPushFrom to the end of the array. The frames are put on our overflow
660 * list or moved directly to our next-in-flow if one exists.
662 typedef nsAutoTPtrArray
<nsIFrame
, 8> FrameArray
;
663 void PushChildren(const FrameArray
& aFrames
, PRInt32 aPushFrom
);
666 // put the children frames in the display order (e.g. thead before tbodies
667 // before tfoot). This will handle calling GetRowGroupFrame() on the
668 // children, and not append nulls, so the array is guaranteed to contain
669 // nsTableRowGroupFrames. If there are multiple theads or tfoots, all but
670 // the first one are treated as tbodies instead.
671 typedef nsAutoTPtrArray
<nsTableRowGroupFrame
, 8> RowGroupArray
;
672 void OrderRowGroups(RowGroupArray
& aChildren
) const;
674 // Return the thead, if any
675 nsTableRowGroupFrame
* GetTHead() const;
677 // Return the tfoot, if any
678 nsTableRowGroupFrame
* GetTFoot() const;
681 // As above, but does NOT actually call GetRowGroupFrame() on the kids, so
682 // returns an array of nsIFrames. This is to be used when you really want
683 // the flowable kids of the table, not the rowgroups. This outputs the thead
684 // and tfoot if they happen to be rowgroups. All the child nsIFrames of the
685 // table that return null if you call GetRowGroupFrame() on them will appear
686 // at the end of the array, after the tfoot, if any.
688 // aHead and aFoot must not be null.
690 // @return the number of frames in aChildren which return non-null if you
691 // call GetRowGroupFrame() on them.
693 // XXXbz why do we really care about the non-rowgroup kids?
694 PRUint32
OrderRowGroups(FrameArray
& aChildren
,
695 nsTableRowGroupFrame
** aHead
,
696 nsTableRowGroupFrame
** aFoot
) const;
699 // Returns PR_TRUE if there are any cells above the row at
700 // aRowIndex and spanning into the row at aRowIndex, the number of
701 // effective columns limits the search up to that column
702 PRBool
RowIsSpannedInto(PRInt32 aRowIndex
, PRInt32 aNumEffCols
);
704 // Returns PR_TRUE if there is a cell originating in aRowIndex
705 // which spans into the next row, the number of effective
706 // columns limits the search up to that column
707 PRBool
RowHasSpanningCells(PRInt32 aRowIndex
, PRInt32 aNumEffCols
);
709 // Returns PR_TRUE if there are any cells to the left of the column at
710 // aColIndex and spanning into the column at aColIndex
711 PRBool
ColIsSpannedInto(PRInt32 aColIndex
);
713 // Returns PR_TRUE if there is a cell originating in aColIndex
714 // which spans into the next col
715 PRBool
ColHasSpanningCells(PRInt32 aColIndex
);
719 PRBool
HaveReflowedColGroups() const;
720 void SetHaveReflowedColGroups(PRBool aValue
);
723 PRBool
IsBorderCollapse() const;
725 PRBool
NeedToCalcBCBorders() const;
726 void SetNeedToCalcBCBorders(PRBool aValue
);
728 PRBool
NeedToCollapse() const;
729 void SetNeedToCollapse(PRBool aValue
);
731 PRBool
HasZeroColSpans() const;
732 void SetHasZeroColSpans(PRBool aValue
);
734 PRBool
NeedColSpanExpansion() const;
735 void SetNeedColSpanExpansion(PRBool aValue
);
737 /** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame
738 * state bit, which implies that all descendants are dirty. The
739 * GeometryDirty still implies that all the parts of the table are
740 * dirty, but resizing optimizations should still apply to the
741 * contents of the individual cells.
743 void SetGeometryDirty() { mBits
.mGeometryDirty
= PR_TRUE
; }
744 void ClearGeometryDirty() { mBits
.mGeometryDirty
= PR_FALSE
; }
745 PRBool
IsGeometryDirty() const { return mBits
.mGeometryDirty
; }
747 /** Get the cell map for this table frame. It is not always mCellMap.
748 * Only the firstInFlow has a legit cell map
750 virtual nsTableCellMap
* GetCellMap() const;
752 /** Iterate over the row groups and adjust the row indices of all rows
753 * whose index is >= aRowIndex.
754 * @param aRowIndex - start adjusting with this index
755 * @param aAdjustment - shift the row index by this amount
757 void AdjustRowIndices(PRInt32 aRowIndex
,
758 PRInt32 aAdjustment
);
760 /** Reset the rowindices of all rows as they might have changed due to
761 * rowgroup reordering, exclude new row group frames that show in the
762 * reordering but are not yet inserted into the cellmap
763 * @param aFirstRowGroupFrame - first row group to be excluded
764 * @param aLastRowGroupFrame - last sibling of aFirstRowGroupFrame that
765 * should be excluded when reseting the row
768 void ResetRowIndices(nsIFrame
* aFirstRowGroupFrame
= nsnull
,
769 nsIFrame
* aLastRowGroupFrame
= nsnull
);
771 nsVoidArray
& GetColCache();
773 /** Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
775 static nsTableRowGroupFrame
* GetRowGroupFrame(nsIFrame
* aFrame
,
776 nsIAtom
* aFrameTypeIn
= nsnull
);
780 void SetBorderCollapse(PRBool aValue
);
782 void CalcBCBorders();
784 void ExpandBCDamageArea(nsRect
& aRect
) const;
786 void SetColumnDimensions(nscoord aHeight
,
787 const nsMargin
& aReflowState
);
789 PRInt32
CollectRows(nsIFrame
* aFrame
,
790 nsVoidArray
& aCollection
);
792 public: /* ----- Cell Map public methods ----- */
794 PRInt32
GetStartRowIndex(nsTableRowGroupFrame
& aRowGroupFrame
);
796 /** returns the number of rows in this table.
798 PRInt32
GetRowCount () const
800 return GetCellMap()->GetRowCount();
803 /** returns the number of columns in this table after redundant columns have been removed
805 PRInt32
GetEffectiveColCount() const;
807 /* return the col count including dead cols */
808 PRInt32
GetColCount () const
810 return GetCellMap()->GetColCount();
813 // return the last col index which isn't of type eColAnonymousCell
814 PRInt32
GetIndexOfLastRealCol();
816 /** returns PR_TRUE if table-layout:auto */
817 virtual PRBool
IsAutoLayout();
819 /*---------------- nsITableLayout methods ------------------------*/
821 /** Get the cell and associated data for a table cell from the frame's cellmap */
822 NS_IMETHOD
GetCellDataAt(PRInt32 aRowIndex
, PRInt32 aColIndex
,
823 nsIDOMElement
* &aCell
, //out params
824 PRInt32
& aStartRowIndex
, PRInt32
& aStartColIndex
,
825 PRInt32
& aRowSpan
, PRInt32
& aColSpan
,
826 PRInt32
& aActualRowSpan
, PRInt32
& aActualColSpan
,
827 PRBool
& aIsSelected
);
829 /** Get the number of rows and column for a table from the frame's cellmap
830 * Some rows may not have enough cells (the number returned is the maximum possible),
831 * which displays as a ragged-right edge table
833 NS_IMETHOD
GetTableSize(PRInt32
& aRowCount
, PRInt32
& aColCount
);
835 /*------------end of nsITableLayout methods -----------------------*/
840 void Dump(PRBool aDumpRows
,
842 PRBool aDumpCellMap
);
843 static void DumpTableFrames(nsIFrame
* aFrame
);
848 void DumpRowGroup(nsIFrame
* aChildFrame
);
851 nsAutoVoidArray mColFrames
;
854 PRUint32 mHaveReflowedColGroups
:1; // have the col groups gotten their initial reflow
855 PRUint32 mHasPctCol
:1; // does any cell or col have a pct width
856 PRUint32 mCellSpansPctCol
:1; // does any cell span a col with a pct width (or containing a cell with a pct width)
857 PRUint32 mIsBorderCollapse
:1; // border collapsing model vs. separate model
858 PRUint32 mRowInserted
:1;
859 PRUint32 mNeedToCalcBCBorders
:1;
860 PRUint32 mGeometryDirty
:1;
861 PRUint32 mLeftContBCBorder
:8;
862 PRUint32 mNeedToCollapse
:1; // rows, cols that have visibility:collapse need to be collapsed
863 PRUint32 mHasZeroColSpans
:1;
864 PRUint32 mNeedColSpanExpansion
:1;
865 PRUint32 mResizedColumns
:1; // have we resized columns since last reflow?
868 nsTableCellMap
* mCellMap
; // maintains the relationships between rows, cols, and cells
869 nsITableLayoutStrategy
* mTableLayoutStrategy
;// the layout strategy for this frame
870 nsFrameList mColGroups
; // the list of colgroup frames
874 inline PRBool
nsTableFrame::IsRowGroup(PRInt32 aDisplayType
) const
876 return PRBool((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP
== aDisplayType
) ||
877 (NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP
== aDisplayType
) ||
878 (NS_STYLE_DISPLAY_TABLE_ROW_GROUP
== aDisplayType
));
881 inline void nsTableFrame::SetHaveReflowedColGroups(PRBool aValue
)
883 mBits
.mHaveReflowedColGroups
= aValue
;
886 inline PRBool
nsTableFrame::HaveReflowedColGroups() const
888 return (PRBool
)mBits
.mHaveReflowedColGroups
;
891 inline PRBool
nsTableFrame::HasPctCol() const
893 return (PRBool
)mBits
.mHasPctCol
;
896 inline void nsTableFrame::SetHasPctCol(PRBool aValue
)
898 mBits
.mHasPctCol
= (unsigned)aValue
;
901 inline PRBool
nsTableFrame::HasCellSpanningPctCol() const
903 return (PRBool
)mBits
.mCellSpansPctCol
;
906 inline void nsTableFrame::SetHasCellSpanningPctCol(PRBool aValue
)
908 mBits
.mCellSpansPctCol
= (unsigned)aValue
;
911 inline PRBool
nsTableFrame::IsRowInserted() const
913 return (PRBool
)mBits
.mRowInserted
;
916 inline void nsTableFrame::SetRowInserted(PRBool aValue
)
918 mBits
.mRowInserted
= (unsigned)aValue
;
921 inline void nsTableFrame::SetNeedToCollapse(PRBool aValue
)
923 mBits
.mNeedToCollapse
= (unsigned)aValue
;
926 inline PRBool
nsTableFrame::NeedToCollapse() const
928 return (PRBool
)mBits
.mNeedToCollapse
;
931 inline void nsTableFrame::SetHasZeroColSpans(PRBool aValue
)
933 mBits
.mHasZeroColSpans
= (unsigned)aValue
;
936 inline PRBool
nsTableFrame::HasZeroColSpans() const
938 return (PRBool
)mBits
.mHasZeroColSpans
;
941 inline void nsTableFrame::SetNeedColSpanExpansion(PRBool aValue
)
943 mBits
.mNeedColSpanExpansion
= (unsigned)aValue
;
946 inline PRBool
nsTableFrame::NeedColSpanExpansion() const
948 return (PRBool
)mBits
.mNeedColSpanExpansion
;
952 inline nsFrameList
& nsTableFrame::GetColGroups()
954 return static_cast<nsTableFrame
*>(GetFirstInFlow())->mColGroups
;
957 inline nsVoidArray
& nsTableFrame::GetColCache()
962 inline PRBool
nsTableFrame::IsBorderCollapse() const
964 return (PRBool
)mBits
.mIsBorderCollapse
;
967 inline void nsTableFrame::SetBorderCollapse(PRBool aValue
)
969 mBits
.mIsBorderCollapse
= aValue
;
972 inline PRBool
nsTableFrame::NeedToCalcBCBorders() const
974 return (PRBool
)mBits
.mNeedToCalcBCBorders
;
977 inline void nsTableFrame::SetNeedToCalcBCBorders(PRBool aValue
)
979 mBits
.mNeedToCalcBCBorders
= (unsigned)aValue
;
983 nsTableFrame::GetContinuousLeftBCBorderWidth() const
985 PRInt32 aPixelsToTwips
= nsPresContext::AppUnitsPerCSSPixel();
986 return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips
, mBits
.mLeftContBCBorder
);
989 class nsTableIterator
992 nsTableIterator(nsIFrame
& aSource
);
993 nsTableIterator(nsFrameList
& aSource
);
996 PRBool
IsLeftToRight();
1000 void Init(nsIFrame
* aFirstChild
);
1001 PRBool mLeftToRight
;
1002 nsIFrame
* mFirstListChild
;
1003 nsIFrame
* mFirstChild
;
1004 nsIFrame
* mCurrentChild
;
1009 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
1012 #define ABORT1(aReturn) \
1013 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \