/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ #ifndef nsTableFrame_h__ #define nsTableFrame_h__ #include "nscore.h" #include "nsVoidArray.h" #include "nsHTMLContainerFrame.h" #include "nsStyleCoord.h" #include "nsStyleConsts.h" #include "nsIStyleContext.h" #include "nsITableLayout.h" #include "nsTableColFrame.h" #include "nsTableColGroupFrame.h" class nsTableCellMap; class nsTableCellFrame; class nsTableColFrame; class nsTableRowGroupFrame; class nsTableRowFrame; class nsTableColGroupFrame; class nsTableBorderCollapser; class nsITableLayoutStrategy; class nsHTMLValue; struct InnerTableReflowState; struct nsStylePosition; struct nsStyleSpacing; /** * Child list name indices * @see #GetAdditionalChildListName() */ #define NS_TABLE_FRAME_COLGROUP_LIST_INDEX 0 #define NS_TABLE_FRAME_LAST_LIST_INDEX NS_TABLE_FRAME_COLGROUP_LIST_INDEX struct nsDebugTable { static PRBool gRflTableOuter; static PRBool gRflTable; static PRBool gRflRowGrp; static PRBool gRflRow; static PRBool gRflCell; static PRBool gRflArea; }; /* ============================================================================ */ /** nsTableFrame maps the inner portion of a table (everything except captions.) * Used as a pseudo-frame within nsTableOuterFrame, it may also be used * stand-alone as the top-level frame. * * The flowed child list contains row group frames. There is also an additional * named child list: * - "ColGroup-list" which contains the col group frames * * @see nsLayoutAtoms::colGroupList * * TODO: make methods virtual so nsTableFrame can be used as a base class in the future. */ class nsTableFrame : public nsHTMLContainerFrame, public nsITableLayout { public: // nsISupports NS_DECL_ISUPPORTS_INHERITED /** nsTableOuterFrame has intimate knowledge of the inner table frame */ friend class nsTableOuterFrame; /** instantiate a new instance of nsTableFrame. * @param aResult the new object is returned in this out-param * @param aContent the table object to map * @param aParent the parent of the new frame * * @return NS_OK if the frame was properly allocated, otherwise an error code */ friend nsresult NS_NewTableFrame(nsIPresShell* aPresShell, nsIFrame** aResult); /** sets defaults for table-specific style. * @see nsIFrame::Init */ NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow); NS_IMETHOD IsPercentageBase(PRBool& aBase) const; static nsresult AddTableDirtyReflowCommand(nsIPresContext* aPresContext, nsIFrame* aTableFrame); /* * Notification that aAttribute has changed for content inside a table (cell, row, etc) */ void AttributeChangedFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsIContent* aContent, nsIAtom* aAttribute); /** @see nsIFrame::Destroy */ NS_IMETHOD Destroy(nsIPresContext* aPresContext); NS_IMETHOD AppendFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aFrameList); NS_IMETHOD InsertFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aPrevFrame, nsIFrame* aFrameList); NS_IMETHOD RemoveFrame(nsIPresContext* aPresContext, nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aOldFrame); /** helper method to find the table parent of any table frame object */ // TODO: today, this depends on display types. This should be changed to rely // on stronger criteria, like an inner table frame atom static NS_METHOD GetTableFrame(nsIFrame* aSourceFrame, nsTableFrame*& aTableFrame); // calculate the width of aFrame including its border and padding given // given its reflow state. nscoord CalcBorderBoxWidth(const nsHTMLReflowState& aReflowState); // calculate the height of aFrame including its border and padding given // its reflow state. nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState, PRBool aDoNavHacks); // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame) // of type aChildType. static nsIFrame* GetFrameAtOrBefore(nsIPresContext* aPresContext, nsIFrame* aParentFrame, nsIFrame* aPriorChildFrame, nsIAtom* aChildType); PRBool IsAutoWidth(); /** @return PR_TRUE if aDisplayType represents a rowgroup of any sort * (header, footer, or body) */ PRBool IsRowGroup(PRInt32 aDisplayType) const; /** Initialize the table frame with a set of children. * @see nsIFrame::SetInitialChildList */ NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, nsIFrame* aChildList); /** return the first child belonging to the list aListName. * @see nsIFrame::FirstChild */ NS_IMETHOD FirstChild(nsIPresContext* aPresContext, nsIAtom* aListName, nsIFrame** aFirstChild) const; /** @see nsIFrame::GetAdditionalChildListName */ NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const; /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer); NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsFramePaintLayer aWhichLayer, nsIFrame** aFrame); /** nsIFrame method overridden to handle table specifics */ NS_IMETHOD SetSelected(nsIPresContext* aPresContext, nsIDOMRange *aRange, PRBool aSelected, nsSpread aSpread); /** inner tables are reflowed in two steps. *
* if mFirstPassValid is false, this is our first time through since content was last changed
* set pass to 1
* do pass 1
* get min/max info for all cells in an infinite space
* do column balancing
* set mFirstPassValid to true
* do pass 2
* use column widths to Reflow cells
*
*
* @see ResizeReflowPass1
* @see ResizeReflowPass2
* @see BalanceColumnWidths
* @see nsIFrameReflow::Reflow
*/
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** the COLS attribute can be modified by any cell's width attribute.
* deal with it here. Must be called before any call to
* ColumnInfoCache::AddColumnInfo
*/
virtual void AdjustColumnsForCOLSAttribute();
/** return the column frame corresponding to the given column index
* there are two ways to do this, depending on whether we have cached
* column information yet.
*/
NS_METHOD GetColumnFrame(PRInt32 aColIndex, nsTableColFrame *&aColFrame);
static nsMargin GetPadding(const nsHTMLReflowState& aReflowState,
const nsTableCellFrame* aCellFrame);
static nsMargin GetPadding(const nsSize& aBasis,
const nsTableCellFrame* aCellFrame);
nsFrameList& GetColGroups();
/** return PR_TRUE if the column width information has been set */
PRBool IsColumnWidthsSet();
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::tableFrame
*/
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
#ifdef DEBUG
/** @see nsIFrame::GetFrameName */
NS_IMETHOD GetFrameName(nsString& aResult) const;
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
#endif
/** get the max border thickness for each edge */
void GetTableBorder(nsMargin &aBorder);
void SetBorderEdgeLength(PRUint8 aSide,
PRInt32 aIndex,
nscoord aLength);
/** get the border values for the row and column */
void GetTableBorderAt(PRInt32 aRowIndex,
PRInt32 aColIndex,
nsMargin &aBorder);
/** get the max border thickness for each edge encompassed by the row group */
void GetTableBorderForRowGroup(nsTableRowGroupFrame * aRowGroupFrame, nsMargin &aBorder);
/** return the width of the column at aColIndex */
virtual PRInt32 GetColumnWidth(PRInt32 aColIndex);
/** set the width of the column at aColIndex to aWidth */
virtual void SetColumnWidth(PRInt32 aColIndex, nscoord aWidth);
/** helper to get the border collapse style value */
virtual PRUint8 GetBorderCollapseStyle();
/** helper to get the cell spacing X style value */
virtual nscoord GetCellSpacingX();
/** helper to get the cell spacing Y style value */
virtual nscoord GetCellSpacingY();
/** helper to get the cell padding style value */
virtual nscoord GetCellPadding();
// Get cell margin information
NS_IMETHOD GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin& aMargin);
/** return the row span of a cell, taking into account row span magic at the bottom
* of a table. The row span equals the number of rows spanned by aCell starting at
* aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
* index in which aCell originates.
*
* @param aStartRowIndex the cell
* @param aCell the cell
*
* @return the row span, correcting for row spans that extend beyond the bottom
* of the table.
*/
virtual PRInt32 GetEffectiveRowSpan(PRInt32 aStartRowIndex,
const nsTableCellFrame& aCell) const;
virtual PRInt32 GetEffectiveRowSpan(const nsTableCellFrame& aCell) const;
/** return the col span of a cell, taking into account col span magic at the edge
* of a table.
*
* @param aCell the cell
*
* @return the col span, correcting for col spans that extend beyond the edge
* of the table.
*/
virtual PRInt32 GetEffectiveColSpan(const nsTableCellFrame& aCell) const;
/** return the value of the COLS attribute, adjusted for the
* actual number of columns in the table
*/
PRInt32 GetEffectiveCOLSAttribute();
/** return the column frame associated with aColIndex */
nsTableColFrame* GetColFrame(PRInt32 aColIndex) const;
void InsertCol(nsIPresContext& aPresContext,
nsTableColFrame& aColFrame,
PRInt32 aColIndex);
nsTableColGroupFrame* CreateAnonymousColGroupFrame(nsIPresContext& aPresContext,
nsTableColGroupType aType);
PRInt32 DestroyAnonymousColFrames(nsIPresContext& aPresContext,
PRInt32 aNumFrames);
void CreateAnonymousColFrames(nsIPresContext& aPresContext,
PRInt32 aNumColsToAdd,
nsTableColType aColType,
PRBool aDoAppend,
nsIFrame* aPrevCol = nsnull);
void CreateAnonymousColFrames(nsIPresContext& aPresContext,
nsTableColGroupFrame& aColGroupFrame,
PRInt32 aNumColsToAdd,
nsTableColType aColType,
PRBool aAddToColGroupAndTable,
nsIFrame* aPrevCol,
nsIFrame** aFirstNewFrame);
/** empty the column frame cache */
void ClearColCache();
virtual PRInt32 AppendCell(nsIPresContext& aPresContext,
nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex);
virtual void InsertCells(nsIPresContext& aPresContext,
nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore);
virtual void RemoveCell(nsIPresContext& aPresContext,
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex);
void AppendRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aRowFrames);
PRInt32 InsertRow(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsIFrame& aFrame,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
PRInt32 InsertRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aFrames,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
virtual void RemoveRows(nsIPresContext& aPresContext,
PRInt32 aFirstRowFrame,
PRInt32 aNumRowsToRemove,
PRBool aConsiderSpans);
void AppendRowGroups(nsIPresContext& aPresContext,
nsIFrame* aFirstRowGroupFrame);
void InsertRowGroups(nsIPresContext& aPresContext,
nsIFrame* aFirstRowGroupFrame,
PRInt32 aRowIndex);
void InsertColGroups(nsIPresContext& aPresContext,
PRInt32 aColIndex,
nsIFrame* aFirstFrame,
nsIFrame* aLastFrame = nsnull);
virtual void RemoveCol(nsIPresContext& aPresContext,
nsTableColGroupFrame* aColGroupFrame,
PRInt32 aColIndex,
PRBool aRemoveFromCache,
PRBool aRemoveFromCellMap);
static PRBool IsFinalPass(const nsHTMLReflowState& aReflowState);
nsTableCellFrame* GetCellInfoAt(PRInt32 aRowX,
PRInt32 aColX,
PRBool* aOriginates = nsnull,
PRInt32* aColSpan = nsnull);
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
PRBool HasNonPercentSpanningPercent() const;
void SetHasNonPercentSpanningPercent(PRBool aValue);
static void DebugReflow(char* aMessage,
const nsIFrame* aFrame,
const nsHTMLReflowState* aState,
const nsHTMLReflowMetrics* aMetrics,
const nsReflowStatus aStatus = NS_FRAME_COMPLETE);
static void DebugGetIndent(const nsIFrame* aFrame,
char* aBuf);
protected:
/** protected constructor.
* @see NewFrame
*/
nsTableFrame();
/** destructor, responsible for mColumnLayoutData and mColumnWidths */
virtual ~nsTableFrame();
/** implement abstract method on nsHTMLContainerFrame */
virtual PRIntn GetSkipSides() const;
virtual PRBool ParentDisablesSelection() const; //override default behavior
/** helper method for determining if this is a nested table or not
* @param aReflowState The reflow state for this inner table frame
* @param aPosition [OUT] The position style struct for the parent table, if nested.
* If not nested, undefined.
* @return PR_TRUE if this table is nested inside another table.
*/
PRBool IsNested(const nsHTMLReflowState& aReflowState, const nsStylePosition *& aPosition) const;
// Sets the starting column index for aColGroupFrame and the siblings frames that
// follow
void SetStartingColumnIndexFor(nsTableColGroupFrame* aColGroupFrame,
PRInt32 aIndex);
// Calculate the starting column index to use for the specified col group frame
PRInt32 CalculateStartingColumnIndexFor(nsTableColGroupFrame* aColGroupFrame);
public:
/** first pass of ResizeReflow.
* lays out all table content with aMaxSize(NS_UNCONSTRAINEDSIZE,NS_UNCONSTRAINEDSIZE) and
* a non-null aMaxElementSize so we get all the metrics we need to do column balancing.
* Pass 1 only needs to be executed once no matter how many times the table is resized,
* as long as content and style don't change. This is managed in the member variable mFirstPassIsValid.
* The layout information for each cell is cached in mColumLayoutData.
* Incremental layout can take advantage of aStartingFrame to pick up where a previous
* ResizeReflowPass1 left off.
*
* @see nsIFrameReflow::Reflow
*/
NS_IMETHOD ResizeReflowPass1(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus,
nsTableRowGroupFrame * aStartingFrame,
nsReflowReason aReason,
PRBool aDoSiblings);
virtual PRBool RowGroupsShouldBeConstrained() { return PR_FALSE; }
/** do I need to do a reflow? */
virtual PRBool NeedsReflow(const nsHTMLReflowState& aReflowState);
protected:
/** second pass of ResizeReflow.
* lays out all table content with aMaxSize(computed_table_width, given_table_height)
* Pass 2 is executed every time the table needs to resize. An optimization is included
* so that if the table doesn't need to actually be resized, no work is done (see NeedsReflow).
*
* @see nsIFrameReflow::Reflow
*/
NS_IMETHOD ResizeReflowPass2(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
// begin incremental reflow methods
/** Incremental Reflow attempts to do column balancing with the minimum number of reflow
* commands to child elements. This is done by processing the reflow command,
* rebalancing column widths (if necessary), then comparing the resulting column widths
* to the prior column widths and reflowing only those cells that require a reflow.
* All incremental reflows go through this method.
*
* @see Reflow
*/
NS_IMETHOD IncrementalReflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process an incremental reflow command targeted at a child of this frame.
* @param aNextFrame the next frame in the reflow target chain
* @see nsIFrameReflow::Reflow
*/
NS_IMETHOD IR_TargetIsChild(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
nsIFrame * aNextFrame);
/** process an incremental reflow command targeted at this frame.
* @see nsIFrameReflow::Reflow
*/
NS_IMETHOD IR_TargetIsMe(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus);
/** process a style chnaged notification.
* @see nsIFrameReflow::Reflow
* TODO: needs to be optimized for which attribute was actually changed.
*/
NS_IMETHOD IR_StyleChanged(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
InnerTableReflowState& aReflowState,
nsIFrame* aKidFrame,
nsSize* aMaxElementSize,
nscoord aDeltaY);
nsresult RecoverState(InnerTableReflowState& aReflowState,
nsIFrame* aKidFrame,
nsSize* aMaxElementSize);
NS_METHOD CollapseRowGroupIfNecessary(nsIPresContext* aPresContext,
nsIFrame* aRowGroupFrame,
const nscoord& aYTotalOffset,
nscoord& aYGroupOffset, PRInt32& aRowX);
NS_METHOD AdjustForCollapsingRows(nsIPresContext* aPresContext,
nscoord& aHeight);
NS_METHOD AdjustForCollapsingCols(nsIPresContext* aPresContext,
nscoord& aWidth);
// end incremental reflow methods
/** return the desired width of this table accounting for the current
* reflow state, and for the table attributes and parent
*/
nscoord ComputeDesiredWidth(const nsHTMLReflowState& aReflowState) const;
/** return the desired height of this table accounting for the current
* reflow state, and for the table attributes and parent
*/
nscoord ComputeDesiredHeight(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nscoord aDefaultHeight);
/** The following two functions are helpers for ComputeDesiredHeight
*/
void DistributeSpaceToCells(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame);
void DistributeSpaceToRows(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsIFrame* aRowGroupFrame, const nscoord& aSumOfRowHeights,
const nscoord& aExcess, const nsStyleTable* aTableStyle,
nscoord& aExcessForRowGroup,
nscoord& aRowGroupYPos);
nscoord GetEffectiveContainerHeight(const nsHTMLReflowState& aReflowState);
void PlaceChild(nsIPresContext* aPresContext,
InnerTableReflowState& aReflowState,
nsIFrame* aKidFrame,
nsHTMLReflowMetrics& aDesiredSize,
nscoord aX,
nscoord aY,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
/**
* Reflow the frames we've already created
*
* @param aPresContext presentation context to use
* @param aReflowState current inline state
* @return true if we successfully reflowed all the mapped children and false
* otherwise, e.g. we pushed children to the next in flow
*/
NS_IMETHOD ReflowMappedChildren(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus);
/**
* Try and pull-up frames from our next-in-flow
*
* @param aPresContext presentation context to use
* @param aReflowState current reflow state
* @return true if we successfully pulled-up all the children and false
* otherwise, e.g. child didn't fit
*/
NS_IMETHOD PullUpChildren(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus);
/** assign widths for each column, taking into account the table content, the effective style,
* the layout constraints, and the compatibility mode. Sets mColumnWidths as a side effect.
* @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aMaxSize the height and width constraints
* @param aMaxElementSize the min size of the largest indivisible object
*/
virtual void BalanceColumnWidths(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
const nsSize& aMaxSize,
nsSize* aMaxElementSize);
/** sets the width of the table according to the computed widths of each column. */
virtual void SetTableWidth(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState);
/** returns PR_TRUE if the cached pass 1 data is still valid */
virtual PRBool IsFirstPassValid() const;
/** returns PR_TRUE if the cached column info is still valid */
virtual PRBool IsColumnWidthsValid() const;
/** returns PR_TRUE if the cached pass1 maximum width is still valid */
virtual PRBool IsMaximumWidthValid() const;
nsIFrame* GetFirstBodyRowGroupFrame();
PRBool MoveOverflowToChildList(nsIPresContext* aPresContext);
void PushChildren(nsIPresContext *aPresContext,
nsIFrame* aFromChild,
nsIFrame* aPrevSibling);
public:
// Returns PR_TRUE if there are any cells above the row at
// aRowIndex and spanning into the row at aRowIndex
PRBool RowIsSpannedInto(PRInt32 aRowIndex);
// Returns PR_TRUE if there is a cell originating in aRowIndex
// which spans into the next row
PRBool RowHasSpanningCells(PRInt32 aRowIndex);
// Returns PR_TRUE if there are any cells to the left of the column at
// aColIndex and spanning into the column at aColIndex
PRBool ColIsSpannedInto(PRInt32 aColIndex);
// Returns PR_TRUE if there is a cell originating in aColIndex
// which spans into the next col
PRBool ColHasSpanningCells(PRInt32 aColIndex);
// Returns PR_TRUE if the style width change, aPrevStyleWidth, for aCellFrame
// could require the columns to be rebalanced. This method can be used to
// determine if an incremental reflow on aCellFrame is necessary as the result
// of the style width change. If aConsiderMinWidth is PR_TRUE, then potential
// changes to aCellFrame's min width is considered (however, if considered,
// the function will always return PR_TRUE if the layout strategy is Basic).
PRBool ColumnsCanBeInvalidatedBy(nsStyleCoord* aPrevStyleWidth,
const nsTableCellFrame& aCellFrame) const;
// Returns PR_TRUE if potential width changes to aCellFrame could require the
// columns to be rebalanced. This method can be used after an incremental reflow
// of aCellFrame to determine if a pass1 reflow on aCellFrame is necessary. If
// aConsiderMinWidth is PR_TRUE, then potential changes to aCellFrame's min width
// is considered (however, if considered, the function will always return PR_TRUE
// if the layout strategy is Basic).
PRBool ColumnsCanBeInvalidatedBy(const nsTableCellFrame& aCellFrame,
PRBool aConsiderMinWidth = PR_FALSE) const;
// Returns PR_TRUE if changes to aCellFrame's pass1 min and desired (max) sizes
// don't require the columns to be rebalanced. This method can be used after a
// pass1 reflow of aCellFrame to determine if the columns need rebalancing.
// aPrevCellMin and aPrevCellDes are the values aCellFrame had before the last
// pass1 reflow.
PRBool ColumnsAreValidFor(const nsTableCellFrame& aCellFrame,
nscoord aPrevCellMin,
nscoord aPrevCellDes) const;
virtual void InvalidateFirstPassCache();
virtual void InvalidateColumnWidths();
virtual void InvalidateMaximumWidth();
protected:
/** Support methods for DidSetStyleContext */
void MapBorderMarginPadding(nsIPresContext* aPresContext);
void MapHTMLBorderStyle(nsStyleSpacing& aSpacingStyle, nscoord aBorderWidth);
PRBool ConvertToPixelValue(nsHTMLValue& aValue, PRInt32 aDefault, PRInt32& aResult);
public:
/** Get the cell map for this table frame. It is not always mCellMap.
* Only the firstInFlow has a legit cell map
*/
virtual nsTableCellMap* GetCellMap() const;
void AdjustRowIndices(nsIPresContext* aPresContext,
PRInt32 aRowIndex,
PRInt32 aAdjustment);
NS_IMETHOD AdjustRowIndices(nsIPresContext* aPresContext,
nsIFrame* aRowGroup,
PRInt32 aRowIndex,
PRInt32 anAdjustment);
// Return PR_TRUE if rules=groups is set for the table content
PRBool HasGroupRules() const;
// Remove cell borders which aren't bordering row and/or col groups
void ProcessGroupRules(nsIPresContext* aPresContext);
nsVoidArray& GetColCache();
/**
* Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
*/
nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay);
nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
nsIAtom* aFrameTypeIn = nsnull);
protected:
void SetColumnDimensions(nsIPresContext* aPresContext,
nscoord aHeight,
const nsMargin& aReflowState);
#ifdef NS_DEBUG
/** for debugging only
* prints out info about the table layout state, printing columns and their cells
*/
void ListColumnLayoutData(FILE* out, PRInt32 aIndent);
#endif
/** return the number of columns as specified by the input.
* has 2 side effects: