mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
lots of work for incremental reflow when the target frame is a table frame
This commit is contained in:
parent
e28895d594
commit
0d373afd21
@ -119,6 +119,9 @@ public:
|
||||
*/
|
||||
void AppendColumnFrame(nsTableColFrame *aColFrame);
|
||||
|
||||
/** empty the column frame cache */
|
||||
void ClearColumnCache();
|
||||
|
||||
/** returns PR_TRUE if the row at aRowIndex has any cells that are the result
|
||||
* of a row-spanning cell above it. So, given this table:<BR>
|
||||
* <PRE>
|
||||
@ -227,5 +230,11 @@ inline void nsCellMap::AppendColumnFrame(nsTableColFrame *aColFrame)
|
||||
mColFrames->AppendElement(aColFrame);
|
||||
}
|
||||
|
||||
inline void nsCellMap::ClearColumnCache()
|
||||
{
|
||||
if (nsnull!=mColFrames)
|
||||
mColFrames->Clear();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -52,8 +52,10 @@ nsresult
|
||||
nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
nsIFrame* tableFrame=nsnull;
|
||||
GetGeometricParent(tableFrame);
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
// Process the newly added column frames
|
||||
for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
|
||||
// Set the preliminary values for the column frame
|
||||
@ -74,7 +76,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
|
||||
mColCount+= repeat;
|
||||
((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
|
||||
((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame);
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame);
|
||||
}
|
||||
// colgroup's span attribute is how many columns the group represents
|
||||
// in the absence of any COL children
|
||||
@ -107,7 +109,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
PRInt32 absColIndex = mStartColIndex + colIndex;
|
||||
((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1);
|
||||
((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
|
||||
((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)colFrame);
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)colFrame);
|
||||
|
||||
//hook into list of children
|
||||
if (nsnull==firstImplicitColFrame)
|
||||
@ -132,7 +134,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
}
|
||||
}
|
||||
SetStyleContextForFirstPass(aPresContext);
|
||||
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -233,9 +235,10 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPresContext)
|
||||
{
|
||||
// get the table frame
|
||||
nsIFrame* tableFrame=nsnull;
|
||||
GetGeometricParent(tableFrame);
|
||||
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
// get the style for the table frame
|
||||
nsStyleTable *tableStyle;
|
||||
tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
@ -277,10 +280,10 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPre
|
||||
}
|
||||
colFrame->GetNextSibling(colFrame);
|
||||
}
|
||||
|
||||
mStyleContext->RecalcAutomaticData(&aPresContext);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
@ -270,6 +270,7 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
|
||||
mColCache(nsnull),
|
||||
mTableLayoutStrategy(nsnull),
|
||||
mFirstPassValid(PR_FALSE),
|
||||
mCellMapValid(PR_TRUE),
|
||||
mIsInvariantWidth(PR_FALSE)
|
||||
{
|
||||
mEffectiveColCount = -1; // -1 means uninitialized
|
||||
@ -298,10 +299,43 @@ nsTableFrame::~nsTableFrame()
|
||||
NS_IMETHODIMP
|
||||
nsTableFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
mFirstChild = aChildList;
|
||||
EnsureColumns(aPresContext);
|
||||
return NS_OK;
|
||||
// I know now that I have all my children, so build the cell map
|
||||
nsIFrame *nextRowGroup=mFirstChild;
|
||||
for ( ; nsnull!=nextRowGroup; nextRowGroup->GetNextSibling(nextRowGroup))
|
||||
{
|
||||
const nsStyleDisplay *rowGroupDisplay;
|
||||
nextRowGroup->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowGroupDisplay);
|
||||
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
|
||||
{
|
||||
rv = DidAppendRowGroup((nsTableRowGroupFrame*)nextRowGroup);
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(rv))
|
||||
EnsureColumns(aPresContext);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTableFrame::DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
nsIFrame *nextRow=nsnull;
|
||||
aRowGroupFrame->FirstChild(nextRow);
|
||||
for ( ; nsnull!=nextRow; nextRow->GetNextSibling(nextRow))
|
||||
{
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
nextRow->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
|
||||
{
|
||||
rv = ((nsTableRowFrame *)nextRow)->InitChildren();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* ****** CellMap methods ******* */
|
||||
|
||||
@ -322,14 +356,12 @@ nsTableRowGroupFrame* nsTableFrame::NextRowGroupFrame(nsTableRowGroupFrame* aRow
|
||||
const nsStyleDisplay *display;
|
||||
aRowGroupFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (PR_TRUE==IsRowGroup(display->mDisplay))
|
||||
{ //XXX: assumes content order
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the next frame
|
||||
aRowGroupFrame->GetNextSibling((nsIFrame*&)aRowGroupFrame);
|
||||
}
|
||||
|
||||
return aRowGroupFrame;
|
||||
}
|
||||
|
||||
@ -346,10 +378,6 @@ PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
|
||||
{
|
||||
mColCount += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
|
||||
}
|
||||
else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{ //XXX: assumes content order
|
||||
break;
|
||||
}
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
return mColCount;
|
||||
@ -358,24 +386,10 @@ PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
|
||||
PRInt32 nsTableFrame::GetRowCount ()
|
||||
{
|
||||
PRInt32 rowCount = 0;
|
||||
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_ASSERTION(nsnull!=cellMap, "GetRowCount null cellmap");
|
||||
if (nsnull!=cellMap)
|
||||
return cellMap->GetRowCount();
|
||||
|
||||
nsIFrame *child=mFirstChild;
|
||||
while (nsnull!=child)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
child->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{
|
||||
PRInt32 thisRowCount=0;
|
||||
((nsTableRowGroupFrame *)child)->GetRowCount(thisRowCount);
|
||||
rowCount += thisRowCount;
|
||||
}
|
||||
child->GetNextSibling(child);
|
||||
}
|
||||
rowCount = cellMap->GetRowCount();
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
@ -383,7 +397,7 @@ PRInt32 nsTableFrame::GetRowCount ()
|
||||
PRInt32 nsTableFrame::GetColCount ()
|
||||
{
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_ASSERTION(nsnull!=cellMap, "GetColCount can only be called after cellmap has been created");
|
||||
NS_ASSERTION(nsnull!=cellMap, "GetColCount null cellmap");
|
||||
|
||||
if (nsnull!=cellMap)
|
||||
{
|
||||
@ -396,6 +410,7 @@ PRInt32 nsTableFrame::GetColCount ()
|
||||
void nsTableFrame::SetEffectiveColCount()
|
||||
{
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_ASSERTION(nsnull!=cellMap, "SetEffectiveColCount null cellmap");
|
||||
if (nsnull!=cellMap)
|
||||
{
|
||||
PRInt32 colCount = cellMap->GetColCount();
|
||||
@ -589,7 +604,7 @@ NS_ASSERTION(0<result, "bad effective col span");
|
||||
PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
|
||||
{
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_PRECONDITION (nsnull!=cellMap, "bad call, cellMap not yet allocated.");
|
||||
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
|
||||
PRInt32 result;
|
||||
nsIFrame *tableFrame = this;
|
||||
nsStyleTable *tableStyle=nsnull;
|
||||
@ -601,16 +616,6 @@ PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
|
||||
void nsTableFrame::ResetCellMap ()
|
||||
{
|
||||
// XXX: SEC should this call ResetCellMap on firstInFlow?
|
||||
if (nsnull!=mCellMap)
|
||||
delete mCellMap;
|
||||
mCellMap = nsnull; // for now, will rebuild when needed
|
||||
}
|
||||
|
||||
/** sum the columns represented by all nsTableColGroup objects
|
||||
* if the cell map says there are more columns than this,
|
||||
* add extra implicit columns to the content tree.
|
||||
@ -632,7 +637,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext)
|
||||
PRInt32 actualColumns = 0;
|
||||
nsTableColGroupFrame *lastColGroupFrame = nsnull;
|
||||
nsIFrame * firstRowGroupFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull; // this is the child just before the first row group frame
|
||||
nsIFrame * childFrame=mFirstChild;
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
@ -646,11 +651,14 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext)
|
||||
if (PR_TRUE==gsDebug) printf("EC: found a col group %p\n", lastColGroupFrame);
|
||||
}
|
||||
else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{ // XXX: assumes content order
|
||||
{
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
{
|
||||
firstRowGroupFrame = childFrame;
|
||||
if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
prevSibFrame = childFrame;
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
@ -666,7 +674,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext)
|
||||
nsAutoString colGroupTag;
|
||||
nsHTMLAtoms::colgroup->ToString(colGroupTag);
|
||||
rv = NS_CreateHTMLElement(&lastColGroup, colGroupTag); // ADDREF a: lastColGroup++
|
||||
//XXX mark it as implicit!
|
||||
//XXX: make synthetic
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // add the implicit colgroup to my content
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* colGroupStyleContext =
|
||||
@ -716,7 +724,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext)
|
||||
nsIHTMLContent *col=nsnull;
|
||||
// create an implicit col
|
||||
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
|
||||
//XXX mark the col implicit
|
||||
//XXX: make synthetic
|
||||
lastColGroup->AppendChildTo((nsIContent*)col, PR_FALSE);
|
||||
|
||||
// Create a new col frame
|
||||
@ -759,7 +767,7 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
PRInt32 actualColumns = 0;
|
||||
nsTableColGroupFrame *lastColGroupFrame = nsnull;
|
||||
nsIFrame * firstRowGroupFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull; // this is the child just before the first row group frame
|
||||
nsIFrame * childFrame=mFirstChild;
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
@ -774,10 +782,11 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
break; // we have enough col frames at this point
|
||||
}
|
||||
else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{ // XXX: assumes content order
|
||||
{
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
firstRowGroupFrame = childFrame;
|
||||
break;
|
||||
}
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
prevSibFrame = childFrame;
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
@ -790,6 +799,7 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
nsAutoString colGroupTag;
|
||||
nsHTMLAtoms::colgroup->ToString(colGroupTag);
|
||||
rv = NS_CreateHTMLElement(&lastColGroup, colGroupTag); // ADDREF a: lastColGroup++
|
||||
//XXX: make synthetic
|
||||
//XXX mark it as implicit!
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // add the implicit colgroup to my content
|
||||
// Resolve style for the child
|
||||
@ -837,7 +847,7 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
nsIHTMLContent *col=nsnull;
|
||||
// create an implicit col
|
||||
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
|
||||
//XXX mark the col implicit
|
||||
//XXX: make synthetic
|
||||
lastColGroup->AppendChildTo((nsIContent*)col, PR_FALSE);
|
||||
|
||||
// Create a new col frame
|
||||
@ -868,17 +878,22 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
|
||||
void nsTableFrame::AddColumnFrame (nsTableColFrame *aColFrame)
|
||||
{
|
||||
mCellMap->AppendColumnFrame(aColFrame);
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
|
||||
if (nsnull!=cellMap)
|
||||
cellMap->AppendColumnFrame(aColFrame);
|
||||
}
|
||||
|
||||
/** return the index of the next row that is not yet assigned */
|
||||
PRInt32 nsTableFrame::GetNextAvailRowIndex() const
|
||||
{
|
||||
PRInt32 result=0;
|
||||
if (nsnull!=mCellMap)
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
|
||||
if (nsnull!=cellMap)
|
||||
{
|
||||
result = mCellMap->GetRowCount(); // the next index is the current count
|
||||
mCellMap->GrowToRow(result+1); // expand the cell map to include this new row
|
||||
result = cellMap->GetRowCount(); // the next index is the current count
|
||||
cellMap->GrowToRow(result+1); // expand the cell map to include this new row
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -887,15 +902,17 @@ PRInt32 nsTableFrame::GetNextAvailRowIndex() const
|
||||
PRInt32 nsTableFrame::GetNextAvailColIndex(PRInt32 aRowIndex, PRInt32 aColIndex) const
|
||||
{
|
||||
PRInt32 result=0;
|
||||
if (nsnull!=mCellMap)
|
||||
result = mCellMap->GetNextAvailColIndex(aRowIndex, aColIndex);
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
|
||||
if (nsnull!=cellMap)
|
||||
result = cellMap->GetNextAvailColIndex(aRowIndex, aColIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
nsCellMap * nsTableFrame::GetCellMap()
|
||||
nsCellMap * nsTableFrame::GetCellMap() const
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
if (this!=firstInFlow)
|
||||
@ -951,7 +968,6 @@ void nsTableFrame::AddCellToTable (nsTableRowFrame *aRowFrame,
|
||||
}
|
||||
|
||||
PRInt32 rowIndex;
|
||||
// If we have a cell map reset it; otherwise allocate a new cell map
|
||||
// also determine the index of aRowFrame and set it if necessary
|
||||
if (0==mCellMap->GetRowCount())
|
||||
{ // this is the first time we've ever been called
|
||||
@ -979,6 +995,34 @@ void nsTableFrame::AddCellToTable (nsTableRowFrame *aRowFrame,
|
||||
DumpCellMap ();
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::ReBuildCellMap()
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
nsIFrame *rowGroupFrame=mFirstChild;
|
||||
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(rowGroupFrame))
|
||||
{
|
||||
const nsStyleDisplay *rowGroupDisplay;
|
||||
rowGroupFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowGroupDisplay);
|
||||
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
|
||||
{
|
||||
nsIFrame *rowFrame;
|
||||
rowGroupFrame->FirstChild(rowFrame);
|
||||
for ( ; nsnull!=rowFrame; rowFrame->GetNextSibling(rowFrame))
|
||||
{
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
|
||||
{
|
||||
rv = ((nsTableRowFrame *)rowFrame)->InitChildren();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
void nsTableFrame::DumpCellMap ()
|
||||
@ -1054,20 +1098,20 @@ void nsTableFrame::BuildCellIntoMap (nsTableCellFrame *aCell, PRInt32 aRowIndex,
|
||||
// Setup CellMap for this cell
|
||||
int rowSpan = aCell->GetRowSpan();
|
||||
int colSpan = aCell->GetColSpan();
|
||||
if (gsDebug==PR_TRUE) printf(" BuildCellIntoMap. rowSpan = %d, colSpan = %d\n", rowSpan, colSpan);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: rowSpan = %d, colSpan = %d\n", rowSpan, colSpan);
|
||||
|
||||
// Grow the mCellMap array if we will end up addressing
|
||||
// some new columns.
|
||||
if (mCellMap->GetColCount() < (aColIndex + colSpan))
|
||||
{
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf(" calling GrowCellMap(%d)\n", aColIndex+colSpan);
|
||||
printf("BCIM: calling GrowCellMap(%d)\n", aColIndex+colSpan);
|
||||
GrowCellMap (aColIndex + colSpan);
|
||||
}
|
||||
|
||||
if (mCellMap->GetRowCount() < (aRowIndex+1))
|
||||
{
|
||||
printf("*********************************************** calling GrowToRow(%d)\n", aRowIndex+1);
|
||||
printf("BCIM: calling GrowToRow(%d)\n", aRowIndex+1);
|
||||
mCellMap->GrowToRow(aRowIndex+1);
|
||||
}
|
||||
|
||||
@ -1075,7 +1119,7 @@ void nsTableFrame::BuildCellIntoMap (nsTableCellFrame *aCell, PRInt32 aRowIndex,
|
||||
CellData *data = new CellData ();
|
||||
data->mCell = aCell;
|
||||
data->mRealCell = data;
|
||||
if (gsDebug==PR_TRUE) printf(" calling mCellMap->SetCellAt(data, %d, %d)\n", aRowIndex, aColIndex);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: calling mCellMap->SetCellAt(data, %d, %d)\n", aRowIndex, aColIndex);
|
||||
mCellMap->SetCellAt(data, aRowIndex, aColIndex);
|
||||
|
||||
// Create CellData objects for the rows that this cell spans. Set
|
||||
@ -1084,28 +1128,28 @@ void nsTableFrame::BuildCellIntoMap (nsTableCellFrame *aCell, PRInt32 aRowIndex,
|
||||
// CellData object for each row that we span...
|
||||
if ((1 < rowSpan) || (1 < colSpan))
|
||||
{
|
||||
if (gsDebug==PR_TRUE) printf(" spans\n");
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: spans\n");
|
||||
for (int rowIndex = 0; rowIndex < rowSpan; rowIndex++)
|
||||
{
|
||||
if (gsDebug==PR_TRUE) printf(" rowIndex = %d\n", rowIndex);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: rowIndex = %d\n", rowIndex);
|
||||
int workRow = aRowIndex + rowIndex;
|
||||
if (gsDebug==PR_TRUE) printf(" workRow = %d\n", workRow);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: workRow = %d\n", workRow);
|
||||
for (int colIndex = 0; colIndex < colSpan; colIndex++)
|
||||
{
|
||||
if (gsDebug==PR_TRUE) printf(" colIndex = %d\n", colIndex);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: colIndex = %d\n", colIndex);
|
||||
int workCol = aColIndex + colIndex;
|
||||
if (gsDebug==PR_TRUE) printf(" workCol = %d\n", workCol);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: workCol = %d\n", workCol);
|
||||
CellData *testData = mCellMap->GetCellAt(workRow, workCol);
|
||||
if (nsnull == testData)
|
||||
{
|
||||
CellData *spanData = new CellData ();
|
||||
spanData->mRealCell = data;
|
||||
if (gsDebug==PR_TRUE) printf(" null GetCellFrameAt(%d, %d) so setting to spanData\n", workRow, workCol);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: null GetCellFrameAt(%d, %d) so setting to spanData\n", workRow, workCol);
|
||||
mCellMap->SetCellAt(spanData, workRow, workCol);
|
||||
}
|
||||
else if ((0 < rowIndex) || (0 < colIndex))
|
||||
{ // we overlap, replace existing data, it might be shared
|
||||
if (gsDebug==PR_TRUE) printf(" overlapping Cell from GetCellFrameAt(%d, %d) so setting to spanData\n", workRow, workCol);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: overlapping Cell from GetCellFrameAt(%d, %d) so setting to spanData\n", workRow, workCol);
|
||||
CellData *overlap = new CellData ();
|
||||
overlap->mCell = testData->mCell;
|
||||
overlap->mRealCell = testData->mRealCell;
|
||||
@ -1414,12 +1458,15 @@ NS_METHOD nsTableFrame::Paint(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::NeedsReflow(const nsSize& aMaxSize)
|
||||
PRBool nsTableFrame::NeedsReflow(const nsHTMLReflowState& aReflowState, const nsSize& aMaxSize)
|
||||
{
|
||||
PRBool result = PR_TRUE;
|
||||
if (eReflowReason_Incremental != aReflowState.reason)
|
||||
{ // incremental reflows always need to be reflowed (for now)
|
||||
if (PR_TRUE==mIsInvariantWidth)
|
||||
result = PR_FALSE;
|
||||
// TODO: other cases...
|
||||
// XXX TODO: other optimization cases...
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1509,20 +1556,44 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
rv = IncrementalReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
}
|
||||
|
||||
if (PR_TRUE==NeedsReflow(aReflowState.maxSize))
|
||||
// NeedsReflow and IsFirstPassValid take into account reflow type = Initial_Reflow
|
||||
if (PR_TRUE==NeedsReflow(aReflowState, aReflowState.maxSize))
|
||||
{
|
||||
PRBool needsRecalc=PR_FALSE;
|
||||
if (PR_TRUE==gsDebug) printf("TF Reflow: needs reflow\n");
|
||||
if (eReflowReason_Initial!=aReflowState.reason && PR_FALSE==IsCellMapValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug) printf("TF Reflow: not initial reflow, so resetting cell map.\n");
|
||||
if (nsnull!=mCellMap)
|
||||
delete mCellMap;
|
||||
mCellMap = new nsCellMap(0,0);
|
||||
ReBuildCellMap();
|
||||
needsRecalc=PR_TRUE;
|
||||
}
|
||||
if (PR_FALSE==IsFirstPassValid())
|
||||
{
|
||||
// XXX TROY: we used to rebuild the cellmap here for incremental reflow.
|
||||
// now that the cellmap is built in the constructor
|
||||
// we need to reset the cellmap during incremental reflow before we get here
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TF Reflow: first pass is invalid\n");
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
needsRecalc=PR_TRUE;
|
||||
}
|
||||
if (PR_TRUE==needsRecalc)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TF 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("TF Reflow: Re-init layout strategy\n");
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
}
|
||||
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
RecalcLayoutData(); // Recalculate Layout Dependencies
|
||||
}
|
||||
|
||||
|
||||
if (nsnull==mPrevInFlow)
|
||||
{
|
||||
{ // only do this for a first-in-flow table frame
|
||||
// assign column widths, and assign aMaxElementSize->width
|
||||
BalanceColumnWidths(aPresContext, aReflowState, aReflowState.maxSize,
|
||||
aDesiredSize.maxElementSize);
|
||||
@ -1656,10 +1727,6 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
// Recalculate Layout Dependencies
|
||||
RecalcLayoutData();
|
||||
|
||||
aDesiredSize.width = kidSize.width;
|
||||
mFirstPassValid = PR_TRUE;
|
||||
|
||||
@ -1756,6 +1823,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
@ -1776,7 +1844,10 @@ NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
rv = aReflowState.reflowCommand->GetTarget(target);
|
||||
if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target))
|
||||
{
|
||||
if (this==target)
|
||||
// this is the target if target is either this or the outer table frame containing this inner frame
|
||||
nsIFrame *outerTableFrame=nsnull;
|
||||
GetGeometricParent(outerTableFrame);
|
||||
if ((this==target) || (outerTableFrame==target))
|
||||
rv = IR_TargetIsMe(aPresContext, aDesiredSize, state, aStatus);
|
||||
else
|
||||
{
|
||||
@ -1802,14 +1873,12 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
@ -1826,7 +1895,22 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
}
|
||||
else if (IsRowGroup(childDisplay->mDisplay))
|
||||
{
|
||||
rv = IR_RowGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
@ -1834,9 +1918,6 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
@ -1854,7 +1935,6 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
objectFrame);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
@ -1898,6 +1978,80 @@ NS_METHOD nsTableFrame::IR_ColGroupInserted(nsIPresContext& aPresContext,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::IR_ColGroupAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
/*
|
||||
find where to place colgroup (skipping implicit children?)
|
||||
for every col in the colgroup (including implicit cols due to span attribute)
|
||||
an implicit col from the first implicit colgroup is removed
|
||||
when an implicit colgroups col count goes to 0, it is removed
|
||||
*/
|
||||
/* need to really verify that issynthetic is specified on implicit colgroups and cols */
|
||||
|
||||
|
||||
// build a vector of colgroups. XXX might want to do this as a class thing, so we don't have to rebuild it each time
|
||||
nsVoidArray colGroupList;
|
||||
nsIFrame *childFrame=mFirstChild;
|
||||
nsIFrame *lastChild=mFirstChild;
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
colGroupList.AppendElement((void*)childFrame);
|
||||
}
|
||||
lastChild=childFrame;
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
// append aAppendedFrame
|
||||
if (nsnull!=lastChild)
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
else
|
||||
mFirstChild = aAppendedFrame;
|
||||
|
||||
/* go through the list of colgroups, sucking out implicit columns that are not the result of a span attribute
|
||||
* and replacing them with columns in aAppendedFrame
|
||||
* if the column had an attribute from a cell, be sure to preserve that
|
||||
* if any implicit colgroup becomes empty, destroy it
|
||||
* if any real colgroup becomes empty, we have to keep it
|
||||
* factor the new cols into the column cache
|
||||
* this means having a flag that says whether the col cache needs to be rebuilt or not
|
||||
*/
|
||||
PRInt32 colGroupCount = colGroupList.Count();
|
||||
if (0<colGroupCount)
|
||||
{
|
||||
aAppendedFrame->FirstChild(childFrame);
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *colDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)colDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
|
||||
{ // find an implicit column that is not from a span attribute if there is one and remove it
|
||||
for (PRInt32 colGroupIndex=0; colGroupIndex<colGroupCount; colGroupIndex++)
|
||||
{
|
||||
nsTableColGroupFrame *colGroup = (nsTableColGroupFrame *)(colGroupList.ElementAt(colGroupIndex));
|
||||
// XXX: here's where we yank colGroups if necessary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//InvalidateFirstPassCache(); // for now, redo the first pass reflow
|
||||
// could probably just get away with mTableLayoutStrategy->Initialize(aMaxElementSize);
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
//XXX: what we want to do here is determine if the new COL information changes anything about layout
|
||||
// if not, skip invalidating the first passs
|
||||
// if so, and we can fix the first pass info
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsTableFrame::IR_ColGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
@ -1921,6 +2075,39 @@ NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv;
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
return rv;
|
||||
}
|
||||
|
||||
// since we know we're doing an append here, we can optimize
|
||||
NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame)
|
||||
{
|
||||
// hook aAppendedFrame into the child list
|
||||
nsIFrame *lastChild = mFirstChild;
|
||||
nsIFrame *nextChild = lastChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
lastChild = nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aAppendedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
|
||||
// account for the cells in the rows that are children of aAppendedFrame
|
||||
nsresult rv = DidAppendRowGroup((nsTableRowGroupFrame*)aAppendedFrame);
|
||||
|
||||
// do a pass-1 layout of all the cells in all the rows of the rowgroup
|
||||
InvalidateFirstPassCache();
|
||||
|
||||
// if any column widths have to change due to this, re-init the layout strategy
|
||||
// mTableLayoutStrategy->Initialize(aDesiredSize.aMaxElementSize); //XXX for now, we're just doing the whole enchelada
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2032,7 +2219,7 @@ NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
aReflowState.reflowState,
|
||||
aReflowState.reflowState.maxSize);
|
||||
|
||||
ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Resize the row group frame
|
||||
nsRect kidRect;
|
||||
@ -2160,8 +2347,6 @@ void nsTableFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
{
|
||||
nsMargin borderPadding;
|
||||
const nsStyleSpacing* tableSpacing;
|
||||
// begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED!
|
||||
nsIFrame * parent = nsnull;
|
||||
GetStyleData(eStyleStruct_Spacing , ((nsStyleStruct *&)tableSpacing));
|
||||
tableSpacing->CalcBorderPaddingFor(this, borderPadding);
|
||||
nscoord cellSpacing = GetCellSpacing();
|
||||
@ -2753,13 +2938,18 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
nsReflowStatus& aStatus
|
||||
)
|
||||
{
|
||||
// probably want this assertion : NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
|
||||
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!");
|
||||
nsStyleTable* tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
EnsureColumns(aPresContext);
|
||||
if (nsnull==mColCache)
|
||||
if (nsnull!=mColCache)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF BCB: clearing column cache and cell map column frame cache.\n");
|
||||
mCellMap->ClearColumnCache();
|
||||
delete mColCache;
|
||||
}
|
||||
|
||||
mColCache = new ColumnInfoCache(mColCount);
|
||||
nsIFrame * childFrame = mFirstChild;
|
||||
while (nsnull!=childFrame)
|
||||
@ -2836,14 +3026,9 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
colFrame->GetNextSibling((nsIFrame *&)colFrame);
|
||||
}
|
||||
}
|
||||
else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{ // XXX: assumes content order
|
||||
break; // once we hit a row group, we're done
|
||||
}
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsFirstPassValid() const
|
||||
{
|
||||
@ -2852,6 +3037,48 @@ PRBool nsTableFrame::IsFirstPassValid() const
|
||||
return firstInFlow->mFirstPassValid;
|
||||
}
|
||||
|
||||
void nsTableFrame::InvalidateFirstPassCache()
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mFirstPassValid=PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsCellMapValid() const
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
return firstInFlow->mCellMapValid;
|
||||
}
|
||||
|
||||
void nsTableFrame::InvalidateCellMap()
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mCellMapValid=PR_FALSE;
|
||||
// reset the state in each row
|
||||
nsIFrame *rowGroupFrame=mFirstChild;
|
||||
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(rowGroupFrame))
|
||||
{
|
||||
const nsStyleDisplay *rowGroupDisplay;
|
||||
rowGroupFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowGroupDisplay);
|
||||
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
|
||||
{
|
||||
nsIFrame *rowFrame;
|
||||
rowGroupFrame->FirstChild(rowFrame);
|
||||
for ( ; nsnull!=rowFrame; rowFrame->GetNextSibling(rowFrame))
|
||||
{
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
|
||||
{
|
||||
((nsTableRowFrame *)rowFrame)->ResetInitChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsTableFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
nsIFrame* aParent,
|
||||
@ -3148,25 +3375,44 @@ NS_NewTableFrame(nsIContent* aContent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aOutFrame)
|
||||
NS_METHOD nsTableFrame::GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aTableFrame)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
aOutFrame = nsnull; // initialize out-param
|
||||
aTableFrame = nsnull; // initialize out-param
|
||||
if (nsnull!=aSourceFrame)
|
||||
{
|
||||
nsresult result = aSourceFrame->GetContentParent((nsIFrame *&)aOutFrame);
|
||||
while ((NS_OK==result) && (nsnull!=aOutFrame))
|
||||
nsresult result = aSourceFrame->GetContentParent((nsIFrame *&)aTableFrame);
|
||||
while ((NS_OK==result) && (nsnull!=aTableFrame))
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
aOutFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
aTableFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE == display->mDisplay)
|
||||
{
|
||||
// at this point, aTableFrame could be an outer frame,
|
||||
// to find out, scan it's children for another frame with a table display type
|
||||
// if found, the childFrame must be the inner frame
|
||||
nsresult rv;
|
||||
nsIFrame *childFrame=nsnull;
|
||||
rv = aTableFrame->FirstChild(childFrame);
|
||||
while ((NS_OK==rv) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)childDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE == childDisplay->mDisplay)
|
||||
{
|
||||
aTableFrame = (nsTableFrame *)childFrame;
|
||||
break;
|
||||
result = aOutFrame->GetContentParent((nsIFrame *&)aOutFrame);
|
||||
}
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
break;
|
||||
}
|
||||
result = aTableFrame->GetContentParent((nsIFrame *&)aTableFrame);
|
||||
}
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_UNEXPECTED; // bad source param
|
||||
NS_POSTCONDITION(nsnull!=aOutFrame, "unable to find table parent. aOutFrame null.");
|
||||
NS_POSTCONDITION(nsnull!=aTableFrame, "unable to find table parent. aTableFrame null.");
|
||||
NS_POSTCONDITION(NS_OK==result, "unable to find table parent. result!=NS_OK");
|
||||
return result;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
PRBool IsNested(const nsHTMLReflowState& aReflowState, nsStylePosition *& aPosition) const;
|
||||
|
||||
/** helper method to find the table parent of any table frame object */
|
||||
static NS_METHOD GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aOutFrame);
|
||||
static NS_METHOD GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aTableFrame);
|
||||
|
||||
/** helper method for getting the width of the table's containing block */
|
||||
static nscoord GetTableContainerWidth(const nsHTMLReflowState& aState);
|
||||
@ -97,6 +97,11 @@ public:
|
||||
|
||||
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
|
||||
/** complete the append of aRowGroupFrame to the table
|
||||
* this builds the cell map
|
||||
*/
|
||||
NS_IMETHOD DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFrame);
|
||||
|
||||
/** @see nsIFrame::Paint */
|
||||
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
@ -315,6 +320,12 @@ protected:
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_ColGroupAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_ColGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
@ -328,6 +339,12 @@ protected:
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_RowGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
@ -414,11 +431,16 @@ protected:
|
||||
nscoord aMaxHeight);
|
||||
|
||||
/** given the new parent size, do I really need to do a reflow? */
|
||||
virtual PRBool NeedsReflow(const nsSize& aMaxSize);
|
||||
virtual PRBool NeedsReflow(const nsHTMLReflowState& aReflowState,
|
||||
const nsSize& aMaxSize);
|
||||
|
||||
/** returns PR_TRUE if the cached pass 1 data is still valid */
|
||||
virtual PRBool IsFirstPassValid() const;
|
||||
|
||||
public:
|
||||
virtual void InvalidateFirstPassCache();
|
||||
|
||||
protected:
|
||||
/** do post processing to setting up style information for the frame */
|
||||
NS_IMETHOD DidSetStyleContext(nsIPresContext& aPresContext);
|
||||
|
||||
@ -431,16 +453,24 @@ protected:
|
||||
*/
|
||||
virtual void GrowCellMap(PRInt32 aColCount);
|
||||
|
||||
/** returns PR_TRUE if the cached pass 1 data is still valid */
|
||||
virtual PRBool IsCellMapValid() const;
|
||||
|
||||
public:
|
||||
/** ResetCellMap is called when the cell structure of the table is changed.
|
||||
* Call with caution, only when changing the structure of the table such as
|
||||
* inserting or removing rows, changing the rowspan or colspan attribute of a cell, etc.
|
||||
*/
|
||||
virtual void ResetCellMap ();
|
||||
virtual void InvalidateCellMap();
|
||||
|
||||
protected:
|
||||
/** iterates all child frames and creates a new cell map */
|
||||
NS_IMETHOD ReBuildCellMap();
|
||||
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
virtual nsCellMap *GetCellMap();
|
||||
virtual nsCellMap *GetCellMap() const;
|
||||
|
||||
/** for debugging only
|
||||
* prints out information about the cell map
|
||||
@ -559,6 +589,7 @@ private:
|
||||
PRInt32 mColumnWidthsLength; // the number of column lengths this frame has allocated
|
||||
PRBool mColumnWidthsSet; // PR_TRUE if column widths have been set at least once
|
||||
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit
|
||||
PRBool mCellMapValid; // PR_TRUE if cell map data is still legit
|
||||
PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change
|
||||
PRInt32 mColCount; // the number of columns in this table
|
||||
PRInt32 mEffectiveColCount; // the number of columns in this table adjusted for weird table attributes
|
||||
|
@ -132,11 +132,11 @@ NS_METHOD nsTableOuterFrame::Paint(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsTableOuterFrame::NeedsReflow(const nsSize& aMaxSize)
|
||||
PRBool nsTableOuterFrame::NeedsReflow(const nsHTMLReflowState& aReflowState, const nsSize& aMaxSize)
|
||||
{
|
||||
PRBool result=PR_TRUE;
|
||||
if (nsnull!=mInnerTableFrame)
|
||||
result = ((nsTableFrame *)mInnerTableFrame)->NeedsReflow(aMaxSize);
|
||||
result = ((nsTableFrame *)mInnerTableFrame)->NeedsReflow(aReflowState, aMaxSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ protected:
|
||||
* or if the table style attributes or parent max height/width have
|
||||
* changed.
|
||||
*/
|
||||
PRBool NeedsReflow(const nsSize& aMaxSize);
|
||||
PRBool NeedsReflow(const nsHTMLReflowState& aReflowState, const nsSize& aMaxSize);
|
||||
|
||||
void PlaceChild(OuterTableReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
|
@ -39,10 +39,10 @@ NS_DEF_PTR(nsIStyleContext);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gsDebug = PR_FALSE;
|
||||
//#define NOISY
|
||||
//#define NOISY_FLOW
|
||||
static PRBool gsDebugIR = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
#endif
|
||||
|
||||
/* ----------- RowReflowState ---------- */
|
||||
@ -88,7 +88,8 @@ nsTableRowFrame::nsTableRowFrame(nsIContent* aContent,
|
||||
mTallestCell(0),
|
||||
mCellMaxTopMargin(0),
|
||||
mCellMaxBottomMargin(0),
|
||||
mMinRowSpan(1)
|
||||
mMinRowSpan(1),
|
||||
mInitializedChildren(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -100,13 +101,29 @@ NS_IMETHODIMP
|
||||
nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
mFirstChild = aChildList;
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InitChildren(PRInt32 aRowIndex)
|
||||
{
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
// each child cell can only be added to the table one time.
|
||||
// for now, we remember globally whether we've added all or none
|
||||
if (PR_FALSE==mInitializedChildren)
|
||||
{
|
||||
result = nsTableFrame::GetTableFrame(this, table);
|
||||
if ((NS_OK==result) && (table != nsnull))
|
||||
{
|
||||
SetRowIndex(table->GetNextAvailRowIndex());
|
||||
mInitializedChildren=PR_TRUE;
|
||||
PRInt32 rowIndex;
|
||||
if (-1==aRowIndex)
|
||||
rowIndex = table->GetNextAvailRowIndex();
|
||||
else
|
||||
rowIndex = aRowIndex;
|
||||
SetRowIndex(rowIndex);
|
||||
PRInt32 colIndex = 0;
|
||||
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame))
|
||||
{
|
||||
@ -142,6 +159,7 @@ nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -346,7 +364,7 @@ void nsTableRowFrame::FixMinCellHeight(nsTableFrame *aTableFrame)
|
||||
// aKidRect is relative to the upper-left origin of our frame, and includes
|
||||
// any left/top margin.
|
||||
void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
RowReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
@ -360,10 +378,10 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
aKidFrame->SetRect(aKidRect);
|
||||
|
||||
// update the running total for the row width
|
||||
aState.x += aKidRect.width;
|
||||
aReflowState.x += aKidRect.width;
|
||||
|
||||
// Update the maximum element size
|
||||
PRInt32 rowSpan = aState.tableFrame->GetEffectiveRowSpan(mRowIndex,
|
||||
PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan(mRowIndex,
|
||||
((nsTableCellFrame*)aKidFrame));
|
||||
if (nsnull != aMaxElementSize)
|
||||
{
|
||||
@ -377,18 +395,18 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
if (mMinRowSpan == rowSpan)
|
||||
{
|
||||
// Update maxCellHeight
|
||||
if (aKidRect.height > aState.maxCellHeight)
|
||||
aState.maxCellHeight = aKidRect.height;
|
||||
if (aKidRect.height > aReflowState.maxCellHeight)
|
||||
aReflowState.maxCellHeight = aKidRect.height;
|
||||
|
||||
// Update maxCellVertSpace
|
||||
nsMargin margin;
|
||||
|
||||
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK)
|
||||
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK)
|
||||
{
|
||||
nscoord height = aKidRect.height + margin.top + margin.bottom;
|
||||
|
||||
if (height > aState.maxCellVertSpace)
|
||||
aState.maxCellVertSpace = height;
|
||||
if (height > aReflowState.maxCellVertSpace)
|
||||
aReflowState.maxCellVertSpace = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -398,7 +416,7 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
* changed. Reflows all the existing table cell frames
|
||||
*/
|
||||
nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
RowReflowState& aReflowState,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
if (nsnull == mFirstChild)
|
||||
@ -410,7 +428,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
&kidMaxElementSize : nsnull;
|
||||
nscoord maxCellTopMargin = 0;
|
||||
nscoord maxCellBottomMargin = 0;
|
||||
nscoord cellSpacing = aState.tableFrame->GetCellSpacing();
|
||||
nscoord cellSpacing = aReflowState.tableFrame->GetCellSpacing();
|
||||
PRInt32 cellColSpan=1; // must be defined here so it's set properly for non-cell kids
|
||||
if (PR_TRUE==gsDebug) printf("%p: RR\n", this);
|
||||
// Reflow each of our existing cell frames
|
||||
@ -421,7 +439,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
|
||||
{
|
||||
nsMargin kidMargin;
|
||||
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
maxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > maxCellBottomMargin)
|
||||
@ -434,31 +452,31 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
{ // if this cell is not immediately adjacent to the previous cell, factor in missing col info
|
||||
for (PRInt32 colIndex=prevColIndex+1; colIndex<cellColIndex; colIndex++)
|
||||
{
|
||||
aState.x += aState.tableFrame->GetColumnWidth(colIndex);
|
||||
aState.x += cellSpacing;
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
aReflowState.x += cellSpacing;
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" in loop, aState.x set to %d from cellSpacing %d and col width\n",
|
||||
aState.x, aState.tableFrame->GetColumnWidth(colIndex), cellSpacing);
|
||||
printf(" in loop, aReflowState.x set to %d from cellSpacing %d and col width\n",
|
||||
aReflowState.x, aReflowState.tableFrame->GetColumnWidth(colIndex), cellSpacing);
|
||||
}
|
||||
}
|
||||
aState.x += cellSpacing;
|
||||
if (PR_TRUE==gsDebug) printf(" past loop, aState.x set to %d\n", aState.x);
|
||||
aReflowState.x += cellSpacing;
|
||||
if (PR_TRUE==gsDebug) printf(" past loop, aReflowState.x set to %d\n", aReflowState.x);
|
||||
|
||||
// at this point, we know the column widths.
|
||||
// so we get the avail width from the known column widths
|
||||
cellColSpan = aState.tableFrame->GetEffectiveColSpan(((nsTableCellFrame *)kidFrame)->GetColIndex(),
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(((nsTableCellFrame *)kidFrame)->GetColIndex(),
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
|
||||
{
|
||||
availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
availWidth += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
if (numColSpan != 0)
|
||||
{
|
||||
availWidth += cellSpacing;
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" in loop, availWidth set to %d from colIndex %d width %d and cellSpacing\n",
|
||||
availWidth, cellColIndex, aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan), cellSpacing);
|
||||
availWidth, cellColIndex, aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan), cellSpacing);
|
||||
}
|
||||
if (PR_TRUE==gsDebug) printf(" availWidth for this cell is %d\n", availWidth);
|
||||
|
||||
@ -478,7 +496,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
|
||||
// Reflow the child
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aState.reflowState, kidAvailSize,
|
||||
aReflowState.reflowState, kidAvailSize,
|
||||
eReflowReason_Resize);
|
||||
if (gsDebug) printf ("%p RR: avail=%d\n", this, availWidth);
|
||||
nsReflowStatus status;
|
||||
@ -545,12 +563,12 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
// end special Nav4 compatibility code
|
||||
|
||||
// Place the child
|
||||
nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
if (PR_TRUE==gsDebug) printf(" past PlaceChild, aState.x set to %d\n", aState.x);
|
||||
if (PR_TRUE==gsDebug) printf(" past PlaceChild, aReflowState.x set to %d\n", aReflowState.x);
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
@ -558,27 +576,27 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
// if this was the last child, and it had a colspan>1, add in the cellSpacing for the colspan
|
||||
// if the last kid wasn't a colspan, then we still have the colspan of the last real cell
|
||||
if ((nsnull==kidFrame) && (cellColSpan>1))
|
||||
aState.x += cellSpacing;
|
||||
aReflowState.x += cellSpacing;
|
||||
}
|
||||
|
||||
SetMaxChildHeight(aState.maxCellHeight,maxCellTopMargin, maxCellBottomMargin); // remember height of tallest child who doesn't have a row span
|
||||
SetMaxChildHeight(aReflowState.maxCellHeight,maxCellTopMargin, maxCellBottomMargin); // remember height of tallest child who doesn't have a row span
|
||||
|
||||
// Return our desired size. Note that our desired width is just whatever width
|
||||
// we were given by the row group frame
|
||||
aDesiredSize.width = aState.x;
|
||||
aDesiredSize.height = aState.maxCellVertSpace;
|
||||
aDesiredSize.width = aReflowState.x;
|
||||
aDesiredSize.height = aReflowState.maxCellVertSpace;
|
||||
|
||||
if (gsDebug)
|
||||
printf("rr -- row %p width = %d from maxSize %d\n",
|
||||
this, aDesiredSize.width, aState.reflowState.maxSize.width);
|
||||
this, aDesiredSize.width, aReflowState.reflowState.maxSize.width);
|
||||
|
||||
if (aDesiredSize.width > aState.reflowState.maxSize.width)
|
||||
if (aDesiredSize.width > aReflowState.reflowState.maxSize.width)
|
||||
{
|
||||
printf ("%p error case, desired width = %d, maxSize=%d\n",
|
||||
this, aDesiredSize.width, aState.reflowState.maxSize.width);
|
||||
this, aDesiredSize.width, aReflowState.reflowState.maxSize.width);
|
||||
fflush (stdout);
|
||||
}
|
||||
NS_ASSERTION(aDesiredSize.width <= aState.reflowState.maxSize.width, "row calculated to be too wide.");
|
||||
NS_ASSERTION(aDesiredSize.width <= aReflowState.reflowState.maxSize.width, "row calculated to be too wide.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -588,7 +606,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
*/
|
||||
nsresult
|
||||
nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
RowReflowState& aReflowState,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
// Place our children, one at a time, until we are out of children
|
||||
@ -622,7 +640,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
nsMargin margin;
|
||||
nscoord topMargin = 0;
|
||||
|
||||
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
|
||||
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
|
||||
{
|
||||
topMargin = margin.top;
|
||||
}
|
||||
@ -647,7 +665,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
}
|
||||
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aState.reflowState, kidAvailSize,
|
||||
aReflowState.reflowState, kidAvailSize,
|
||||
eReflowReason_Initial);
|
||||
|
||||
if (gsDebug) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width);
|
||||
@ -677,17 +695,17 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
// Place the child
|
||||
x += margin.left;
|
||||
nsRect kidRect(x, topMargin, kidSize.width, kidSize.height);
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
&kidMaxElementSize);
|
||||
x += kidSize.width + margin.right;
|
||||
}
|
||||
}
|
||||
|
||||
SetMaxChildHeight(aState.maxCellHeight, maxTopMargin, maxBottomMargin); // remember height of tallest child who doesn't have a row span
|
||||
SetMaxChildHeight(aReflowState.maxCellHeight, maxTopMargin, maxBottomMargin); // remember height of tallest child who doesn't have a row span
|
||||
|
||||
// Return our desired size
|
||||
aDesiredSize.width = x;
|
||||
aDesiredSize.height = aState.maxCellVertSpace;
|
||||
aDesiredSize.height = aReflowState.maxCellVertSpace;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -700,7 +718,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
// - maxVertCellSpace
|
||||
// - x
|
||||
nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
RowReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
nscoord& aMaxCellTopMargin,
|
||||
nscoord& aMaxCellBottomMargin)
|
||||
@ -710,8 +728,8 @@ nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
// Walk the list of children looking for aKidFrame. While we're at
|
||||
// it get the maxCellHeight and maxVertCellSpace for all the
|
||||
// frames except aKidFrame
|
||||
// nsIFrame* prevKidFrame = nsnull;
|
||||
for (nsIFrame* frame = mFirstChild; nsnull != frame;) {
|
||||
for (nsIFrame* frame = mFirstChild; nsnull != frame;)
|
||||
{
|
||||
const nsStyleDisplay *kidDisplay;
|
||||
frame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
|
||||
@ -719,13 +737,13 @@ nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
if (frame != aKidFrame) {
|
||||
// Update the max top and bottom margins
|
||||
nsMargin kidMargin;
|
||||
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, kidMargin);
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, kidMargin);
|
||||
if (kidMargin.top > aMaxCellTopMargin)
|
||||
aMaxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > aMaxCellBottomMargin)
|
||||
aMaxCellBottomMargin = kidMargin.bottom;
|
||||
|
||||
PRInt32 rowSpan = aState.tableFrame->GetEffectiveRowSpan(mRowIndex, ((nsTableCellFrame *)frame));
|
||||
PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan(mRowIndex, ((nsTableCellFrame *)frame));
|
||||
if (mMinRowSpan == rowSpan) {
|
||||
// Get the cell's desired height the last time it was reflowed
|
||||
nsSize desiredSize = ((nsTableCellFrame *)frame)->GetDesiredSize();
|
||||
@ -751,18 +769,18 @@ nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
desiredSize.height = specifiedHeight;
|
||||
|
||||
// Update maxCellHeight
|
||||
if (desiredSize.height > aState.maxCellHeight) {
|
||||
aState.maxCellHeight = desiredSize.height;
|
||||
if (desiredSize.height > aReflowState.maxCellHeight) {
|
||||
aReflowState.maxCellHeight = desiredSize.height;
|
||||
}
|
||||
|
||||
// Update maxCellVertHeight
|
||||
nsMargin margin;
|
||||
|
||||
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, margin) == NS_OK)
|
||||
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, margin) == NS_OK)
|
||||
{
|
||||
nscoord height = desiredSize.height + margin.top + margin.bottom;
|
||||
if (height > aState.maxCellVertSpace) {
|
||||
aState.maxCellVertSpace = height;
|
||||
if (height > aReflowState.maxCellVertSpace) {
|
||||
aReflowState.maxCellVertSpace = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -775,44 +793,294 @@ nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the frame that precedes aKidFrame
|
||||
// prevKidFrame = frame;
|
||||
frame->GetNextSibling(frame);
|
||||
}
|
||||
|
||||
// Update the running x-offset based on the frame's current x-origin
|
||||
nsPoint origin;
|
||||
aKidFrame->GetOrigin(origin);
|
||||
aState.x = origin.x;
|
||||
aReflowState.x = origin.x;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nsresult status;
|
||||
|
||||
// XXX Deal with the case where the reflow command is targeted at us
|
||||
nsIFrame* target;
|
||||
aState.reflowState.reflowCommand->GetTarget(target);
|
||||
if (this == target) {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
NS_METHOD nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRF IR: IncrementalReflow\n");
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// determine if this frame is the target or not
|
||||
nsIFrame *target=nsnull;
|
||||
rv = aReflowState.reflowState.reflowCommand->GetTarget(target);
|
||||
if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target))
|
||||
{
|
||||
if (this==target)
|
||||
rv = IR_TargetIsMe(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
else
|
||||
{
|
||||
// Get the next frame in the reflow chain
|
||||
nsIFrame* nextFrame;
|
||||
aReflowState.reflowState.reflowCommand->GetNext(nextFrame);
|
||||
rv = IR_TargetIsChild(aPresContext, aDesiredSize, aReflowState, aStatus, nextFrame);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get the next frame in the reflow chain
|
||||
nsIFrame* kidFrame;
|
||||
aState.reflowState.reflowCommand->GetNext(kidFrame);
|
||||
NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_FRAME_COMPLETE;
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: StyleChanged not implemented.\n");
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::ContentChanged :
|
||||
NS_ASSERTION(PR_FALSE, "illegal reflow type: ContentChanged");
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::PullupReflow:
|
||||
case nsIReflowCommand::PushReflow:
|
||||
case nsIReflowCommand::CheckPullupReflow :
|
||||
case nsIReflowCommand::UserDefined :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_CellInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_DidAppendCell(nsTableRowFrame *aRowFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// since we know we're doing an append here, we can optimize
|
||||
NS_METHOD nsTableRowFrame::IR_CellAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
// 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 cell
|
||||
const nsStyleDisplay *childDisplay;
|
||||
nextChild->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
lastRow = nextChild;
|
||||
lastChild = nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aAppendedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
|
||||
aReflowState.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 col index of the new cell
|
||||
|
||||
// account for the new cell
|
||||
nsresult rv = DidAppendCell((nsTableCellFrame*)aAppendedFrame);
|
||||
|
||||
// need to increment the row index of all subsequent rows
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_CellRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//XXX: handle aReplace
|
||||
NS_METHOD nsTableRowFrame::IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
// we have a generic frame that gets inserted but doesn't effect reflow
|
||||
// hook it up then ignore it
|
||||
if (nsIReflowCommand::FrameAppended==type)
|
||||
{ // frameAppended reflow -- find the last child and make aInsertedFrame its next sibling
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: FrameAppended adding unknown frame type.\n");
|
||||
nsIFrame *lastChild=mFirstChild;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
lastChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aInsertedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aInsertedFrame);
|
||||
}
|
||||
else
|
||||
{ // frameInserted reflow -- hook up aInsertedFrame as prevSibling's next sibling,
|
||||
// and be sure to hook in aInsertedFrame's nextSibling (from prevSibling)
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: FrameInserted adding unknown frame type.\n");
|
||||
nsIFrame *prevSibling=nsnull;
|
||||
nsresult rv = aReflowState.reflowState.reflowCommand->GetPrevSiblingFrame(prevSibling);
|
||||
if (NS_SUCCEEDED(rv) && (nsnull!=prevSibling))
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
prevSibling->GetNextSibling(nextSibling);
|
||||
prevSibling->SetNextSibling(aInsertedFrame);
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
}
|
||||
return NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame)
|
||||
{
|
||||
// we have a generic frame that gets removed but doesn't effect reflow
|
||||
// unhook it then ignore it
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: FrameRemoved removing unknown frame type.\n");
|
||||
nsIFrame *prevChild=nsnull;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nextChild!=aRemovedFrame)
|
||||
{
|
||||
prevChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
nextChild=nsnull;
|
||||
aRemovedFrame->GetNextSibling(nextChild);
|
||||
if (nsnull==prevChild) // objectFrame was first child
|
||||
mFirstChild = nextChild;
|
||||
else
|
||||
prevChild->SetNextSibling(nextChild);
|
||||
return NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame)
|
||||
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
const nsStyleDisplay *childDisplay;
|
||||
aNextFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
// Recover our reflow state
|
||||
nscoord maxCellTopMargin, maxCellBottomMargin;
|
||||
RecoverState(aPresContext, aState, kidFrame, maxCellTopMargin, maxCellBottomMargin);
|
||||
RecoverState(aPresContext, aReflowState, aNextFrame, maxCellTopMargin, maxCellBottomMargin);
|
||||
|
||||
// Get the frame's margins
|
||||
nsMargin kidMargin;
|
||||
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aNextFrame, kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
maxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > maxCellBottomMargin)
|
||||
@ -820,13 +1088,13 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
|
||||
// At this point, we know the column widths. Get the available width
|
||||
// from the known column widths
|
||||
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
|
||||
PRInt32 cellColSpan = aState.tableFrame->GetEffectiveColSpan(((nsTableCellFrame *)kidFrame)->GetColIndex(),
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
PRInt32 cellColIndex = ((nsTableCellFrame *)aNextFrame)->GetColIndex();
|
||||
PRInt32 cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(((nsTableCellFrame *)aNextFrame)->GetColIndex(),
|
||||
((nsTableCellFrame *)aNextFrame));
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan = 0; numColSpan < cellColSpan; numColSpan++)
|
||||
{
|
||||
availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
availWidth += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
if (0<numColSpan)
|
||||
{
|
||||
availWidth += kidMargin.right;
|
||||
@ -843,14 +1111,14 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
// Pass along the reflow command
|
||||
nsSize kidMaxElementSize;
|
||||
nsHTMLReflowMetrics desiredSize(&kidMaxElementSize);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aState.reflowState,
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aNextFrame, aReflowState.reflowState,
|
||||
kidAvailSize);
|
||||
|
||||
// XXX Unfortunately we need to reflow the child several times.
|
||||
// The first time is for the incremental reflow command. We can't pass in
|
||||
// a max width of NS_UNCONSTRAINEDSIZE, because the max width must match
|
||||
// the width of the previous reflow...
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Now do the regular pass 1 reflow and gather the max width and max element
|
||||
// size.
|
||||
@ -859,10 +1127,10 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
kidReflowState.reason = eReflowReason_Resize;
|
||||
kidReflowState.reflowCommand = nsnull;
|
||||
kidReflowState.maxSize.width = NS_UNCONSTRAINEDSIZE;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
if (gsDebug)
|
||||
printf ("TR %p for cell %p Incremental Reflow: desired=%d, MES=%d\n",
|
||||
this, kidFrame, desiredSize.width, kidMaxElementSize.width);
|
||||
this, aNextFrame, desiredSize.width, kidMaxElementSize.width);
|
||||
// Update the cell layout data.
|
||||
//XXX: this is a hack, shouldn't it be the case that a min size is
|
||||
// never larger than a desired size?
|
||||
@ -870,13 +1138,13 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
desiredSize.width = kidMaxElementSize.width;
|
||||
if (kidMaxElementSize.height>desiredSize.height)
|
||||
desiredSize.height = kidMaxElementSize.height;
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(desiredSize);
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
|
||||
((nsTableCellFrame *)aNextFrame)->SetPass1DesiredSize(desiredSize);
|
||||
((nsTableCellFrame *)aNextFrame)->SetPass1MaxElementSize(kidMaxElementSize);
|
||||
|
||||
// Now reflow the cell again this time constraining the width
|
||||
// XXX Ignore for now the possibility that the column width has changed...
|
||||
kidReflowState.maxSize.width = availWidth;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Place the child after taking into account it's margin and attributes
|
||||
// XXX We need to ask the table (or the table layout strategy) if the column
|
||||
@ -885,7 +1153,7 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nscoord specifiedHeight = 0;
|
||||
nscoord cellHeight = desiredSize.height;
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(&aPresContext, kidSC.AssignRef());
|
||||
aNextFrame->GetStyleContext(&aPresContext, kidSC.AssignRef());
|
||||
const nsStylePosition* kidPosition = (const nsStylePosition*)
|
||||
kidSC->GetStyleData(eStyleStruct_Position);
|
||||
switch (kidPosition->mHeight.GetUnit()) {
|
||||
@ -906,30 +1174,35 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
// begin special Nav4 compatibility code
|
||||
if (0==cellWidth)
|
||||
{
|
||||
cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
|
||||
cellWidth = aReflowState.tableFrame->GetColumnWidth(cellColIndex);
|
||||
}
|
||||
// end special Nav4 compatibility code
|
||||
|
||||
// Now place the child
|
||||
nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
PlaceChild(aPresContext, aReflowState, aNextFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
&kidMaxElementSize);
|
||||
|
||||
SetMaxChildHeight(aState.maxCellHeight, maxCellTopMargin, maxCellBottomMargin);
|
||||
SetMaxChildHeight(aReflowState.maxCellHeight, maxCellTopMargin, maxCellBottomMargin);
|
||||
|
||||
// Return our desired size. Note that our desired width is just whatever width
|
||||
// we were given by the row group frame
|
||||
aDesiredSize.width = aState.availSize.width;
|
||||
aDesiredSize.height = aState.maxCellVertSpace;
|
||||
aDesiredSize.width = aReflowState.availSize.width;
|
||||
aDesiredSize.height = aReflowState.maxCellVertSpace;
|
||||
|
||||
if (gsDebug)
|
||||
printf("incr -- row %p width = %d MES=%d from maxSize %d\n",
|
||||
this, aDesiredSize.width, aDesiredSize.maxElementSize->width,
|
||||
aState.reflowState.maxSize.width);
|
||||
|
||||
return status;
|
||||
aReflowState.reflowState.maxSize.width);
|
||||
}
|
||||
else
|
||||
{ // pass reflow to unknown frame child
|
||||
// aDesiredSize does not change
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/** Layout the entire row.
|
||||
* This method stacks cells horizontally according to HTML 4.0 rules.
|
||||
@ -940,45 +1213,46 @@ nsTableRowFrame::Reflow(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf("nsTableRowFrame::Reflow - aMaxSize = %d, %d\n",
|
||||
aReflowState.maxSize.width, aReflowState.maxSize.height);
|
||||
|
||||
// Initialize 'out' parameters
|
||||
// Initialize 'out' parameters (aStatus set below, undefined if rv returns an error)
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = 0;
|
||||
aDesiredSize.maxElementSize->height = 0;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE; // we're never continued
|
||||
|
||||
// Initialize our internal data
|
||||
ResetMaxChildHeight();
|
||||
|
||||
// Initialize our automatic state object
|
||||
nsTableFrame* tableFrame;
|
||||
mContentParent->GetContentParent((nsIFrame*&)tableFrame);
|
||||
// Create a reflow state
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
RowReflowState state(aReflowState, tableFrame);
|
||||
|
||||
// Do the reflow
|
||||
nsresult result;
|
||||
|
||||
switch (aReflowState.reason) {
|
||||
case eReflowReason_Initial:
|
||||
result = InitialReflow(aPresContext, state, aDesiredSize);
|
||||
rv = InitialReflow(aPresContext, state, aDesiredSize);
|
||||
GetMinRowSpan(tableFrame);
|
||||
FixMinCellHeight(tableFrame);
|
||||
break;
|
||||
|
||||
case eReflowReason_Resize:
|
||||
result = ResizeReflow(aPresContext, state, aDesiredSize);
|
||||
rv = ResizeReflow(aPresContext, state, aDesiredSize);
|
||||
break;
|
||||
|
||||
case eReflowReason_Incremental:
|
||||
result = IncrementalReflow(aPresContext, state, aDesiredSize);
|
||||
rv = IncrementalReflow(aPresContext, aDesiredSize, state, aStatus);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE; // we're never continued
|
||||
|
||||
if (gsDebug==PR_TRUE)
|
||||
{
|
||||
if (nsnull!=aDesiredSize.maxElementSize)
|
||||
@ -992,7 +1266,7 @@ nsTableRowFrame::Reflow(nsIPresContext& aPresContext,
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
}
|
||||
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
|
@ -38,8 +38,13 @@ struct RowReflowState;
|
||||
class nsTableRowFrame : public nsContainerFrame
|
||||
{
|
||||
public:
|
||||
/** Initialization procedure */
|
||||
void Init(PRInt32 aRowIndex);
|
||||
/** Initialization of frame as a row */
|
||||
void InitRowData(PRInt32 aRowIndex);
|
||||
|
||||
/** Initialization of data */
|
||||
NS_IMETHOD InitChildren(PRInt32 aRowIndex=-1);
|
||||
|
||||
void ResetInitChildren();
|
||||
|
||||
/** instantiate a new instance of nsTableRowFrame.
|
||||
* @param aResult the new object is returned in this out-param
|
||||
@ -126,6 +131,64 @@ protected:
|
||||
/** destructor */
|
||||
virtual ~nsTableRowFrame();
|
||||
|
||||
/** Incremental Reflow attempts to do column balancing with the minimum number of reflow
|
||||
* commands to child elements. This is done by processing the reflow command,
|
||||
* rebalancing column widths (if necessary), then comparing the resulting column widths
|
||||
* to the prior column widths and reflowing only those cells that require a reflow.
|
||||
*
|
||||
* @see Reflow
|
||||
*/
|
||||
NS_IMETHOD IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame);
|
||||
|
||||
NS_IMETHOD IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_CellInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_CellAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_DidAppendCell(nsTableRowFrame *aRowFrame);
|
||||
|
||||
NS_IMETHOD IR_CellRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
|
||||
// row-specific methods
|
||||
|
||||
void GetMinRowSpan(nsTableFrame *aTableFrame);
|
||||
@ -180,11 +243,14 @@ private:
|
||||
nscoord mCellMaxTopMargin;
|
||||
nscoord mCellMaxBottomMargin;
|
||||
PRInt32 mMinRowSpan; // the smallest row span among all my child cells
|
||||
PRBool mInitializedChildren; // PR_TRUE if child cells have been initialized
|
||||
// (for now, that means "added to the table", and
|
||||
// is NOT the same as having nsIFrame::Init() called.)
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline void nsTableRowFrame::Init(PRInt32 aRowIndex)
|
||||
inline void nsTableRowFrame::InitRowData(PRInt32 aRowIndex)
|
||||
{
|
||||
NS_ASSERTION(0<=aRowIndex, "bad param row index");
|
||||
mRowIndex = aRowIndex;
|
||||
@ -196,4 +262,7 @@ inline PRInt32 nsTableRowFrame::GetRowIndex() const
|
||||
return (mRowIndex);
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::ResetInitChildren()
|
||||
{ mInitializedChildren=PR_FALSE; }
|
||||
|
||||
#endif
|
||||
|
@ -30,10 +30,10 @@
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gsDebug = PR_FALSE;
|
||||
//#define NOISY
|
||||
//#define NOISY_FLOW
|
||||
static PRBool gsDebugIR = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
#endif
|
||||
|
||||
NS_DEF_PTR(nsIStyleContext);
|
||||
@ -42,8 +42,8 @@ NS_DEF_PTR(nsIContent);
|
||||
/* ----------- RowGroupReflowState ---------- */
|
||||
|
||||
struct RowGroupReflowState {
|
||||
// Our reflow state
|
||||
const nsHTMLReflowState& reflowState;
|
||||
nsIPresContext& mPresContext; // Our pres context
|
||||
const nsHTMLReflowState& reflowState; // Our reflow state
|
||||
|
||||
// The body's available size (computed from the body's parent)
|
||||
nsSize availSize;
|
||||
@ -65,9 +65,10 @@ struct RowGroupReflowState {
|
||||
// Remember the height of the first row, because it's our maxElementHeight (plus header/footers)
|
||||
nscoord firstRowHeight;
|
||||
|
||||
RowGroupReflowState(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState)
|
||||
: reflowState(aReflowState)
|
||||
: mPresContext(aPresContext),
|
||||
reflowState(aReflowState)
|
||||
{
|
||||
availSize.width = reflowState.maxSize.width;
|
||||
availSize.height = reflowState.maxSize.height;
|
||||
@ -686,7 +687,7 @@ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
|
||||
delete []rowHeights;
|
||||
}
|
||||
|
||||
nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||
nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
nscoord aDeltaY)
|
||||
@ -708,7 +709,7 @@ nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext* aP
|
||||
// XXX We need to send move notifications to the frame...
|
||||
nsIHTMLReflow* htmlReflow;
|
||||
if (NS_OK == kidFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
|
||||
htmlReflow->WillReflow(*aPresContext);
|
||||
htmlReflow->WillReflow(aPresContext);
|
||||
}
|
||||
kidFrame->MoveTo(origin.x, origin.y);
|
||||
|
||||
@ -742,6 +743,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf("nsTableRowGroupFrame::Reflow - aMaxSize = %d, %d\n",
|
||||
aReflowState.maxSize.width, aReflowState.maxSize.height);
|
||||
@ -752,45 +754,10 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
aDesiredSize.maxElementSize->height = 0;
|
||||
}
|
||||
|
||||
RowGroupReflowState state(&aPresContext, aReflowState);
|
||||
RowGroupReflowState state(aPresContext, aReflowState);
|
||||
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
nsIFrame* target;
|
||||
aReflowState.reflowCommand->GetTarget(target);
|
||||
if (this == target) {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
}
|
||||
|
||||
// XXX Recover state
|
||||
// XXX Deal with the case where the reflow command is targeted at us
|
||||
nsIFrame* kidFrame;
|
||||
aReflowState.reflowCommand->GetNext(kidFrame);
|
||||
|
||||
// Remember the old rect
|
||||
nsRect oldKidRect;
|
||||
kidFrame->GetRect(oldKidRect);
|
||||
|
||||
// Pass along the reflow command
|
||||
// XXX Correctly compute the available space...
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aReflowState, aReflowState.maxSize);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Resize the row frame
|
||||
nsRect kidRect;
|
||||
kidFrame->GetRect(kidRect);
|
||||
kidFrame->SizeTo(desiredSize.width, desiredSize.height);
|
||||
|
||||
// Adjust the frames that follow...
|
||||
AdjustSiblingsAfterReflow(&aPresContext, state, kidFrame, desiredSize.height -
|
||||
oldKidRect.height);
|
||||
|
||||
// Return of desired size
|
||||
aDesiredSize.width = aReflowState.maxSize.width;
|
||||
aDesiredSize.height = state.y;
|
||||
|
||||
rv = IncrementalReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
} else {
|
||||
PRBool reflowMappedOK = PR_TRUE;
|
||||
|
||||
@ -855,10 +822,329 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IncrementalReflow\n");
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// create an inner table reflow state
|
||||
RowGroupReflowState state(aPresContext, aReflowState);
|
||||
|
||||
// determine if this frame is the target or not
|
||||
nsIFrame *target=nsnull;
|
||||
rv = aReflowState.reflowCommand->GetTarget(target);
|
||||
if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target))
|
||||
{
|
||||
if (this==target)
|
||||
rv = IR_TargetIsMe(aPresContext, aDesiredSize, state, aStatus);
|
||||
else
|
||||
{
|
||||
// Get the next frame in the reflow chain
|
||||
nsIFrame* nextFrame;
|
||||
aReflowState.reflowCommand->GetNext(nextFrame);
|
||||
|
||||
// Recover our reflow state
|
||||
//RecoverState(state, nextFrame);
|
||||
rv = IR_TargetIsChild(aPresContext, aDesiredSize, state, aStatus, nextFrame);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_FRAME_COMPLETE;
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
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);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: StyleChanged not implemented.\n");
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::ContentChanged :
|
||||
NS_ASSERTION(PR_FALSE, "illegal reflow type: ContentChanged");
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::PullupReflow:
|
||||
case nsIReflowCommand::PushReflow:
|
||||
case nsIReflowCommand::CheckPullupReflow :
|
||||
case nsIReflowCommand::UserDefined :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_RowInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
{
|
||||
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.
|
||||
it will automatically find the row to initialize into.
|
||||
but this is tough because a cell in aInsertedFrame could have a rowspan
|
||||
which must be respected if a subsequent row is appended.
|
||||
*/
|
||||
rv = aRowFrame->InitChildren();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
// 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)
|
||||
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!=
|
||||
|
||||
lastChild=mFirstChild;
|
||||
nextChild=lastChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
}
|
||||
// account for the cells in aAppendedFrame
|
||||
nsresult rv = DidAppendRow((nsTableRowFrame*)aAppendedFrame, newRowIndex);
|
||||
|
||||
// need to increment the row index of all subsequent rows
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_RowRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//XXX: handle aReplace
|
||||
NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
// we have a generic frame that gets inserted but doesn't effect reflow
|
||||
// hook it up then ignore it
|
||||
if (nsIReflowCommand::FrameAppended==type)
|
||||
{ // frameAppended reflow -- find the last child and make aInsertedFrame its next sibling
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: FrameAppended adding unknown frame type.\n");
|
||||
nsIFrame *lastChild=mFirstChild;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
lastChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aInsertedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aInsertedFrame);
|
||||
}
|
||||
else
|
||||
{ // frameInserted reflow -- hook up aInsertedFrame as prevSibling's next sibling,
|
||||
// and be sure to hook in aInsertedFrame's nextSibling (from prevSibling)
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: FrameInserted adding unknown frame type.\n");
|
||||
nsIFrame *prevSibling=nsnull;
|
||||
nsresult rv = aReflowState.reflowState.reflowCommand->GetPrevSiblingFrame(prevSibling);
|
||||
if (NS_SUCCEEDED(rv) && (nsnull!=prevSibling))
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
prevSibling->GetNextSibling(nextSibling);
|
||||
prevSibling->SetNextSibling(aInsertedFrame);
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
}
|
||||
return NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame)
|
||||
{
|
||||
// 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");
|
||||
nsIFrame *prevChild=nsnull;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nextChild!=aRemovedFrame)
|
||||
{
|
||||
prevChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
nextChild=nsnull;
|
||||
aRemovedFrame->GetNextSibling(nextChild);
|
||||
if (nsnull==prevChild) // objectFrame was first child
|
||||
mFirstChild = nextChild;
|
||||
else
|
||||
prevChild->SetNextSibling(nextChild);
|
||||
return NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame)
|
||||
|
||||
{
|
||||
nsresult rv;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_TargetIsChild\n");
|
||||
// XXX Recover state
|
||||
|
||||
// Remember the old rect
|
||||
nsRect oldKidRect;
|
||||
aNextFrame->GetRect(oldKidRect);
|
||||
|
||||
// Pass along the reflow command
|
||||
// XXX Correctly compute the available space...
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aNextFrame, aReflowState.reflowState, aReflowState.reflowState.maxSize);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Resize the row frame
|
||||
nsRect kidRect;
|
||||
aNextFrame->GetRect(kidRect);
|
||||
aNextFrame->SizeTo(desiredSize.width, desiredSize.height);
|
||||
|
||||
// Adjust the frames that follow...
|
||||
AdjustSiblingsAfterReflow(aPresContext, aReflowState, aNextFrame, desiredSize.height -
|
||||
oldKidRect.height);
|
||||
|
||||
// Return of desired size
|
||||
aDesiredSize.width = aReflowState.reflowState.maxSize.width;
|
||||
aDesiredSize.height = aReflowState.y;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsTableRowGroupFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
nsIFrame* aParent,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
class nsTableRowFrame;
|
||||
struct RowGroupReflowState;
|
||||
|
||||
/**
|
||||
@ -79,6 +80,65 @@ public:
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
/** Incremental Reflow attempts to do column balancing with the minimum number of reflow
|
||||
* commands to child elements. This is done by processing the reflow command,
|
||||
* rebalancing column widths (if necessary), then comparing the resulting column widths
|
||||
* to the prior column widths and reflowing only those cells that require a reflow.
|
||||
*
|
||||
* @see Reflow
|
||||
*/
|
||||
NS_IMETHOD IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame);
|
||||
|
||||
NS_IMETHOD IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_RowInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_RowAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_DidAppendRow(nsTableRowFrame *aRowFrame);
|
||||
|
||||
NS_IMETHOD IR_RowRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
|
||||
|
||||
/** @see nsContainerFrame::CreateContinuingFrame */
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
nsIFrame* aParent,
|
||||
@ -111,11 +171,11 @@ protected:
|
||||
~nsTableRowGroupFrame();
|
||||
|
||||
nscoord GetTopMarginFor(nsIPresContext* aCX,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
const nsMargin& aKidMargin);
|
||||
|
||||
void PlaceChild( nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
@ -124,8 +184,8 @@ protected:
|
||||
void ShrinkWrapChildren(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
nsresult AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsresult AdjustSiblingsAfterReflow(nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
nscoord aDeltaY);
|
||||
|
||||
@ -133,24 +193,24 @@ protected:
|
||||
* 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 ReflowMappedChildren(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsSize* aMaxElementSize);
|
||||
|
||||
/**
|
||||
* 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 PullUpChildren(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsSize* aMaxElementSize);
|
||||
|
||||
private:
|
||||
|
@ -119,6 +119,9 @@ public:
|
||||
*/
|
||||
void AppendColumnFrame(nsTableColFrame *aColFrame);
|
||||
|
||||
/** empty the column frame cache */
|
||||
void ClearColumnCache();
|
||||
|
||||
/** returns PR_TRUE if the row at aRowIndex has any cells that are the result
|
||||
* of a row-spanning cell above it. So, given this table:<BR>
|
||||
* <PRE>
|
||||
@ -227,5 +230,11 @@ inline void nsCellMap::AppendColumnFrame(nsTableColFrame *aColFrame)
|
||||
mColFrames->AppendElement(aColFrame);
|
||||
}
|
||||
|
||||
inline void nsCellMap::ClearColumnCache()
|
||||
{
|
||||
if (nsnull!=mColFrames)
|
||||
mColFrames->Clear();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -52,8 +52,10 @@ nsresult
|
||||
nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
nsIFrame* tableFrame=nsnull;
|
||||
GetGeometricParent(tableFrame);
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
// Process the newly added column frames
|
||||
for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
|
||||
// Set the preliminary values for the column frame
|
||||
@ -74,7 +76,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
|
||||
mColCount+= repeat;
|
||||
((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
|
||||
((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame);
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame);
|
||||
}
|
||||
// colgroup's span attribute is how many columns the group represents
|
||||
// in the absence of any COL children
|
||||
@ -107,7 +109,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
PRInt32 absColIndex = mStartColIndex + colIndex;
|
||||
((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1);
|
||||
((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
|
||||
((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)colFrame);
|
||||
tableFrame->AddColumnFrame((nsTableColFrame *)colFrame);
|
||||
|
||||
//hook into list of children
|
||||
if (nsnull==firstImplicitColFrame)
|
||||
@ -132,7 +134,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
|
||||
}
|
||||
}
|
||||
SetStyleContextForFirstPass(aPresContext);
|
||||
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -233,9 +235,10 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPresContext)
|
||||
{
|
||||
// get the table frame
|
||||
nsIFrame* tableFrame=nsnull;
|
||||
GetGeometricParent(tableFrame);
|
||||
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
|
||||
{
|
||||
// get the style for the table frame
|
||||
nsStyleTable *tableStyle;
|
||||
tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
@ -277,10 +280,10 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPre
|
||||
}
|
||||
colFrame->GetNextSibling(colFrame);
|
||||
}
|
||||
|
||||
mStyleContext->RecalcAutomaticData(&aPresContext);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
@ -270,6 +270,7 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
|
||||
mColCache(nsnull),
|
||||
mTableLayoutStrategy(nsnull),
|
||||
mFirstPassValid(PR_FALSE),
|
||||
mCellMapValid(PR_TRUE),
|
||||
mIsInvariantWidth(PR_FALSE)
|
||||
{
|
||||
mEffectiveColCount = -1; // -1 means uninitialized
|
||||
@ -298,10 +299,43 @@ nsTableFrame::~nsTableFrame()
|
||||
NS_IMETHODIMP
|
||||
nsTableFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
mFirstChild = aChildList;
|
||||
EnsureColumns(aPresContext);
|
||||
return NS_OK;
|
||||
// I know now that I have all my children, so build the cell map
|
||||
nsIFrame *nextRowGroup=mFirstChild;
|
||||
for ( ; nsnull!=nextRowGroup; nextRowGroup->GetNextSibling(nextRowGroup))
|
||||
{
|
||||
const nsStyleDisplay *rowGroupDisplay;
|
||||
nextRowGroup->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowGroupDisplay);
|
||||
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
|
||||
{
|
||||
rv = DidAppendRowGroup((nsTableRowGroupFrame*)nextRowGroup);
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(rv))
|
||||
EnsureColumns(aPresContext);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTableFrame::DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
nsIFrame *nextRow=nsnull;
|
||||
aRowGroupFrame->FirstChild(nextRow);
|
||||
for ( ; nsnull!=nextRow; nextRow->GetNextSibling(nextRow))
|
||||
{
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
nextRow->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
|
||||
{
|
||||
rv = ((nsTableRowFrame *)nextRow)->InitChildren();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* ****** CellMap methods ******* */
|
||||
|
||||
@ -322,14 +356,12 @@ nsTableRowGroupFrame* nsTableFrame::NextRowGroupFrame(nsTableRowGroupFrame* aRow
|
||||
const nsStyleDisplay *display;
|
||||
aRowGroupFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (PR_TRUE==IsRowGroup(display->mDisplay))
|
||||
{ //XXX: assumes content order
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the next frame
|
||||
aRowGroupFrame->GetNextSibling((nsIFrame*&)aRowGroupFrame);
|
||||
}
|
||||
|
||||
return aRowGroupFrame;
|
||||
}
|
||||
|
||||
@ -346,10 +378,6 @@ PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
|
||||
{
|
||||
mColCount += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
|
||||
}
|
||||
else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{ //XXX: assumes content order
|
||||
break;
|
||||
}
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
return mColCount;
|
||||
@ -358,24 +386,10 @@ PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
|
||||
PRInt32 nsTableFrame::GetRowCount ()
|
||||
{
|
||||
PRInt32 rowCount = 0;
|
||||
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_ASSERTION(nsnull!=cellMap, "GetRowCount null cellmap");
|
||||
if (nsnull!=cellMap)
|
||||
return cellMap->GetRowCount();
|
||||
|
||||
nsIFrame *child=mFirstChild;
|
||||
while (nsnull!=child)
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
child->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{
|
||||
PRInt32 thisRowCount=0;
|
||||
((nsTableRowGroupFrame *)child)->GetRowCount(thisRowCount);
|
||||
rowCount += thisRowCount;
|
||||
}
|
||||
child->GetNextSibling(child);
|
||||
}
|
||||
rowCount = cellMap->GetRowCount();
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
@ -383,7 +397,7 @@ PRInt32 nsTableFrame::GetRowCount ()
|
||||
PRInt32 nsTableFrame::GetColCount ()
|
||||
{
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_ASSERTION(nsnull!=cellMap, "GetColCount can only be called after cellmap has been created");
|
||||
NS_ASSERTION(nsnull!=cellMap, "GetColCount null cellmap");
|
||||
|
||||
if (nsnull!=cellMap)
|
||||
{
|
||||
@ -396,6 +410,7 @@ PRInt32 nsTableFrame::GetColCount ()
|
||||
void nsTableFrame::SetEffectiveColCount()
|
||||
{
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_ASSERTION(nsnull!=cellMap, "SetEffectiveColCount null cellmap");
|
||||
if (nsnull!=cellMap)
|
||||
{
|
||||
PRInt32 colCount = cellMap->GetColCount();
|
||||
@ -589,7 +604,7 @@ NS_ASSERTION(0<result, "bad effective col span");
|
||||
PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
|
||||
{
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_PRECONDITION (nsnull!=cellMap, "bad call, cellMap not yet allocated.");
|
||||
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
|
||||
PRInt32 result;
|
||||
nsIFrame *tableFrame = this;
|
||||
nsStyleTable *tableStyle=nsnull;
|
||||
@ -601,16 +616,6 @@ PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
|
||||
void nsTableFrame::ResetCellMap ()
|
||||
{
|
||||
// XXX: SEC should this call ResetCellMap on firstInFlow?
|
||||
if (nsnull!=mCellMap)
|
||||
delete mCellMap;
|
||||
mCellMap = nsnull; // for now, will rebuild when needed
|
||||
}
|
||||
|
||||
/** sum the columns represented by all nsTableColGroup objects
|
||||
* if the cell map says there are more columns than this,
|
||||
* add extra implicit columns to the content tree.
|
||||
@ -632,7 +637,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext)
|
||||
PRInt32 actualColumns = 0;
|
||||
nsTableColGroupFrame *lastColGroupFrame = nsnull;
|
||||
nsIFrame * firstRowGroupFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull; // this is the child just before the first row group frame
|
||||
nsIFrame * childFrame=mFirstChild;
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
@ -646,11 +651,14 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext)
|
||||
if (PR_TRUE==gsDebug) printf("EC: found a col group %p\n", lastColGroupFrame);
|
||||
}
|
||||
else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{ // XXX: assumes content order
|
||||
{
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
{
|
||||
firstRowGroupFrame = childFrame;
|
||||
if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
prevSibFrame = childFrame;
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
@ -666,7 +674,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext)
|
||||
nsAutoString colGroupTag;
|
||||
nsHTMLAtoms::colgroup->ToString(colGroupTag);
|
||||
rv = NS_CreateHTMLElement(&lastColGroup, colGroupTag); // ADDREF a: lastColGroup++
|
||||
//XXX mark it as implicit!
|
||||
//XXX: make synthetic
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // add the implicit colgroup to my content
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* colGroupStyleContext =
|
||||
@ -716,7 +724,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext)
|
||||
nsIHTMLContent *col=nsnull;
|
||||
// create an implicit col
|
||||
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
|
||||
//XXX mark the col implicit
|
||||
//XXX: make synthetic
|
||||
lastColGroup->AppendChildTo((nsIContent*)col, PR_FALSE);
|
||||
|
||||
// Create a new col frame
|
||||
@ -759,7 +767,7 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
PRInt32 actualColumns = 0;
|
||||
nsTableColGroupFrame *lastColGroupFrame = nsnull;
|
||||
nsIFrame * firstRowGroupFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull;
|
||||
nsIFrame * prevSibFrame=nsnull; // this is the child just before the first row group frame
|
||||
nsIFrame * childFrame=mFirstChild;
|
||||
while (nsnull!=childFrame)
|
||||
{
|
||||
@ -774,10 +782,11 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
break; // we have enough col frames at this point
|
||||
}
|
||||
else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{ // XXX: assumes content order
|
||||
{
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
firstRowGroupFrame = childFrame;
|
||||
break;
|
||||
}
|
||||
if (nsnull==firstRowGroupFrame)
|
||||
prevSibFrame = childFrame;
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
@ -790,6 +799,7 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
nsAutoString colGroupTag;
|
||||
nsHTMLAtoms::colgroup->ToString(colGroupTag);
|
||||
rv = NS_CreateHTMLElement(&lastColGroup, colGroupTag); // ADDREF a: lastColGroup++
|
||||
//XXX: make synthetic
|
||||
//XXX mark it as implicit!
|
||||
mContent->AppendChildTo(lastColGroup, PR_FALSE); // add the implicit colgroup to my content
|
||||
// Resolve style for the child
|
||||
@ -837,7 +847,7 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
nsIHTMLContent *col=nsnull;
|
||||
// create an implicit col
|
||||
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
|
||||
//XXX mark the col implicit
|
||||
//XXX: make synthetic
|
||||
lastColGroup->AppendChildTo((nsIContent*)col, PR_FALSE);
|
||||
|
||||
// Create a new col frame
|
||||
@ -868,17 +878,22 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
|
||||
|
||||
void nsTableFrame::AddColumnFrame (nsTableColFrame *aColFrame)
|
||||
{
|
||||
mCellMap->AppendColumnFrame(aColFrame);
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
|
||||
if (nsnull!=cellMap)
|
||||
cellMap->AppendColumnFrame(aColFrame);
|
||||
}
|
||||
|
||||
/** return the index of the next row that is not yet assigned */
|
||||
PRInt32 nsTableFrame::GetNextAvailRowIndex() const
|
||||
{
|
||||
PRInt32 result=0;
|
||||
if (nsnull!=mCellMap)
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
|
||||
if (nsnull!=cellMap)
|
||||
{
|
||||
result = mCellMap->GetRowCount(); // the next index is the current count
|
||||
mCellMap->GrowToRow(result+1); // expand the cell map to include this new row
|
||||
result = cellMap->GetRowCount(); // the next index is the current count
|
||||
cellMap->GrowToRow(result+1); // expand the cell map to include this new row
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -887,15 +902,17 @@ PRInt32 nsTableFrame::GetNextAvailRowIndex() const
|
||||
PRInt32 nsTableFrame::GetNextAvailColIndex(PRInt32 aRowIndex, PRInt32 aColIndex) const
|
||||
{
|
||||
PRInt32 result=0;
|
||||
if (nsnull!=mCellMap)
|
||||
result = mCellMap->GetNextAvailColIndex(aRowIndex, aColIndex);
|
||||
nsCellMap *cellMap = GetCellMap();
|
||||
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
|
||||
if (nsnull!=cellMap)
|
||||
result = cellMap->GetNextAvailColIndex(aRowIndex, aColIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
nsCellMap * nsTableFrame::GetCellMap()
|
||||
nsCellMap * nsTableFrame::GetCellMap() const
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
if (this!=firstInFlow)
|
||||
@ -951,7 +968,6 @@ void nsTableFrame::AddCellToTable (nsTableRowFrame *aRowFrame,
|
||||
}
|
||||
|
||||
PRInt32 rowIndex;
|
||||
// If we have a cell map reset it; otherwise allocate a new cell map
|
||||
// also determine the index of aRowFrame and set it if necessary
|
||||
if (0==mCellMap->GetRowCount())
|
||||
{ // this is the first time we've ever been called
|
||||
@ -979,6 +995,34 @@ void nsTableFrame::AddCellToTable (nsTableRowFrame *aRowFrame,
|
||||
DumpCellMap ();
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::ReBuildCellMap()
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
nsIFrame *rowGroupFrame=mFirstChild;
|
||||
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(rowGroupFrame))
|
||||
{
|
||||
const nsStyleDisplay *rowGroupDisplay;
|
||||
rowGroupFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowGroupDisplay);
|
||||
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
|
||||
{
|
||||
nsIFrame *rowFrame;
|
||||
rowGroupFrame->FirstChild(rowFrame);
|
||||
for ( ; nsnull!=rowFrame; rowFrame->GetNextSibling(rowFrame))
|
||||
{
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
|
||||
{
|
||||
rv = ((nsTableRowFrame *)rowFrame)->InitChildren();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
void nsTableFrame::DumpCellMap ()
|
||||
@ -1054,20 +1098,20 @@ void nsTableFrame::BuildCellIntoMap (nsTableCellFrame *aCell, PRInt32 aRowIndex,
|
||||
// Setup CellMap for this cell
|
||||
int rowSpan = aCell->GetRowSpan();
|
||||
int colSpan = aCell->GetColSpan();
|
||||
if (gsDebug==PR_TRUE) printf(" BuildCellIntoMap. rowSpan = %d, colSpan = %d\n", rowSpan, colSpan);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: rowSpan = %d, colSpan = %d\n", rowSpan, colSpan);
|
||||
|
||||
// Grow the mCellMap array if we will end up addressing
|
||||
// some new columns.
|
||||
if (mCellMap->GetColCount() < (aColIndex + colSpan))
|
||||
{
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf(" calling GrowCellMap(%d)\n", aColIndex+colSpan);
|
||||
printf("BCIM: calling GrowCellMap(%d)\n", aColIndex+colSpan);
|
||||
GrowCellMap (aColIndex + colSpan);
|
||||
}
|
||||
|
||||
if (mCellMap->GetRowCount() < (aRowIndex+1))
|
||||
{
|
||||
printf("*********************************************** calling GrowToRow(%d)\n", aRowIndex+1);
|
||||
printf("BCIM: calling GrowToRow(%d)\n", aRowIndex+1);
|
||||
mCellMap->GrowToRow(aRowIndex+1);
|
||||
}
|
||||
|
||||
@ -1075,7 +1119,7 @@ void nsTableFrame::BuildCellIntoMap (nsTableCellFrame *aCell, PRInt32 aRowIndex,
|
||||
CellData *data = new CellData ();
|
||||
data->mCell = aCell;
|
||||
data->mRealCell = data;
|
||||
if (gsDebug==PR_TRUE) printf(" calling mCellMap->SetCellAt(data, %d, %d)\n", aRowIndex, aColIndex);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: calling mCellMap->SetCellAt(data, %d, %d)\n", aRowIndex, aColIndex);
|
||||
mCellMap->SetCellAt(data, aRowIndex, aColIndex);
|
||||
|
||||
// Create CellData objects for the rows that this cell spans. Set
|
||||
@ -1084,28 +1128,28 @@ void nsTableFrame::BuildCellIntoMap (nsTableCellFrame *aCell, PRInt32 aRowIndex,
|
||||
// CellData object for each row that we span...
|
||||
if ((1 < rowSpan) || (1 < colSpan))
|
||||
{
|
||||
if (gsDebug==PR_TRUE) printf(" spans\n");
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: spans\n");
|
||||
for (int rowIndex = 0; rowIndex < rowSpan; rowIndex++)
|
||||
{
|
||||
if (gsDebug==PR_TRUE) printf(" rowIndex = %d\n", rowIndex);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: rowIndex = %d\n", rowIndex);
|
||||
int workRow = aRowIndex + rowIndex;
|
||||
if (gsDebug==PR_TRUE) printf(" workRow = %d\n", workRow);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: workRow = %d\n", workRow);
|
||||
for (int colIndex = 0; colIndex < colSpan; colIndex++)
|
||||
{
|
||||
if (gsDebug==PR_TRUE) printf(" colIndex = %d\n", colIndex);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: colIndex = %d\n", colIndex);
|
||||
int workCol = aColIndex + colIndex;
|
||||
if (gsDebug==PR_TRUE) printf(" workCol = %d\n", workCol);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: workCol = %d\n", workCol);
|
||||
CellData *testData = mCellMap->GetCellAt(workRow, workCol);
|
||||
if (nsnull == testData)
|
||||
{
|
||||
CellData *spanData = new CellData ();
|
||||
spanData->mRealCell = data;
|
||||
if (gsDebug==PR_TRUE) printf(" null GetCellFrameAt(%d, %d) so setting to spanData\n", workRow, workCol);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: null GetCellFrameAt(%d, %d) so setting to spanData\n", workRow, workCol);
|
||||
mCellMap->SetCellAt(spanData, workRow, workCol);
|
||||
}
|
||||
else if ((0 < rowIndex) || (0 < colIndex))
|
||||
{ // we overlap, replace existing data, it might be shared
|
||||
if (gsDebug==PR_TRUE) printf(" overlapping Cell from GetCellFrameAt(%d, %d) so setting to spanData\n", workRow, workCol);
|
||||
if (gsDebug==PR_TRUE) printf("BCIM: overlapping Cell from GetCellFrameAt(%d, %d) so setting to spanData\n", workRow, workCol);
|
||||
CellData *overlap = new CellData ();
|
||||
overlap->mCell = testData->mCell;
|
||||
overlap->mRealCell = testData->mRealCell;
|
||||
@ -1414,12 +1458,15 @@ NS_METHOD nsTableFrame::Paint(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::NeedsReflow(const nsSize& aMaxSize)
|
||||
PRBool nsTableFrame::NeedsReflow(const nsHTMLReflowState& aReflowState, const nsSize& aMaxSize)
|
||||
{
|
||||
PRBool result = PR_TRUE;
|
||||
if (eReflowReason_Incremental != aReflowState.reason)
|
||||
{ // incremental reflows always need to be reflowed (for now)
|
||||
if (PR_TRUE==mIsInvariantWidth)
|
||||
result = PR_FALSE;
|
||||
// TODO: other cases...
|
||||
// XXX TODO: other optimization cases...
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1509,20 +1556,44 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||
rv = IncrementalReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
}
|
||||
|
||||
if (PR_TRUE==NeedsReflow(aReflowState.maxSize))
|
||||
// NeedsReflow and IsFirstPassValid take into account reflow type = Initial_Reflow
|
||||
if (PR_TRUE==NeedsReflow(aReflowState, aReflowState.maxSize))
|
||||
{
|
||||
PRBool needsRecalc=PR_FALSE;
|
||||
if (PR_TRUE==gsDebug) printf("TF Reflow: needs reflow\n");
|
||||
if (eReflowReason_Initial!=aReflowState.reason && PR_FALSE==IsCellMapValid())
|
||||
{
|
||||
if (PR_TRUE==gsDebug) printf("TF Reflow: not initial reflow, so resetting cell map.\n");
|
||||
if (nsnull!=mCellMap)
|
||||
delete mCellMap;
|
||||
mCellMap = new nsCellMap(0,0);
|
||||
ReBuildCellMap();
|
||||
needsRecalc=PR_TRUE;
|
||||
}
|
||||
if (PR_FALSE==IsFirstPassValid())
|
||||
{
|
||||
// XXX TROY: we used to rebuild the cellmap here for incremental reflow.
|
||||
// now that the cellmap is built in the constructor
|
||||
// we need to reset the cellmap during incremental reflow before we get here
|
||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TF Reflow: first pass is invalid\n");
|
||||
rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
needsRecalc=PR_TRUE;
|
||||
}
|
||||
if (PR_TRUE==needsRecalc)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TF 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("TF Reflow: Re-init layout strategy\n");
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
}
|
||||
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
RecalcLayoutData(); // Recalculate Layout Dependencies
|
||||
}
|
||||
|
||||
|
||||
if (nsnull==mPrevInFlow)
|
||||
{
|
||||
{ // only do this for a first-in-flow table frame
|
||||
// assign column widths, and assign aMaxElementSize->width
|
||||
BalanceColumnWidths(aPresContext, aReflowState, aReflowState.maxSize,
|
||||
aDesiredSize.maxElementSize);
|
||||
@ -1656,10 +1727,6 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
// Recalculate Layout Dependencies
|
||||
RecalcLayoutData();
|
||||
|
||||
aDesiredSize.width = kidSize.width;
|
||||
mFirstPassValid = PR_TRUE;
|
||||
|
||||
@ -1756,6 +1823,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
@ -1776,7 +1844,10 @@ NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
rv = aReflowState.reflowCommand->GetTarget(target);
|
||||
if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target))
|
||||
{
|
||||
if (this==target)
|
||||
// this is the target if target is either this or the outer table frame containing this inner frame
|
||||
nsIFrame *outerTableFrame=nsnull;
|
||||
GetGeometricParent(outerTableFrame);
|
||||
if ((this==target) || (outerTableFrame==target))
|
||||
rv = IR_TargetIsMe(aPresContext, aDesiredSize, state, aStatus);
|
||||
else
|
||||
{
|
||||
@ -1802,14 +1873,12 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
@ -1826,7 +1895,22 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
}
|
||||
else if (IsRowGroup(childDisplay->mDisplay))
|
||||
{
|
||||
rv = IR_RowGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
@ -1834,9 +1918,6 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_ColGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
@ -1854,7 +1935,6 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
objectFrame);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
@ -1898,6 +1978,80 @@ NS_METHOD nsTableFrame::IR_ColGroupInserted(nsIPresContext& aPresContext,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::IR_ColGroupAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
/*
|
||||
find where to place colgroup (skipping implicit children?)
|
||||
for every col in the colgroup (including implicit cols due to span attribute)
|
||||
an implicit col from the first implicit colgroup is removed
|
||||
when an implicit colgroups col count goes to 0, it is removed
|
||||
*/
|
||||
/* need to really verify that issynthetic is specified on implicit colgroups and cols */
|
||||
|
||||
|
||||
// build a vector of colgroups. XXX might want to do this as a class thing, so we don't have to rebuild it each time
|
||||
nsVoidArray colGroupList;
|
||||
nsIFrame *childFrame=mFirstChild;
|
||||
nsIFrame *lastChild=mFirstChild;
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
|
||||
{
|
||||
colGroupList.AppendElement((void*)childFrame);
|
||||
}
|
||||
lastChild=childFrame;
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
// append aAppendedFrame
|
||||
if (nsnull!=lastChild)
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
else
|
||||
mFirstChild = aAppendedFrame;
|
||||
|
||||
/* go through the list of colgroups, sucking out implicit columns that are not the result of a span attribute
|
||||
* and replacing them with columns in aAppendedFrame
|
||||
* if the column had an attribute from a cell, be sure to preserve that
|
||||
* if any implicit colgroup becomes empty, destroy it
|
||||
* if any real colgroup becomes empty, we have to keep it
|
||||
* factor the new cols into the column cache
|
||||
* this means having a flag that says whether the col cache needs to be rebuilt or not
|
||||
*/
|
||||
PRInt32 colGroupCount = colGroupList.Count();
|
||||
if (0<colGroupCount)
|
||||
{
|
||||
aAppendedFrame->FirstChild(childFrame);
|
||||
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *colDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)colDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
|
||||
{ // find an implicit column that is not from a span attribute if there is one and remove it
|
||||
for (PRInt32 colGroupIndex=0; colGroupIndex<colGroupCount; colGroupIndex++)
|
||||
{
|
||||
nsTableColGroupFrame *colGroup = (nsTableColGroupFrame *)(colGroupList.ElementAt(colGroupIndex));
|
||||
// XXX: here's where we yank colGroups if necessary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//InvalidateFirstPassCache(); // for now, redo the first pass reflow
|
||||
// could probably just get away with mTableLayoutStrategy->Initialize(aMaxElementSize);
|
||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
|
||||
//XXX: what we want to do here is determine if the new COL information changes anything about layout
|
||||
// if not, skip invalidating the first passs
|
||||
// if so, and we can fix the first pass info
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsTableFrame::IR_ColGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
@ -1921,6 +2075,39 @@ NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv;
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
return rv;
|
||||
}
|
||||
|
||||
// since we know we're doing an append here, we can optimize
|
||||
NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame)
|
||||
{
|
||||
// hook aAppendedFrame into the child list
|
||||
nsIFrame *lastChild = mFirstChild;
|
||||
nsIFrame *nextChild = lastChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
lastChild = nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aAppendedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
|
||||
// account for the cells in the rows that are children of aAppendedFrame
|
||||
nsresult rv = DidAppendRowGroup((nsTableRowGroupFrame*)aAppendedFrame);
|
||||
|
||||
// do a pass-1 layout of all the cells in all the rows of the rowgroup
|
||||
InvalidateFirstPassCache();
|
||||
|
||||
// if any column widths have to change due to this, re-init the layout strategy
|
||||
// mTableLayoutStrategy->Initialize(aDesiredSize.aMaxElementSize); //XXX for now, we're just doing the whole enchelada
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2032,7 +2219,7 @@ NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
aReflowState.reflowState,
|
||||
aReflowState.reflowState.maxSize);
|
||||
|
||||
ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Resize the row group frame
|
||||
nsRect kidRect;
|
||||
@ -2160,8 +2347,6 @@ void nsTableFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
{
|
||||
nsMargin borderPadding;
|
||||
const nsStyleSpacing* tableSpacing;
|
||||
// begin REMOVE_ME_WHEN_TABLE_STYLE_IS_RESOLVED!
|
||||
nsIFrame * parent = nsnull;
|
||||
GetStyleData(eStyleStruct_Spacing , ((nsStyleStruct *&)tableSpacing));
|
||||
tableSpacing->CalcBorderPaddingFor(this, borderPadding);
|
||||
nscoord cellSpacing = GetCellSpacing();
|
||||
@ -2753,13 +2938,18 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
nsReflowStatus& aStatus
|
||||
)
|
||||
{
|
||||
// probably want this assertion : NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
|
||||
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!");
|
||||
nsStyleTable* tableStyle;
|
||||
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
|
||||
EnsureColumns(aPresContext);
|
||||
if (nsnull==mColCache)
|
||||
if (nsnull!=mColCache)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("TIF BCB: clearing column cache and cell map column frame cache.\n");
|
||||
mCellMap->ClearColumnCache();
|
||||
delete mColCache;
|
||||
}
|
||||
|
||||
mColCache = new ColumnInfoCache(mColCount);
|
||||
nsIFrame * childFrame = mFirstChild;
|
||||
while (nsnull!=childFrame)
|
||||
@ -2836,14 +3026,9 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
|
||||
colFrame->GetNextSibling((nsIFrame *&)colFrame);
|
||||
}
|
||||
}
|
||||
else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
|
||||
{ // XXX: assumes content order
|
||||
break; // once we hit a row group, we're done
|
||||
}
|
||||
childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsFirstPassValid() const
|
||||
{
|
||||
@ -2852,6 +3037,48 @@ PRBool nsTableFrame::IsFirstPassValid() const
|
||||
return firstInFlow->mFirstPassValid;
|
||||
}
|
||||
|
||||
void nsTableFrame::InvalidateFirstPassCache()
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mFirstPassValid=PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsTableFrame::IsCellMapValid() const
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
return firstInFlow->mCellMapValid;
|
||||
}
|
||||
|
||||
void nsTableFrame::InvalidateCellMap()
|
||||
{
|
||||
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
|
||||
NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
|
||||
firstInFlow->mCellMapValid=PR_FALSE;
|
||||
// reset the state in each row
|
||||
nsIFrame *rowGroupFrame=mFirstChild;
|
||||
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(rowGroupFrame))
|
||||
{
|
||||
const nsStyleDisplay *rowGroupDisplay;
|
||||
rowGroupFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowGroupDisplay);
|
||||
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
|
||||
{
|
||||
nsIFrame *rowFrame;
|
||||
rowGroupFrame->FirstChild(rowFrame);
|
||||
for ( ; nsnull!=rowFrame; rowFrame->GetNextSibling(rowFrame))
|
||||
{
|
||||
const nsStyleDisplay *rowDisplay;
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)rowDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
|
||||
{
|
||||
((nsTableRowFrame *)rowFrame)->ResetInitChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsTableFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
nsIFrame* aParent,
|
||||
@ -3148,25 +3375,44 @@ NS_NewTableFrame(nsIContent* aContent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableFrame::GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aOutFrame)
|
||||
NS_METHOD nsTableFrame::GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aTableFrame)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
aOutFrame = nsnull; // initialize out-param
|
||||
aTableFrame = nsnull; // initialize out-param
|
||||
if (nsnull!=aSourceFrame)
|
||||
{
|
||||
nsresult result = aSourceFrame->GetContentParent((nsIFrame *&)aOutFrame);
|
||||
while ((NS_OK==result) && (nsnull!=aOutFrame))
|
||||
nsresult result = aSourceFrame->GetContentParent((nsIFrame *&)aTableFrame);
|
||||
while ((NS_OK==result) && (nsnull!=aTableFrame))
|
||||
{
|
||||
const nsStyleDisplay *display;
|
||||
aOutFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
aTableFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
|
||||
if (NS_STYLE_DISPLAY_TABLE == display->mDisplay)
|
||||
{
|
||||
// at this point, aTableFrame could be an outer frame,
|
||||
// to find out, scan it's children for another frame with a table display type
|
||||
// if found, the childFrame must be the inner frame
|
||||
nsresult rv;
|
||||
nsIFrame *childFrame=nsnull;
|
||||
rv = aTableFrame->FirstChild(childFrame);
|
||||
while ((NS_OK==rv) && (nsnull!=childFrame))
|
||||
{
|
||||
const nsStyleDisplay *childDisplay;
|
||||
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)childDisplay);
|
||||
if (NS_STYLE_DISPLAY_TABLE == childDisplay->mDisplay)
|
||||
{
|
||||
aTableFrame = (nsTableFrame *)childFrame;
|
||||
break;
|
||||
result = aOutFrame->GetContentParent((nsIFrame *&)aOutFrame);
|
||||
}
|
||||
rv = childFrame->GetNextSibling(childFrame);
|
||||
}
|
||||
break;
|
||||
}
|
||||
result = aTableFrame->GetContentParent((nsIFrame *&)aTableFrame);
|
||||
}
|
||||
}
|
||||
else
|
||||
result = NS_ERROR_UNEXPECTED; // bad source param
|
||||
NS_POSTCONDITION(nsnull!=aOutFrame, "unable to find table parent. aOutFrame null.");
|
||||
NS_POSTCONDITION(nsnull!=aTableFrame, "unable to find table parent. aTableFrame null.");
|
||||
NS_POSTCONDITION(NS_OK==result, "unable to find table parent. result!=NS_OK");
|
||||
return result;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
PRBool IsNested(const nsHTMLReflowState& aReflowState, nsStylePosition *& aPosition) const;
|
||||
|
||||
/** helper method to find the table parent of any table frame object */
|
||||
static NS_METHOD GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aOutFrame);
|
||||
static NS_METHOD GetTableFrame(nsIFrame *aSourceFrame, nsTableFrame *& aTableFrame);
|
||||
|
||||
/** helper method for getting the width of the table's containing block */
|
||||
static nscoord GetTableContainerWidth(const nsHTMLReflowState& aState);
|
||||
@ -97,6 +97,11 @@ public:
|
||||
|
||||
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
|
||||
/** complete the append of aRowGroupFrame to the table
|
||||
* this builds the cell map
|
||||
*/
|
||||
NS_IMETHOD DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFrame);
|
||||
|
||||
/** @see nsIFrame::Paint */
|
||||
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
@ -315,6 +320,12 @@ protected:
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_ColGroupAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_ColGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
@ -328,6 +339,12 @@ protected:
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_RowGroupAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_RowGroupRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
InnerTableReflowState& aReflowState,
|
||||
@ -414,11 +431,16 @@ protected:
|
||||
nscoord aMaxHeight);
|
||||
|
||||
/** given the new parent size, do I really need to do a reflow? */
|
||||
virtual PRBool NeedsReflow(const nsSize& aMaxSize);
|
||||
virtual PRBool NeedsReflow(const nsHTMLReflowState& aReflowState,
|
||||
const nsSize& aMaxSize);
|
||||
|
||||
/** returns PR_TRUE if the cached pass 1 data is still valid */
|
||||
virtual PRBool IsFirstPassValid() const;
|
||||
|
||||
public:
|
||||
virtual void InvalidateFirstPassCache();
|
||||
|
||||
protected:
|
||||
/** do post processing to setting up style information for the frame */
|
||||
NS_IMETHOD DidSetStyleContext(nsIPresContext& aPresContext);
|
||||
|
||||
@ -431,16 +453,24 @@ protected:
|
||||
*/
|
||||
virtual void GrowCellMap(PRInt32 aColCount);
|
||||
|
||||
/** returns PR_TRUE if the cached pass 1 data is still valid */
|
||||
virtual PRBool IsCellMapValid() const;
|
||||
|
||||
public:
|
||||
/** ResetCellMap is called when the cell structure of the table is changed.
|
||||
* Call with caution, only when changing the structure of the table such as
|
||||
* inserting or removing rows, changing the rowspan or colspan attribute of a cell, etc.
|
||||
*/
|
||||
virtual void ResetCellMap ();
|
||||
virtual void InvalidateCellMap();
|
||||
|
||||
protected:
|
||||
/** iterates all child frames and creates a new cell map */
|
||||
NS_IMETHOD ReBuildCellMap();
|
||||
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
virtual nsCellMap *GetCellMap();
|
||||
virtual nsCellMap *GetCellMap() const;
|
||||
|
||||
/** for debugging only
|
||||
* prints out information about the cell map
|
||||
@ -559,6 +589,7 @@ private:
|
||||
PRInt32 mColumnWidthsLength; // the number of column lengths this frame has allocated
|
||||
PRBool mColumnWidthsSet; // PR_TRUE if column widths have been set at least once
|
||||
PRBool mFirstPassValid; // PR_TRUE if first pass data is still legit
|
||||
PRBool mCellMapValid; // PR_TRUE if cell map data is still legit
|
||||
PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change
|
||||
PRInt32 mColCount; // the number of columns in this table
|
||||
PRInt32 mEffectiveColCount; // the number of columns in this table adjusted for weird table attributes
|
||||
|
@ -132,11 +132,11 @@ NS_METHOD nsTableOuterFrame::Paint(nsIPresContext& aPresContext,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsTableOuterFrame::NeedsReflow(const nsSize& aMaxSize)
|
||||
PRBool nsTableOuterFrame::NeedsReflow(const nsHTMLReflowState& aReflowState, const nsSize& aMaxSize)
|
||||
{
|
||||
PRBool result=PR_TRUE;
|
||||
if (nsnull!=mInnerTableFrame)
|
||||
result = ((nsTableFrame *)mInnerTableFrame)->NeedsReflow(aMaxSize);
|
||||
result = ((nsTableFrame *)mInnerTableFrame)->NeedsReflow(aReflowState, aMaxSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ protected:
|
||||
* or if the table style attributes or parent max height/width have
|
||||
* changed.
|
||||
*/
|
||||
PRBool NeedsReflow(const nsSize& aMaxSize);
|
||||
PRBool NeedsReflow(const nsHTMLReflowState& aReflowState, const nsSize& aMaxSize);
|
||||
|
||||
void PlaceChild(OuterTableReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
|
@ -39,10 +39,10 @@ NS_DEF_PTR(nsIStyleContext);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gsDebug = PR_FALSE;
|
||||
//#define NOISY
|
||||
//#define NOISY_FLOW
|
||||
static PRBool gsDebugIR = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
#endif
|
||||
|
||||
/* ----------- RowReflowState ---------- */
|
||||
@ -88,7 +88,8 @@ nsTableRowFrame::nsTableRowFrame(nsIContent* aContent,
|
||||
mTallestCell(0),
|
||||
mCellMaxTopMargin(0),
|
||||
mCellMaxBottomMargin(0),
|
||||
mMinRowSpan(1)
|
||||
mMinRowSpan(1),
|
||||
mInitializedChildren(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -100,13 +101,29 @@ NS_IMETHODIMP
|
||||
nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
mFirstChild = aChildList;
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableRowFrame::InitChildren(PRInt32 aRowIndex)
|
||||
{
|
||||
nsTableFrame* table = nsnull;
|
||||
nsresult result=NS_OK;
|
||||
|
||||
// each child cell can only be added to the table one time.
|
||||
// for now, we remember globally whether we've added all or none
|
||||
if (PR_FALSE==mInitializedChildren)
|
||||
{
|
||||
result = nsTableFrame::GetTableFrame(this, table);
|
||||
if ((NS_OK==result) && (table != nsnull))
|
||||
{
|
||||
SetRowIndex(table->GetNextAvailRowIndex());
|
||||
mInitializedChildren=PR_TRUE;
|
||||
PRInt32 rowIndex;
|
||||
if (-1==aRowIndex)
|
||||
rowIndex = table->GetNextAvailRowIndex();
|
||||
else
|
||||
rowIndex = aRowIndex;
|
||||
SetRowIndex(rowIndex);
|
||||
PRInt32 colIndex = 0;
|
||||
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame))
|
||||
{
|
||||
@ -142,6 +159,7 @@ nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -346,7 +364,7 @@ void nsTableRowFrame::FixMinCellHeight(nsTableFrame *aTableFrame)
|
||||
// aKidRect is relative to the upper-left origin of our frame, and includes
|
||||
// any left/top margin.
|
||||
void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
RowReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
@ -360,10 +378,10 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
aKidFrame->SetRect(aKidRect);
|
||||
|
||||
// update the running total for the row width
|
||||
aState.x += aKidRect.width;
|
||||
aReflowState.x += aKidRect.width;
|
||||
|
||||
// Update the maximum element size
|
||||
PRInt32 rowSpan = aState.tableFrame->GetEffectiveRowSpan(mRowIndex,
|
||||
PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan(mRowIndex,
|
||||
((nsTableCellFrame*)aKidFrame));
|
||||
if (nsnull != aMaxElementSize)
|
||||
{
|
||||
@ -377,18 +395,18 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
if (mMinRowSpan == rowSpan)
|
||||
{
|
||||
// Update maxCellHeight
|
||||
if (aKidRect.height > aState.maxCellHeight)
|
||||
aState.maxCellHeight = aKidRect.height;
|
||||
if (aKidRect.height > aReflowState.maxCellHeight)
|
||||
aReflowState.maxCellHeight = aKidRect.height;
|
||||
|
||||
// Update maxCellVertSpace
|
||||
nsMargin margin;
|
||||
|
||||
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK)
|
||||
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK)
|
||||
{
|
||||
nscoord height = aKidRect.height + margin.top + margin.bottom;
|
||||
|
||||
if (height > aState.maxCellVertSpace)
|
||||
aState.maxCellVertSpace = height;
|
||||
if (height > aReflowState.maxCellVertSpace)
|
||||
aReflowState.maxCellVertSpace = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -398,7 +416,7 @@ void nsTableRowFrame::PlaceChild(nsIPresContext& aPresContext,
|
||||
* changed. Reflows all the existing table cell frames
|
||||
*/
|
||||
nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
RowReflowState& aReflowState,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
if (nsnull == mFirstChild)
|
||||
@ -410,7 +428,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
&kidMaxElementSize : nsnull;
|
||||
nscoord maxCellTopMargin = 0;
|
||||
nscoord maxCellBottomMargin = 0;
|
||||
nscoord cellSpacing = aState.tableFrame->GetCellSpacing();
|
||||
nscoord cellSpacing = aReflowState.tableFrame->GetCellSpacing();
|
||||
PRInt32 cellColSpan=1; // must be defined here so it's set properly for non-cell kids
|
||||
if (PR_TRUE==gsDebug) printf("%p: RR\n", this);
|
||||
// Reflow each of our existing cell frames
|
||||
@ -421,7 +439,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
|
||||
{
|
||||
nsMargin kidMargin;
|
||||
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
maxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > maxCellBottomMargin)
|
||||
@ -434,31 +452,31 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
{ // if this cell is not immediately adjacent to the previous cell, factor in missing col info
|
||||
for (PRInt32 colIndex=prevColIndex+1; colIndex<cellColIndex; colIndex++)
|
||||
{
|
||||
aState.x += aState.tableFrame->GetColumnWidth(colIndex);
|
||||
aState.x += cellSpacing;
|
||||
aReflowState.x += aReflowState.tableFrame->GetColumnWidth(colIndex);
|
||||
aReflowState.x += cellSpacing;
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" in loop, aState.x set to %d from cellSpacing %d and col width\n",
|
||||
aState.x, aState.tableFrame->GetColumnWidth(colIndex), cellSpacing);
|
||||
printf(" in loop, aReflowState.x set to %d from cellSpacing %d and col width\n",
|
||||
aReflowState.x, aReflowState.tableFrame->GetColumnWidth(colIndex), cellSpacing);
|
||||
}
|
||||
}
|
||||
aState.x += cellSpacing;
|
||||
if (PR_TRUE==gsDebug) printf(" past loop, aState.x set to %d\n", aState.x);
|
||||
aReflowState.x += cellSpacing;
|
||||
if (PR_TRUE==gsDebug) printf(" past loop, aReflowState.x set to %d\n", aReflowState.x);
|
||||
|
||||
// at this point, we know the column widths.
|
||||
// so we get the avail width from the known column widths
|
||||
cellColSpan = aState.tableFrame->GetEffectiveColSpan(((nsTableCellFrame *)kidFrame)->GetColIndex(),
|
||||
cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(((nsTableCellFrame *)kidFrame)->GetColIndex(),
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
|
||||
{
|
||||
availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
availWidth += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
if (numColSpan != 0)
|
||||
{
|
||||
availWidth += cellSpacing;
|
||||
}
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf(" in loop, availWidth set to %d from colIndex %d width %d and cellSpacing\n",
|
||||
availWidth, cellColIndex, aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan), cellSpacing);
|
||||
availWidth, cellColIndex, aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan), cellSpacing);
|
||||
}
|
||||
if (PR_TRUE==gsDebug) printf(" availWidth for this cell is %d\n", availWidth);
|
||||
|
||||
@ -478,7 +496,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
|
||||
// Reflow the child
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aState.reflowState, kidAvailSize,
|
||||
aReflowState.reflowState, kidAvailSize,
|
||||
eReflowReason_Resize);
|
||||
if (gsDebug) printf ("%p RR: avail=%d\n", this, availWidth);
|
||||
nsReflowStatus status;
|
||||
@ -545,12 +563,12 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
// end special Nav4 compatibility code
|
||||
|
||||
// Place the child
|
||||
nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
pKidMaxElementSize);
|
||||
|
||||
if (PR_TRUE==gsDebug) printf(" past PlaceChild, aState.x set to %d\n", aState.x);
|
||||
if (PR_TRUE==gsDebug) printf(" past PlaceChild, aReflowState.x set to %d\n", aReflowState.x);
|
||||
}
|
||||
|
||||
// Get the next child
|
||||
@ -558,27 +576,27 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
// if this was the last child, and it had a colspan>1, add in the cellSpacing for the colspan
|
||||
// if the last kid wasn't a colspan, then we still have the colspan of the last real cell
|
||||
if ((nsnull==kidFrame) && (cellColSpan>1))
|
||||
aState.x += cellSpacing;
|
||||
aReflowState.x += cellSpacing;
|
||||
}
|
||||
|
||||
SetMaxChildHeight(aState.maxCellHeight,maxCellTopMargin, maxCellBottomMargin); // remember height of tallest child who doesn't have a row span
|
||||
SetMaxChildHeight(aReflowState.maxCellHeight,maxCellTopMargin, maxCellBottomMargin); // remember height of tallest child who doesn't have a row span
|
||||
|
||||
// Return our desired size. Note that our desired width is just whatever width
|
||||
// we were given by the row group frame
|
||||
aDesiredSize.width = aState.x;
|
||||
aDesiredSize.height = aState.maxCellVertSpace;
|
||||
aDesiredSize.width = aReflowState.x;
|
||||
aDesiredSize.height = aReflowState.maxCellVertSpace;
|
||||
|
||||
if (gsDebug)
|
||||
printf("rr -- row %p width = %d from maxSize %d\n",
|
||||
this, aDesiredSize.width, aState.reflowState.maxSize.width);
|
||||
this, aDesiredSize.width, aReflowState.reflowState.maxSize.width);
|
||||
|
||||
if (aDesiredSize.width > aState.reflowState.maxSize.width)
|
||||
if (aDesiredSize.width > aReflowState.reflowState.maxSize.width)
|
||||
{
|
||||
printf ("%p error case, desired width = %d, maxSize=%d\n",
|
||||
this, aDesiredSize.width, aState.reflowState.maxSize.width);
|
||||
this, aDesiredSize.width, aReflowState.reflowState.maxSize.width);
|
||||
fflush (stdout);
|
||||
}
|
||||
NS_ASSERTION(aDesiredSize.width <= aState.reflowState.maxSize.width, "row calculated to be too wide.");
|
||||
NS_ASSERTION(aDesiredSize.width <= aReflowState.reflowState.maxSize.width, "row calculated to be too wide.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -588,7 +606,7 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
|
||||
*/
|
||||
nsresult
|
||||
nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
RowReflowState& aReflowState,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
// Place our children, one at a time, until we are out of children
|
||||
@ -622,7 +640,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
nsMargin margin;
|
||||
nscoord topMargin = 0;
|
||||
|
||||
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
|
||||
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
|
||||
{
|
||||
topMargin = margin.top;
|
||||
}
|
||||
@ -647,7 +665,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
}
|
||||
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aState.reflowState, kidAvailSize,
|
||||
aReflowState.reflowState, kidAvailSize,
|
||||
eReflowReason_Initial);
|
||||
|
||||
if (gsDebug) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width);
|
||||
@ -677,17 +695,17 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
// Place the child
|
||||
x += margin.left;
|
||||
nsRect kidRect(x, topMargin, kidSize.width, kidSize.height);
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
&kidMaxElementSize);
|
||||
x += kidSize.width + margin.right;
|
||||
}
|
||||
}
|
||||
|
||||
SetMaxChildHeight(aState.maxCellHeight, maxTopMargin, maxBottomMargin); // remember height of tallest child who doesn't have a row span
|
||||
SetMaxChildHeight(aReflowState.maxCellHeight, maxTopMargin, maxBottomMargin); // remember height of tallest child who doesn't have a row span
|
||||
|
||||
// Return our desired size
|
||||
aDesiredSize.width = x;
|
||||
aDesiredSize.height = aState.maxCellVertSpace;
|
||||
aDesiredSize.height = aReflowState.maxCellVertSpace;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -700,7 +718,7 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
|
||||
// - maxVertCellSpace
|
||||
// - x
|
||||
nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
RowReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
nscoord& aMaxCellTopMargin,
|
||||
nscoord& aMaxCellBottomMargin)
|
||||
@ -710,8 +728,8 @@ nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
// Walk the list of children looking for aKidFrame. While we're at
|
||||
// it get the maxCellHeight and maxVertCellSpace for all the
|
||||
// frames except aKidFrame
|
||||
// nsIFrame* prevKidFrame = nsnull;
|
||||
for (nsIFrame* frame = mFirstChild; nsnull != frame;) {
|
||||
for (nsIFrame* frame = mFirstChild; nsnull != frame;)
|
||||
{
|
||||
const nsStyleDisplay *kidDisplay;
|
||||
frame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
|
||||
@ -719,13 +737,13 @@ nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
if (frame != aKidFrame) {
|
||||
// Update the max top and bottom margins
|
||||
nsMargin kidMargin;
|
||||
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, kidMargin);
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, kidMargin);
|
||||
if (kidMargin.top > aMaxCellTopMargin)
|
||||
aMaxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > aMaxCellBottomMargin)
|
||||
aMaxCellBottomMargin = kidMargin.bottom;
|
||||
|
||||
PRInt32 rowSpan = aState.tableFrame->GetEffectiveRowSpan(mRowIndex, ((nsTableCellFrame *)frame));
|
||||
PRInt32 rowSpan = aReflowState.tableFrame->GetEffectiveRowSpan(mRowIndex, ((nsTableCellFrame *)frame));
|
||||
if (mMinRowSpan == rowSpan) {
|
||||
// Get the cell's desired height the last time it was reflowed
|
||||
nsSize desiredSize = ((nsTableCellFrame *)frame)->GetDesiredSize();
|
||||
@ -751,18 +769,18 @@ nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
desiredSize.height = specifiedHeight;
|
||||
|
||||
// Update maxCellHeight
|
||||
if (desiredSize.height > aState.maxCellHeight) {
|
||||
aState.maxCellHeight = desiredSize.height;
|
||||
if (desiredSize.height > aReflowState.maxCellHeight) {
|
||||
aReflowState.maxCellHeight = desiredSize.height;
|
||||
}
|
||||
|
||||
// Update maxCellVertHeight
|
||||
nsMargin margin;
|
||||
|
||||
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, margin) == NS_OK)
|
||||
if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)frame, margin) == NS_OK)
|
||||
{
|
||||
nscoord height = desiredSize.height + margin.top + margin.bottom;
|
||||
if (height > aState.maxCellVertSpace) {
|
||||
aState.maxCellVertSpace = height;
|
||||
if (height > aReflowState.maxCellVertSpace) {
|
||||
aReflowState.maxCellVertSpace = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -775,44 +793,294 @@ nsresult nsTableRowFrame::RecoverState(nsIPresContext& aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the frame that precedes aKidFrame
|
||||
// prevKidFrame = frame;
|
||||
frame->GetNextSibling(frame);
|
||||
}
|
||||
|
||||
// Update the running x-offset based on the frame's current x-origin
|
||||
nsPoint origin;
|
||||
aKidFrame->GetOrigin(origin);
|
||||
aState.x = origin.x;
|
||||
aReflowState.x = origin.x;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
RowReflowState& aState,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nsresult status;
|
||||
|
||||
// XXX Deal with the case where the reflow command is targeted at us
|
||||
nsIFrame* target;
|
||||
aState.reflowState.reflowCommand->GetTarget(target);
|
||||
if (this == target) {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
NS_METHOD nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRF IR: IncrementalReflow\n");
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// determine if this frame is the target or not
|
||||
nsIFrame *target=nsnull;
|
||||
rv = aReflowState.reflowState.reflowCommand->GetTarget(target);
|
||||
if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target))
|
||||
{
|
||||
if (this==target)
|
||||
rv = IR_TargetIsMe(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
else
|
||||
{
|
||||
// Get the next frame in the reflow chain
|
||||
nsIFrame* nextFrame;
|
||||
aReflowState.reflowState.reflowCommand->GetNext(nextFrame);
|
||||
rv = IR_TargetIsChild(aPresContext, aDesiredSize, aReflowState, aStatus, nextFrame);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get the next frame in the reflow chain
|
||||
nsIFrame* kidFrame;
|
||||
aState.reflowState.reflowCommand->GetNext(kidFrame);
|
||||
NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_FRAME_COMPLETE;
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame);
|
||||
const nsStyleDisplay *childDisplay;
|
||||
objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: IncrementalReflow_TargetIsMe with type=%d\n", type);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_CellRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: StyleChanged not implemented.\n");
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::ContentChanged :
|
||||
NS_ASSERTION(PR_FALSE, "illegal reflow type: ContentChanged");
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::PullupReflow:
|
||||
case nsIReflowCommand::PushReflow:
|
||||
case nsIReflowCommand::CheckPullupReflow :
|
||||
case nsIReflowCommand::UserDefined :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_CellInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_DidAppendCell(nsTableRowFrame *aRowFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// since we know we're doing an append here, we can optimize
|
||||
NS_METHOD nsTableRowFrame::IR_CellAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
// 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 cell
|
||||
const nsStyleDisplay *childDisplay;
|
||||
nextChild->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
lastRow = nextChild;
|
||||
lastChild = nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aAppendedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aAppendedFrame);
|
||||
|
||||
aReflowState.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 col index of the new cell
|
||||
|
||||
// account for the new cell
|
||||
nsresult rv = DidAppendCell((nsTableCellFrame*)aAppendedFrame);
|
||||
|
||||
// need to increment the row index of all subsequent rows
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_CellRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//XXX: handle aReplace
|
||||
NS_METHOD nsTableRowFrame::IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
// we have a generic frame that gets inserted but doesn't effect reflow
|
||||
// hook it up then ignore it
|
||||
if (nsIReflowCommand::FrameAppended==type)
|
||||
{ // frameAppended reflow -- find the last child and make aInsertedFrame its next sibling
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: FrameAppended adding unknown frame type.\n");
|
||||
nsIFrame *lastChild=mFirstChild;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
lastChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aInsertedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aInsertedFrame);
|
||||
}
|
||||
else
|
||||
{ // frameInserted reflow -- hook up aInsertedFrame as prevSibling's next sibling,
|
||||
// and be sure to hook in aInsertedFrame's nextSibling (from prevSibling)
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: FrameInserted adding unknown frame type.\n");
|
||||
nsIFrame *prevSibling=nsnull;
|
||||
nsresult rv = aReflowState.reflowState.reflowCommand->GetPrevSiblingFrame(prevSibling);
|
||||
if (NS_SUCCEEDED(rv) && (nsnull!=prevSibling))
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
prevSibling->GetNextSibling(nextSibling);
|
||||
prevSibling->SetNextSibling(aInsertedFrame);
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
}
|
||||
return NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame)
|
||||
{
|
||||
// we have a generic frame that gets removed but doesn't effect reflow
|
||||
// unhook it then ignore it
|
||||
if (PR_TRUE==gsDebugIR) printf("TRF IR: FrameRemoved removing unknown frame type.\n");
|
||||
nsIFrame *prevChild=nsnull;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nextChild!=aRemovedFrame)
|
||||
{
|
||||
prevChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
nextChild=nsnull;
|
||||
aRemovedFrame->GetNextSibling(nextChild);
|
||||
if (nsnull==prevChild) // objectFrame was first child
|
||||
mFirstChild = nextChild;
|
||||
else
|
||||
prevChild->SetNextSibling(nextChild);
|
||||
return NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame)
|
||||
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
const nsStyleDisplay *childDisplay;
|
||||
aNextFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay)
|
||||
{
|
||||
// Recover our reflow state
|
||||
nscoord maxCellTopMargin, maxCellBottomMargin;
|
||||
RecoverState(aPresContext, aState, kidFrame, maxCellTopMargin, maxCellBottomMargin);
|
||||
RecoverState(aPresContext, aReflowState, aNextFrame, maxCellTopMargin, maxCellBottomMargin);
|
||||
|
||||
// Get the frame's margins
|
||||
nsMargin kidMargin;
|
||||
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
|
||||
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aNextFrame, kidMargin);
|
||||
if (kidMargin.top > maxCellTopMargin)
|
||||
maxCellTopMargin = kidMargin.top;
|
||||
if (kidMargin.bottom > maxCellBottomMargin)
|
||||
@ -820,13 +1088,13 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
|
||||
// At this point, we know the column widths. Get the available width
|
||||
// from the known column widths
|
||||
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
|
||||
PRInt32 cellColSpan = aState.tableFrame->GetEffectiveColSpan(((nsTableCellFrame *)kidFrame)->GetColIndex(),
|
||||
((nsTableCellFrame *)kidFrame));
|
||||
PRInt32 cellColIndex = ((nsTableCellFrame *)aNextFrame)->GetColIndex();
|
||||
PRInt32 cellColSpan = aReflowState.tableFrame->GetEffectiveColSpan(((nsTableCellFrame *)aNextFrame)->GetColIndex(),
|
||||
((nsTableCellFrame *)aNextFrame));
|
||||
nscoord availWidth = 0;
|
||||
for (PRInt32 numColSpan = 0; numColSpan < cellColSpan; numColSpan++)
|
||||
{
|
||||
availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
availWidth += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
|
||||
if (0<numColSpan)
|
||||
{
|
||||
availWidth += kidMargin.right;
|
||||
@ -843,14 +1111,14 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
// Pass along the reflow command
|
||||
nsSize kidMaxElementSize;
|
||||
nsHTMLReflowMetrics desiredSize(&kidMaxElementSize);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aState.reflowState,
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aNextFrame, aReflowState.reflowState,
|
||||
kidAvailSize);
|
||||
|
||||
// XXX Unfortunately we need to reflow the child several times.
|
||||
// The first time is for the incremental reflow command. We can't pass in
|
||||
// a max width of NS_UNCONSTRAINEDSIZE, because the max width must match
|
||||
// the width of the previous reflow...
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Now do the regular pass 1 reflow and gather the max width and max element
|
||||
// size.
|
||||
@ -859,10 +1127,10 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
kidReflowState.reason = eReflowReason_Resize;
|
||||
kidReflowState.reflowCommand = nsnull;
|
||||
kidReflowState.maxSize.width = NS_UNCONSTRAINEDSIZE;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
if (gsDebug)
|
||||
printf ("TR %p for cell %p Incremental Reflow: desired=%d, MES=%d\n",
|
||||
this, kidFrame, desiredSize.width, kidMaxElementSize.width);
|
||||
this, aNextFrame, desiredSize.width, kidMaxElementSize.width);
|
||||
// Update the cell layout data.
|
||||
//XXX: this is a hack, shouldn't it be the case that a min size is
|
||||
// never larger than a desired size?
|
||||
@ -870,13 +1138,13 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
desiredSize.width = kidMaxElementSize.width;
|
||||
if (kidMaxElementSize.height>desiredSize.height)
|
||||
desiredSize.height = kidMaxElementSize.height;
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(desiredSize);
|
||||
((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize);
|
||||
((nsTableCellFrame *)aNextFrame)->SetPass1DesiredSize(desiredSize);
|
||||
((nsTableCellFrame *)aNextFrame)->SetPass1MaxElementSize(kidMaxElementSize);
|
||||
|
||||
// Now reflow the cell again this time constraining the width
|
||||
// XXX Ignore for now the possibility that the column width has changed...
|
||||
kidReflowState.maxSize.width = availWidth;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Place the child after taking into account it's margin and attributes
|
||||
// XXX We need to ask the table (or the table layout strategy) if the column
|
||||
@ -885,7 +1153,7 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nscoord specifiedHeight = 0;
|
||||
nscoord cellHeight = desiredSize.height;
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(&aPresContext, kidSC.AssignRef());
|
||||
aNextFrame->GetStyleContext(&aPresContext, kidSC.AssignRef());
|
||||
const nsStylePosition* kidPosition = (const nsStylePosition*)
|
||||
kidSC->GetStyleData(eStyleStruct_Position);
|
||||
switch (kidPosition->mHeight.GetUnit()) {
|
||||
@ -906,30 +1174,35 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
// begin special Nav4 compatibility code
|
||||
if (0==cellWidth)
|
||||
{
|
||||
cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
|
||||
cellWidth = aReflowState.tableFrame->GetColumnWidth(cellColIndex);
|
||||
}
|
||||
// end special Nav4 compatibility code
|
||||
|
||||
// Now place the child
|
||||
nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
|
||||
|
||||
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
PlaceChild(aPresContext, aReflowState, aNextFrame, kidRect, aDesiredSize.maxElementSize,
|
||||
&kidMaxElementSize);
|
||||
|
||||
SetMaxChildHeight(aState.maxCellHeight, maxCellTopMargin, maxCellBottomMargin);
|
||||
SetMaxChildHeight(aReflowState.maxCellHeight, maxCellTopMargin, maxCellBottomMargin);
|
||||
|
||||
// Return our desired size. Note that our desired width is just whatever width
|
||||
// we were given by the row group frame
|
||||
aDesiredSize.width = aState.availSize.width;
|
||||
aDesiredSize.height = aState.maxCellVertSpace;
|
||||
aDesiredSize.width = aReflowState.availSize.width;
|
||||
aDesiredSize.height = aReflowState.maxCellVertSpace;
|
||||
|
||||
if (gsDebug)
|
||||
printf("incr -- row %p width = %d MES=%d from maxSize %d\n",
|
||||
this, aDesiredSize.width, aDesiredSize.maxElementSize->width,
|
||||
aState.reflowState.maxSize.width);
|
||||
|
||||
return status;
|
||||
aReflowState.reflowState.maxSize.width);
|
||||
}
|
||||
else
|
||||
{ // pass reflow to unknown frame child
|
||||
// aDesiredSize does not change
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/** Layout the entire row.
|
||||
* This method stacks cells horizontally according to HTML 4.0 rules.
|
||||
@ -940,45 +1213,46 @@ nsTableRowFrame::Reflow(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf("nsTableRowFrame::Reflow - aMaxSize = %d, %d\n",
|
||||
aReflowState.maxSize.width, aReflowState.maxSize.height);
|
||||
|
||||
// Initialize 'out' parameters
|
||||
// Initialize 'out' parameters (aStatus set below, undefined if rv returns an error)
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = 0;
|
||||
aDesiredSize.maxElementSize->height = 0;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE; // we're never continued
|
||||
|
||||
// Initialize our internal data
|
||||
ResetMaxChildHeight();
|
||||
|
||||
// Initialize our automatic state object
|
||||
nsTableFrame* tableFrame;
|
||||
mContentParent->GetContentParent((nsIFrame*&)tableFrame);
|
||||
// Create a reflow state
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return rv;
|
||||
RowReflowState state(aReflowState, tableFrame);
|
||||
|
||||
// Do the reflow
|
||||
nsresult result;
|
||||
|
||||
switch (aReflowState.reason) {
|
||||
case eReflowReason_Initial:
|
||||
result = InitialReflow(aPresContext, state, aDesiredSize);
|
||||
rv = InitialReflow(aPresContext, state, aDesiredSize);
|
||||
GetMinRowSpan(tableFrame);
|
||||
FixMinCellHeight(tableFrame);
|
||||
break;
|
||||
|
||||
case eReflowReason_Resize:
|
||||
result = ResizeReflow(aPresContext, state, aDesiredSize);
|
||||
rv = ResizeReflow(aPresContext, state, aDesiredSize);
|
||||
break;
|
||||
|
||||
case eReflowReason_Incremental:
|
||||
result = IncrementalReflow(aPresContext, state, aDesiredSize);
|
||||
rv = IncrementalReflow(aPresContext, aDesiredSize, state, aStatus);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE; // we're never continued
|
||||
|
||||
if (gsDebug==PR_TRUE)
|
||||
{
|
||||
if (nsnull!=aDesiredSize.maxElementSize)
|
||||
@ -992,7 +1266,7 @@ nsTableRowFrame::Reflow(nsIPresContext& aPresContext,
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
}
|
||||
|
||||
return result;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
|
@ -38,8 +38,13 @@ struct RowReflowState;
|
||||
class nsTableRowFrame : public nsContainerFrame
|
||||
{
|
||||
public:
|
||||
/** Initialization procedure */
|
||||
void Init(PRInt32 aRowIndex);
|
||||
/** Initialization of frame as a row */
|
||||
void InitRowData(PRInt32 aRowIndex);
|
||||
|
||||
/** Initialization of data */
|
||||
NS_IMETHOD InitChildren(PRInt32 aRowIndex=-1);
|
||||
|
||||
void ResetInitChildren();
|
||||
|
||||
/** instantiate a new instance of nsTableRowFrame.
|
||||
* @param aResult the new object is returned in this out-param
|
||||
@ -126,6 +131,64 @@ protected:
|
||||
/** destructor */
|
||||
virtual ~nsTableRowFrame();
|
||||
|
||||
/** Incremental Reflow attempts to do column balancing with the minimum number of reflow
|
||||
* commands to child elements. This is done by processing the reflow command,
|
||||
* rebalancing column widths (if necessary), then comparing the resulting column widths
|
||||
* to the prior column widths and reflowing only those cells that require a reflow.
|
||||
*
|
||||
* @see Reflow
|
||||
*/
|
||||
NS_IMETHOD IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame);
|
||||
|
||||
NS_IMETHOD IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_CellInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_CellAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_DidAppendCell(nsTableRowFrame *aRowFrame);
|
||||
|
||||
NS_IMETHOD IR_CellRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
|
||||
// row-specific methods
|
||||
|
||||
void GetMinRowSpan(nsTableFrame *aTableFrame);
|
||||
@ -180,11 +243,14 @@ private:
|
||||
nscoord mCellMaxTopMargin;
|
||||
nscoord mCellMaxBottomMargin;
|
||||
PRInt32 mMinRowSpan; // the smallest row span among all my child cells
|
||||
PRBool mInitializedChildren; // PR_TRUE if child cells have been initialized
|
||||
// (for now, that means "added to the table", and
|
||||
// is NOT the same as having nsIFrame::Init() called.)
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline void nsTableRowFrame::Init(PRInt32 aRowIndex)
|
||||
inline void nsTableRowFrame::InitRowData(PRInt32 aRowIndex)
|
||||
{
|
||||
NS_ASSERTION(0<=aRowIndex, "bad param row index");
|
||||
mRowIndex = aRowIndex;
|
||||
@ -196,4 +262,7 @@ inline PRInt32 nsTableRowFrame::GetRowIndex() const
|
||||
return (mRowIndex);
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::ResetInitChildren()
|
||||
{ mInitializedChildren=PR_FALSE; }
|
||||
|
||||
#endif
|
||||
|
@ -30,10 +30,10 @@
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static PRBool gsDebug = PR_FALSE;
|
||||
//#define NOISY
|
||||
//#define NOISY_FLOW
|
||||
static PRBool gsDebugIR = PR_FALSE;
|
||||
#else
|
||||
static const PRBool gsDebug = PR_FALSE;
|
||||
static const PRBool gsDebugIR = PR_FALSE;
|
||||
#endif
|
||||
|
||||
NS_DEF_PTR(nsIStyleContext);
|
||||
@ -42,8 +42,8 @@ NS_DEF_PTR(nsIContent);
|
||||
/* ----------- RowGroupReflowState ---------- */
|
||||
|
||||
struct RowGroupReflowState {
|
||||
// Our reflow state
|
||||
const nsHTMLReflowState& reflowState;
|
||||
nsIPresContext& mPresContext; // Our pres context
|
||||
const nsHTMLReflowState& reflowState; // Our reflow state
|
||||
|
||||
// The body's available size (computed from the body's parent)
|
||||
nsSize availSize;
|
||||
@ -65,9 +65,10 @@ struct RowGroupReflowState {
|
||||
// Remember the height of the first row, because it's our maxElementHeight (plus header/footers)
|
||||
nscoord firstRowHeight;
|
||||
|
||||
RowGroupReflowState(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState)
|
||||
: reflowState(aReflowState)
|
||||
: mPresContext(aPresContext),
|
||||
reflowState(aReflowState)
|
||||
{
|
||||
availSize.width = reflowState.maxSize.width;
|
||||
availSize.height = reflowState.maxSize.height;
|
||||
@ -686,7 +687,7 @@ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,
|
||||
delete []rowHeights;
|
||||
}
|
||||
|
||||
nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||
nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsIFrame* aKidFrame,
|
||||
nscoord aDeltaY)
|
||||
@ -708,7 +709,7 @@ nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext* aP
|
||||
// XXX We need to send move notifications to the frame...
|
||||
nsIHTMLReflow* htmlReflow;
|
||||
if (NS_OK == kidFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
|
||||
htmlReflow->WillReflow(*aPresContext);
|
||||
htmlReflow->WillReflow(aPresContext);
|
||||
}
|
||||
kidFrame->MoveTo(origin.x, origin.y);
|
||||
|
||||
@ -742,6 +743,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf("nsTableRowGroupFrame::Reflow - aMaxSize = %d, %d\n",
|
||||
aReflowState.maxSize.width, aReflowState.maxSize.height);
|
||||
@ -752,45 +754,10 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
aDesiredSize.maxElementSize->height = 0;
|
||||
}
|
||||
|
||||
RowGroupReflowState state(&aPresContext, aReflowState);
|
||||
RowGroupReflowState state(aPresContext, aReflowState);
|
||||
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
nsIFrame* target;
|
||||
aReflowState.reflowCommand->GetTarget(target);
|
||||
if (this == target) {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
}
|
||||
|
||||
// XXX Recover state
|
||||
// XXX Deal with the case where the reflow command is targeted at us
|
||||
nsIFrame* kidFrame;
|
||||
aReflowState.reflowCommand->GetNext(kidFrame);
|
||||
|
||||
// Remember the old rect
|
||||
nsRect oldKidRect;
|
||||
kidFrame->GetRect(oldKidRect);
|
||||
|
||||
// Pass along the reflow command
|
||||
// XXX Correctly compute the available space...
|
||||
nsHTMLReflowState kidReflowState(aPresContext, kidFrame,
|
||||
aReflowState, aReflowState.maxSize);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Resize the row frame
|
||||
nsRect kidRect;
|
||||
kidFrame->GetRect(kidRect);
|
||||
kidFrame->SizeTo(desiredSize.width, desiredSize.height);
|
||||
|
||||
// Adjust the frames that follow...
|
||||
AdjustSiblingsAfterReflow(&aPresContext, state, kidFrame, desiredSize.height -
|
||||
oldKidRect.height);
|
||||
|
||||
// Return of desired size
|
||||
aDesiredSize.width = aReflowState.maxSize.width;
|
||||
aDesiredSize.height = state.y;
|
||||
|
||||
rv = IncrementalReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
} else {
|
||||
PRBool reflowMappedOK = PR_TRUE;
|
||||
|
||||
@ -855,10 +822,329 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IncrementalReflow\n");
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// create an inner table reflow state
|
||||
RowGroupReflowState state(aPresContext, aReflowState);
|
||||
|
||||
// determine if this frame is the target or not
|
||||
nsIFrame *target=nsnull;
|
||||
rv = aReflowState.reflowCommand->GetTarget(target);
|
||||
if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target))
|
||||
{
|
||||
if (this==target)
|
||||
rv = IR_TargetIsMe(aPresContext, aDesiredSize, state, aStatus);
|
||||
else
|
||||
{
|
||||
// Get the next frame in the reflow chain
|
||||
nsIFrame* nextFrame;
|
||||
aReflowState.reflowCommand->GetNext(nextFrame);
|
||||
|
||||
// Recover our reflow state
|
||||
//RecoverState(state, nextFrame);
|
||||
rv = IR_TargetIsChild(aPresContext, aDesiredSize, state, aStatus, nextFrame);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_FRAME_COMPLETE;
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
nsIFrame *objectFrame;
|
||||
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);
|
||||
switch (type)
|
||||
{
|
||||
case nsIReflowCommand::FrameInserted :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameAppended :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
|
||||
}
|
||||
else
|
||||
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
|
||||
rv = IR_UnknownFrameInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
case nsIReflowCommand::FrameReplaced :
|
||||
|
||||
*/
|
||||
|
||||
case nsIReflowCommand::FrameRemoved :
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
rv = IR_RowRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
|
||||
objectFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::StyleChanged :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: StyleChanged not implemented.\n");
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::ContentChanged :
|
||||
NS_ASSERTION(PR_FALSE, "illegal reflow type: ContentChanged");
|
||||
rv = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::PullupReflow:
|
||||
case nsIReflowCommand::PushReflow:
|
||||
case nsIReflowCommand::CheckPullupReflow :
|
||||
case nsIReflowCommand::UserDefined :
|
||||
NS_NOTYETIMPLEMENTED("unimplemented reflow command type");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: reflow command not implemented.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_RowInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
// inserting the rowgroup only effects reflow if the rowgroup includes at least one row
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_DidAppendRow(nsTableRowFrame *aRowFrame)
|
||||
{
|
||||
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.
|
||||
it will automatically find the row to initialize into.
|
||||
but this is tough because a cell in aInsertedFrame could have a rowspan
|
||||
which must be respected if a subsequent row is appended.
|
||||
*/
|
||||
rv = aRowFrame->InitChildren();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
// 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)
|
||||
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!=
|
||||
|
||||
lastChild=mFirstChild;
|
||||
nextChild=lastChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
}
|
||||
// account for the cells in aAppendedFrame
|
||||
nsresult rv = DidAppendRow((nsTableRowFrame*)aAppendedFrame, newRowIndex);
|
||||
|
||||
// need to increment the row index of all subsequent rows
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_RowRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//XXX: handle aReplace
|
||||
NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace)
|
||||
{
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowState.reflowState.reflowCommand->GetType(type);
|
||||
// we have a generic frame that gets inserted but doesn't effect reflow
|
||||
// hook it up then ignore it
|
||||
if (nsIReflowCommand::FrameAppended==type)
|
||||
{ // frameAppended reflow -- find the last child and make aInsertedFrame its next sibling
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: FrameAppended adding unknown frame type.\n");
|
||||
nsIFrame *lastChild=mFirstChild;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nsnull!=nextChild)
|
||||
{
|
||||
lastChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
if (nsnull==lastChild)
|
||||
mFirstChild = aInsertedFrame;
|
||||
else
|
||||
lastChild->SetNextSibling(aInsertedFrame);
|
||||
}
|
||||
else
|
||||
{ // frameInserted reflow -- hook up aInsertedFrame as prevSibling's next sibling,
|
||||
// and be sure to hook in aInsertedFrame's nextSibling (from prevSibling)
|
||||
if (PR_TRUE==gsDebugIR) printf("TRGF IR: FrameInserted adding unknown frame type.\n");
|
||||
nsIFrame *prevSibling=nsnull;
|
||||
nsresult rv = aReflowState.reflowState.reflowCommand->GetPrevSiblingFrame(prevSibling);
|
||||
if (NS_SUCCEEDED(rv) && (nsnull!=prevSibling))
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
prevSibling->GetNextSibling(nextSibling);
|
||||
prevSibling->SetNextSibling(aInsertedFrame);
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsIFrame *nextSibling=nsnull;
|
||||
if (nsnull!=mFirstChild)
|
||||
mFirstChild->GetNextSibling(nextSibling);
|
||||
mFirstChild = aInsertedFrame;
|
||||
aInsertedFrame->SetNextSibling(nextSibling);
|
||||
}
|
||||
}
|
||||
return NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aRemovedFrame)
|
||||
{
|
||||
// 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");
|
||||
nsIFrame *prevChild=nsnull;
|
||||
nsIFrame *nextChild=mFirstChild;
|
||||
while (nextChild!=aRemovedFrame)
|
||||
{
|
||||
prevChild=nextChild;
|
||||
nextChild->GetNextSibling(nextChild);
|
||||
}
|
||||
nextChild=nsnull;
|
||||
aRemovedFrame->GetNextSibling(nextChild);
|
||||
if (nsnull==prevChild) // objectFrame was first child
|
||||
mFirstChild = nextChild;
|
||||
else
|
||||
prevChild->SetNextSibling(nextChild);
|
||||
return NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
NS_METHOD nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame)
|
||||
|
||||
{
|
||||
nsresult rv;
|
||||
if (PR_TRUE==gsDebugIR) printf("\nTRGF IR: IR_TargetIsChild\n");
|
||||
// XXX Recover state
|
||||
|
||||
// Remember the old rect
|
||||
nsRect oldKidRect;
|
||||
aNextFrame->GetRect(oldKidRect);
|
||||
|
||||
// Pass along the reflow command
|
||||
// XXX Correctly compute the available space...
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aNextFrame, aReflowState.reflowState, aReflowState.reflowState.maxSize);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState, aStatus);
|
||||
|
||||
// Resize the row frame
|
||||
nsRect kidRect;
|
||||
aNextFrame->GetRect(kidRect);
|
||||
aNextFrame->SizeTo(desiredSize.width, desiredSize.height);
|
||||
|
||||
// Adjust the frames that follow...
|
||||
AdjustSiblingsAfterReflow(aPresContext, aReflowState, aNextFrame, desiredSize.height -
|
||||
oldKidRect.height);
|
||||
|
||||
// Return of desired size
|
||||
aDesiredSize.width = aReflowState.reflowState.maxSize.width;
|
||||
aDesiredSize.height = aReflowState.y;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsTableRowGroupFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
nsIFrame* aParent,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
class nsTableRowFrame;
|
||||
struct RowGroupReflowState;
|
||||
|
||||
/**
|
||||
@ -79,6 +80,65 @@ public:
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
/** Incremental Reflow attempts to do column balancing with the minimum number of reflow
|
||||
* commands to child elements. This is done by processing the reflow command,
|
||||
* rebalancing column widths (if necessary), then comparing the resulting column widths
|
||||
* to the prior column widths and reflowing only those cells that require a reflow.
|
||||
*
|
||||
* @see Reflow
|
||||
*/
|
||||
NS_IMETHOD IncrementalReflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_TargetIsChild(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aNextFrame);
|
||||
|
||||
NS_IMETHOD IR_TargetIsMe(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD IR_RowInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_RowAppended(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aAppendedFrame);
|
||||
|
||||
NS_IMETHOD IR_DidAppendRow(nsTableRowFrame *aRowFrame);
|
||||
|
||||
NS_IMETHOD IR_RowRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aInsertedFrame,
|
||||
PRBool aReplace);
|
||||
|
||||
NS_IMETHOD IR_UnknownFrameRemoved(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus,
|
||||
nsIFrame * aDeletedFrame);
|
||||
|
||||
|
||||
|
||||
/** @see nsContainerFrame::CreateContinuingFrame */
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||
nsIFrame* aParent,
|
||||
@ -111,11 +171,11 @@ protected:
|
||||
~nsTableRowGroupFrame();
|
||||
|
||||
nscoord GetTopMarginFor(nsIPresContext* aCX,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
const nsMargin& aKidMargin);
|
||||
|
||||
void PlaceChild( nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
const nsRect& aKidRect,
|
||||
nsSize* aMaxElementSize,
|
||||
@ -124,8 +184,8 @@ protected:
|
||||
void ShrinkWrapChildren(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
nsresult AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
nsresult AdjustSiblingsAfterReflow(nsIPresContext& aPresContext,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame,
|
||||
nscoord aDeltaY);
|
||||
|
||||
@ -133,24 +193,24 @@ protected:
|
||||
* 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 ReflowMappedChildren(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsSize* aMaxElementSize);
|
||||
|
||||
/**
|
||||
* 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 PullUpChildren(nsIPresContext* aPresContext,
|
||||
RowGroupReflowState& aState,
|
||||
RowGroupReflowState& aReflowState,
|
||||
nsSize* aMaxElementSize);
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user