Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / layout / tables / nsTableFrame.h
bloba548a26196c007f30f3315ede67fcdac8f95d1d7
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 "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;
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 // nsISupports
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,
160 nsIFrame* aParent,
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
238 * display list set.
240 static nsresult DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
241 nsFrame* aFrame,
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,
286 nsPoint aPt);
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
300 // no margin).
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,
321 nsIDOMRange *aRange,
322 PRBool aSelected,
323 nsSpread aSpread,
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,
337 PRBool aShrinkWrap);
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,
347 nscoord aWidthInCB);
349 // XXXldb REWRITE THIS COMMENT!
350 /** inner tables are reflowed in two steps.
351 * <pre>
352 * if mFirstPassValid is false, this is our first time through since content was last changed
353 * set pass to 1
354 * do pass 1
355 * get min/max info for all cells in an infinite space
356 * do column balancing
357 * set mFirstPassValid to true
358 * do pass 2
359 * use column widths to Reflow cells
360 * </pre>
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,
379 PRBool* aIsChild);
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;
394 #ifdef DEBUG
395 /** @see nsIFrame::GetFrameName */
396 NS_IMETHOD GetFrameName(nsAString& aResult) const;
397 #endif
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
421 * of the table.
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
429 * of a table.
431 * @param aCell the cell
433 * @return the col span, correcting for col spans that extend beyond the edge
434 * of the table.
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
458 * colframe cache
460 void InsertCol(nsTableColFrame& aColFrame,
461 PRInt32 aColIndex);
463 nsTableColGroupFrame* CreateAnonymousColGroupFrame(nsTableColGroupType aType);
465 PRInt32 DestroyAnonymousColFrames(PRInt32 aNumFrames);
467 void CreateAnonymousColFrames(PRInt32 aNumColsToAdd,
468 nsTableColType aColType,
469 PRBool aDoAppend,
470 nsIFrame* aPrevCol = nsnull);
472 void CreateAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
473 PRInt32 aNumColsToAdd,
474 nsTableColType aColType,
475 PRBool aAddToColGroupAndTable,
476 nsIFrame* aPrevCol,
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,
486 PRInt32 aRowIndex);
488 virtual void InsertCells(nsVoidArray& aCellFrames,
489 PRInt32 aRowIndex,
490 PRInt32 aColIndexBefore);
492 virtual void RemoveCell(nsTableCellFrame* aCellFrame,
493 PRInt32 aRowIndex);
495 void AppendRows(nsTableRowGroupFrame& aRowGroupFrame,
496 PRInt32 aRowIndex,
497 nsVoidArray& aRowFrames);
499 PRInt32 InsertRow(nsTableRowGroupFrame& aRowGroupFrame,
500 nsIFrame& aFrame,
501 PRInt32 aRowIndex,
502 PRBool aConsiderSpans);
504 PRInt32 InsertRows(nsTableRowGroupFrame& aRowGroupFrame,
505 nsVoidArray& aFrames,
506 PRInt32 aRowIndex,
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,
532 PRInt32 aColIndex,
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);
564 protected:
566 /** protected constructor.
567 * @see NewFrame
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
581 public:
582 PRBool IsRowInserted() const;
583 void SetRowInserted(PRBool aValue);
585 protected:
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
589 // height.
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
612 * and cols
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;
624 private:
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
631 public:
633 // calculate the computed height of aFrame including its border and padding given
634 // its reflow state.
635 nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
637 protected:
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,
647 nscoord aAmount);
649 void PlaceChild(nsTableReflowState& aReflowState,
650 nsIFrame* aKidFrame,
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);
665 public:
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;
680 protected:
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;
698 public:
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);
717 protected:
719 PRBool HaveReflowedColGroups() const;
720 void SetHaveReflowedColGroups(PRBool aValue);
722 public:
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
766 * indices.
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);
778 protected:
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 -----------------------*/
837 public:
839 #ifdef DEBUG
840 void Dump(PRBool aDumpRows,
841 PRBool aDumpCols,
842 PRBool aDumpCellMap);
843 static void DumpTableFrames(nsIFrame* aFrame);
844 #endif
846 protected:
847 #ifdef DEBUG
848 void DumpRowGroup(nsIFrame* aChildFrame);
849 #endif
850 // DATA MEMBERS
851 nsAutoVoidArray mColFrames;
853 struct TableBits {
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?
866 } mBits;
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()
959 return mColFrames;
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;
982 inline nscoord
983 nsTableFrame::GetContinuousLeftBCBorderWidth() const
985 PRInt32 aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
986 return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, mBits.mLeftContBCBorder);
989 class nsTableIterator
991 public:
992 nsTableIterator(nsIFrame& aSource);
993 nsTableIterator(nsFrameList& aSource);
994 nsIFrame* First();
995 nsIFrame* Next();
996 PRBool IsLeftToRight();
997 PRInt32 Count();
999 protected:
1000 void Init(nsIFrame* aFirstChild);
1001 PRBool mLeftToRight;
1002 nsIFrame* mFirstListChild;
1003 nsIFrame* mFirstChild;
1004 nsIFrame* mCurrentChild;
1005 PRInt32 mCount;
1008 #define ABORT0() \
1009 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
1010 return;}
1012 #define ABORT1(aReturn) \
1013 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
1014 return aReturn;}
1016 #endif