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 "nsTPtrArray.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
145 /** nsTableOuterFrame has intimate knowledge of the inner table frame */
146 friend class nsTableOuterFrame
;
148 /** instantiate a new instance of nsTableRowFrame.
149 * @param aPresShell the pres shell for this frame
151 * @return the frame that was created
153 friend nsIFrame
* NS_NewTableFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
);
155 /** sets defaults for table-specific style.
156 * @see nsIFrame::Init
158 NS_IMETHOD
Init(nsIContent
* aContent
,
160 nsIFrame
* aPrevInFlow
);
163 static void* GetProperty(nsIFrame
* aFrame
,
164 nsIAtom
* aPropertyName
,
165 PRBool aCreateIfNecessary
= PR_FALSE
);
167 static float GetTwipsToPixels(nsPresContext
* aPresContext
);
169 // Return true if aParentReflowState.frame or any of its ancestors within
170 // the containing table have non-auto height. (e.g. pct or fixed height)
171 static PRBool
AncestorsHaveStyleHeight(const nsHTMLReflowState
& aParentReflowState
);
173 // See if a special height reflow will occur due to having a pct height when
174 // the pct height basis may not yet be valid.
175 static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState
& aReflowState
);
177 // Notify the frame and its ancestors (up to the containing table) that a special
178 // height reflow will occur.
179 static void RequestSpecialHeightReflow(const nsHTMLReflowState
& aReflowState
);
181 virtual PRBool
IsContainingBlock() const;
183 static void RePositionViews(nsIFrame
* aFrame
);
185 static PRBool
PageBreakAfter(nsIFrame
& aSourceFrame
,
186 nsIFrame
* aNextFrame
);
188 nsPoint
GetFirstSectionOrigin(const nsHTMLReflowState
& aReflowState
) const;
190 * Notification that aAttribute has changed for content inside a table (cell, row, etc)
192 void AttributeChangedFor(nsIFrame
* aFrame
,
193 nsIContent
* aContent
,
194 nsIAtom
* aAttribute
);
196 /** @see nsIFrame::Destroy */
197 virtual void Destroy();
199 /** @see nsIFrame::DidSetStyleContext */
200 virtual void DidSetStyleContext(nsStyleContext
* aOldStyleContext
);
202 NS_IMETHOD
AppendFrames(nsIAtom
* aListName
,
203 nsFrameList
& aFrameList
);
204 NS_IMETHOD
InsertFrames(nsIAtom
* aListName
,
205 nsIFrame
* aPrevFrame
,
206 nsFrameList
& aFrameList
);
207 NS_IMETHOD
RemoveFrame(nsIAtom
* aListName
,
208 nsIFrame
* aOldFrame
);
210 virtual nsMargin
GetUsedBorder() const;
211 virtual nsMargin
GetUsedPadding() const;
213 // Get the offset from the border box to the area where the row groups fit
214 nsMargin
GetChildAreaOffset(const nsHTMLReflowState
* aReflowState
) const;
216 /** helper method to find the table parent of any table frame object */
217 static nsTableFrame
* GetTableFrame(nsIFrame
* aSourceFrame
);
219 typedef nsresult (* DisplayGenericTablePartTraversal
)
220 (nsDisplayListBuilder
* aBuilder
, nsFrame
* aFrame
,
221 const nsRect
& aDirtyRect
, const nsDisplayListSet
& aLists
);
222 static nsresult
GenericTraversal(nsDisplayListBuilder
* aBuilder
, nsFrame
* aFrame
,
223 const nsRect
& aDirtyRect
, const nsDisplayListSet
& aLists
);
226 * Helper method to handle display common to table frames, rowgroup frames
227 * and row frames. It creates a background display item for handling events
228 * if necessary, an outline display item if necessary, and displays
229 * all the the frame's children.
230 * @param aDisplayItem the display item created for this part, or null
231 * if this part's border/background painting is delegated to an ancestor
232 * @param aTraversal a function that gets called to traverse the table
233 * part's child frames and add their display list items to a
236 static nsresult
DisplayGenericTablePart(nsDisplayListBuilder
* aBuilder
,
238 const nsRect
& aDirtyRect
,
239 const nsDisplayListSet
& aLists
,
240 nsDisplayTableItem
* aDisplayItem
,
241 DisplayGenericTablePartTraversal aTraversal
= GenericTraversal
);
243 // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
244 // of type aChildType.
245 static nsIFrame
* GetFrameAtOrBefore(nsIFrame
* aParentFrame
,
246 nsIFrame
* aPriorChildFrame
,
247 nsIAtom
* aChildType
);
248 PRBool
IsAutoWidth(PRBool
* aIsPctWidth
= nsnull
);
249 PRBool
IsAutoHeight();
250 static PRBool
IsPctHeight(nsStyleContext
* aStyleContext
);
252 /** @return PR_TRUE if aDisplayType represents a rowgroup of any sort
253 * (header, footer, or body)
255 PRBool
IsRowGroup(PRInt32 aDisplayType
) const;
257 /** Initialize the table frame with a set of children.
258 * @see nsIFrame::SetInitialChildList
260 NS_IMETHOD
SetInitialChildList(nsIAtom
* aListName
,
261 nsFrameList
& aChildList
);
263 virtual nsFrameList
GetChildList(nsIAtom
* aListName
) const;
265 /** @see nsIFrame::GetAdditionalChildListName */
266 virtual nsIAtom
* GetAdditionalChildListName(PRInt32 aIndex
) const;
268 NS_IMETHOD
BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
269 const nsRect
& aDirtyRect
,
270 const nsDisplayListSet
& aLists
);
273 * Paint the background of the table and its parts (column groups,
274 * columns, row groups, rows, and cells), and the table border, and all
275 * internal borders if border-collapse is on.
277 void PaintTableBorderBackground(nsIRenderingContext
& aRenderingContext
,
278 const nsRect
& aDirtyRect
,
281 /** Get the outer half (i.e., the part outside the height and width of
282 * the table) of the largest segment (?) of border-collapsed border on
283 * the table on each side, or 0 for non border-collapsed tables.
285 nsMargin
GetOuterBCBorder() const;
287 /** Same as above, but only if it's included from the border-box width
290 nsMargin
GetIncludedOuterBCBorder() const;
292 /** Same as above, but only if it's excluded from the border-box width
293 * of the table. This is the area that leaks out into the margin
294 * (or potentially past it, if there is no margin).
296 nsMargin
GetExcludedOuterBCBorder() const;
299 * In quirks mode, the size of the table background is reduced
300 * by the outer BC border. Compute the reduction needed.
302 nsMargin
GetDeflationForBackground(nsPresContext
* aPresContext
) const;
304 /** Get width of table + colgroup + col collapse: elements that
305 * continue along the length of the whole left side.
306 * see nsTablePainter about continuous borders
308 nscoord
GetContinuousLeftBCBorderWidth() const;
309 void SetContinuousLeftBCBorderWidth(nscoord aValue
);
311 friend class nsDelayedCalcBCBorders
;
313 void SetBCDamageArea(const nsRect
& aValue
);
314 PRBool
BCRecalcNeeded(nsStyleContext
* aOldStyleContext
,
315 nsStyleContext
* aNewStyleContext
);
316 void PaintBCBorders(nsIRenderingContext
& aRenderingContext
,
317 const nsRect
& aDirtyRect
);
319 virtual void MarkIntrinsicWidthsDirty();
320 // For border-collapse tables, the caller must not add padding and
321 // border to the results of these functions.
322 virtual nscoord
GetMinWidth(nsIRenderingContext
*aRenderingContext
);
323 virtual nscoord
GetPrefWidth(nsIRenderingContext
*aRenderingContext
);
324 virtual IntrinsicWidthOffsetData
325 IntrinsicWidthOffsets(nsIRenderingContext
* aRenderingContext
);
327 virtual nsSize
ComputeSize(nsIRenderingContext
*aRenderingContext
,
328 nsSize aCBSize
, nscoord aAvailableWidth
,
329 nsSize aMargin
, nsSize aBorder
, nsSize aPadding
,
331 virtual nsSize
ComputeAutoSize(nsIRenderingContext
*aRenderingContext
,
332 nsSize aCBSize
, nscoord aAvailableWidth
,
333 nsSize aMargin
, nsSize aBorder
,
334 nsSize aPadding
, PRBool aShrinkWrap
);
336 * A copy of nsFrame::ShrinkWidthToFit that calls a different
337 * GetPrefWidth, since tables have two different ones.
339 nscoord
TableShrinkWidthToFit(nsIRenderingContext
*aRenderingContext
,
342 // XXXldb REWRITE THIS COMMENT!
343 /** inner tables are reflowed in two steps.
345 * if mFirstPassValid is false, this is our first time through since content was last changed
348 * get min/max info for all cells in an infinite space
349 * do column balancing
350 * set mFirstPassValid to true
352 * use column widths to Reflow cells
355 * @see nsIFrame::Reflow
357 NS_IMETHOD
Reflow(nsPresContext
* aPresContext
,
358 nsHTMLReflowMetrics
& aDesiredSize
,
359 const nsHTMLReflowState
& aReflowState
,
360 nsReflowStatus
& aStatus
);
362 nsresult
ReflowTable(nsHTMLReflowMetrics
& aDesiredSize
,
363 const nsHTMLReflowState
& aReflowState
,
364 nscoord aAvailHeight
,
365 nsIFrame
*& aLastChildReflowed
,
366 nsReflowStatus
& aStatus
);
368 nsFrameList
& GetColGroups();
370 NS_IMETHOD
GetParentStyleContextFrame(nsPresContext
* aPresContext
,
371 nsIFrame
** aProviderFrame
,
375 * Get the "type" of the frame
377 * @see nsGkAtoms::tableFrame
379 virtual nsIAtom
* GetType() const;
382 /** @see nsIFrame::GetFrameName */
383 NS_IMETHOD
GetFrameName(nsAString
& aResult
) const;
386 /** return the width of the column at aColIndex */
387 virtual PRInt32
GetColumnWidth(PRInt32 aColIndex
);
389 /** set the width of the column at aColIndex to aWidth */
390 virtual void SetColumnWidth(PRInt32 aColIndex
, nscoord aWidth
);
392 /** helper to get the cell spacing X style value */
393 virtual nscoord
GetCellSpacingX();
395 /** helper to get the cell spacing Y style value */
396 virtual nscoord
GetCellSpacingY();
398 virtual nscoord
GetBaseline() const;
399 /** return the row span of a cell, taking into account row span magic at the bottom
400 * of a table. The row span equals the number of rows spanned by aCell starting at
401 * aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
402 * index in which aCell originates.
404 * @param aStartRowIndex the cell
405 * @param aCell the cell
407 * @return the row span, correcting for row spans that extend beyond the bottom
410 virtual PRInt32
GetEffectiveRowSpan(PRInt32 aStartRowIndex
,
411 const nsTableCellFrame
& aCell
) const;
412 virtual PRInt32
GetEffectiveRowSpan(const nsTableCellFrame
& aCell
,
413 nsCellMap
* aCellMap
= nsnull
);
415 /** return the col span of a cell, taking into account col span magic at the edge
418 * @param aCell the cell
420 * @return the col span, correcting for col spans that extend beyond the edge
423 virtual PRInt32
GetEffectiveColSpan(const nsTableCellFrame
& aCell
,
424 nsCellMap
* aCellMap
= nsnull
) const;
426 /** indicate whether the row has more than one cell that either originates
427 * or is spanned from the rows above
429 PRBool
HasMoreThanOneCell(PRInt32 aRowIndex
) const;
431 /** return the value of the COLS attribute, adjusted for the
432 * actual number of columns in the table
434 PRInt32
GetEffectiveCOLSAttribute();
436 /** return the column frame associated with aColIndex
437 * returns nsnull if the col frame has not yet been allocated, or if
438 * aColIndex is out of range
440 nsTableColFrame
* GetColFrame(PRInt32 aColIndex
) const;
442 /** Insert a col frame reference into the colframe cache and adapt the cellmap
443 * @param aColFrame - the column frame
444 * @param aColIndex - index where the column should be inserted into the
447 void InsertCol(nsTableColFrame
& aColFrame
,
450 nsTableColGroupFrame
* CreateAnonymousColGroupFrame(nsTableColGroupType aType
);
452 PRInt32
DestroyAnonymousColFrames(PRInt32 aNumFrames
);
454 // Append aNumColsToAdd anonymous col frames of type eColAnonymousCell to our
455 // last eColGroupAnonymousCell colgroup. If we have no such colgroup, then
457 void AppendAnonymousColFrames(PRInt32 aNumColsToAdd
);
459 // Append aNumColsToAdd anonymous col frames of type aColType to
460 // aColGroupFrame. If aAddToTable is true, also call AddColsToTable on the
462 void AppendAnonymousColFrames(nsTableColGroupFrame
* aColGroupFrame
,
463 PRInt32 aNumColsToAdd
,
464 nsTableColType aColType
,
467 void MatchCellMapToColCache(nsTableCellMap
* aCellMap
);
468 /** empty the column frame cache */
469 void ClearColCache();
471 void DidResizeColumns();
473 virtual void AppendCell(nsTableCellFrame
& aCellFrame
,
476 virtual void InsertCells(nsTArray
<nsTableCellFrame
*>& aCellFrames
,
478 PRInt32 aColIndexBefore
);
480 virtual void RemoveCell(nsTableCellFrame
* aCellFrame
,
483 void AppendRows(nsTableRowGroupFrame
& aRowGroupFrame
,
485 nsTArray
<nsTableRowFrame
*>& aRowFrames
);
487 PRInt32
InsertRow(nsTableRowGroupFrame
& aRowGroupFrame
,
490 PRBool aConsiderSpans
);
492 PRInt32
InsertRows(nsTableRowGroupFrame
& aRowGroupFrame
,
493 nsTArray
<nsTableRowFrame
*>& aFrames
,
495 PRBool aConsiderSpans
);
497 virtual void RemoveRows(nsTableRowFrame
& aFirstRowFrame
,
498 PRInt32 aNumRowsToRemove
,
499 PRBool aConsiderSpans
);
501 /** Insert multiple rowgroups into the table cellmap handling
502 * @param aRowGroups - iterator that iterates over the rowgroups to insert
504 void InsertRowGroups(const nsFrameList::Slice
& aRowGroups
);
506 void InsertColGroups(PRInt32 aStartColIndex
,
507 const nsFrameList::Slice
& aColgroups
);
509 virtual void RemoveCol(nsTableColGroupFrame
* aColGroupFrame
,
511 PRBool aRemoveFromCache
,
512 PRBool aRemoveFromCellMap
);
514 NS_IMETHOD
GetIndexByRowAndColumn(PRInt32 aRow
, PRInt32 aColumn
, PRInt32
*aIndex
);
515 NS_IMETHOD
GetRowAndColumnByIndex(PRInt32 aIndex
, PRInt32
*aRow
, PRInt32
*aColumn
);
517 PRBool
ColumnHasCellSpacingBefore(PRInt32 aColIndex
) const;
519 PRBool
HasPctCol() const;
520 void SetHasPctCol(PRBool aValue
);
522 PRBool
HasCellSpanningPctCol() const;
523 void SetHasCellSpanningPctCol(PRBool aValue
);
526 * To be called on a frame by its parent after setting its size/position and
527 * calling DidReflow (possibly via FinishReflowChild()). This can also be
528 * used for child frames which are not being reflowed but did have their size
529 * or position changed.
531 * @param aFrame The frame to invalidate
532 * @param aOrigRect The original rect of aFrame (before the change).
533 * @param aOrigOverflowRect The original overflow rect of aFrame.
534 * @param aIsFirstReflow True if the size/position change is due to the
535 * first reflow of aFrame.
537 static void InvalidateFrame(nsIFrame
* aFrame
,
538 const nsRect
& aOrigRect
,
539 const nsRect
& aOrigOverflowRect
,
540 PRBool aIsFirstReflow
);
544 /** protected constructor.
547 nsTableFrame(nsStyleContext
* aContext
);
549 /** destructor, responsible for mColumnLayoutData */
550 virtual ~nsTableFrame();
552 void InitChildReflowState(nsHTMLReflowState
& aReflowState
);
554 /** implement abstract method on nsHTMLContainerFrame */
555 virtual PRIntn
GetSkipSides() const;
558 PRBool
IsRowInserted() const;
559 void SetRowInserted(PRBool aValue
);
563 // A helper function to reflow a header or footer with unconstrained height
564 // to see if it should be made repeatable and also to determine its desired
566 nsresult
SetupHeaderFooterChild(const nsTableReflowState
& aReflowState
,
567 nsTableRowGroupFrame
* aFrame
,
568 nscoord
* aDesiredHeight
);
570 NS_METHOD
ReflowChildren(nsTableReflowState
& aReflowState
,
571 nsReflowStatus
& aStatus
,
572 nsIFrame
*& aLastChildReflowed
,
573 nsRect
& aOverflowArea
);
575 // This calls the col group and column reflow methods, which do two things:
576 // (1) set all the dimensions to 0
577 // (2) notify the table about colgroups or columns with hidden visibility
578 void ReflowColGroups(nsIRenderingContext
* aRenderingContext
);
580 /** return the width of the table taking into account visibility collapse
581 * on columns and colgroups
582 * @param aBorderPadding the border and padding of the table
584 nscoord
GetCollapsedWidth(nsMargin aBorderPadding
);
587 /** Adjust the table for visibilty.collapse set on rowgroups, rows, colgroups
589 * @param aDesiredSize the metrics of the table
590 * @param aBorderPadding the border and padding of the table
592 void AdjustForCollapsingRowsCols(nsHTMLReflowMetrics
& aDesiredSize
,
593 nsMargin aBorderPadding
);
595 nsITableLayoutStrategy
* LayoutStrategy() const {
596 return static_cast<nsTableFrame
*>(GetFirstInFlow())->
597 mTableLayoutStrategy
;
601 /* Handle a row that got inserted during reflow. aNewHeight is the
602 new height of the table after reflow. */
603 void ProcessRowInserted(nscoord aNewHeight
);
605 // WIDTH AND HEIGHT CALCULATION
609 // calculate the computed height of aFrame including its border and padding given
611 nscoord
CalcBorderBoxHeight(const nsHTMLReflowState
& aReflowState
);
615 // update the desired height of this table taking into account the current
616 // reflow state, the table attributes and the content driven rowgroup heights
617 // this function can change the overflow area
618 void CalcDesiredHeight(const nsHTMLReflowState
& aReflowState
, nsHTMLReflowMetrics
& aDesiredSize
);
620 // The following is a helper for CalcDesiredHeight
622 void DistributeHeightToRows(const nsHTMLReflowState
& aReflowState
,
625 void PlaceChild(nsTableReflowState
& aReflowState
,
627 nsHTMLReflowMetrics
& aKidDesiredSize
,
628 const nsRect
& aOriginalKidRect
,
629 const nsRect
& aOriginalKidOverflowRect
);
631 nsIFrame
* GetFirstBodyRowGroupFrame();
633 * Push all our child frames from the aFrames array, in order, starting from the
634 * frame at aPushFrom to the end of the array. The frames are put on our overflow
635 * list or moved directly to our next-in-flow if one exists.
637 typedef nsAutoTPtrArray
<nsIFrame
, 8> FrameArray
;
638 void PushChildren(const FrameArray
& aFrames
, PRInt32 aPushFrom
);
641 // put the children frames in the display order (e.g. thead before tbodies
642 // before tfoot). This will handle calling GetRowGroupFrame() on the
643 // children, and not append nulls, so the array is guaranteed to contain
644 // nsTableRowGroupFrames. If there are multiple theads or tfoots, all but
645 // the first one are treated as tbodies instead.
646 typedef nsAutoTPtrArray
<nsTableRowGroupFrame
, 8> RowGroupArray
;
647 void OrderRowGroups(RowGroupArray
& aChildren
) const;
649 // Return the thead, if any
650 nsTableRowGroupFrame
* GetTHead() const;
652 // Return the tfoot, if any
653 nsTableRowGroupFrame
* GetTFoot() const;
656 // As above, but does NOT actually call GetRowGroupFrame() on the kids, so
657 // returns an array of nsIFrames. This is to be used when you really want
658 // the flowable kids of the table, not the rowgroups. This outputs the thead
659 // and tfoot if they happen to be rowgroups. All the child nsIFrames of the
660 // table that return null if you call GetRowGroupFrame() on them will appear
661 // at the end of the array, after the tfoot, if any.
663 // aHead and aFoot must not be null.
665 // @return the number of frames in aChildren which return non-null if you
666 // call GetRowGroupFrame() on them.
668 // XXXbz why do we really care about the non-rowgroup kids?
669 PRUint32
OrderRowGroups(FrameArray
& aChildren
,
670 nsTableRowGroupFrame
** aHead
,
671 nsTableRowGroupFrame
** aFoot
) const;
674 // Returns PR_TRUE if there are any cells above the row at
675 // aRowIndex and spanning into the row at aRowIndex, the number of
676 // effective columns limits the search up to that column
677 PRBool
RowIsSpannedInto(PRInt32 aRowIndex
, PRInt32 aNumEffCols
);
679 // Returns PR_TRUE if there is a cell originating in aRowIndex
680 // which spans into the next row, the number of effective
681 // columns limits the search up to that column
682 PRBool
RowHasSpanningCells(PRInt32 aRowIndex
, PRInt32 aNumEffCols
);
684 // Returns PR_TRUE if there are any cells to the left of the column at
685 // aColIndex and spanning into the column at aColIndex
686 PRBool
ColIsSpannedInto(PRInt32 aColIndex
);
688 // Returns PR_TRUE if there is a cell originating in aColIndex
689 // which spans into the next col
690 PRBool
ColHasSpanningCells(PRInt32 aColIndex
);
694 PRBool
HaveReflowedColGroups() const;
695 void SetHaveReflowedColGroups(PRBool aValue
);
698 PRBool
IsBorderCollapse() const;
700 PRBool
NeedToCalcBCBorders() const;
701 void SetNeedToCalcBCBorders(PRBool aValue
);
703 PRBool
NeedToCollapse() const;
704 void SetNeedToCollapse(PRBool aValue
);
706 PRBool
HasZeroColSpans() const;
707 void SetHasZeroColSpans(PRBool aValue
);
709 PRBool
NeedColSpanExpansion() const;
710 void SetNeedColSpanExpansion(PRBool aValue
);
712 /** The GeometryDirty bit is similar to the NS_FRAME_IS_DIRTY frame
713 * state bit, which implies that all descendants are dirty. The
714 * GeometryDirty still implies that all the parts of the table are
715 * dirty, but resizing optimizations should still apply to the
716 * contents of the individual cells.
718 void SetGeometryDirty() { mBits
.mGeometryDirty
= PR_TRUE
; }
719 void ClearGeometryDirty() { mBits
.mGeometryDirty
= PR_FALSE
; }
720 PRBool
IsGeometryDirty() const { return mBits
.mGeometryDirty
; }
722 /** Get the cell map for this table frame. It is not always mCellMap.
723 * Only the firstInFlow has a legit cell map
725 virtual nsTableCellMap
* GetCellMap() const;
727 /** Iterate over the row groups and adjust the row indices of all rows
728 * whose index is >= aRowIndex.
729 * @param aRowIndex - start adjusting with this index
730 * @param aAdjustment - shift the row index by this amount
732 void AdjustRowIndices(PRInt32 aRowIndex
,
733 PRInt32 aAdjustment
);
735 /** Reset the rowindices of all rows as they might have changed due to
736 * rowgroup reordering, exclude new row group frames that show in the
737 * reordering but are not yet inserted into the cellmap
738 * @param aRowGroupsToExclude - an iterator that will produce the row groups
741 void ResetRowIndices(const nsFrameList::Slice
& aRowGroupsToExclude
);
743 nsTArray
<nsTableColFrame
*>& GetColCache();
745 /** Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
747 static nsTableRowGroupFrame
* GetRowGroupFrame(nsIFrame
* aFrame
,
748 nsIAtom
* aFrameTypeIn
= nsnull
);
752 void SetBorderCollapse(PRBool aValue
);
754 void CalcBCBorders();
756 void ExpandBCDamageArea(nsRect
& aRect
) const;
758 void SetColumnDimensions(nscoord aHeight
,
759 const nsMargin
& aReflowState
);
761 PRInt32
CollectRows(nsIFrame
* aFrame
,
762 nsTArray
<nsTableRowFrame
*>& aCollection
);
764 public: /* ----- Cell Map public methods ----- */
766 PRInt32
GetStartRowIndex(nsTableRowGroupFrame
& aRowGroupFrame
);
768 /** returns the number of rows in this table.
770 PRInt32
GetRowCount () const
772 return GetCellMap()->GetRowCount();
775 /** returns the number of columns in this table after redundant columns have been removed
777 PRInt32
GetEffectiveColCount() const;
779 /* return the col count including dead cols */
780 PRInt32
GetColCount () const
782 return GetCellMap()->GetColCount();
785 // return the last col index which isn't of type eColAnonymousCell
786 PRInt32
GetIndexOfLastRealCol();
788 /** returns PR_TRUE if table-layout:auto */
789 virtual PRBool
IsAutoLayout();
791 /*---------------- nsITableLayout methods ------------------------*/
793 /** Get the cell and associated data for a table cell from the frame's cellmap */
794 NS_IMETHOD
GetCellDataAt(PRInt32 aRowIndex
, PRInt32 aColIndex
,
795 nsIDOMElement
* &aCell
, //out params
796 PRInt32
& aStartRowIndex
, PRInt32
& aStartColIndex
,
797 PRInt32
& aRowSpan
, PRInt32
& aColSpan
,
798 PRInt32
& aActualRowSpan
, PRInt32
& aActualColSpan
,
799 PRBool
& aIsSelected
);
801 /** Get the number of rows and column for a table from the frame's cellmap
802 * Some rows may not have enough cells (the number returned is the maximum possible),
803 * which displays as a ragged-right edge table
805 NS_IMETHOD
GetTableSize(PRInt32
& aRowCount
, PRInt32
& aColCount
);
807 /*------------end of nsITableLayout methods -----------------------*/
812 void Dump(PRBool aDumpRows
,
814 PRBool aDumpCellMap
);
819 void DumpRowGroup(nsIFrame
* aChildFrame
);
822 nsAutoTPtrArray
<nsTableColFrame
, 8> mColFrames
;
825 PRUint32 mHaveReflowedColGroups
:1; // have the col groups gotten their initial reflow
826 PRUint32 mHasPctCol
:1; // does any cell or col have a pct width
827 PRUint32 mCellSpansPctCol
:1; // does any cell span a col with a pct width (or containing a cell with a pct width)
828 PRUint32 mIsBorderCollapse
:1; // border collapsing model vs. separate model
829 PRUint32 mRowInserted
:1;
830 PRUint32 mNeedToCalcBCBorders
:1;
831 PRUint32 mGeometryDirty
:1;
832 PRUint32 mLeftContBCBorder
:8;
833 PRUint32 mNeedToCollapse
:1; // rows, cols that have visibility:collapse need to be collapsed
834 PRUint32 mHasZeroColSpans
:1;
835 PRUint32 mNeedColSpanExpansion
:1;
836 PRUint32 mResizedColumns
:1; // have we resized columns since last reflow?
839 nsTableCellMap
* mCellMap
; // maintains the relationships between rows, cols, and cells
840 nsITableLayoutStrategy
* mTableLayoutStrategy
;// the layout strategy for this frame
841 nsFrameList mColGroups
; // the list of colgroup frames
845 inline PRBool
nsTableFrame::IsRowGroup(PRInt32 aDisplayType
) const
847 return PRBool((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP
== aDisplayType
) ||
848 (NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP
== aDisplayType
) ||
849 (NS_STYLE_DISPLAY_TABLE_ROW_GROUP
== aDisplayType
));
852 inline void nsTableFrame::SetHaveReflowedColGroups(PRBool aValue
)
854 mBits
.mHaveReflowedColGroups
= aValue
;
857 inline PRBool
nsTableFrame::HaveReflowedColGroups() const
859 return (PRBool
)mBits
.mHaveReflowedColGroups
;
862 inline PRBool
nsTableFrame::HasPctCol() const
864 return (PRBool
)mBits
.mHasPctCol
;
867 inline void nsTableFrame::SetHasPctCol(PRBool aValue
)
869 mBits
.mHasPctCol
= (unsigned)aValue
;
872 inline PRBool
nsTableFrame::HasCellSpanningPctCol() const
874 return (PRBool
)mBits
.mCellSpansPctCol
;
877 inline void nsTableFrame::SetHasCellSpanningPctCol(PRBool aValue
)
879 mBits
.mCellSpansPctCol
= (unsigned)aValue
;
882 inline PRBool
nsTableFrame::IsRowInserted() const
884 return (PRBool
)mBits
.mRowInserted
;
887 inline void nsTableFrame::SetRowInserted(PRBool aValue
)
889 mBits
.mRowInserted
= (unsigned)aValue
;
892 inline void nsTableFrame::SetNeedToCollapse(PRBool aValue
)
894 static_cast<nsTableFrame
*>(GetFirstInFlow())->mBits
.mNeedToCollapse
= (unsigned)aValue
;
897 inline PRBool
nsTableFrame::NeedToCollapse() const
899 return (PRBool
) static_cast<nsTableFrame
*>(GetFirstInFlow())->mBits
.mNeedToCollapse
;
902 inline void nsTableFrame::SetHasZeroColSpans(PRBool aValue
)
904 mBits
.mHasZeroColSpans
= (unsigned)aValue
;
907 inline PRBool
nsTableFrame::HasZeroColSpans() const
909 return (PRBool
)mBits
.mHasZeroColSpans
;
912 inline void nsTableFrame::SetNeedColSpanExpansion(PRBool aValue
)
914 mBits
.mNeedColSpanExpansion
= (unsigned)aValue
;
917 inline PRBool
nsTableFrame::NeedColSpanExpansion() const
919 return (PRBool
)mBits
.mNeedColSpanExpansion
;
923 inline nsFrameList
& nsTableFrame::GetColGroups()
925 return static_cast<nsTableFrame
*>(GetFirstInFlow())->mColGroups
;
928 inline nsTArray
<nsTableColFrame
*>& nsTableFrame::GetColCache()
933 inline PRBool
nsTableFrame::IsBorderCollapse() const
935 return (PRBool
)mBits
.mIsBorderCollapse
;
938 inline void nsTableFrame::SetBorderCollapse(PRBool aValue
)
940 mBits
.mIsBorderCollapse
= aValue
;
943 inline PRBool
nsTableFrame::NeedToCalcBCBorders() const
945 return (PRBool
)mBits
.mNeedToCalcBCBorders
;
948 inline void nsTableFrame::SetNeedToCalcBCBorders(PRBool aValue
)
950 mBits
.mNeedToCalcBCBorders
= (unsigned)aValue
;
954 nsTableFrame::GetContinuousLeftBCBorderWidth() const
956 PRInt32 aPixelsToTwips
= nsPresContext::AppUnitsPerCSSPixel();
957 return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips
, mBits
.mLeftContBCBorder
);
960 inline void nsTableFrame::SetContinuousLeftBCBorderWidth(nscoord aValue
)
962 mBits
.mLeftContBCBorder
= (unsigned) aValue
;
965 class nsTableIterator
968 nsTableIterator(nsIFrame
& aSource
);
969 nsTableIterator(nsFrameList
& aSource
);
972 PRBool
IsLeftToRight();
976 void Init(nsIFrame
* aFirstChild
);
978 nsIFrame
* mFirstListChild
;
979 nsIFrame
* mFirstChild
;
980 nsIFrame
* mCurrentChild
;
985 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
988 #define ABORT1(aReturn) \
989 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \