1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
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 the GNU General Public License Version 2 or later (the "GPL"), or
26
* 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 NPL, 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 NPL, the GPL or the LGPL.
36
* ***** END LICENSE BLOCK ***** */
37
#ifndef nsTableFrame_h__
38
#define nsTableFrame_h__
41
#include "nsVoidArray.h"
42
#include "nsHTMLContainerFrame.h"
43
#include "nsStyleCoord.h"
44
#include "nsStyleConsts.h"
45
#include "nsITableLayout.h"
46
#include "nsTableColFrame.h"
47
#include "nsTableColGroupFrame.h"
51
class nsTableCellFrame;
52
class nsTableColFrame;
53
class nsTableRowGroupFrame;
54
class nsTableRowFrame;
55
class nsTableColGroupFrame;
56
class nsITableLayoutStrategy;
60
struct nsTableReflowState;
61
struct nsStylePosition;
63
enum nsPixelRound {eAlwaysRoundUp=0, eAlwaysRoundDown, eRoundUpIfHalfOrMore};
65
#ifdef DEBUG_TABLE_REFLOW_TIMING
72
nsReflowTimer(nsIFrame* aFrame) {
74
mNextSibling = nsnull;
75
mFrameType = aFrame->GetType();
76
NS_IF_ADDREF(mFrameType);
82
PRInt32 numChildren = mChildren.Count();
83
for (PRInt32 childX = 0; childX < numChildren; childX++) {
84
((nsReflowTimer*)mChildren.ElementAt(childX))->Destroy();
86
NS_IF_RELEASE(mFrameType);
87
if (mNextSibling) { // table frames have 3 auxillary timers
88
delete mNextSibling->mNextSibling->mNextSibling;
89
delete mNextSibling->mNextSibling;
95
void Print(PRUint32 aIndent,
98
printf("%s", aHeader);
100
printf(" elapsed=%d numStarts=%d \n", Elapsed(), mNumStarts);
108
mTotalTime = mNumStarts = 0;
113
NS_ASSERTION(!mStarted, "started timer without stopping");
115
mStartTime = GetTickCount();
124
NS_ASSERTION(mStarted, "stopped timer without starting");
125
mTotalTime += GetTickCount() - mStartTime;
132
const nsIFrame* mFrame;
133
nsIAtom* mFrameType; // needed for frame summary timer
134
nsReflowReason mReason;
135
nsVoidArray mChildren;
137
// reflow state/reflow metrics data
139
nscoord mComputedWidth;
140
nscoord mComputedHeight;
141
nscoord mMaxElementWidth;
142
nscoord mMaxWidth; // preferred width
143
nscoord mDesiredWidth;
144
nscoord mDesiredHeight;
145
nsReflowStatus mStatus;
146
nsReflowTimer* mNextSibling;
157
* Child list name indices
158
* @see #GetAdditionalChildListName()
160
#define NS_TABLE_FRAME_COLGROUP_LIST_INDEX 0
161
#define NS_TABLE_FRAME_LAST_LIST_INDEX NS_TABLE_FRAME_COLGROUP_LIST_INDEX
163
/* ============================================================================ */
165
/** nsTableFrame maps the inner portion of a table (everything except captions.)
166
* Used as a pseudo-frame within nsTableOuterFrame, it may also be used
167
* stand-alone as the top-level frame.
169
* The flowed child list contains row group frames. There is also an additional
171
* - "ColGroup-list" which contains the col group frames
173
* @see nsLayoutAtoms::colGroupList
175
* TODO: make methods virtual so nsTableFrame can be used as a base class in the future.
177
class nsTableFrame : public nsHTMLContainerFrame, public nsITableLayout
182
NS_DECL_ISUPPORTS_INHERITED
184
/** nsTableOuterFrame has intimate knowledge of the inner table frame */
185
friend class nsTableOuterFrame;
187
/** instantiate a new instance of nsTableFrame.
188
* @param aResult the new object is returned in this out-param
189
* @param aContent the table object to map
190
* @param aParent the parent of the new frame
192
* @return NS_OK if the frame was properly allocated, otherwise an error code
195
NS_NewTableFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
197
/** sets defaults for table-specific style.
198
* @see nsIFrame::Init
200
NS_IMETHOD Init(nsIPresContext* aPresContext,
201
nsIContent* aContent,
203
nsStyleContext* aContext,
204
nsIFrame* aPrevInFlow);
207
static void* GetProperty(nsIPresContext* aPresContext,
209
nsIAtom* aPropertyName,
210
PRBool aCreateIfNecessary = PR_FALSE);
212
static float GetTwipsToPixels(nsIPresContext* aPresContext);
214
static nscoord RoundToPixel(nscoord aValue,
216
nsPixelRound aRound= eAlwaysRoundUp);
218
// See if a special height reflow will occur due to having a pct height when
219
// the pct height basis may not yet be valid.
220
static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
222
// Notify the frame and its ancestors (up to the containing table) that a special
223
// height reflow will occur.
224
static void RequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
226
// Return true (and set aMetrics's desiredSize to aRect) if the special height reflow
227
// was not initiated by aReflowState.frame's containing table.
228
static PRBool IsPrematureSpecialHeightReflow(const nsHTMLReflowState& aReflowState,
230
PRBool aNeedSpecialHeightReflow,
231
nsHTMLReflowMetrics& aMetrics);
233
virtual PRBool IsContainingBlock() const;
235
static nsresult AppendDirtyReflowCommand(nsIPresShell* aPresShell,
238
static void RePositionViews(nsIPresContext* aPresContext,
241
static PRBool PageBreakAfter(nsIFrame& aSourceFrame,
242
nsIFrame* aNextFrame);
244
nsPoint GetFirstSectionOrigin(const nsHTMLReflowState& aReflowState) const;
246
* Notification that aAttribute has changed for content inside a table (cell, row, etc)
248
void AttributeChangedFor(nsIPresContext* aPresContext,
250
nsIContent* aContent,
251
nsIAtom* aAttribute);
253
/** @see nsIFrame::Destroy */
254
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
256
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
257
nsIPresShell& aPresShell,
259
nsIFrame* aFrameList);
260
NS_IMETHOD InsertFrames(nsIPresContext* aPresContext,
261
nsIPresShell& aPresShell,
263
nsIFrame* aPrevFrame,
264
nsIFrame* aFrameList);
265
NS_IMETHOD RemoveFrame(nsIPresContext* aPresContext,
266
nsIPresShell& aPresShell,
268
nsIFrame* aOldFrame);
270
// Get the offset from the border box to the area where the row groups fit
271
nsMargin GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const;
273
// Get the offset from the border box to the area where the content fits
274
nsMargin GetContentAreaOffset(const nsHTMLReflowState* aReflowState) const;
276
/** helper method to find the table parent of any table frame object */
277
// TODO: today, this depends on display types. This should be changed to rely
278
// on stronger criteria, like an inner table frame atom
279
static NS_METHOD GetTableFrame(nsIFrame* aSourceFrame,
280
nsTableFrame*& aTableFrame);
282
// Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
283
// of type aChildType.
284
static nsIFrame* GetFrameAtOrBefore(nsIFrame* aParentFrame,
285
nsIFrame* aPriorChildFrame,
286
nsIAtom* aChildType);
287
PRBool IsAutoWidth(PRBool* aIsPctWidth = nsnull);
288
PRBool IsAutoHeight();
289
static PRBool IsPctHeight(nsStyleContext* aStyleContext);
291
/** @return PR_TRUE if aDisplayType represents a rowgroup of any sort
292
* (header, footer, or body)
294
PRBool IsRowGroup(PRInt32 aDisplayType) const;
296
/** Initialize the table frame with a set of children.
297
* @see nsIFrame::SetInitialChildList
299
NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext,
301
nsIFrame* aChildList);
303
/** return the first child belonging to the list aListName.
304
* @see nsIFrame::GetFirstChild
306
virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
308
/** @see nsIFrame::GetAdditionalChildListName */
309
virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
311
/** @see nsIFrame::Paint */
312
NS_IMETHOD Paint(nsIPresContext* aPresContext,
313
nsIRenderingContext& aRenderingContext,
314
const nsRect& aDirtyRect,
315
nsFramePaintLayer aWhichLayer,
316
PRUint32 aFlags = 0);
318
virtual void PaintChildren(nsIPresContext* aPresContext,
319
nsIRenderingContext& aRenderingContext,
320
const nsRect& aDirtyRect,
321
nsFramePaintLayer aWhichLayer,
322
PRUint32 aFlags = 0);
324
nsMargin GetBCBorder() const;
326
// get the area that the border leak out from the inner table frame into
327
// the surrounding margin space
328
nsMargin GetBCMargin(nsIPresContext* aPresContext) const;
330
/** Get width of table + colgroup + col collapse: elements that
331
* continue along the length of the whole left side.
332
* see nsTablePainter about continuous borders
333
* @param aPixelsToTwips - conversion factor
334
* @param aGetInner - get only inner half of border width
336
nscoord GetContinuousLeftBCBorderWidth(float aPixelsToTwips) const;
338
void SetBCDamageArea(nsIPresContext& aPresContext,
339
const nsRect& aValue);
341
void PaintBCBorders(nsIPresContext* aPresContext,
342
nsIRenderingContext& aRenderingContext,
343
const nsRect& aDirtyRect);
345
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
346
const nsPoint& aPoint,
347
nsFramePaintLayer aWhichLayer,
350
/** nsIFrame method overridden to handle table specifics
352
NS_IMETHOD SetSelected(nsIPresContext* aPresContext,
357
/** inner tables are reflowed in two steps.
359
* if mFirstPassValid is false, this is our first time through since content was last changed
362
* get min/max info for all cells in an infinite space
363
* do column balancing
364
* set mFirstPassValid to true
366
* use column widths to Reflow cells
369
* @see ResizeReflowPass1
370
* @see ResizeReflowPass2
371
* @see BalanceColumnWidths
372
* @see nsIFrameReflow::Reflow
374
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
375
nsHTMLReflowMetrics& aDesiredSize,
376
const nsHTMLReflowState& aReflowState,
377
nsReflowStatus& aStatus);
379
nsresult ReflowTable(nsIPresContext* aPresContext,
380
nsHTMLReflowMetrics& aDesiredSize,
381
const nsHTMLReflowState& aReflowState,
382
nscoord aAvailHeight,
383
nsReflowReason aReason,
384
nsIFrame*& aLastChildReflowed,
387
nsReflowStatus& aStatus);
389
static nsMargin GetBorderPadding(const nsHTMLReflowState& aReflowState,
391
const nsTableCellFrame* aCellFrame);
393
static nsMargin GetBorderPadding(const nsSize& aBasis,
395
const nsTableCellFrame* aCellFrame);
397
nsFrameList& GetColGroups();
399
NS_IMETHOD GetParentStyleContextFrame(nsIPresContext* aPresContext,
400
nsIFrame** aProviderFrame,
404
* Get the "type" of the frame
406
* @see nsLayoutAtoms::tableFrame
408
virtual nsIAtom* GetType() const;
411
/** @see nsIFrame::GetFrameName */
412
NS_IMETHOD GetFrameName(nsAString& aResult) const;
415
/** return the width of the column at aColIndex */
416
virtual PRInt32 GetColumnWidth(PRInt32 aColIndex);
418
/** set the width of the column at aColIndex to aWidth */
419
virtual void SetColumnWidth(PRInt32 aColIndex, nscoord aWidth);
421
/** helper to get the cell spacing X style value */
422
virtual nscoord GetCellSpacingX();
424
/** helper to get the cell spacing Y style value */
425
virtual nscoord GetCellSpacingY();
427
/** return the row span of a cell, taking into account row span magic at the bottom
428
* of a table. The row span equals the number of rows spanned by aCell starting at
429
* aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
430
* index in which aCell originates.
432
* @param aStartRowIndex the cell
433
* @param aCell the cell
435
* @return the row span, correcting for row spans that extend beyond the bottom
438
virtual PRInt32 GetEffectiveRowSpan(PRInt32 aStartRowIndex,
439
const nsTableCellFrame& aCell) const;
440
virtual PRInt32 GetEffectiveRowSpan(const nsTableCellFrame& aCell,
441
nsCellMap* aCellMap = nsnull);
443
/** return the col span of a cell, taking into account col span magic at the edge
446
* @param aCell the cell
448
* @return the col span, correcting for col spans that extend beyond the edge
451
virtual PRInt32 GetEffectiveColSpan(const nsTableCellFrame& aCell,
452
nsCellMap* aCellMap = nsnull) const;
454
/** return the value of the COLS attribute, adjusted for the
455
* actual number of columns in the table
457
PRInt32 GetEffectiveCOLSAttribute();
459
/** return the column frame associated with aColIndex */
460
nsTableColFrame* GetColFrame(PRInt32 aColIndex) const;
462
void InsertCol(nsIPresContext& aPresContext,
463
nsTableColFrame& aColFrame,
466
nsTableColGroupFrame* CreateAnonymousColGroupFrame(nsIPresContext& aPresContext,
467
nsTableColGroupType aType);
469
PRInt32 DestroyAnonymousColFrames(nsIPresContext& aPresContext,
472
void CreateAnonymousColFrames(nsIPresContext& aPresContext,
473
PRInt32 aNumColsToAdd,
474
nsTableColType aColType,
476
nsIFrame* aPrevCol = nsnull);
478
void CreateAnonymousColFrames(nsIPresContext& aPresContext,
479
nsTableColGroupFrame& aColGroupFrame,
480
PRInt32 aNumColsToAdd,
481
nsTableColType aColType,
482
PRBool aAddToColGroupAndTable,
484
nsIFrame** aFirstNewFrame);
486
/** empty the column frame cache */
487
void ClearColCache();
489
virtual void AppendCell(nsIPresContext& aPresContext,
490
nsTableCellFrame& aCellFrame,
493
virtual void InsertCells(nsIPresContext& aPresContext,
494
nsVoidArray& aCellFrames,
496
PRInt32 aColIndexBefore);
498
virtual void RemoveCell(nsIPresContext& aPresContext,
499
nsTableCellFrame* aCellFrame,
502
void AppendRows(nsIPresContext& aPresContext,
503
nsTableRowGroupFrame& aRowGroupFrame,
505
nsVoidArray& aRowFrames);
507
PRInt32 InsertRow(nsIPresContext& aPresContext,
508
nsTableRowGroupFrame& aRowGroupFrame,
511
PRBool aConsiderSpans);
513
PRInt32 InsertRows(nsIPresContext& aPresContext,
514
nsTableRowGroupFrame& aRowGroupFrame,
515
nsVoidArray& aFrames,
517
PRBool aConsiderSpans);
519
virtual void RemoveRows(nsIPresContext& aPresContext,
520
nsTableRowFrame& aFirstRowFrame,
521
PRInt32 aNumRowsToRemove,
522
PRBool aConsiderSpans);
524
void AppendRowGroups(nsIPresContext& aPresContext,
525
nsIFrame* aFirstRowGroupFrame);
527
void InsertRowGroups(nsIPresContext& aPresContext,
528
nsIFrame* aFirstRowGroupFrame,
529
nsIFrame* aLastRowGroupFrame);
531
void InsertColGroups(nsIPresContext& aPresContext,
533
nsIFrame* aFirstFrame,
534
nsIFrame* aLastFrame = nsnull);
536
virtual void RemoveCol(nsIPresContext& aPresContext,
537
nsTableColGroupFrame* aColGroupFrame,
539
PRBool aRemoveFromCache,
540
PRBool aRemoveFromCellMap);
542
nsTableCellFrame* GetCellInfoAt(PRInt32 aRowX,
544
PRBool* aOriginates = nsnull,
545
PRInt32* aColSpan = nsnull);
547
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
548
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
550
PRBool HasPctCol() const;
551
void SetHasPctCol(PRBool aValue);
553
PRBool HasCellSpanningPctCol() const;
554
void SetHasCellSpanningPctCol(PRBool aValue);
556
PRBool NeedSpecialReflow() const;
557
void SetNeedSpecialReflow(PRBool aValue);
559
PRBool NeedToInitiateSpecialReflow() const;
560
void SetNeedToInitiateSpecialReflow(PRBool aValue);
562
PRBool InitiatedSpecialReflow() const;
563
void SetInitiatedSpecialReflow(PRBool aValue);
567
/** protected constructor.
572
/** destructor, responsible for mColumnLayoutData */
573
virtual ~nsTableFrame();
575
void InitChildReflowState(nsIPresContext& aPresContext,
576
nsHTMLReflowState& aReflowState);
578
/** implement abstract method on nsHTMLContainerFrame */
579
virtual PRIntn GetSkipSides() const;
581
virtual PRBool ParentDisablesSelection() const; //override default behavior
583
// Sets the starting column index for aColGroupFrame and the siblings frames that
585
void SetStartingColumnIndexFor(nsTableColGroupFrame* aColGroupFrame,
588
// Calculate the starting column index to use for the specified col group frame
589
PRInt32 CalculateStartingColumnIndexFor(nsTableColGroupFrame* aColGroupFrame);
592
/** first pass of ResizeReflow.
593
* lays out all table content with aMaxSize(NS_UNCONSTRAINEDSIZE,NS_UNCONSTRAINEDSIZE) and
594
* a true mComputeMEW so we get all the metrics we need to do column balancing.
595
* Pass 1 only needs to be executed once no matter how many times the table is resized,
596
* as long as content and style don't change. This is managed in the member variable mFirstPassIsValid.
597
* The layout information for each cell is cached in mColumLayoutData.
598
* Incremental layout can take advantage of aStartingFrame to pick up where a previous
599
* ResizeReflowPass1 left off.
601
* @see nsIFrameReflow::Reflow
604
/** do I need to do a reflow? */
605
virtual PRBool NeedsReflow(const nsHTMLReflowState& aReflowState);
607
PRBool IsRowInserted() const;
608
void SetRowInserted(PRBool aValue);
612
NS_METHOD ReflowChildren(nsIPresContext* aPresContext,
613
nsTableReflowState& aReflowState,
616
nsReflowStatus& aStatus,
617
nsIFrame*& aLastChildReflowed,
618
nsRect& aOverflowArea,
619
PRBool* aReflowedAtLeastOne = nsnull);
620
// begin incremental reflow methods
622
/** Incremental Reflow attempts to do column balancing with the minimum number of reflow
623
* commands to child elements. This is done by processing the reflow command,
624
* rebalancing column widths (if necessary), then comparing the resulting column widths
625
* to the prior column widths and reflowing only those cells that require a reflow.
626
* All incremental reflows go through this method.
630
NS_IMETHOD IncrementalReflow(nsIPresContext* aPresContext,
631
const nsHTMLReflowState& aReflowState,
632
nsReflowStatus& aStatus);
634
/** process an incremental reflow command targeted at a child of this frame.
635
* @param aNextFrame the next frame in the reflow target chain
636
* @see nsIFrameReflow::Reflow
638
NS_IMETHOD IR_TargetIsChild(nsIPresContext* aPresContext,
639
nsTableReflowState& aReflowStatet,
640
nsReflowStatus& aStatus,
641
nsIFrame* aNextFrame);
643
/** process an incremental reflow command targeted at this frame.
644
* @see nsIFrameReflow::Reflow
646
NS_IMETHOD IR_TargetIsMe(nsIPresContext* aPresContext,
647
nsTableReflowState& aReflowState,
648
nsReflowStatus& aStatus);
650
/** process a style changed notification.
651
* @see nsIFrameReflow::Reflow
652
* TODO: needs to be optimized for which attribute was actually changed.
654
NS_IMETHOD IR_StyleChanged(nsIPresContext* aPresContext,
655
nsTableReflowState& aReflowState,
656
nsReflowStatus& aStatus);
658
NS_IMETHOD AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
659
nsTableReflowState& aReflowState,
663
nsresult RecoverState(nsTableReflowState& aReflowState,
664
nsIFrame* aKidFrame);
666
NS_METHOD CollapseRowGroupIfNecessary(nsIPresContext* aPresContext,
667
nsIFrame* aRowGroupFrame,
668
const nscoord& aYTotalOffset,
669
nscoord& aYGroupOffset, PRInt32& aRowX);
671
NS_METHOD AdjustForCollapsingRows(nsIPresContext* aPresContext,
674
NS_METHOD AdjustForCollapsingCols(nsIPresContext* aPresContext,
676
// end incremental reflow methods
679
// WIDTH AND HEIGHT CALCULATION
683
// calculate the computed width of aFrame including its border and padding given
685
nscoord CalcBorderBoxWidth(const nsHTMLReflowState& aReflowState);
687
// calculate the computed height of aFrame including its border and padding given
689
nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
690
// calculate the minimum width to layout aFrame and its desired width
691
// including border and padding given its reflow state and column width information
692
void CalcMinAndPreferredWidths(const nsHTMLReflowState& aReflowState,
693
PRBool aCalcPrefWidthIfAutoWithPctCol,
695
nscoord& aPreferredWidth);
698
// calcs the width of the table according to the computed widths of each column.
699
virtual PRInt32 CalcDesiredWidth(const nsHTMLReflowState& aReflowState);
701
// return the desired height of this table accounting for the current
702
// reflow state, and for the table attributes and parent
703
nscoord CalcDesiredHeight(const nsHTMLReflowState& aReflowState);
705
// The following is a helper for CalcDesiredHeight
707
void DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
710
void PlaceChild(nsIPresContext* aPresContext,
711
nsTableReflowState& aReflowState,
713
nsHTMLReflowMetrics& aKidDesiredSize);
715
/** assign widths for each column, taking into account the table content, the effective style,
716
* the layout constraints, and the compatibility mode.
717
* @param aPresContext the presentation context
718
* @param aTableStyle the resolved style for the table
719
* @param aMaxSize the height and width constraints
720
* @param aMaxElementSize the min size of the largest indivisible object
722
virtual void BalanceColumnWidths(nsIPresContext* aPresContext,
723
const nsHTMLReflowState& aReflowState);
726
nsIFrame* GetFirstBodyRowGroupFrame();
727
PRBool MoveOverflowToChildList(nsIPresContext* aPresContext);
728
void PushChildren(nsIPresContext *aPresContext,
729
nsIFrame* aFromChild,
730
nsIFrame* aPrevSibling);
733
// put the children frames in the display order (e.g. thead before tbody before tfoot)
734
// and put the non row group frames at the end. Also return the number of row group frames.
735
void OrderRowGroups(nsVoidArray& aChildren,
736
PRUint32& aNumRowGroups,
737
nsIFrame** aFirstBody = nsnull,
738
nsTableRowGroupFrame** aHead = nsnull,
739
nsTableRowGroupFrame** aFoot = nsnull) const;
741
// Returns PR_TRUE if there are any cells above the row at
742
// aRowIndex and spanning into the row at aRowIndex
743
PRBool RowIsSpannedInto(PRInt32 aRowIndex);
745
// Returns PR_TRUE if there is a cell originating in aRowIndex
746
// which spans into the next row
747
PRBool RowHasSpanningCells(PRInt32 aRowIndex);
749
// Returns PR_TRUE if there are any cells to the left of the column at
750
// aColIndex and spanning into the column at aColIndex
751
PRBool ColIsSpannedInto(PRInt32 aColIndex);
753
// Returns PR_TRUE if there is a cell originating in aColIndex
754
// which spans into the next col
755
PRBool ColHasSpanningCells(PRInt32 aColIndex);
757
// Allows rows to notify the table of additions or changes to a cell's width
758
// The table uses this to update the appropriate column widths and to decide
759
// whether to reinitialize (and then rebalance) or rebalance the table. If the
760
// most extreme measure results (e.g. reinitialize) then PR_TRUE is returned
761
// indicating that further calls are not going to accomplish anyting.
762
PRBool CellChangedWidth(const nsTableCellFrame& aCellFrame,
763
nscoord aPrevMinWidth,
764
nscoord aPrevMaxWidth,
765
PRBool aCellWasDestroyed = PR_FALSE);
769
PRBool HaveReflowedColGroups() const;
770
void SetHaveReflowedColGroups(PRBool aValue);
772
PRBool DidResizeReflow() const;
773
void SetResizeReflow(PRBool aValue);
776
PRBool NeedStrategyInit() const;
777
void SetNeedStrategyInit(PRBool aValue);
779
PRBool NeedStrategyBalance() const;
780
void SetNeedStrategyBalance(PRBool aValue);
782
PRBool IsBorderCollapse() const;
784
PRBool NeedToCalcBCBorders() const;
785
void SetNeedToCalcBCBorders(PRBool aValue);
787
/** Get the cell map for this table frame. It is not always mCellMap.
788
* Only the firstInFlow has a legit cell map
790
virtual nsTableCellMap* GetCellMap() const;
792
void AdjustRowIndices(PRInt32 aRowIndex,
793
PRInt32 aAdjustment);
795
NS_IMETHOD AdjustRowIndices(nsIFrame* aRowGroup,
797
PRInt32 anAdjustment);
799
// Remove cell borders which aren't bordering row and/or col groups
800
void ProcessGroupRules(nsIPresContext* aPresContext);
802
nsVoidArray& GetColCache();
804
/** Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
806
static nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
807
nsIAtom* aFrameTypeIn = nsnull);
811
void SetBorderCollapse(PRBool aValue);
813
void CalcBCBorders(nsIPresContext& aPresContext);
815
void ExpandBCDamageArea(nsRect& aRect) const;
817
PRBool HadInitialReflow() const;
818
void SetHadInitialReflow(PRBool aValue);
820
void SetColumnDimensions(nscoord aHeight,
821
const nsMargin& aReflowState);
823
/** return the number of columns as specified by the input.
824
* has 2 side effects:<br>
825
* calls SetStartColumnIndex on each nsTableColumn<br>
826
* sets mSpecifiedColCount.<br>
828
virtual PRInt32 GetSpecifiedColumnCount ();
830
PRInt32 CollectRows(nsIFrame* aFrame,
831
nsVoidArray& aCollection);
833
public: /* ----- Cell Map public methods ----- */
835
PRInt32 GetStartRowIndex(nsTableRowGroupFrame& aRowGroupFrame);
837
/** returns the number of rows in this table.
838
* if mCellMap has been created, it is asked for the number of rows.<br>
839
* otherwise, the content is enumerated and the rows are counted.
841
virtual PRInt32 GetRowCount() const;
843
/** returns the number of columns in this table after redundant columns have been removed
845
virtual PRInt32 GetEffectiveColCount() const;
846
virtual PRInt32 GetColCount() const;
848
/** return the column frame at colIndex.
849
* returns nsnull if the col frame has not yet been allocated, or if aColIndex is out of range
851
nsTableColFrame * GetColFrame(PRInt32 aColIndex);
852
// return the last col index which isn't of type eColAnonymousCell
853
PRInt32 GetIndexOfLastRealCol();
855
/** return the cell frame at aRowIndex, aColIndex.
856
* returns nsnull if the cell frame has not yet been allocated,
857
* or if aRowIndex or aColIndex is out of range
859
nsTableCellFrame * GetCellFrameAt(PRInt32 aRowIndex, PRInt32 aColIndex);
861
/** return the minimum width of the table caption. Return 0 if there is no caption. */
862
nscoord GetMinCaptionWidth();
864
/** returns PR_TRUE if table-layout:auto */
865
virtual PRBool IsAutoLayout();
867
nscoord GetMinWidth() const;
868
void SetMinWidth(nscoord aWidth);
870
nscoord GetDesiredWidth() const;
871
void SetDesiredWidth(nscoord aWidth);
873
nscoord GetPreferredWidth() const;
874
void SetPreferredWidth(nscoord aWidth);
876
/*---------------- nsITableLayout methods ------------------------*/
878
/** Get the cell and associated data for a table cell from the frame's cellmap */
879
NS_IMETHOD GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
880
nsIDOMElement* &aCell, //out params
881
PRInt32& aStartRowIndex, PRInt32& aStartColIndex,
882
PRInt32& aRowSpan, PRInt32& aColSpan,
883
PRInt32& aActualRowSpan, PRInt32& aActualColSpan,
884
PRBool& aIsSelected);
886
/** Get the number of rows and column for a table from the frame's cellmap
887
* Some rows may not have enough cells (the number returned is the maximum possible),
888
* which displays as a ragged-right edge table
890
NS_IMETHOD GetTableSize(PRInt32& aRowCount, PRInt32& aColCount);
892
/*------------end of nsITableLayout methods -----------------------*/
895
static nsIAtom* gColGroupAtom;
897
void Dump(PRBool aDumpRows,
899
PRBool aDumpCellMap);
901
nsAutoVoidArray mColFrames; // XXX temporarily public
904
static void DumpTableFrames(nsIFrame* aFrame);
909
void DumpRowGroup(nsIFrame* aChildFrame);
914
PRUint32 mHadInitialReflow:1; // has intial reflow happened
915
PRUint32 mHaveReflowedColGroups:1; // have the col groups gotten their initial reflow
916
PRUint32 mNeedStrategyBalance:1; // does the strategy needs to balance the table
917
PRUint32 mNeedStrategyInit:1; // does the strategy needs to be initialized and then balance the table
918
PRUint32 mHasPctCol:1; // does any cell or col have a pct width
919
PRUint32 mCellSpansPctCol:1; // does any cell span a col with a pct width (or containing a cell with a pct width)
920
PRUint32 mDidResizeReflow:1; // did a resize reflow happen (indicating pass 2)
921
PRUint32 mIsBorderCollapse:1; // border collapsing model vs. separate model
922
PRUint32 mRowInserted:1;
923
PRUint32 mNeedSpecialReflow:1;
924
PRUint32 mNeedToInitiateSpecialReflow:1;
925
PRUint32 mInitiatedSpecialReflow:1;
926
PRUint32 mNeedToCalcBCBorders:1;
927
PRUint32 mLeftContBCBorder:8;
928
PRUint32 : 11; // unused
931
nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
932
nsITableLayoutStrategy* mTableLayoutStrategy;// the layout strategy for this frame
933
nsFrameList mColGroups; // the list of colgroup frames
934
nscoord mMinWidth; // XXX could store as PRUint16 with pixels
935
nscoord mDesiredWidth; // XXX could store as PRUint16 with pixels
936
nscoord mPreferredWidth; // XXX could store as PRUint16 with pixels
940
#if defined DEBUG_TABLE_REFLOW_TIMING
942
static void DebugReflow(nsIFrame* aFrame,
943
nsHTMLReflowState& aReflowState,
944
nsHTMLReflowMetrics* aMetrics = nsnull,
945
nsReflowStatus aStatus = NS_FRAME_COMPLETE);
947
static void DebugReflowDone(nsIFrame* aFrame);
949
enum nsMethod {eInit=0, eBalanceCols, eNonPctCols, eNonPctColspans, ePctCols};
950
static void DebugTimeMethod(nsMethod aMethod,
951
nsTableFrame& aFrame,
952
nsHTMLReflowState& aReflowState,
954
nsReflowTimer* mTimer;
959
inline PRBool nsTableFrame::IsRowGroup(PRInt32 aDisplayType) const
961
return PRBool((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == aDisplayType) ||
962
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == aDisplayType) ||
963
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == aDisplayType));
966
inline void nsTableFrame::SetHadInitialReflow(PRBool aValue)
968
mBits.mHadInitialReflow = aValue;
971
inline PRBool nsTableFrame::HadInitialReflow() const
973
return (PRBool)mBits.mHadInitialReflow;
976
inline void nsTableFrame::SetHaveReflowedColGroups(PRBool aValue)
978
mBits.mHaveReflowedColGroups = aValue;
981
inline PRBool nsTableFrame::HaveReflowedColGroups() const
983
return (PRBool)mBits.mHaveReflowedColGroups;
986
inline PRBool nsTableFrame::HasPctCol() const
988
return (PRBool)mBits.mHasPctCol;
991
inline void nsTableFrame::SetHasPctCol(PRBool aValue)
993
mBits.mHasPctCol = (unsigned)aValue;
996
inline PRBool nsTableFrame::HasCellSpanningPctCol() const
998
return (PRBool)mBits.mCellSpansPctCol;
1001
inline void nsTableFrame::SetHasCellSpanningPctCol(PRBool aValue)
1003
mBits.mCellSpansPctCol = (unsigned)aValue;
1006
inline PRBool nsTableFrame::NeedSpecialReflow() const
1008
return (PRBool)mBits.mNeedSpecialReflow;
1011
inline void nsTableFrame::SetNeedSpecialReflow(PRBool aValue)
1013
mBits.mNeedSpecialReflow = (unsigned)aValue;
1016
inline PRBool nsTableFrame::NeedToInitiateSpecialReflow() const
1018
return (PRBool)mBits.mNeedToInitiateSpecialReflow;
1021
inline void nsTableFrame::SetNeedToInitiateSpecialReflow(PRBool aValue)
1023
mBits.mNeedToInitiateSpecialReflow = (unsigned)aValue;
1026
inline PRBool nsTableFrame::InitiatedSpecialReflow() const
1028
return (PRBool)mBits.mInitiatedSpecialReflow;
1031
inline void nsTableFrame::SetInitiatedSpecialReflow(PRBool aValue)
1033
mBits.mInitiatedSpecialReflow = (unsigned)aValue;
1036
inline PRBool nsTableFrame::IsRowInserted() const
1038
return (PRBool)mBits.mRowInserted;
1041
inline void nsTableFrame::SetRowInserted(PRBool aValue)
1043
mBits.mRowInserted = (unsigned)aValue;
1046
inline nsFrameList& nsTableFrame::GetColGroups()
1048
return NS_STATIC_CAST(nsTableFrame*, GetFirstInFlow())->mColGroups;
1051
inline nsVoidArray& nsTableFrame::GetColCache()
1056
inline void nsTableFrame::SetMinWidth(nscoord aWidth)
1061
inline void nsTableFrame::SetDesiredWidth(nscoord aWidth)
1063
mDesiredWidth = aWidth;
1066
inline void nsTableFrame::SetPreferredWidth(nscoord aWidth)
1068
mPreferredWidth = aWidth;
1071
inline PRBool nsTableFrame::IsBorderCollapse() const
1073
return (PRBool)mBits.mIsBorderCollapse;
1076
inline void nsTableFrame::SetBorderCollapse(PRBool aValue)
1078
mBits.mIsBorderCollapse = aValue;
1081
inline PRBool nsTableFrame::NeedToCalcBCBorders() const
1083
return (PRBool)mBits.mNeedToCalcBCBorders;
1086
inline void nsTableFrame::SetNeedToCalcBCBorders(PRBool aValue)
1088
mBits.mNeedToCalcBCBorders = (unsigned)aValue;
1092
nsTableFrame::GetContinuousLeftBCBorderWidth(float aPixelsToTwips) const
1094
return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, mBits.mLeftContBCBorder);
1097
enum nsTableIteration {
1103
class nsTableIterator
1106
nsTableIterator(nsIFrame& aSource,
1107
nsTableIteration aType);
1108
nsTableIterator(nsFrameList& aSource,
1109
nsTableIteration aType);
1112
PRBool IsLeftToRight();
1116
void Init(nsIFrame* aFirstChild,
1117
nsTableIteration aType);
1118
PRBool mLeftToRight;
1119
nsIFrame* mFirstListChild;
1120
nsIFrame* mFirstChild;
1121
nsIFrame* mCurrentChild;
1126
{NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
1129
#define ABORT1(aReturn) \
1130
{NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
1133
#define GET_PIXELS_TO_TWIPS(presContext,var) \
1135
(presContext)->GetScaledPixelsToTwips(&var);
1137
#define GET_TWIPS_TO_PIXELS(presContext,var) \
1139
(presContext)->GetScaledPixelsToTwips(&var); \