Backed out changeset 8366e5cc9f57 (bug 125282) because of four windows unit test...
[mozilla-central.git] / layout / tables / nsTableFrame.h
blob2fc7589abf5a8cb6eddf3c460cad51ec1bf416ca
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
13 * License.
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.
22 * Contributor(s):
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__
40 #include "nscore.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;
58 class nsStyleContext;
60 struct nsTableReflowState;
61 struct nsStylePosition;
63 /**
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
78 public:
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);
91 private:
92 PRPackedBool mPartHasFixedBackground;
95 class nsAutoPushCurrentTableItem
97 public:
98 nsAutoPushCurrentTableItem() : mBuilder(nsnull) {}
100 void Push(nsDisplayListBuilder* aBuilder, nsDisplayTableItem* aPushItem)
102 mBuilder = aBuilder;
103 mOldCurrentItem = aBuilder->GetCurrentTableItem();
104 aBuilder->SetCurrentTableItem(aPushItem);
105 #ifdef DEBUG
106 mPushedItem = aPushItem;
107 #endif
109 ~nsAutoPushCurrentTableItem() {
110 if (!mBuilder)
111 return;
112 #ifdef DEBUG
113 NS_ASSERTION(mBuilder->GetCurrentTableItem() == mPushedItem,
114 "Someone messed with the current table item behind our back!");
115 #endif
116 mBuilder->SetCurrentTableItem(mOldCurrentItem);
119 private:
120 nsDisplayListBuilder* mBuilder;
121 nsDisplayTableItem* mOldCurrentItem;
122 #ifdef DEBUG
123 nsDisplayTableItem* mPushedItem;
124 #endif
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
134 * named child list:
135 * - "ColGroup-list" which contains the col group frames
137 * @see nsGkAtoms::colGroupList
139 class nsTableFrame : public nsHTMLContainerFrame, public nsITableLayout
141 public:
143 NS_DECL_QUERYFRAME
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,
159 nsIFrame* aParent,
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
234 * display list set.
236 static nsresult DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
237 nsFrame* aFrame,
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,
279 nsPoint aPt);
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
288 * of the table.
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,
330 PRBool aShrinkWrap);
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,
340 nscoord aWidthInCB);
342 // XXXldb REWRITE THIS COMMENT!
343 /** inner tables are reflowed in two steps.
344 * <pre>
345 * if mFirstPassValid is false, this is our first time through since content was last changed
346 * set pass to 1
347 * do pass 1
348 * get min/max info for all cells in an infinite space
349 * do column balancing
350 * set mFirstPassValid to true
351 * do pass 2
352 * use column widths to Reflow cells
353 * </pre>
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,
372 PRBool* aIsChild);
375 * Get the "type" of the frame
377 * @see nsGkAtoms::tableFrame
379 virtual nsIAtom* GetType() const;
381 #ifdef DEBUG
382 /** @see nsIFrame::GetFrameName */
383 NS_IMETHOD GetFrameName(nsAString& aResult) const;
384 #endif
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
408 * of the table.
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
416 * of a table.
418 * @param aCell the cell
420 * @return the col span, correcting for col spans that extend beyond the edge
421 * of the table.
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
445 * colframe cache
447 void InsertCol(nsTableColFrame& aColFrame,
448 PRInt32 aColIndex);
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
456 // create one.
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
461 // new cols.
462 void AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
463 PRInt32 aNumColsToAdd,
464 nsTableColType aColType,
465 PRBool aAddToTable);
467 void MatchCellMapToColCache(nsTableCellMap* aCellMap);
468 /** empty the column frame cache */
469 void ClearColCache();
471 void DidResizeColumns();
473 virtual void AppendCell(nsTableCellFrame& aCellFrame,
474 PRInt32 aRowIndex);
476 virtual void InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
477 PRInt32 aRowIndex,
478 PRInt32 aColIndexBefore);
480 virtual void RemoveCell(nsTableCellFrame* aCellFrame,
481 PRInt32 aRowIndex);
483 void AppendRows(nsTableRowGroupFrame& aRowGroupFrame,
484 PRInt32 aRowIndex,
485 nsTArray<nsTableRowFrame*>& aRowFrames);
487 PRInt32 InsertRow(nsTableRowGroupFrame& aRowGroupFrame,
488 nsIFrame& aFrame,
489 PRInt32 aRowIndex,
490 PRBool aConsiderSpans);
492 PRInt32 InsertRows(nsTableRowGroupFrame& aRowGroupFrame,
493 nsTArray<nsTableRowFrame*>& aFrames,
494 PRInt32 aRowIndex,
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,
510 PRInt32 aColIndex,
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);
542 protected:
544 /** protected constructor.
545 * @see NewFrame
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;
557 public:
558 PRBool IsRowInserted() const;
559 void SetRowInserted(PRBool aValue);
561 protected:
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
565 // height.
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
588 * and cols
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;
600 private:
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
607 public:
609 // calculate the computed height of aFrame including its border and padding given
610 // its reflow state.
611 nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
613 protected:
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,
623 nscoord aAmount);
625 void PlaceChild(nsTableReflowState& aReflowState,
626 nsIFrame* aKidFrame,
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);
640 public:
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;
655 protected:
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;
673 public:
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);
692 protected:
694 PRBool HaveReflowedColGroups() const;
695 void SetHaveReflowedColGroups(PRBool aValue);
697 public:
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
739 * to exclude.
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);
750 protected:
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 -----------------------*/
809 public:
811 #ifdef DEBUG
812 void Dump(PRBool aDumpRows,
813 PRBool aDumpCols,
814 PRBool aDumpCellMap);
815 #endif
817 protected:
818 #ifdef DEBUG
819 void DumpRowGroup(nsIFrame* aChildFrame);
820 #endif
821 // DATA MEMBERS
822 nsAutoTPtrArray<nsTableColFrame, 8> mColFrames;
824 struct TableBits {
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?
837 } mBits;
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()
930 return mColFrames;
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;
953 inline nscoord
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
967 public:
968 nsTableIterator(nsIFrame& aSource);
969 nsTableIterator(nsFrameList& aSource);
970 nsIFrame* First();
971 nsIFrame* Next();
972 PRBool IsLeftToRight();
973 PRInt32 Count();
975 protected:
976 void Init(nsIFrame* aFirstChild);
977 PRBool mLeftToRight;
978 nsIFrame* mFirstListChild;
979 nsIFrame* mFirstChild;
980 nsIFrame* mCurrentChild;
981 PRInt32 mCount;
984 #define ABORT0() \
985 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
986 return;}
988 #define ABORT1(aReturn) \
989 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
990 return aReturn;}
992 #endif