mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
rows can now be incrementally inserted, appended, and deleted.
This commit is contained in:
parent
da133d64f2
commit
7cb1f39626
@ -103,25 +103,21 @@ PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosit
|
||||
}
|
||||
|
||||
|
||||
BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols)
|
||||
BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aFrame)
|
||||
{
|
||||
NS_ASSERTION(nsnull!=aFrame, "bad frame arg");
|
||||
|
||||
mTableFrame = aFrame;
|
||||
mNumCols = aNumCols;
|
||||
mMinTableWidth=0;
|
||||
mMaxTableWidth=0;
|
||||
mFixedTableWidth=0;
|
||||
|
||||
//cache the value of the cols attribute
|
||||
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
||||
}
|
||||
|
||||
BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
|
||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
nsIFrame *tablePIF=nsnull;
|
||||
@ -132,9 +128,11 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
// re-init instance variables
|
||||
mNumCols = aNumCols;
|
||||
mMinTableWidth=0;
|
||||
mMaxTableWidth=0;
|
||||
mFixedTableWidth=0;
|
||||
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
||||
|
||||
// Step 1 - assign the width of all fixed-width columns
|
||||
AssignPreliminaryColumnWidths();
|
||||
|
@ -76,15 +76,17 @@ public:
|
||||
|
||||
/** Public constructor.
|
||||
* @paran aFrame the table frame for which this delegate will do layout
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
BasicTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols);
|
||||
BasicTableLayoutStrategy(nsTableFrame *aFrame);
|
||||
|
||||
/** destructor */
|
||||
virtual ~BasicTableLayoutStrategy();
|
||||
|
||||
/** call once every time any table thing changes (content, structure, or style) */
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize);
|
||||
/** call once every time any table thing changes (content, structure, or style)
|
||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols);
|
||||
|
||||
virtual void SetMaxElementSize(nsSize* aMaxElementSize);
|
||||
|
||||
|
@ -35,8 +35,8 @@ static PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebug = PR_FALSE;
|
||||
#endif
|
||||
|
||||
FixedTableLayoutStrategy::FixedTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols)
|
||||
: BasicTableLayoutStrategy(aFrame, aNumCols)
|
||||
FixedTableLayoutStrategy::FixedTableLayoutStrategy(nsTableFrame *aFrame)
|
||||
: BasicTableLayoutStrategy(aFrame)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -44,19 +44,16 @@ public:
|
||||
* @paran aFrame the table frame for which this delegate will do layout
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
FixedTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols);
|
||||
FixedTableLayoutStrategy(nsTableFrame *aFrame);
|
||||
|
||||
/** destructor */
|
||||
virtual ~FixedTableLayoutStrategy();
|
||||
|
||||
/** no need to override Initialize since it calls our AssignPreliminaryColumnWidths */
|
||||
// virtual PRBool Initialize(nsSize* aMaxElementSize);
|
||||
|
||||
/** Called during resize reflow to determine the new column widths
|
||||
* @param aTableStyle - the resolved style for mTableFrame
|
||||
* @param aReflowState - the reflow state for mTableFrame
|
||||
* @param aMaxWidth - the computed max width for columns to fit into
|
||||
*/
|
||||
* @param aReflowState - the reflow state for mTableFrame
|
||||
* @param aMaxWidth - the computed max width for columns to fit into
|
||||
*/
|
||||
virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aMaxWidth);
|
||||
|
@ -30,9 +30,10 @@ class nsITableLayoutStrategy
|
||||
public:
|
||||
|
||||
/** call once every time any table thing changes (content, structure, or style)
|
||||
* @param aMaxElementSize [OUT] the min possible size of the table
|
||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize)=0;
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols)=0;
|
||||
|
||||
/** compute the max-element-size for the table
|
||||
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
|
||||
|
@ -928,7 +928,8 @@ void nsTableFrame::SetMinColSpanForTable()
|
||||
{ // XXX: must be called ONLY on first-in-flow
|
||||
// set the minColSpan for each column
|
||||
PRInt32 rowCount = mCellMap->GetRowCount();
|
||||
for (PRInt32 colIndex=0; colIndex<mColCount; colIndex++)
|
||||
PRInt32 colCount = mCellMap->GetColCount();
|
||||
for (PRInt32 colIndex=0; colIndex<colCount; colIndex++)
|
||||
{
|
||||
PRInt32 minColSpan;
|
||||
for (PRInt32 rowIndex=0; rowIndex<rowCount; rowIndex++)
|
||||
@ -999,6 +1000,7 @@ void nsTableFrame::AddCellToTable (nsTableRowFrame *aRowFrame,
|
||||
|
||||
NS_METHOD nsTableFrame::ReBuildCellMap()
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: ReBuildCellMap.\n");
|
||||
nsresult rv=NS_OK;
|
||||
nsIFrame *rowGroupFrame=mFirstChild;
|
||||
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(rowGroupFrame))
|
||||
@ -1022,6 +1024,7 @@ NS_METHOD nsTableFrame::ReBuildCellMap()
|
||||
}
|
||||
}
|
||||
}
|
||||
mCellMapValid=PR_TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1562,10 +1565,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
if (PR_TRUE==NeedsReflow(aReflowState, aReflowState.maxSize))
|
||||
{
|
||||
PRBool needsRecalc=PR_FALSE;
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: needs reflow\n");
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: needs reflow\n");
|
||||
if (eReflowReason_Initial!=aReflowState.reason && PR_FALSE==IsCellMapValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: cell map invalid, rebuilding...\n");
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: cell map invalid, rebuilding...\n");
|
||||
if (nsnull!=mCellMap)
|
||||
delete mCellMap;
|
||||
mCellMap = new nsCellMap(0,0);
|
||||
@ -1575,7 +1578,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
if (PR_FALSE==IsFirstPassValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: first pass is invalid, rebuilding...\n");
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, aReflowState.reason);
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, aReflowState.reason, PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
needsRecalc=PR_TRUE;
|
||||
@ -1587,23 +1590,23 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
}
|
||||
if (PR_TRUE==needsRecalc)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: needs recalc.\n");
|
||||
// if we need to recalc, the data stored in the layout strategy is invalid
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: needs recalc. Calling BuildColumnCache...\n");
|
||||
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
RecalcLayoutData(); // Recalculate Layout Dependencies
|
||||
// if we needed to rebuild the column cache, the data stored in the layout strategy is invalid
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, mCellMap->GetColCount());
|
||||
mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below
|
||||
}
|
||||
}
|
||||
if (PR_FALSE==IsColumnWidthsValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, mCellMap->GetColCount());
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
}
|
||||
@ -1658,7 +1661,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowGroupFrame * aStartingFrame,
|
||||
nsReflowReason aReason)
|
||||
nsReflowReason aReason,
|
||||
PRBool aDoSiblingFrames)
|
||||
{
|
||||
NS_PRECONDITION(aReflowState.frame == this, "bad reflow state");
|
||||
NS_PRECONDITION(aReflowState.parentReflowState->frame == mGeometricParent,
|
||||
@ -1719,7 +1723,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
PRInt32 yCoord = y;
|
||||
if (NS_UNCONSTRAINEDSIZE!=yCoord)
|
||||
yCoord+= topInset;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 1 of frame %p\n", kidFrame);
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 1 of frame %p with reason=%d\n", kidFrame, aReason);
|
||||
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus);
|
||||
|
||||
// Place the child since some of its content fit in us.
|
||||
@ -1744,6 +1748,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
// up all of our available space (or needs us to split).
|
||||
break;
|
||||
}
|
||||
if (PR_FALSE==aDoSiblingFrames)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2185,14 +2191,18 @@ NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext,
|
||||
{
|
||||
nsresult rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState,
|
||||
aStatus, (nsIFrame*)aInsertedFrame, aReplace);
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
PRInt32 rowCount;
|
||||
aInsertedFrame->GetRowCount(rowCount);
|
||||
if (0>rowCount)
|
||||
{ // for now we will assume that if there are rows, then there are cells and we need to recalc table info
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// do a pass-1 layout of all the cells in all the rows of the rowgroup
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState.reflowState, aStatus,
|
||||
aInsertedFrame, eReflowReason_Initial, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2212,10 +2222,12 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
// account for the cells in the rows that are children of aAppendedFrame
|
||||
// this will add the content of the rowgroup to the cell map
|
||||
rv = DidAppendRowGroup((nsTableRowGroupFrame*)aAppendedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// do a pass-1 layout of all the cells in all the rows of the rowgroup
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState.reflowState, aStatus,
|
||||
aAppendedFrame, eReflowReason_Initial);
|
||||
aAppendedFrame, eReflowReason_Initial, PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -2232,17 +2244,11 @@ NS_METHOD nsTableFrame::IR_RowGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowGroupFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aDeletedFrame);
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aDeletedFrame);
|
||||
PRInt32 rowCount=0;
|
||||
aDeletedFrame->GetRowCount(rowCount);
|
||||
if (0>rowCount)
|
||||
{ // for now we will assume that if there are rows, then there are cells and we need to recalc table info
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
}
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
InvalidateColumnWidths();
|
||||
@ -2292,9 +2298,7 @@ NS_METHOD nsTableFrame::IR_UnknownFrameInserted(nsIPresContext& aPresCont
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
nsIFrame *nextSibling = mFirstChild;
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
@ -2555,7 +2559,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext& aPresContext,
|
||||
|
||||
nscoord x = aState.leftInset + kidMargin.left;
|
||||
nscoord y = aState.topInset + aState.y + topMargin;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 2 of frame %p\n", kidFrame);
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 2 of frame %p with reason=%d\n", kidFrame, reason);
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) && (desiredSize.height > kidAvailSize.height))
|
||||
@ -2834,10 +2838,10 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
|
||||
nsStyleTable* tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
if (NS_STYLE_TABLE_LAYOUT_FIXED==tableStyle->mLayoutStrategy)
|
||||
mTableLayoutStrategy = new FixedTableLayoutStrategy(this, numCols);
|
||||
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
|
||||
else
|
||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, numCols);
|
||||
mTableLayoutStrategy->Initialize(aMaxElementSize);
|
||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this);
|
||||
mTableLayoutStrategy->Initialize(aMaxElementSize, mCellMap->GetColCount());
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
|
||||
@ -3070,13 +3074,12 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
{
|
||||
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
|
||||
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
|
||||
NS_ASSERTION(PR_FALSE==mColumnCacheValid, "column cache valid state should be PR_FALSE");
|
||||
nsStyleTable* tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
EnsureColumns(aPresContext);
|
||||
if (nsnull!=mColCache)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF BCB: clearing column cache and cell map column frame cache.\n");
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF BCC: clearing column cache and cell map column frame cache.\n");
|
||||
mCellMap->ClearColumnCache();
|
||||
delete mColCache;
|
||||
}
|
||||
@ -3159,6 +3162,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
}
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF BCC: mColumnCacheValid=PR_TRUE.\n");
|
||||
mColumnCacheValid=PR_TRUE;
|
||||
}
|
||||
|
||||
@ -3167,6 +3171,7 @@ void nsTableFrame::InvalidateColumnWidths()
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mColumnWidthsValid=PR_FALSE;
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: ColWidths invalidated.\n");
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsColumnWidthsValid() const
|
||||
@ -3188,6 +3193,7 @@ void nsTableFrame::InvalidateFirstPassCache()
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mFirstPassValid=PR_FALSE;
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: FirstPass invalidated.\n");
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsColumnCacheValid() const
|
||||
@ -3202,6 +3208,7 @@ void nsTableFrame::InvalidateColumnCache()
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mColumnCacheValid=PR_FALSE;
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: ColCache invalidated.\n");
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsCellMapValid() const
|
||||
@ -3237,6 +3244,7 @@ void nsTableFrame::InvalidateCellMap()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: CellMap invalidated.\n");
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
|
@ -281,7 +281,8 @@ protected:
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowGroupFrame * aStartingFrame,
|
||||
nsReflowReason aReason);
|
||||
nsReflowReason aReason,
|
||||
PRBool aDoSiblings);
|
||||
|
||||
/** second pass of ResizeReflow.
|
||||
* lays out all table content with aMaxSize(computed_table_width, given_table_height)
|
||||
|
@ -59,7 +59,7 @@ struct RowGroupReflowState {
|
||||
// Running y-offset
|
||||
nscoord y;
|
||||
|
||||
// Flag used to set aMaxElementSize to my first row
|
||||
// Flag used to set maxElementSize to my first row
|
||||
PRBool firstRow;
|
||||
|
||||
// Remember the height of the first row, because it's our maxElementHeight (plus header/footers)
|
||||
@ -188,7 +188,7 @@ void nsTableRowGroupFrame::PaintChildren(nsIPresContext& aPresContext,
|
||||
|
||||
// Collapse child's top margin with previous bottom margin
|
||||
nscoord nsTableRowGroupFrame::GetTopMarginFor(nsIPresContext* aCX,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
const nsMargin& aKidMargin)
|
||||
{
|
||||
nscoord margin;
|
||||
@ -200,8 +200,8 @@ nscoord nsTableRowGroupFrame::GetTopMarginFor(nsIPresContext* aCX,
|
||||
maxPosTopMargin = margin;
|
||||
}
|
||||
|
||||
nscoord maxPos = PR_MAX(aState.prevMaxPosBottomMargin, maxPosTopMargin);
|
||||
nscoord maxNeg = PR_MAX(aState.prevMaxNegBottomMargin, maxNegTopMargin);
|
||||
nscoord maxPos = PR_MAX(aReflowState.prevMaxPosBottomMargin, maxPosTopMargin);
|
||||
nscoord maxNeg = PR_MAX(aReflowState.prevMaxNegBottomMargin, maxNegTopMargin);
|
||||
margin = maxPos - maxNeg;
|
||||
|
||||
return margin;
|
||||
@ -210,12 +210,12 @@ nscoord nsTableRowGroupFrame::GetTopMarginFor(nsIPresContext* aCX,
|
||||
// Position and size aKidFrame and update our reflow state. The origin of
|
||||
// aKidRect is relative to the upper-left origin of our frame, and includes
|
||||
// any left/top margin.
|
||||
void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
void nsTableRowGroupFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
{
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf ("rowgroup %p: placing row at %d, %d, %d, %d\n",
|
||||
@ -225,18 +225,18 @@ void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
aKidFrame->SetRect(aKidRect);
|
||||
|
||||
// Adjust the running y-offset
|
||||
aState.y += aKidRect.height;
|
||||
aReflowState.y += aKidRect.height;
|
||||
|
||||
// If our height is constrained then update the available height
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
aState.availSize.height -= aKidRect.height;
|
||||
if (PR_FALSE == aReflowState.unconstrainedHeight) {
|
||||
aReflowState.availSize.height -= aKidRect.height;
|
||||
}
|
||||
|
||||
// Update the maximum element size
|
||||
if (PR_TRUE==aState.firstRow)
|
||||
if (PR_TRUE==aReflowState.firstRow)
|
||||
{
|
||||
aState.firstRow = PR_FALSE;
|
||||
aState.firstRowHeight = aKidRect.height;
|
||||
aReflowState.firstRow = PR_FALSE;
|
||||
aReflowState.firstRowHeight = aKidRect.height;
|
||||
if (nsnull != aMaxElementSize) {
|
||||
aMaxElementSize->width = aKidMaxElementSize.width;
|
||||
aMaxElementSize->height = aKidMaxElementSize.height;
|
||||
@ -254,61 +254,64 @@ void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
* Reflow the frames we've already created
|
||||
*
|
||||
* @param aPresContext presentation context to use
|
||||
* @param aState current inline state
|
||||
* @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
|
||||
*/
|
||||
PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowFrame * aStartFrame,
|
||||
nsReflowReason aReason,
|
||||
PRBool aDoSiblings)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != mFirstChild, "no children");
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: ReflowMappedChildren\n");
|
||||
nsIFrame* prevKidFrame = nsnull;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
PRBool result = PR_TRUE;
|
||||
PRInt32 debugCounter=0;
|
||||
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
nsIFrame* kidFrame;
|
||||
if (nsnull==aStartFrame)
|
||||
kidFrame = mFirstChild;
|
||||
else
|
||||
kidFrame = aStartFrame;
|
||||
for ( ; nsnull != kidFrame; )
|
||||
{
|
||||
nsSize kidAvailSize(aReflowState.availSize);
|
||||
if (0>=kidAvailSize.height)
|
||||
kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
|
||||
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
|
||||
desiredSize.width=desiredSize.height=desiredSize.ascent=desiredSize.descent=0;
|
||||
nsReflowStatus status;
|
||||
|
||||
// Get top margin for this kid
|
||||
nsIContentPtr kid;
|
||||
|
||||
kidFrame->GetContent(kid.AssignRef());
|
||||
nsIStyleContextPtr kidSC;
|
||||
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
|
||||
const nsStyleSpacing* kidSpacing = (const nsStyleSpacing*)
|
||||
kidSC->GetStyleData(eStyleStruct_Spacing);
|
||||
const nsStyleSpacing* kidSpacing;
|
||||
kidFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)kidSpacing);
|
||||
nsMargin kidMargin;
|
||||
kidSpacing->CalcMarginFor(this, kidMargin);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMargin);
|
||||
nscoord topMargin = GetTopMarginFor(&aPresContext, aReflowState, kidMargin);
|
||||
nscoord bottomMargin = kidMargin.bottom;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the top margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
if (PR_FALSE == aReflowState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
if (PR_FALSE == aReflowState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMargin.left + kidMargin.right;
|
||||
}
|
||||
|
||||
// Reflow the child into the available space
|
||||
nsHTMLReflowState kidReflowState(*aPresContext, kidFrame,
|
||||
aState.reflowState, kidAvailSize);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aReflowState.reflowState,
|
||||
kidAvailSize, aReason);
|
||||
|
||||
if (gsDebug) printf("%p RG reflowing child %d (frame=%p) with avail width = %d\n",
|
||||
this, debugCounter, kidFrame, kidAvailSize.width);
|
||||
ReflowChild(kidFrame, *aPresContext, desiredSize, kidReflowState, status);
|
||||
if (gsDebug) printf("%p RG child %d (frame=%p) returned desired width = %d\n",
|
||||
this, debugCounter, kidFrame, desiredSize.width);
|
||||
if ((PR_TRUE==gsDebug) || (PR_TRUE==gsDebugIR))
|
||||
printf("%p RG reflowing child %p with avail width = %d, reason = %d\n",
|
||||
this, kidFrame, kidAvailSize.width, aReason);
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
if (gsDebug) printf("%p RG child %p returned desired width = %d\n",
|
||||
this, kidFrame, desiredSize.width);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
@ -321,18 +324,17 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
PushChildren(kidFrame, prevKidFrame);
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Place the child after taking into account it's margin
|
||||
nsRect kidRect (kidMargin.left, aState.y, desiredSize.width, desiredSize.height);
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize,
|
||||
nsRect kidRect (kidMargin.left, aReflowState.y, desiredSize.width, desiredSize.height);
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
aReflowState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
aReflowState.prevMaxPosBottomMargin = bottomMargin;
|
||||
}
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
@ -344,7 +346,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
||||
* otherwise PushChildren and bail.
|
||||
*/
|
||||
// Special handling for incomplete children
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(status)) {
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||
// XXX It's good to assume that we might still have room
|
||||
// even if the child didn't complete (floaters will want this)
|
||||
nsIFrame* kidNextInFlow;
|
||||
@ -355,8 +357,8 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
||||
// create a continuing frame. This hooks the child into the flow.
|
||||
nsIFrame* continuingFrame;
|
||||
nsIStyleContext* kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC);
|
||||
kidFrame->CreateContinuingFrame(*aPresContext, this, kidSC,
|
||||
kidFrame->GetStyleContext(&aPresContext, kidSC);
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC,
|
||||
continuingFrame);
|
||||
NS_RELEASE(kidSC);
|
||||
|
||||
@ -375,47 +377,47 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame);
|
||||
}
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add back in the left and right margins, because one row does not
|
||||
// impact another row's width
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
if (PR_FALSE == aReflowState.unconstrainedWidth) {
|
||||
kidAvailSize.width += kidMargin.left + kidMargin.right;
|
||||
}
|
||||
|
||||
if (PR_FALSE==aDoSiblings)
|
||||
break;
|
||||
|
||||
// Get the next child
|
||||
kidFrame->GetNextSibling(kidFrame);
|
||||
debugCounter++;
|
||||
}
|
||||
|
||||
// Update the child count
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try and pull-up frames from our next-in-flow
|
||||
*
|
||||
* @param aPresContext presentation context to use
|
||||
* @param aState current inline state
|
||||
* @param aReflowState current inline state
|
||||
* @return true if we successfully pulled-up all the children and false
|
||||
* otherwise, e.g. child didn't fit
|
||||
*/
|
||||
PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
NS_METHOD nsTableRowGroupFrame::PullUpChildren(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsTableRowGroupFrame* nextInFlow = (nsTableRowGroupFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
nsIFrame* prevKidFrame = LastFrame(mFirstChild);
|
||||
PRBool result = PR_TRUE;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
while (nsnull != nextInFlow) {
|
||||
nsHTMLReflowMetrics kidSize(pKidMaxElementSize);
|
||||
kidSize.width=kidSize.height=kidSize.ascent=kidSize.descent=0;
|
||||
nsReflowStatus status;
|
||||
|
||||
// Get the next child
|
||||
nsIFrame* kidFrame = nextInFlow->mFirstChild;
|
||||
@ -444,31 +446,30 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
|
||||
kidFrame->GetSize(kidFrameSize);
|
||||
kidFrame->IsSplittable(kidIsSplittable);
|
||||
if ((kidFrameSize.height > aState.availSize.height) &&
|
||||
if ((kidFrameSize.height > aReflowState.availSize.height) &&
|
||||
NS_FRAME_IS_NOT_SPLITTABLE(kidIsSplittable)) {
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
nsHTMLReflowState kidReflowState(*aPresContext, kidFrame,
|
||||
aState.reflowState, aState.availSize,
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aReflowState.reflowState, aReflowState.availSize,
|
||||
eReflowReason_Resize);
|
||||
|
||||
ReflowChild(kidFrame, *aPresContext, kidSize, kidReflowState, status);
|
||||
rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
if ((kidSize.height > aReflowState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
result = PR_FALSE;
|
||||
//result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
//aState.y += topMargin;
|
||||
//aReflowState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
kidRect.y += aReflowState.y;
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Remove the frame from its current parent
|
||||
kidFrame->GetNextSibling(nextInFlow->mFirstChild);
|
||||
@ -492,7 +493,7 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
prevKidFrame = kidFrame;
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(status)) {
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||
// No the child isn't complete
|
||||
nsIFrame* kidNextInFlow;
|
||||
|
||||
@ -503,8 +504,8 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame;
|
||||
nsIStyleContext* kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC);
|
||||
kidFrame->CreateContinuingFrame(*aPresContext, this, kidSC,
|
||||
kidFrame->GetStyleContext(&aPresContext, kidSC);
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC,
|
||||
continuingFrame);
|
||||
NS_RELEASE(kidSC);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
@ -521,12 +522,12 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space.
|
||||
result = PR_FALSE;
|
||||
//result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -691,10 +692,11 @@ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
|
||||
}
|
||||
|
||||
nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
nscoord aDeltaY)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: AdjustSiblingsAfterReflow\n");
|
||||
nsIFrame* lastKidFrame = aKidFrame;
|
||||
|
||||
if (aDeltaY != 0) {
|
||||
@ -731,7 +733,7 @@ nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext& aP
|
||||
// Update our running y-offset to reflect the bottommost child
|
||||
nsRect rect;
|
||||
lastKidFrame->GetRect(rect);
|
||||
aState.y = rect.YMost();
|
||||
aReflowState.y = rect.YMost();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -771,24 +773,18 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
|
||||
// Reflow the existing frames
|
||||
if (nsnull != mFirstChild) {
|
||||
reflowMappedOK = ReflowMappedChildren(&aPresContext, state, aDesiredSize.maxElementSize);
|
||||
if (PR_FALSE == reflowMappedOK) {
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, state, aStatus,
|
||||
nsnull, aReflowState.reason, PR_TRUE);
|
||||
}
|
||||
|
||||
// Did we successfully reflow our mapped children?
|
||||
if (PR_TRUE == reflowMappedOK) {
|
||||
if (NS_FRAME_COMPLETE==aStatus) {
|
||||
// Any space left?
|
||||
PRInt32 numKids;
|
||||
mContent->ChildCount(numKids);
|
||||
if (state.availSize.height > 0) {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if (!PullUpChildren(&aPresContext, state, aDesiredSize.maxElementSize)) {
|
||||
// We were unable to pull-up all the existing frames from the
|
||||
// next in flow
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
rv = PullUpChildren(aPresContext, aDesiredSize, state, aStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@ -803,8 +799,6 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
}
|
||||
|
||||
// Return our desired rect
|
||||
//NS_ASSERTION(0<state.firstRowHeight, "illegal firstRowHeight after reflow");
|
||||
//NS_ASSERTION(0<state.y, "illegal height after reflow");
|
||||
aDesiredSize.width = aReflowState.maxSize.width;
|
||||
aDesiredSize.height = state.y;
|
||||
|
||||
@ -824,9 +818,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
this, NS_FRAME_IS_COMPLETE(aStatus)?"Complete":"Not Complete",
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -874,14 +866,14 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
(nsTableRowFrame *)objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -893,7 +885,8 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
rv = IR_RowAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableRowFrame *)objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
@ -911,7 +904,7 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
(nsTableRowFrame *)objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -948,16 +941,35 @@ NS_METHOD nsTableRowGroupFrame::IR_RowInserted(nsIPresContext& aPresContext
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
nsTableRowFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_RowInserted\n");
|
||||
nsresult rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState,
|
||||
aStatus, (nsIFrame*)aInsertedFrame, aReplace);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// do a pass-1 layout of all the cells in the inserted row
|
||||
//XXX: check the table frame to see if we can skip this
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aInsertedFrame, eReflowReason_Initial, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
NS_METHOD nsTableRowGroupFrame::DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: DidAppendRow\n");
|
||||
nsresult rv=NS_OK;
|
||||
/* need to make space in the cell map. Remeber that row spans can't cross row groups
|
||||
once the space is made, tell the row to initizalize its children.
|
||||
@ -969,56 +981,97 @@ NS_METHOD nsTableRowGroupFrame::IR_DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
return rv;
|
||||
}
|
||||
|
||||
// support method that tells us if there are any rows in the table after our rows
|
||||
// returns PR_TRUE if there are no rows after ours
|
||||
PRBool nsTableRowGroupFrame::NoRowsFollow()
|
||||
{
|
||||
PRBool result = PR_TRUE;
|
||||
nsIFrame *nextSib=nsnull;
|
||||
GetNextSibling(nextSib);
|
||||
while (nsnull!=nextSib)
|
||||
{
|
||||
const nsStyleDisplay *sibDisplay;
|
||||
nextSib->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)sibDisplay));
|
||||
if ((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == sibDisplay->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == sibDisplay->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == sibDisplay->mDisplay))
|
||||
{
|
||||
nsIFrame *childFrame=nsnull;
|
||||
nextSib->FirstChild(childFrame);
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{ // found a row
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nextSib->GetNextSibling(nextSib);
|
||||
}
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: NoRowsFollow returning %d\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// since we know we're doing an append here, we can optimize
|
||||
NS_METHOD nsTableRowGroupFrame::IR_RowAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame)
|
||||
nsTableRowFrame * aAppendedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_RowAppended\n");
|
||||
// hook aAppendedFrame into the child list
|
||||
nsIFrame *lastChild = mFirstChild;
|
||||
nsIFrame *nextChild = lastChild;
|
||||
nsIFrame *lastRow = nsnull;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
// remember the last child that is really a row
|
||||
const nsStyleDisplay *childDisplay;
|
||||
nextChild->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
lastRow = nextChild;
|
||||
lastChild = nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aAppendedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
nsresult rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState,
|
||||
aStatus, (nsIFrame*)aAppendedFrame, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
// the table will see that it's cached info is bogus and rebuild the cell map,
|
||||
// and do a reflow
|
||||
|
||||
#if 0
|
||||
// find the row index of the new row
|
||||
PRInt32 newRowIndex=-1;
|
||||
if (nsnull!=
|
||||
/* we have 2 paths to choose from. If we know that aAppendedFrame is
|
||||
* the last row in the table, we can optimize. Otherwise, we have to
|
||||
* treat it like an insert
|
||||
*/
|
||||
if (PR_TRUE==NoRowsFollow())
|
||||
{ // aAppendedRow is the last row, so do the optimized route
|
||||
// account for the cells in the row aAppendedFrame
|
||||
// this will add the content of the rowgroup to the cell map
|
||||
rv = DidAppendRow(aAppendedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
lastChild=mFirstChild;
|
||||
nextChild=lastChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
// do a pass1 reflow of the new row
|
||||
//XXX: check the table frame to see if we can skip this
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aAppendedFrame, eReflowReason_Initial, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
// account for the cells in aAppendedFrame
|
||||
nsresult rv = DidAppendRow((nsTableRowFrame*)aAppendedFrame, newRowIndex);
|
||||
else
|
||||
{
|
||||
// do a pass1 reflow of the new row
|
||||
//XXX: check the table frame to see if we can skip this
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aAppendedFrame, eReflowReason_Initial, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// need to increment the row index of all subsequent rows
|
||||
#endif
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -1027,9 +1080,25 @@ NS_METHOD nsTableRowGroupFrame::IR_RowRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame)
|
||||
nsTableRowFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_RowRemoved\n");
|
||||
nsresult rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aDeletedFrame);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1041,6 +1110,7 @@ NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameInserted(nsIPresContext& aPr
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_UnknownFrameInserted\n");
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
// we have a generic frame that gets inserted but doesn't effect reflow
|
||||
@ -1075,9 +1145,7 @@ NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameInserted(nsIPresContext& aPr
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
nsIFrame *nextSibling=mFirstChild;
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
@ -1091,6 +1159,7 @@ NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameRemoved(nsIPresContext& aPre
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_UnknownFrameRemoved\n");
|
||||
// we have a generic frame that gets removed but doesn't effect reflow
|
||||
// unhook it then ignore it
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: FrameRemoved removing unknown frame type.\n");
|
||||
|
@ -107,22 +107,20 @@ public:
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
nsTableRowFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_RowAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_DidAppendRow(nsTableRowFrame *aRowFrame);
|
||||
nsTableRowFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_RowRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
nsTableRowFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
@ -138,6 +136,9 @@ public:
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
|
||||
NS_IMETHOD DidAppendRow(nsTableRowFrame *aRowFrame);
|
||||
|
||||
PRBool NoRowsFollow();
|
||||
|
||||
/** @see nsContainerFrame::CreateContinuingFrame */
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
@ -174,7 +175,7 @@ protected:
|
||||
RowGroupReflowState& aReflowState,
|
||||
const nsMargin& aKidMargin);
|
||||
|
||||
void PlaceChild( nsIPresContext* aPresContext,
|
||||
void PlaceChild( nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
@ -197,9 +198,13 @@ protected:
|
||||
* @return true if we successfully reflowed all the mapped children and false
|
||||
* otherwise, e.g. we pushed children to the next in flow
|
||||
*/
|
||||
PRBool ReflowMappedChildren(nsIPresContext* aPresContext,
|
||||
NS_METHOD ReflowMappedChildren(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsSize* aMaxElementSize);
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowFrame * aStartFrame,
|
||||
nsReflowReason aReason,
|
||||
PRBool aDoSiblings);
|
||||
|
||||
/**
|
||||
* Try and pull-up frames from our next-in-flow
|
||||
@ -209,9 +214,10 @@ protected:
|
||||
* @return true if we successfully pulled-up all the children and false
|
||||
* otherwise, e.g. child didn't fit
|
||||
*/
|
||||
PRBool PullUpChildren(nsIPresContext* aPresContext,
|
||||
NS_METHOD PullUpChildren(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsSize* aMaxElementSize);
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
private:
|
||||
nsIAtom *mType;
|
||||
|
@ -6,7 +6,7 @@
|
||||
function insertCaption() {
|
||||
var table = document.getElementsByTagName("TABLE")[0];
|
||||
var caption = document.createElement("CAPTION", null);
|
||||
var text = document.createTextNode("here is the new caption text");
|
||||
var text = document.createTextNode("here is the new caption text\n");
|
||||
caption.appendChild(text);
|
||||
table.appendChild(caption);
|
||||
}
|
||||
@ -25,7 +25,7 @@ function insertColGroup() {
|
||||
colGroup.width=200;
|
||||
colGroup.span=1;
|
||||
table.insertBefore(colGroup, refColGroup);
|
||||
dump("inserted COLGROUP with span=1 width=200 as first colgroup in table");
|
||||
dump("SCRIPT: inserted COLGROUP with span=1 width=200 as first colgroup in table\n");
|
||||
}
|
||||
|
||||
function appendColGroup() {
|
||||
@ -34,13 +34,14 @@ function appendColGroup() {
|
||||
colGroup.width=300;
|
||||
colGroup.span=1;
|
||||
table.appendChild(colGroup);
|
||||
dump("appended COLGROUP with span=1 width=300");
|
||||
dump("SCRIPT: appended COLGROUP with span=1 width=300\n");
|
||||
}
|
||||
|
||||
function deleteColGroup() {
|
||||
var table = document.getElementsByTagName("TABLE")[0];
|
||||
var colGroup = document.getElementsByTagName("COLGROUP")[0];
|
||||
table.removeChild(colGroup);
|
||||
dump("SCRIPT: deleted first COLGROUP\n");
|
||||
}
|
||||
|
||||
|
||||
@ -51,20 +52,21 @@ function insertCol() {
|
||||
col.width=200;
|
||||
col.span=1;
|
||||
table.insertBefore(col, refCol);
|
||||
dump("inserted COL with span=1 width=200 as first col in first col group");
|
||||
dump("SCRIPT: inserted COL with span=1 width=200 as first col in first col group\n");
|
||||
}
|
||||
|
||||
function appendCol() {
|
||||
var table = document.getElementsByTagName("TABLE")[0];
|
||||
var col = document.createElement("COL", null);
|
||||
table.appendChild(col);
|
||||
dump("appended COL with span=1 width=300");
|
||||
dump("SCRIPT: appended COL with span=1 width=300\n");
|
||||
}
|
||||
|
||||
function deleteCol() {
|
||||
var table = document.getElementsByTagName("TABLE")[0];
|
||||
var col = document.getElementsByTagName("COL")[0];
|
||||
table.removeChild(col);
|
||||
dump("SCRIPT: deleted first COL in first COLGROUP\n");
|
||||
}
|
||||
|
||||
|
||||
@ -73,52 +75,110 @@ function insertRowGroup() {
|
||||
var refRowGroup = document.getElementsByTagName("TBODY")[0];
|
||||
var rowGroup = document.createElement("TBODY", null);
|
||||
table.insertBefore(rowGroup, refRowGroup);
|
||||
dump("inserted empty ROWGROUP as first rowgroup in table");
|
||||
dump("SCRIPT: inserted empty ROWGROUP as first rowgroup in table\n");
|
||||
}
|
||||
|
||||
function appendRowGroup() {
|
||||
var table = document.getElementsByTagName("TABLE")[0];
|
||||
var rowGroup = document.createElement("TBODY", null);
|
||||
table.appendChild(rowGroup);
|
||||
dump("appended empty ROWGROUP");
|
||||
dump("SCRIPT: appended empty ROWGROUP\n");
|
||||
}
|
||||
|
||||
function appendRowGroupWithContent() {
|
||||
dump("\nSCRIPT: starting appendRowGroupWithContent\n");
|
||||
var table = document.getElementsByTagName("TABLE")[0];
|
||||
var rowGroup = document.createElement("TBODY", null);
|
||||
var row = document.createElement("TR", null);
|
||||
var cell = document.createElement("TD", null);
|
||||
var text = document.createTextNode("here is content in the cell from the script");
|
||||
var text = document.createTextNode("here is content in the cell from the script appendRowGroupWithContent\n");
|
||||
cell.appendChild(text);
|
||||
row.appendChild(cell);
|
||||
rowGroup.appendChild(row);
|
||||
table.appendChild(rowGroup);
|
||||
dump("appended ROWGROUP with 1 row and 1 cell");
|
||||
dump("SCRIPT: appended ROWGROUP with 1 row and 1 cell\n");
|
||||
}
|
||||
|
||||
function deleteRowGroup() {
|
||||
var table = document.getElementsByTagName("TABLE")[0];
|
||||
var rowGroup = document.getElementsByTagName("TBODY")[0];
|
||||
table.removeChild(rowGroup);
|
||||
dump("SCRIPT: deleted first ROWGROUP\n");
|
||||
}
|
||||
|
||||
|
||||
function insertRow() {
|
||||
var table = document.getElementsByTagName("TABLE")[0];
|
||||
var rg = document.getElementsByTagName("TBODY")[0];
|
||||
var refRow = document.getElementsByTagName("TR")[0];
|
||||
var row = document.createElement("TR", null);
|
||||
table.appendChild(row);
|
||||
rg.insertBefore(row, refRow);
|
||||
dump("SCRIPT: inserted empty ROW as first row in first rowgroup in table\n");
|
||||
}
|
||||
|
||||
function appendRow() {
|
||||
var rg = document.getElementsByTagName("TBODY")[0];
|
||||
var row = document.createElement("TR", null);
|
||||
rg.appendChild(row);
|
||||
dump("SCRIPT: appended empty ROW in first ROWGROUP\n");
|
||||
}
|
||||
|
||||
function appendRowWithContent() {
|
||||
dump("\nSCRIPT: starting appendRowWithContent\n");
|
||||
var rg = document.getElementsByTagName("TBODY")[0];
|
||||
var row = document.createElement("TR", null);
|
||||
var cell = document.createElement("TD", null);
|
||||
var text = document.createTextNode("here is content in the cell from the script appendRowWithContent\n");
|
||||
cell.appendChild(text);
|
||||
row.appendChild(cell);
|
||||
rg.appendChild(row);
|
||||
dump("SCRIPT: appended ROW with 1 cell in first ROWGROUP\n");
|
||||
}
|
||||
|
||||
function deleteRow() {
|
||||
var table = document.getElementsByTagName("TABLE")[0];
|
||||
var rg = document.getElementsByTagName("TBODY")[0];
|
||||
var row = document.getElementsByTagName("TR")[0];
|
||||
table.removeChild(row);
|
||||
rg.removeChild(row);
|
||||
dump("SCRIPT: deleted first ROW in first ROWGROUP\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function insertCell() {
|
||||
var row = document.getElementsByTagName("TR")[0];
|
||||
var refCell = document.getElementsByTagName("TD")[0];
|
||||
var cell = document.createElement("TD", null);
|
||||
row.insertBefore(cell, refCell);
|
||||
dump("SCRIPT: inserted empty Cell as first cell in first row\n");
|
||||
}
|
||||
|
||||
function appendCell() {
|
||||
var row = document.getElementsByTagName("TR")[0];
|
||||
var cell = document.createElement("TD", null);
|
||||
row.appendChild(cell);
|
||||
dump("SCRIPT: appended empty CELL in first ROW\n");
|
||||
}
|
||||
|
||||
function appendCellWithContent() {
|
||||
var row = document.getElementsByTagName("TR")[0];
|
||||
var cell = document.createElement("TD", null);
|
||||
var text = document.createTextNode("here is content in the cell from the script appendRowWithContent\n");
|
||||
cell.appendChild(text);
|
||||
row.appendChild(cell);
|
||||
dump("SCRIPT: appended CELL with text content in first ROW\n");
|
||||
}
|
||||
|
||||
function deleteCell() {
|
||||
var row = document.getElementsByTagName("TR")[0];
|
||||
var cell = document.getElementsByTagName("TD")[0];
|
||||
row.removeChild(cell);
|
||||
dump("SCRIPT: deleted first CELL in first ROW\n");
|
||||
}
|
||||
|
||||
</SCRIPT>
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
all insert buttons currently do an append
|
||||
all delete buttons currently remove the first item of <type> found
|
||||
<table border>
|
||||
<tbody>
|
||||
@ -150,6 +210,12 @@ all delete buttons currently remove the first item of <type> found
|
||||
<INPUT TYPE="button" NAME="Ins Row" VALUE="InsertRow" onClick="insertRow()" width=100>
|
||||
<INPUT TYPE="button" NAME="App Row" VALUE="AppendRow" onClick="appendRow()" width=100>
|
||||
<INPUT TYPE="button" NAME="Del Row" VALUE="DeleteRow" onClick="deleteRow()" width=100>
|
||||
<INPUT TYPE="button" NAME="App Row with content" VALUE="AppendRow with content" onClick="appendRowWithContent()" width=100>
|
||||
<br>
|
||||
<INPUT TYPE="button" NAME="Ins Cell" VALUE="InsertCell" onClick="insertCell()" width=100>
|
||||
<INPUT TYPE="button" NAME="App Cell" VALUE="AppendCell" onClick="appendCell()" width=100>
|
||||
<INPUT TYPE="button" NAME="Del Cell" VALUE="DeleteCell" onClick="deleteCell()" width=100>
|
||||
<INPUT TYPE="button" NAME="App Cell with content" VALUE="AppendCell with content" onClick="appendCellWithContent()" width=100>
|
||||
<br>
|
||||
</form>
|
||||
|
||||
|
@ -103,25 +103,21 @@ PRBool BasicTableLayoutStrategy::IsFixedWidth(const nsStylePosition* aStylePosit
|
||||
}
|
||||
|
||||
|
||||
BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols)
|
||||
BasicTableLayoutStrategy::BasicTableLayoutStrategy(nsTableFrame *aFrame)
|
||||
{
|
||||
NS_ASSERTION(nsnull!=aFrame, "bad frame arg");
|
||||
|
||||
mTableFrame = aFrame;
|
||||
mNumCols = aNumCols;
|
||||
mMinTableWidth=0;
|
||||
mMaxTableWidth=0;
|
||||
mFixedTableWidth=0;
|
||||
|
||||
//cache the value of the cols attribute
|
||||
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
||||
}
|
||||
|
||||
BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
|
||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
nsIFrame *tablePIF=nsnull;
|
||||
@ -132,9 +128,11 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize)
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
// re-init instance variables
|
||||
mNumCols = aNumCols;
|
||||
mMinTableWidth=0;
|
||||
mMaxTableWidth=0;
|
||||
mFixedTableWidth=0;
|
||||
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
||||
|
||||
// Step 1 - assign the width of all fixed-width columns
|
||||
AssignPreliminaryColumnWidths();
|
||||
|
@ -76,15 +76,17 @@ public:
|
||||
|
||||
/** Public constructor.
|
||||
* @paran aFrame the table frame for which this delegate will do layout
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
BasicTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols);
|
||||
BasicTableLayoutStrategy(nsTableFrame *aFrame);
|
||||
|
||||
/** destructor */
|
||||
virtual ~BasicTableLayoutStrategy();
|
||||
|
||||
/** call once every time any table thing changes (content, structure, or style) */
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize);
|
||||
/** call once every time any table thing changes (content, structure, or style)
|
||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols);
|
||||
|
||||
virtual void SetMaxElementSize(nsSize* aMaxElementSize);
|
||||
|
||||
|
@ -35,8 +35,8 @@ static PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebug = PR_FALSE;
|
||||
#endif
|
||||
|
||||
FixedTableLayoutStrategy::FixedTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols)
|
||||
: BasicTableLayoutStrategy(aFrame, aNumCols)
|
||||
FixedTableLayoutStrategy::FixedTableLayoutStrategy(nsTableFrame *aFrame)
|
||||
: BasicTableLayoutStrategy(aFrame)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -44,19 +44,16 @@ public:
|
||||
* @paran aFrame the table frame for which this delegate will do layout
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
FixedTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols);
|
||||
FixedTableLayoutStrategy(nsTableFrame *aFrame);
|
||||
|
||||
/** destructor */
|
||||
virtual ~FixedTableLayoutStrategy();
|
||||
|
||||
/** no need to override Initialize since it calls our AssignPreliminaryColumnWidths */
|
||||
// virtual PRBool Initialize(nsSize* aMaxElementSize);
|
||||
|
||||
/** Called during resize reflow to determine the new column widths
|
||||
* @param aTableStyle - the resolved style for mTableFrame
|
||||
* @param aReflowState - the reflow state for mTableFrame
|
||||
* @param aMaxWidth - the computed max width for columns to fit into
|
||||
*/
|
||||
* @param aReflowState - the reflow state for mTableFrame
|
||||
* @param aMaxWidth - the computed max width for columns to fit into
|
||||
*/
|
||||
virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aMaxWidth);
|
||||
|
@ -30,9 +30,10 @@ class nsITableLayoutStrategy
|
||||
public:
|
||||
|
||||
/** call once every time any table thing changes (content, structure, or style)
|
||||
* @param aMaxElementSize [OUT] the min possible size of the table
|
||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||
* @param aNumCols the total number of columns in the table
|
||||
*/
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize)=0;
|
||||
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols)=0;
|
||||
|
||||
/** compute the max-element-size for the table
|
||||
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
|
||||
|
@ -928,7 +928,8 @@ void nsTableFrame::SetMinColSpanForTable()
|
||||
{ // XXX: must be called ONLY on first-in-flow
|
||||
// set the minColSpan for each column
|
||||
PRInt32 rowCount = mCellMap->GetRowCount();
|
||||
for (PRInt32 colIndex=0; colIndex<mColCount; colIndex++)
|
||||
PRInt32 colCount = mCellMap->GetColCount();
|
||||
for (PRInt32 colIndex=0; colIndex<colCount; colIndex++)
|
||||
{
|
||||
PRInt32 minColSpan;
|
||||
for (PRInt32 rowIndex=0; rowIndex<rowCount; rowIndex++)
|
||||
@ -999,6 +1000,7 @@ void nsTableFrame::AddCellToTable (nsTableRowFrame *aRowFrame,
|
||||
|
||||
NS_METHOD nsTableFrame::ReBuildCellMap()
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: ReBuildCellMap.\n");
|
||||
nsresult rv=NS_OK;
|
||||
nsIFrame *rowGroupFrame=mFirstChild;
|
||||
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(rowGroupFrame))
|
||||
@ -1022,6 +1024,7 @@ NS_METHOD nsTableFrame::ReBuildCellMap()
|
||||
}
|
||||
}
|
||||
}
|
||||
mCellMapValid=PR_TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1562,10 +1565,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
if (PR_TRUE==NeedsReflow(aReflowState, aReflowState.maxSize))
|
||||
{
|
||||
PRBool needsRecalc=PR_FALSE;
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: needs reflow\n");
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: needs reflow\n");
|
||||
if (eReflowReason_Initial!=aReflowState.reason && PR_FALSE==IsCellMapValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug) printf("TIF Reflow: cell map invalid, rebuilding...\n");
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: cell map invalid, rebuilding...\n");
|
||||
if (nsnull!=mCellMap)
|
||||
delete mCellMap;
|
||||
mCellMap = new nsCellMap(0,0);
|
||||
@ -1575,7 +1578,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
if (PR_FALSE==IsFirstPassValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: first pass is invalid, rebuilding...\n");
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, aReflowState.reason);
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, aReflowState.reason, PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
needsRecalc=PR_TRUE;
|
||||
@ -1587,23 +1590,23 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
}
|
||||
if (PR_TRUE==needsRecalc)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: needs recalc.\n");
|
||||
// if we need to recalc, the data stored in the layout strategy is invalid
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: needs recalc. Calling BuildColumnCache...\n");
|
||||
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
RecalcLayoutData(); // Recalculate Layout Dependencies
|
||||
// if we needed to rebuild the column cache, the data stored in the layout strategy is invalid
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, mCellMap->GetColCount());
|
||||
mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below
|
||||
}
|
||||
}
|
||||
if (PR_FALSE==IsColumnWidthsValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||
if (nsnull!=mTableLayoutStrategy)
|
||||
{
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, mCellMap->GetColCount());
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
}
|
||||
@ -1658,7 +1661,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowGroupFrame * aStartingFrame,
|
||||
nsReflowReason aReason)
|
||||
nsReflowReason aReason,
|
||||
PRBool aDoSiblingFrames)
|
||||
{
|
||||
NS_PRECONDITION(aReflowState.frame == this, "bad reflow state");
|
||||
NS_PRECONDITION(aReflowState.parentReflowState->frame == mGeometricParent,
|
||||
@ -1719,7 +1723,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
PRInt32 yCoord = y;
|
||||
if (NS_UNCONSTRAINEDSIZE!=yCoord)
|
||||
yCoord+= topInset;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 1 of frame %p\n", kidFrame);
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 1 of frame %p with reason=%d\n", kidFrame, aReason);
|
||||
ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus);
|
||||
|
||||
// Place the child since some of its content fit in us.
|
||||
@ -1744,6 +1748,8 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
// up all of our available space (or needs us to split).
|
||||
break;
|
||||
}
|
||||
if (PR_FALSE==aDoSiblingFrames)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2185,14 +2191,18 @@ NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext,
|
||||
{
|
||||
nsresult rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState,
|
||||
aStatus, (nsIFrame*)aInsertedFrame, aReplace);
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
PRInt32 rowCount;
|
||||
aInsertedFrame->GetRowCount(rowCount);
|
||||
if (0>rowCount)
|
||||
{ // for now we will assume that if there are rows, then there are cells and we need to recalc table info
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// do a pass-1 layout of all the cells in all the rows of the rowgroup
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState.reflowState, aStatus,
|
||||
aInsertedFrame, eReflowReason_Initial, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2212,10 +2222,12 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
// account for the cells in the rows that are children of aAppendedFrame
|
||||
// this will add the content of the rowgroup to the cell map
|
||||
rv = DidAppendRowGroup((nsTableRowGroupFrame*)aAppendedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// do a pass-1 layout of all the cells in all the rows of the rowgroup
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState.reflowState, aStatus,
|
||||
aAppendedFrame, eReflowReason_Initial);
|
||||
aAppendedFrame, eReflowReason_Initial, PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -2232,17 +2244,11 @@ NS_METHOD nsTableFrame::IR_RowGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowGroupFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aDeletedFrame);
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aDeletedFrame);
|
||||
PRInt32 rowCount=0;
|
||||
aDeletedFrame->GetRowCount(rowCount);
|
||||
if (0>rowCount)
|
||||
{ // for now we will assume that if there are rows, then there are cells and we need to recalc table info
|
||||
InvalidateCellMap();
|
||||
InvalidateColumnCache();
|
||||
}
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
InvalidateColumnWidths();
|
||||
@ -2292,9 +2298,7 @@ NS_METHOD nsTableFrame::IR_UnknownFrameInserted(nsIPresContext& aPresCont
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
nsIFrame *nextSibling = mFirstChild;
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
@ -2555,7 +2559,7 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext& aPresContext,
|
||||
|
||||
nscoord x = aState.leftInset + kidMargin.left;
|
||||
nscoord y = aState.topInset + aState.y + topMargin;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 2 of frame %p\n", kidFrame);
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 2 of frame %p with reason=%d\n", kidFrame, reason);
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) && (desiredSize.height > kidAvailSize.height))
|
||||
@ -2834,10 +2838,10 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
|
||||
nsStyleTable* tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
if (NS_STYLE_TABLE_LAYOUT_FIXED==tableStyle->mLayoutStrategy)
|
||||
mTableLayoutStrategy = new FixedTableLayoutStrategy(this, numCols);
|
||||
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
|
||||
else
|
||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, numCols);
|
||||
mTableLayoutStrategy->Initialize(aMaxElementSize);
|
||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this);
|
||||
mTableLayoutStrategy->Initialize(aMaxElementSize, mCellMap->GetColCount());
|
||||
mColumnWidthsValid=PR_TRUE;
|
||||
}
|
||||
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
|
||||
@ -3070,13 +3074,12 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
{
|
||||
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
|
||||
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
|
||||
NS_ASSERTION(PR_FALSE==mColumnCacheValid, "column cache valid state should be PR_FALSE");
|
||||
nsStyleTable* tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
EnsureColumns(aPresContext);
|
||||
if (nsnull!=mColCache)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF BCB: clearing column cache and cell map column frame cache.\n");
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF BCC: clearing column cache and cell map column frame cache.\n");
|
||||
mCellMap->ClearColumnCache();
|
||||
delete mColCache;
|
||||
}
|
||||
@ -3159,6 +3162,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
}
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF BCC: mColumnCacheValid=PR_TRUE.\n");
|
||||
mColumnCacheValid=PR_TRUE;
|
||||
}
|
||||
|
||||
@ -3167,6 +3171,7 @@ void nsTableFrame::InvalidateColumnWidths()
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mColumnWidthsValid=PR_FALSE;
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: ColWidths invalidated.\n");
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsColumnWidthsValid() const
|
||||
@ -3188,6 +3193,7 @@ void nsTableFrame::InvalidateFirstPassCache()
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mFirstPassValid=PR_FALSE;
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: FirstPass invalidated.\n");
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsColumnCacheValid() const
|
||||
@ -3202,6 +3208,7 @@ void nsTableFrame::InvalidateColumnCache()
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mColumnCacheValid=PR_FALSE;
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: ColCache invalidated.\n");
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsCellMapValid() const
|
||||
@ -3237,6 +3244,7 @@ void nsTableFrame::InvalidateCellMap()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF: CellMap invalidated.\n");
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
|
@ -281,7 +281,8 @@ protected:
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowGroupFrame * aStartingFrame,
|
||||
nsReflowReason aReason);
|
||||
nsReflowReason aReason,
|
||||
PRBool aDoSiblings);
|
||||
|
||||
/** second pass of ResizeReflow.
|
||||
* lays out all table content with aMaxSize(computed_table_width, given_table_height)
|
||||
|
@ -59,7 +59,7 @@ struct RowGroupReflowState {
|
||||
// Running y-offset
|
||||
nscoord y;
|
||||
|
||||
// Flag used to set aMaxElementSize to my first row
|
||||
// Flag used to set maxElementSize to my first row
|
||||
PRBool firstRow;
|
||||
|
||||
// Remember the height of the first row, because it's our maxElementHeight (plus header/footers)
|
||||
@ -188,7 +188,7 @@ void nsTableRowGroupFrame::PaintChildren(nsIPresContext& aPresContext,
|
||||
|
||||
// Collapse child's top margin with previous bottom margin
|
||||
nscoord nsTableRowGroupFrame::GetTopMarginFor(nsIPresContext* aCX,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
const nsMargin& aKidMargin)
|
||||
{
|
||||
nscoord margin;
|
||||
@ -200,8 +200,8 @@ nscoord nsTableRowGroupFrame::GetTopMarginFor(nsIPresContext* aCX,
|
||||
maxPosTopMargin = margin;
|
||||
}
|
||||
|
||||
nscoord maxPos = PR_MAX(aState.prevMaxPosBottomMargin, maxPosTopMargin);
|
||||
nscoord maxNeg = PR_MAX(aState.prevMaxNegBottomMargin, maxNegTopMargin);
|
||||
nscoord maxPos = PR_MAX(aReflowState.prevMaxPosBottomMargin, maxPosTopMargin);
|
||||
nscoord maxNeg = PR_MAX(aReflowState.prevMaxNegBottomMargin, maxNegTopMargin);
|
||||
margin = maxPos - maxNeg;
|
||||
|
||||
return margin;
|
||||
@ -210,12 +210,12 @@ nscoord nsTableRowGroupFrame::GetTopMarginFor(nsIPresContext* aCX,
|
||||
// Position and size aKidFrame and update our reflow state. The origin of
|
||||
// aKidRect is relative to the upper-left origin of our frame, and includes
|
||||
// any left/top margin.
|
||||
void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
void nsTableRowGroupFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
nsSize& aKidMaxElementSize)
|
||||
{
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf ("rowgroup %p: placing row at %d, %d, %d, %d\n",
|
||||
@ -225,18 +225,18 @@ void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
aKidFrame->SetRect(aKidRect);
|
||||
|
||||
// Adjust the running y-offset
|
||||
aState.y += aKidRect.height;
|
||||
aReflowState.y += aKidRect.height;
|
||||
|
||||
// If our height is constrained then update the available height
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
aState.availSize.height -= aKidRect.height;
|
||||
if (PR_FALSE == aReflowState.unconstrainedHeight) {
|
||||
aReflowState.availSize.height -= aKidRect.height;
|
||||
}
|
||||
|
||||
// Update the maximum element size
|
||||
if (PR_TRUE==aState.firstRow)
|
||||
if (PR_TRUE==aReflowState.firstRow)
|
||||
{
|
||||
aState.firstRow = PR_FALSE;
|
||||
aState.firstRowHeight = aKidRect.height;
|
||||
aReflowState.firstRow = PR_FALSE;
|
||||
aReflowState.firstRowHeight = aKidRect.height;
|
||||
if (nsnull != aMaxElementSize) {
|
||||
aMaxElementSize->width = aKidMaxElementSize.width;
|
||||
aMaxElementSize->height = aKidMaxElementSize.height;
|
||||
@ -254,61 +254,64 @@ void nsTableRowGroupFrame::PlaceChild( nsIPresContext* aPresContext,
|
||||
* Reflow the frames we've already created
|
||||
*
|
||||
* @param aPresContext presentation context to use
|
||||
* @param aState current inline state
|
||||
* @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
|
||||
*/
|
||||
PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowFrame * aStartFrame,
|
||||
nsReflowReason aReason,
|
||||
PRBool aDoSiblings)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != mFirstChild, "no children");
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: ReflowMappedChildren\n");
|
||||
nsIFrame* prevKidFrame = nsnull;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
PRBool result = PR_TRUE;
|
||||
PRInt32 debugCounter=0;
|
||||
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
|
||||
nsSize kidAvailSize(aState.availSize);
|
||||
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
nsIFrame* kidFrame;
|
||||
if (nsnull==aStartFrame)
|
||||
kidFrame = mFirstChild;
|
||||
else
|
||||
kidFrame = aStartFrame;
|
||||
for ( ; nsnull != kidFrame; )
|
||||
{
|
||||
nsSize kidAvailSize(aReflowState.availSize);
|
||||
if (0>=kidAvailSize.height)
|
||||
kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
|
||||
nsHTMLReflowMetrics desiredSize(pKidMaxElementSize);
|
||||
desiredSize.width=desiredSize.height=desiredSize.ascent=desiredSize.descent=0;
|
||||
nsReflowStatus status;
|
||||
|
||||
// Get top margin for this kid
|
||||
nsIContentPtr kid;
|
||||
|
||||
kidFrame->GetContent(kid.AssignRef());
|
||||
nsIStyleContextPtr kidSC;
|
||||
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
|
||||
const nsStyleSpacing* kidSpacing = (const nsStyleSpacing*)
|
||||
kidSC->GetStyleData(eStyleStruct_Spacing);
|
||||
const nsStyleSpacing* kidSpacing;
|
||||
kidFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)kidSpacing);
|
||||
nsMargin kidMargin;
|
||||
kidSpacing->CalcMarginFor(this, kidMargin);
|
||||
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMargin);
|
||||
nscoord topMargin = GetTopMarginFor(&aPresContext, aReflowState, kidMargin);
|
||||
nscoord bottomMargin = kidMargin.bottom;
|
||||
|
||||
// Figure out the amount of available size for the child (subtract
|
||||
// off the top margin we are going to apply to it)
|
||||
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||
if (PR_FALSE == aReflowState.unconstrainedHeight) {
|
||||
kidAvailSize.height -= topMargin;
|
||||
}
|
||||
// Subtract off for left and right margin
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
if (PR_FALSE == aReflowState.unconstrainedWidth) {
|
||||
kidAvailSize.width -= kidMargin.left + kidMargin.right;
|
||||
}
|
||||
|
||||
// Reflow the child into the available space
|
||||
nsHTMLReflowState kidReflowState(*aPresContext, kidFrame,
|
||||
aState.reflowState, kidAvailSize);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aReflowState.reflowState,
|
||||
kidAvailSize, aReason);
|
||||
|
||||
if (gsDebug) printf("%p RG reflowing child %d (frame=%p) with avail width = %d\n",
|
||||
this, debugCounter, kidFrame, kidAvailSize.width);
|
||||
ReflowChild(kidFrame, *aPresContext, desiredSize, kidReflowState, status);
|
||||
if (gsDebug) printf("%p RG child %d (frame=%p) returned desired width = %d\n",
|
||||
this, debugCounter, kidFrame, desiredSize.width);
|
||||
if ((PR_TRUE==gsDebug) || (PR_TRUE==gsDebugIR))
|
||||
printf("%p RG reflowing child %p with avail width = %d, reason = %d\n",
|
||||
this, kidFrame, kidAvailSize.width, aReason);
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
if (gsDebug) printf("%p RG child %p returned desired width = %d\n",
|
||||
this, kidFrame, desiredSize.width);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidFrame != mFirstChild) &&
|
||||
@ -321,18 +324,17 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
||||
// Note that if the width is too big that's okay and we allow the
|
||||
// child to extend horizontally outside of the reflow area
|
||||
PushChildren(kidFrame, prevKidFrame);
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Place the child after taking into account it's margin
|
||||
nsRect kidRect (kidMargin.left, aState.y, desiredSize.width, desiredSize.height);
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize,
|
||||
nsRect kidRect (kidMargin.left, aReflowState.y, desiredSize.width, desiredSize.height);
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
kidMaxElementSize);
|
||||
if (bottomMargin < 0) {
|
||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
aReflowState.prevMaxNegBottomMargin = -bottomMargin;
|
||||
} else {
|
||||
aState.prevMaxPosBottomMargin = bottomMargin;
|
||||
aReflowState.prevMaxPosBottomMargin = bottomMargin;
|
||||
}
|
||||
|
||||
// Remember where we just were in case we end up pushing children
|
||||
@ -344,7 +346,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
||||
* otherwise PushChildren and bail.
|
||||
*/
|
||||
// Special handling for incomplete children
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(status)) {
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||
// XXX It's good to assume that we might still have room
|
||||
// even if the child didn't complete (floaters will want this)
|
||||
nsIFrame* kidNextInFlow;
|
||||
@ -355,8 +357,8 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
||||
// create a continuing frame. This hooks the child into the flow.
|
||||
nsIFrame* continuingFrame;
|
||||
nsIStyleContext* kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC);
|
||||
kidFrame->CreateContinuingFrame(*aPresContext, this, kidSC,
|
||||
kidFrame->GetStyleContext(&aPresContext, kidSC);
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC,
|
||||
continuingFrame);
|
||||
NS_RELEASE(kidSC);
|
||||
|
||||
@ -375,47 +377,47 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame);
|
||||
}
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add back in the left and right margins, because one row does not
|
||||
// impact another row's width
|
||||
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||
if (PR_FALSE == aReflowState.unconstrainedWidth) {
|
||||
kidAvailSize.width += kidMargin.left + kidMargin.right;
|
||||
}
|
||||
|
||||
if (PR_FALSE==aDoSiblings)
|
||||
break;
|
||||
|
||||
// Get the next child
|
||||
kidFrame->GetNextSibling(kidFrame);
|
||||
debugCounter++;
|
||||
}
|
||||
|
||||
// Update the child count
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try and pull-up frames from our next-in-flow
|
||||
*
|
||||
* @param aPresContext presentation context to use
|
||||
* @param aState current inline state
|
||||
* @param aReflowState current inline state
|
||||
* @return true if we successfully pulled-up all the children and false
|
||||
* otherwise, e.g. child didn't fit
|
||||
*/
|
||||
PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsSize* aMaxElementSize)
|
||||
NS_METHOD nsTableRowGroupFrame::PullUpChildren(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsTableRowGroupFrame* nextInFlow = (nsTableRowGroupFrame*)mNextInFlow;
|
||||
nsSize kidMaxElementSize;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
nsIFrame* prevKidFrame = LastFrame(mFirstChild);
|
||||
PRBool result = PR_TRUE;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
while (nsnull != nextInFlow) {
|
||||
nsHTMLReflowMetrics kidSize(pKidMaxElementSize);
|
||||
kidSize.width=kidSize.height=kidSize.ascent=kidSize.descent=0;
|
||||
nsReflowStatus status;
|
||||
|
||||
// Get the next child
|
||||
nsIFrame* kidFrame = nextInFlow->mFirstChild;
|
||||
@ -444,31 +446,30 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
|
||||
kidFrame->GetSize(kidFrameSize);
|
||||
kidFrame->IsSplittable(kidIsSplittable);
|
||||
if ((kidFrameSize.height > aState.availSize.height) &&
|
||||
if ((kidFrameSize.height > aReflowState.availSize.height) &&
|
||||
NS_FRAME_IS_NOT_SPLITTABLE(kidIsSplittable)) {
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
nsHTMLReflowState kidReflowState(*aPresContext, kidFrame,
|
||||
aState.reflowState, aState.availSize,
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aReflowState.reflowState, aReflowState.availSize,
|
||||
eReflowReason_Resize);
|
||||
|
||||
ReflowChild(kidFrame, *aPresContext, kidSize, kidReflowState, status);
|
||||
rv = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
if ((kidSize.height > aReflowState.availSize.height) && (nsnull != mFirstChild)) {
|
||||
// The child is too wide to fit in the available space, and it's
|
||||
// not our first child
|
||||
result = PR_FALSE;
|
||||
//result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Place the child
|
||||
//aState.y += topMargin;
|
||||
//aReflowState.y += topMargin;
|
||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
||||
//kidRect.x += kidMol->margin.left;
|
||||
kidRect.y += aState.y;
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize, *pKidMaxElementSize);
|
||||
kidRect.y += aReflowState.y;
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize, *pKidMaxElementSize);
|
||||
|
||||
// Remove the frame from its current parent
|
||||
kidFrame->GetNextSibling(nextInFlow->mFirstChild);
|
||||
@ -492,7 +493,7 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
prevKidFrame = kidFrame;
|
||||
|
||||
// Is the child we just pulled up complete?
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(status)) {
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||
// No the child isn't complete
|
||||
nsIFrame* kidNextInFlow;
|
||||
|
||||
@ -503,8 +504,8 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame;
|
||||
nsIStyleContext* kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC);
|
||||
kidFrame->CreateContinuingFrame(*aPresContext, this, kidSC,
|
||||
kidFrame->GetStyleContext(&aPresContext, kidSC);
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC,
|
||||
continuingFrame);
|
||||
NS_RELEASE(kidSC);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
@ -521,12 +522,12 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
|
||||
|
||||
// If the child isn't complete then it means that we've used up
|
||||
// all of our available space.
|
||||
result = PR_FALSE;
|
||||
//result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -691,10 +692,11 @@ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
|
||||
}
|
||||
|
||||
nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
nscoord aDeltaY)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: AdjustSiblingsAfterReflow\n");
|
||||
nsIFrame* lastKidFrame = aKidFrame;
|
||||
|
||||
if (aDeltaY != 0) {
|
||||
@ -731,7 +733,7 @@ nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext& aP
|
||||
// Update our running y-offset to reflect the bottommost child
|
||||
nsRect rect;
|
||||
lastKidFrame->GetRect(rect);
|
||||
aState.y = rect.YMost();
|
||||
aReflowState.y = rect.YMost();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -771,24 +773,18 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
|
||||
// Reflow the existing frames
|
||||
if (nsnull != mFirstChild) {
|
||||
reflowMappedOK = ReflowMappedChildren(&aPresContext, state, aDesiredSize.maxElementSize);
|
||||
if (PR_FALSE == reflowMappedOK) {
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, state, aStatus,
|
||||
nsnull, aReflowState.reason, PR_TRUE);
|
||||
}
|
||||
|
||||
// Did we successfully reflow our mapped children?
|
||||
if (PR_TRUE == reflowMappedOK) {
|
||||
if (NS_FRAME_COMPLETE==aStatus) {
|
||||
// Any space left?
|
||||
PRInt32 numKids;
|
||||
mContent->ChildCount(numKids);
|
||||
if (state.availSize.height > 0) {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if (!PullUpChildren(&aPresContext, state, aDesiredSize.maxElementSize)) {
|
||||
// We were unable to pull-up all the existing frames from the
|
||||
// next in flow
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
}
|
||||
rv = PullUpChildren(aPresContext, aDesiredSize, state, aStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@ -803,8 +799,6 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
}
|
||||
|
||||
// Return our desired rect
|
||||
//NS_ASSERTION(0<state.firstRowHeight, "illegal firstRowHeight after reflow");
|
||||
//NS_ASSERTION(0<state.y, "illegal height after reflow");
|
||||
aDesiredSize.width = aReflowState.maxSize.width;
|
||||
aDesiredSize.height = state.y;
|
||||
|
||||
@ -824,9 +818,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
this, NS_FRAME_IS_COMPLETE(aStatus)?"Complete":"Not Complete",
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -874,14 +866,14 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
(nsTableRowFrame *)objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -893,7 +885,8 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
rv = IR_RowAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
(nsTableRowFrame *)objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
@ -911,7 +904,7 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
(nsTableRowFrame *)objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -948,16 +941,35 @@ NS_METHOD nsTableRowGroupFrame::IR_RowInserted(nsIPresContext& aPresContext
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
nsTableRowFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_RowInserted\n");
|
||||
nsresult rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState,
|
||||
aStatus, (nsIFrame*)aInsertedFrame, aReplace);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// do a pass-1 layout of all the cells in the inserted row
|
||||
//XXX: check the table frame to see if we can skip this
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aInsertedFrame, eReflowReason_Initial, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
NS_METHOD nsTableRowGroupFrame::DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: DidAppendRow\n");
|
||||
nsresult rv=NS_OK;
|
||||
/* need to make space in the cell map. Remeber that row spans can't cross row groups
|
||||
once the space is made, tell the row to initizalize its children.
|
||||
@ -969,56 +981,97 @@ NS_METHOD nsTableRowGroupFrame::IR_DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
return rv;
|
||||
}
|
||||
|
||||
// support method that tells us if there are any rows in the table after our rows
|
||||
// returns PR_TRUE if there are no rows after ours
|
||||
PRBool nsTableRowGroupFrame::NoRowsFollow()
|
||||
{
|
||||
PRBool result = PR_TRUE;
|
||||
nsIFrame *nextSib=nsnull;
|
||||
GetNextSibling(nextSib);
|
||||
while (nsnull!=nextSib)
|
||||
{
|
||||
const nsStyleDisplay *sibDisplay;
|
||||
nextSib->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)sibDisplay));
|
||||
if ((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == sibDisplay->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == sibDisplay->mDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == sibDisplay->mDisplay))
|
||||
{
|
||||
nsIFrame *childFrame=nsnull;
|
||||
nextSib->FirstChild(childFrame);
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{ // found a row
|
||||
result = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
nextSib->GetNextSibling(nextSib);
|
||||
}
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: NoRowsFollow returning %d\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// since we know we're doing an append here, we can optimize
|
||||
NS_METHOD nsTableRowGroupFrame::IR_RowAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame)
|
||||
nsTableRowFrame * aAppendedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_RowAppended\n");
|
||||
// hook aAppendedFrame into the child list
|
||||
nsIFrame *lastChild = mFirstChild;
|
||||
nsIFrame *nextChild = lastChild;
|
||||
nsIFrame *lastRow = nsnull;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
// remember the last child that is really a row
|
||||
const nsStyleDisplay *childDisplay;
|
||||
nextChild->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
lastRow = nextChild;
|
||||
lastChild = nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aAppendedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
nsresult rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState,
|
||||
aStatus, (nsIFrame*)aAppendedFrame, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
tableFrame->InvalidateFirstPassCache();
|
||||
// the table will see that it's cached info is bogus and rebuild the cell map,
|
||||
// and do a reflow
|
||||
|
||||
#if 0
|
||||
// find the row index of the new row
|
||||
PRInt32 newRowIndex=-1;
|
||||
if (nsnull!=
|
||||
/* we have 2 paths to choose from. If we know that aAppendedFrame is
|
||||
* the last row in the table, we can optimize. Otherwise, we have to
|
||||
* treat it like an insert
|
||||
*/
|
||||
if (PR_TRUE==NoRowsFollow())
|
||||
{ // aAppendedRow is the last row, so do the optimized route
|
||||
// account for the cells in the row aAppendedFrame
|
||||
// this will add the content of the rowgroup to the cell map
|
||||
rv = DidAppendRow(aAppendedFrame);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
lastChild=mFirstChild;
|
||||
nextChild=lastChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
// do a pass1 reflow of the new row
|
||||
//XXX: check the table frame to see if we can skip this
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aAppendedFrame, eReflowReason_Initial, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
// account for the cells in aAppendedFrame
|
||||
nsresult rv = DidAppendRow((nsTableRowFrame*)aAppendedFrame, newRowIndex);
|
||||
else
|
||||
{
|
||||
// do a pass1 reflow of the new row
|
||||
//XXX: check the table frame to see if we can skip this
|
||||
rv = ReflowMappedChildren(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aAppendedFrame, eReflowReason_Initial, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// need to increment the row index of all subsequent rows
|
||||
#endif
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -1027,9 +1080,25 @@ NS_METHOD nsTableRowGroupFrame::IR_RowRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame)
|
||||
nsTableRowFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_RowRemoved\n");
|
||||
nsresult rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
aDeletedFrame);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
tableFrame->InvalidateCellMap();
|
||||
tableFrame->InvalidateColumnCache();
|
||||
|
||||
// if any column widths have to change due to this, rebalance column widths
|
||||
//XXX need to calculate this, but for now just do it
|
||||
tableFrame->InvalidateColumnWidths();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1041,6 +1110,7 @@ NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameInserted(nsIPresContext& aPr
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_UnknownFrameInserted\n");
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
// we have a generic frame that gets inserted but doesn't effect reflow
|
||||
@ -1075,9 +1145,7 @@ NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameInserted(nsIPresContext& aPr
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
nsIFrame *nextSibling=mFirstChild;
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
@ -1091,6 +1159,7 @@ NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameRemoved(nsIPresContext& aPre
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_UnknownFrameRemoved\n");
|
||||
// we have a generic frame that gets removed but doesn't effect reflow
|
||||
// unhook it then ignore it
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: FrameRemoved removing unknown frame type.\n");
|
||||
|
@ -107,22 +107,20 @@ public:
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
nsTableRowFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_RowAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_DidAppendRow(nsTableRowFrame *aRowFrame);
|
||||
nsTableRowFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_RowRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
nsTableRowFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
@ -138,6 +136,9 @@ public:
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
|
||||
NS_IMETHOD DidAppendRow(nsTableRowFrame *aRowFrame);
|
||||
|
||||
PRBool NoRowsFollow();
|
||||
|
||||
/** @see nsContainerFrame::CreateContinuingFrame */
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
@ -174,7 +175,7 @@ protected:
|
||||
RowGroupReflowState& aReflowState,
|
||||
const nsMargin& aKidMargin);
|
||||
|
||||
void PlaceChild( nsIPresContext* aPresContext,
|
||||
void PlaceChild( nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
@ -197,9 +198,13 @@ protected:
|
||||
* @return true if we successfully reflowed all the mapped children and false
|
||||
* otherwise, e.g. we pushed children to the next in flow
|
||||
*/
|
||||
PRBool ReflowMappedChildren(nsIPresContext* aPresContext,
|
||||
NS_METHOD ReflowMappedChildren(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsSize* aMaxElementSize);
|
||||
nsReflowStatus& aStatus,
|
||||
nsTableRowFrame * aStartFrame,
|
||||
nsReflowReason aReason,
|
||||
PRBool aDoSiblings);
|
||||
|
||||
/**
|
||||
* Try and pull-up frames from our next-in-flow
|
||||
@ -209,9 +214,10 @@ protected:
|
||||
* @return true if we successfully pulled-up all the children and false
|
||||
* otherwise, e.g. child didn't fit
|
||||
*/
|
||||
PRBool PullUpChildren(nsIPresContext* aPresContext,
|
||||
NS_METHOD PullUpChildren(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsSize* aMaxElementSize);
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
private:
|
||||
nsIAtom *mType;
|
||||
|
Loading…
Reference in New Issue
Block a user