diff --git a/mozilla/layout/html/table/src/nsCellMap.h b/mozilla/layout/html/table/src/nsCellMap.h
index e5e9a23f71b..723536e3aad 100644
--- a/mozilla/layout/html/table/src/nsCellMap.h
+++ b/mozilla/layout/html/table/src/nsCellMap.h
@@ -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:
*
@@ -227,5 +230,11 @@ inline void nsCellMap::AppendColumnFrame(nsTableColFrame *aColFrame)
mColFrames->AppendElement(aColFrame);
}
+inline void nsCellMap::ClearColumnCache()
+{
+ if (nsnull!=mColFrames)
+ mColFrames->Clear();
+}
+
#endif
diff --git a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp
index c7a676ddc00..ffd056193bd 100644
--- a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp
@@ -52,87 +52,89 @@ nsresult
nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
nsresult rv=NS_OK;
- nsIFrame* tableFrame=nsnull;
- GetGeometricParent(tableFrame);
- // Process the newly added column frames
- for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
- // Set the preliminary values for the column frame
- nsIContent* kid;
- kidFrame->GetContent(kid);
- // should use style to get this value
- PRInt32 repeat=1;
- nsIHTMLTableColElement* colContent = nsnull;
- rv = kid->QueryInterface(kIHTMLTableColElementIID,
- (void**) &colContent); // colContent: ADDREF++
- NS_RELEASE(kid);
- if (rv==NS_OK)
- {
- colContent->GetSpanValue(&repeat);
- NS_RELEASE(colContent);
- }
- PRInt32 colIndex = mStartColIndex + mColCount;
- ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
- mColCount+= repeat;
- ((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
- ((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame);
- }
- // colgroup's span attribute is how many columns the group represents
- // in the absence of any COL children
- if (0==mColCount)
+ nsTableFrame* tableFrame=nsnull;
+ rv = nsTableFrame::GetTableFrame(this, tableFrame);
+ if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
{
- nsIFrame *firstImplicitColFrame=nsnull;
- nsIFrame *prevColFrame=nsnull;
- nsAutoString colTag;
- nsHTMLAtoms::col->ToString(colTag);
- mColCount = GetSpan();
- for (PRInt32 colIndex=0; colIndexAppendChildTo((nsIContent*)col, PR_FALSE);
-
- // Create a new col frame
- nsIFrame* colFrame;
- NS_NewTableColFrame(col, this, colFrame);
-
- // Set its style context
- nsIStyleContextPtr colStyleContext =
- aPresContext.ResolveStyleContextFor(col, this, PR_TRUE);
- colFrame->SetStyleContext(&aPresContext, colStyleContext);
- colFrame->Init(aPresContext, nsnull);
-
- // Set nsColFrame-specific information
- PRInt32 absColIndex = mStartColIndex + colIndex;
- ((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1);
- ((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
- ((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)colFrame);
-
- //hook into list of children
- if (nsnull==firstImplicitColFrame)
- firstImplicitColFrame = colFrame;
- else
- prevColFrame->SetNextSibling(colFrame);
- prevColFrame = colFrame;
- }
- // hook new columns into col group child list
- if (nsnull==mFirstChild)
- mFirstChild = firstImplicitColFrame;
- else
- {
- nsIFrame *lastChild = mFirstChild;
- nsIFrame *nextChild = lastChild;
- while (nsnull!=nextChild)
+ // Process the newly added column frames
+ for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
+ // Set the preliminary values for the column frame
+ nsIContent* kid;
+ kidFrame->GetContent(kid);
+ // should use style to get this value
+ PRInt32 repeat=1;
+ nsIHTMLTableColElement* colContent = nsnull;
+ rv = kid->QueryInterface(kIHTMLTableColElementIID,
+ (void**) &colContent); // colContent: ADDREF++
+ NS_RELEASE(kid);
+ if (rv==NS_OK)
{
- lastChild = nextChild;
- nextChild->GetNextSibling(nextChild);
+ colContent->GetSpanValue(&repeat);
+ NS_RELEASE(colContent);
}
- lastChild->SetNextSibling(firstImplicitColFrame);
+ PRInt32 colIndex = mStartColIndex + mColCount;
+ ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
+ mColCount+= repeat;
+ ((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
+ tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame);
}
- }
- SetStyleContextForFirstPass(aPresContext);
+ // colgroup's span attribute is how many columns the group represents
+ // in the absence of any COL children
+ if (0==mColCount)
+ {
+ nsIFrame *firstImplicitColFrame=nsnull;
+ nsIFrame *prevColFrame=nsnull;
+ nsAutoString colTag;
+ nsHTMLAtoms::col->ToString(colTag);
+ mColCount = GetSpan();
+ for (PRInt32 colIndex=0; colIndexAppendChildTo((nsIContent*)col, PR_FALSE);
+ // Create a new col frame
+ nsIFrame* colFrame;
+ NS_NewTableColFrame(col, this, colFrame);
+
+ // Set its style context
+ nsIStyleContextPtr colStyleContext =
+ aPresContext.ResolveStyleContextFor(col, this, PR_TRUE);
+ colFrame->SetStyleContext(&aPresContext, colStyleContext);
+ colFrame->Init(aPresContext, nsnull);
+
+ // Set nsColFrame-specific information
+ PRInt32 absColIndex = mStartColIndex + colIndex;
+ ((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1);
+ ((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
+ tableFrame->AddColumnFrame((nsTableColFrame *)colFrame);
+
+ //hook into list of children
+ if (nsnull==firstImplicitColFrame)
+ firstImplicitColFrame = colFrame;
+ else
+ prevColFrame->SetNextSibling(colFrame);
+ prevColFrame = colFrame;
+ }
+ // hook new columns into col group child list
+ if (nsnull==mFirstChild)
+ mFirstChild = firstImplicitColFrame;
+ else
+ {
+ nsIFrame *lastChild = mFirstChild;
+ nsIFrame *nextChild = lastChild;
+ while (nsnull!=nextChild)
+ {
+ lastChild = nextChild;
+ nextChild->GetNextSibling(nextChild);
+ }
+ lastChild->SetNextSibling(firstImplicitColFrame);
+ }
+ }
+ SetStyleContextForFirstPass(aPresContext);
+ }
return rv;
}
@@ -233,54 +235,55 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPresContext)
{
// get the table frame
- nsIFrame* tableFrame=nsnull;
- GetGeometricParent(tableFrame);
-
- // get the style for the table frame
- nsStyleTable *tableStyle;
- tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
+ 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);
- // if COLS is set, then map it into the COL frames
- if (NS_STYLE_TABLE_COLS_NONE != tableStyle->mCols)
- {
- // set numCols to the number of columns effected by the COLS attribute
- PRInt32 numCols=0;
- if (NS_STYLE_TABLE_COLS_ALL == tableStyle->mCols)
- numCols = LengthOf(mFirstChild);
- else
- numCols = tableStyle->mCols;
-
- // for every column effected, set its width style
- PRInt32 colIndex=0;
- nsIFrame *colFrame=mFirstChild;
- while (nsnull!=colFrame)
+ // if COLS is set, then map it into the COL frames
+ if (NS_STYLE_TABLE_COLS_NONE != tableStyle->mCols)
{
- nsStyleDisplay * colDisplay=nsnull;
- colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
- if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
- {
- nsIStyleContextPtr colStyleContext;
- nsStylePosition * colPosition=nsnull;
- colFrame->GetStyleContext(&aPresContext, colStyleContext.AssignRef());
- colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
- if (colIndexmWidth = width;
- }
- else
- {
- colPosition->mWidth.SetCoordValue(0);
- }
- colStyleContext->RecalcAutomaticData(&aPresContext);
- colIndex++;
- }
- colFrame->GetNextSibling(colFrame);
- }
+ // set numCols to the number of columns effected by the COLS attribute
+ PRInt32 numCols=0;
+ if (NS_STYLE_TABLE_COLS_ALL == tableStyle->mCols)
+ numCols = LengthOf(mFirstChild);
+ else
+ numCols = tableStyle->mCols;
- mStyleContext->RecalcAutomaticData(&aPresContext);
+ // for every column effected, set its width style
+ PRInt32 colIndex=0;
+ nsIFrame *colFrame=mFirstChild;
+ while (nsnull!=colFrame)
+ {
+ nsStyleDisplay * colDisplay=nsnull;
+ colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
+ {
+ nsIStyleContextPtr colStyleContext;
+ nsStylePosition * colPosition=nsnull;
+ colFrame->GetStyleContext(&aPresContext, colStyleContext.AssignRef());
+ colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
+ if (colIndexmWidth = width;
+ }
+ else
+ {
+ colPosition->mWidth.SetCoordValue(0);
+ }
+ colStyleContext->RecalcAutomaticData(&aPresContext);
+ colIndex++;
+ }
+ colFrame->GetNextSibling(colFrame);
+ }
+ mStyleContext->RecalcAutomaticData(&aPresContext);
+ }
}
- return NS_OK;
+ return rv;
}
diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp
index dcf88de6ec8..64e775c30a1 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableFrame.cpp
@@ -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,11 +299,44 @@ 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 ******* */
/* return the next row group frame after aRowGroupFrame */
@@ -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();
- 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);
- }
+ NS_ASSERTION(nsnull!=cellMap, "GetRowCount null cellmap");
+ if (nsnull!=cellMap)
+ 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(0mDisplay))
- { // XXX: assumes content order
- firstRowGroupFrame = childFrame;
- if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame);
- break;
+ {
+ if (nsnull==firstRowGroupFrame)
+ {
+ firstRowGroupFrame = childFrame;
+ if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame);
+ }
}
- prevSibFrame = childFrame;
+ if (nsnull==firstRowGroupFrame)
+ prevSibFrame = childFrame;
childFrame->GetNextSibling(childFrame);
}
PRInt32 colCount = GetColCount();
@@ -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,11 +782,12 @@ 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
- firstRowGroupFrame = childFrame;
- break;
+ {
+ if (nsnull==firstRowGroupFrame)
+ firstRowGroupFrame = childFrame;
}
- prevSibFrame = childFrame;
+ if (nsnull==firstRowGroupFrame)
+ prevSibFrame = childFrame;
childFrame->GetNextSibling(childFrame);
}
if (actualColumns <= aColIndex)
@@ -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 (PR_TRUE==mIsInvariantWidth)
- result = PR_FALSE;
- // TODO: other cases...
+ if (eReflowReason_Incremental != aReflowState.reason)
+ { // incremental reflows always need to be reflowed (for now)
+ if (PR_TRUE==mIsInvariantWidth)
+ result = PR_FALSE;
+ // 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 (0FirstChild(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; colGroupIndexInitialize(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,95 +2938,95 @@ 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)
{
- mColCache = new ColumnInfoCache(mColCount);
- nsIFrame * childFrame = mFirstChild;
- while (nsnull!=childFrame)
- { // in this loop, we cache column info and set column style info from cells in first row
- const nsStyleDisplay *childDisplay;
- childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (PR_TRUE==gsDebugIR) printf("TIF BCB: clearing column cache and cell map column frame cache.\n");
+ mCellMap->ClearColumnCache();
+ delete mColCache;
+ }
- if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
- { // if it's a col group then get the columns and cache them in the CellMap
- nsTableColFrame *colFrame=nsnull;
- childFrame->FirstChild((nsIFrame *&)colFrame);
- while (nsnull!=colFrame)
- {
- mCellMap->AppendColumnFrame(colFrame);
- colFrame->GetNextSibling((nsIFrame *&)colFrame);
- }
+ mColCache = new ColumnInfoCache(mColCount);
+ nsIFrame * childFrame = mFirstChild;
+ while (nsnull!=childFrame)
+ { // in this loop, we cache column info and set column style info from cells in first row
+ const nsStyleDisplay *childDisplay;
+ childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ { // if it's a col group then get the columns and cache them in the CellMap
+ nsTableColFrame *colFrame=nsnull;
+ childFrame->FirstChild((nsIFrame *&)colFrame);
+ while (nsnull!=colFrame)
+ {
+ mCellMap->AppendColumnFrame(colFrame);
+ colFrame->GetNextSibling((nsIFrame *&)colFrame);
}
- else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
- { // if it's a row group, get the cells and set the column style if appropriate
- if (NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy)
- {
- nsIFrame *rowFrame;
- childFrame->FirstChild(rowFrame);
- while (nsnull!=rowFrame)
- {
- const nsStyleDisplay *rowDisplay;
- rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowDisplay));
- if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
- {
- nsIFrame *cellFrame;
- rowFrame->FirstChild(cellFrame);
- while (nsnull!=cellFrame)
- {
- /* this is the first time we are guaranteed to have both the cell frames
- * and the column frames, so it's a good time to
- * set the column style from the cell's width attribute (if this is the first row)
- */
- const nsStyleDisplay *cellDisplay;
- cellFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)cellDisplay));
- if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay)
- SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
- cellFrame->GetNextSibling(cellFrame);
- }
- }
- rowFrame->GetNextSibling(rowFrame);
- }
- }
- }
- childFrame->GetNextSibling(childFrame);
}
-
- // second time through, set column cache info for each column
- // we can't do this until the loop above has set the column style info from the cells in the first row
- childFrame = mFirstChild;
- while (nsnull!=childFrame)
- { // for every child, if it's a col group then get the columns
- const nsStyleDisplay *childDisplay;
- childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
- if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
+ { // if it's a row group, get the cells and set the column style if appropriate
+ if (NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy)
{
- nsTableColFrame *colFrame=nsnull;
- childFrame->FirstChild((nsIFrame *&)colFrame);
- while (nsnull!=colFrame)
- { // for every column, create an entry in the column cache
- // assumes that the col style has been twiddled to account for first cell width attribute
- const nsStyleDisplay *colDisplay;
- colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
- if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
+ nsIFrame *rowFrame;
+ childFrame->FirstChild(rowFrame);
+ while (nsnull!=rowFrame)
+ {
+ const nsStyleDisplay *rowDisplay;
+ rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
{
- const nsStylePosition* colPosition;
- colFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)colPosition));
- mColCache->AddColumnInfo(colPosition->mWidth.GetUnit(), colFrame->GetColumnIndex());
+ nsIFrame *cellFrame;
+ rowFrame->FirstChild(cellFrame);
+ while (nsnull!=cellFrame)
+ {
+ /* this is the first time we are guaranteed to have both the cell frames
+ * and the column frames, so it's a good time to
+ * set the column style from the cell's width attribute (if this is the first row)
+ */
+ const nsStyleDisplay *cellDisplay;
+ cellFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)cellDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay)
+ SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
+ cellFrame->GetNextSibling(cellFrame);
+ }
}
- colFrame->GetNextSibling((nsIFrame *&)colFrame);
+ rowFrame->GetNextSibling(rowFrame);
}
}
- else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
- { // XXX: assumes content order
- break; // once we hit a row group, we're done
- }
- childFrame->GetNextSibling(childFrame);
}
+ childFrame->GetNextSibling(childFrame);
+ }
+
+ // second time through, set column cache info for each column
+ // we can't do this until the loop above has set the column style info from the cells in the first row
+ childFrame = mFirstChild;
+ while (nsnull!=childFrame)
+ { // for every child, if it's a col group then get the columns
+ const nsStyleDisplay *childDisplay;
+ childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ {
+ nsTableColFrame *colFrame=nsnull;
+ childFrame->FirstChild((nsIFrame *&)colFrame);
+ while (nsnull!=colFrame)
+ { // for every column, create an entry in the column cache
+ // assumes that the col style has been twiddled to account for first cell width attribute
+ const nsStyleDisplay *colDisplay;
+ colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
+ {
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)colPosition));
+ mColCache->AddColumnInfo(colPosition->mWidth.GetUnit(), colFrame->GetColumnIndex());
+ }
+ colFrame->GetNextSibling((nsIFrame *&)colFrame);
+ }
+ }
+ childFrame->GetNextSibling(childFrame);
}
}
@@ -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;
+ }
+ rv = childFrame->GetNextSibling(childFrame);
+ }
break;
- result = aOutFrame->GetContentParent((nsIFrame *&)aOutFrame);
+ }
+ 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;
}
diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h
index db2c20038a2..af7c9a5bb8f 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.h
+++ b/mozilla/layout/html/table/src/nsTableFrame.h
@@ -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
diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp
index fa7585144e5..f002487dfdb 100644
--- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp
@@ -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;
}
diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.h b/mozilla/layout/html/table/src/nsTableOuterFrame.h
index 539d6013569..316601f159e 100644
--- a/mozilla/layout/html/table/src/nsTableOuterFrame.h
+++ b/mozilla/layout/html/table/src/nsTableOuterFrame.h
@@ -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,
diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
index 22742db37c0..14d07ef3cec 100644
--- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
@@ -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,45 +101,62 @@ NS_IMETHODIMP
nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
mFirstChild = aChildList;
- nsTableFrame* table = nsnull;
- nsresult result;
+ return NS_OK;
+}
- result = nsTableFrame::GetTableFrame(this, table);
- if ((NS_OK==result) && (table != nsnull))
+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)
{
- SetRowIndex(table->GetNextAvailRowIndex());
- PRInt32 colIndex = 0;
- for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame))
+ result = nsTableFrame::GetTableFrame(this, table);
+ if ((NS_OK==result) && (table != nsnull))
{
- const nsStyleDisplay *kidDisplay;
- kidFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
- if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
+ 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))
{
- // what column does this cell belong to?
- colIndex = table->GetNextAvailColIndex(mRowIndex, colIndex);
- /* for style context optimization, set the content's column index if possible.
- * this can only be done if we really have an nsTableCell.
- * other tags mapped to table cell display won't benefit from this optimization
- * see nsHTMLStyleSheet::RulesMatching
- */
- nsIContent* cell;
- kidFrame->GetContent(cell);
- nsIHTMLTableCellElement *cellContent = nsnull;
- nsresult rv = cell->QueryInterface(kIHTMLTableCellElementIID,
- (void **)&cellContent); // cellContent: REFCNT++
- NS_RELEASE(cell);
- if (NS_SUCCEEDED(rv))
- { // we know it's a table cell
- cellContent->SetColIndex(colIndex);
- if (gsDebug) printf("%p : set cell content %p to col index = %d\n", this, cellContent, colIndex);
- NS_RELEASE(cellContent);
- }
+ const nsStyleDisplay *kidDisplay;
+ kidFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
+ {
+ // what column does this cell belong to?
+ colIndex = table->GetNextAvailColIndex(mRowIndex, colIndex);
+ /* for style context optimization, set the content's column index if possible.
+ * this can only be done if we really have an nsTableCell.
+ * other tags mapped to table cell display won't benefit from this optimization
+ * see nsHTMLStyleSheet::RulesMatching
+ */
+ nsIContent* cell;
+ kidFrame->GetContent(cell);
+ nsIHTMLTableCellElement *cellContent = nsnull;
+ nsresult rv = cell->QueryInterface(kIHTMLTableCellElementIID,
+ (void **)&cellContent); // cellContent: REFCNT++
+ NS_RELEASE(cell);
+ if (NS_SUCCEEDED(rv))
+ { // we know it's a table cell
+ cellContent->SetColIndex(colIndex);
+ if (gsDebug) printf("%p : set cell content %p to col index = %d\n", this, cellContent, colIndex);
+ NS_RELEASE(cellContent);
+ }
- // this sets the frame's notion of it's column index
- ((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
- if (gsDebug) printf("%p : set cell frame %p to col index = %d\n", this, kidFrame, colIndex);
- // add the cell frame to the table's cell map
- table->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild);
+ // this sets the frame's notion of it's column index
+ ((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
+ if (gsDebug) printf("%p : set cell frame %p to col index = %d\n", this, kidFrame, colIndex);
+ // add the cell frame to the table's cell map
+ table->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild);
+ }
}
}
}
@@ -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; colIndexGetColumnWidth(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; numColSpanGetColumnWidth(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,162 +793,417 @@ 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)
+
+
+NS_METHOD nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ RowReflowState& aReflowState,
+ nsReflowStatus& aStatus)
{
- nsresult status;
+ if (PR_TRUE==gsDebugIR) printf("\nTRF IR: IncrementalReflow\n");
+ nsresult rv = NS_OK;
- // 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;
- }
-
- // Get the next frame in the reflow chain
- nsIFrame* kidFrame;
- aState.reflowState.reflowCommand->GetNext(kidFrame);
-
- // Recover our reflow state
- nscoord maxCellTopMargin, maxCellBottomMargin;
- RecoverState(aPresContext, aState, kidFrame, maxCellTopMargin, maxCellBottomMargin);
-
- // Get the frame's margins
- nsMargin kidMargin;
- aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
- if (kidMargin.top > maxCellTopMargin)
- maxCellTopMargin = kidMargin.top;
- if (kidMargin.bottom > maxCellBottomMargin)
- maxCellBottomMargin = kidMargin.bottom;
-
- // 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));
- nscoord availWidth = 0;
- for (PRInt32 numColSpan = 0; numColSpan < cellColSpan; numColSpan++)
+ // 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))
{
- availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
- if (0GetNext(nextFrame);
+ rv = IR_TargetIsChild(aPresContext, aDesiredSize, aReflowState, aStatus, nextFrame);
}
}
-
- // Always let the cell be as high as it wants. We ignore the height that's
- // passed in and always place the entire row. Let the row group decide
- // whether we fit or wehther the entire row is pushed
- nsSize kidAvailSize(availWidth, NS_UNCONSTRAINEDSIZE);
-
- // Pass along the reflow command
- nsSize kidMaxElementSize;
- nsHTMLReflowMetrics desiredSize(&kidMaxElementSize);
- nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aState.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);
-
- // Now do the regular pass 1 reflow and gather the max width and max element
- // size.
- // XXX It would be nice if we could skip this step and the next step if the
- // column width isn't dependent on the max cell width...
- kidReflowState.reason = eReflowReason_Resize;
- kidReflowState.reflowCommand = nsnull;
- kidReflowState.maxSize.width = NS_UNCONSTRAINEDSIZE;
- ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
- if (gsDebug)
- printf ("TR %p for cell %p Incremental Reflow: desired=%d, MES=%d\n",
- this, kidFrame, 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?
- if (kidMaxElementSize.width>desiredSize.width)
- desiredSize.width = kidMaxElementSize.width;
- if (kidMaxElementSize.height>desiredSize.height)
- desiredSize.height = kidMaxElementSize.height;
- ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(desiredSize);
- ((nsTableCellFrame *)kidFrame)->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);
-
- // 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
- // widths have changed. If so, we just bail and return a status indicating
- // what happened and let the table reflow all the table cells...
- nscoord specifiedHeight = 0;
- nscoord cellHeight = desiredSize.height;
- nsIStyleContextPtr kidSC;
- kidFrame->GetStyleContext(&aPresContext, kidSC.AssignRef());
- const nsStylePosition* kidPosition = (const nsStylePosition*)
- kidSC->GetStyleData(eStyleStruct_Position);
- switch (kidPosition->mHeight.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedHeight = kidPosition->mHeight.GetCoordValue();
- break;
-
- case eStyleUnit_Inherit:
- // XXX for now, do nothing
- default:
- case eStyleUnit_Auto:
- break;
- }
- if (specifiedHeight>cellHeight)
- cellHeight = specifiedHeight;
-
- nscoord cellWidth = desiredSize.width;
- // begin special Nav4 compatibility code
- if (0==cellWidth)
- {
- cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
- }
- // end special Nav4 compatibility code
-
- // Now place the child
- nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
-
- PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
- &kidMaxElementSize);
-
- SetMaxChildHeight(aState.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;
-
- 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;
+ return rv;
}
+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, aReflowState, aNextFrame, maxCellTopMargin, maxCellBottomMargin);
+
+ // Get the frame's margins
+ nsMargin kidMargin;
+ aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aNextFrame, kidMargin);
+ if (kidMargin.top > maxCellTopMargin)
+ maxCellTopMargin = kidMargin.top;
+ if (kidMargin.bottom > maxCellBottomMargin)
+ maxCellBottomMargin = kidMargin.bottom;
+
+ // At this point, we know the column widths. Get the available width
+ // from the known column widths
+ 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 += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
+ if (0desiredSize.width)
+ desiredSize.width = kidMaxElementSize.width;
+ if (kidMaxElementSize.height>desiredSize.height)
+ desiredSize.height = kidMaxElementSize.height;
+ ((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;
+ 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
+ // widths have changed. If so, we just bail and return a status indicating
+ // what happened and let the table reflow all the table cells...
+ nscoord specifiedHeight = 0;
+ nscoord cellHeight = desiredSize.height;
+ nsIStyleContextPtr kidSC;
+ aNextFrame->GetStyleContext(&aPresContext, kidSC.AssignRef());
+ const nsStylePosition* kidPosition = (const nsStylePosition*)
+ kidSC->GetStyleData(eStyleStruct_Position);
+ switch (kidPosition->mHeight.GetUnit()) {
+ case eStyleUnit_Coord:
+ specifiedHeight = kidPosition->mHeight.GetCoordValue();
+ break;
+
+ case eStyleUnit_Inherit:
+ // XXX for now, do nothing
+ default:
+ case eStyleUnit_Auto:
+ break;
+ }
+ if (specifiedHeight>cellHeight)
+ cellHeight = specifiedHeight;
+
+ nscoord cellWidth = desiredSize.width;
+ // begin special Nav4 compatibility code
+ if (0==cellWidth)
+ {
+ cellWidth = aReflowState.tableFrame->GetColumnWidth(cellColIndex);
+ }
+ // end special Nav4 compatibility code
+
+ // Now place the child
+ nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
+
+ PlaceChild(aPresContext, aReflowState, aNextFrame, kidRect, aDesiredSize.maxElementSize,
+ &kidMaxElementSize);
+
+ 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 = 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,
+ 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
diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.h b/mozilla/layout/html/table/src/nsTableRowFrame.h
index 43e6d0cd3f8..51d6d09debc 100644
--- a/mozilla/layout/html/table/src/nsTableRowFrame.h
+++ b/mozilla/layout/html/table/src/nsTableRowFrame.h
@@ -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
diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp
index b485bfec9c6..09df6333da1 100644
--- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp
@@ -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,
diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.h b/mozilla/layout/html/table/src/nsTableRowGroupFrame.h
index 309f7afa04a..302619e9315 100644
--- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.h
+++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.h
@@ -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:
diff --git a/mozilla/layout/tables/nsCellMap.h b/mozilla/layout/tables/nsCellMap.h
index e5e9a23f71b..723536e3aad 100644
--- a/mozilla/layout/tables/nsCellMap.h
+++ b/mozilla/layout/tables/nsCellMap.h
@@ -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:
*
@@ -227,5 +230,11 @@ inline void nsCellMap::AppendColumnFrame(nsTableColFrame *aColFrame)
mColFrames->AppendElement(aColFrame);
}
+inline void nsCellMap::ClearColumnCache()
+{
+ if (nsnull!=mColFrames)
+ mColFrames->Clear();
+}
+
#endif
diff --git a/mozilla/layout/tables/nsTableColGroupFrame.cpp b/mozilla/layout/tables/nsTableColGroupFrame.cpp
index c7a676ddc00..ffd056193bd 100644
--- a/mozilla/layout/tables/nsTableColGroupFrame.cpp
+++ b/mozilla/layout/tables/nsTableColGroupFrame.cpp
@@ -52,87 +52,89 @@ nsresult
nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
nsresult rv=NS_OK;
- nsIFrame* tableFrame=nsnull;
- GetGeometricParent(tableFrame);
- // Process the newly added column frames
- for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
- // Set the preliminary values for the column frame
- nsIContent* kid;
- kidFrame->GetContent(kid);
- // should use style to get this value
- PRInt32 repeat=1;
- nsIHTMLTableColElement* colContent = nsnull;
- rv = kid->QueryInterface(kIHTMLTableColElementIID,
- (void**) &colContent); // colContent: ADDREF++
- NS_RELEASE(kid);
- if (rv==NS_OK)
- {
- colContent->GetSpanValue(&repeat);
- NS_RELEASE(colContent);
- }
- PRInt32 colIndex = mStartColIndex + mColCount;
- ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
- mColCount+= repeat;
- ((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
- ((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame);
- }
- // colgroup's span attribute is how many columns the group represents
- // in the absence of any COL children
- if (0==mColCount)
+ nsTableFrame* tableFrame=nsnull;
+ rv = nsTableFrame::GetTableFrame(this, tableFrame);
+ if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame))
{
- nsIFrame *firstImplicitColFrame=nsnull;
- nsIFrame *prevColFrame=nsnull;
- nsAutoString colTag;
- nsHTMLAtoms::col->ToString(colTag);
- mColCount = GetSpan();
- for (PRInt32 colIndex=0; colIndexAppendChildTo((nsIContent*)col, PR_FALSE);
-
- // Create a new col frame
- nsIFrame* colFrame;
- NS_NewTableColFrame(col, this, colFrame);
-
- // Set its style context
- nsIStyleContextPtr colStyleContext =
- aPresContext.ResolveStyleContextFor(col, this, PR_TRUE);
- colFrame->SetStyleContext(&aPresContext, colStyleContext);
- colFrame->Init(aPresContext, nsnull);
-
- // Set nsColFrame-specific information
- PRInt32 absColIndex = mStartColIndex + colIndex;
- ((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1);
- ((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
- ((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)colFrame);
-
- //hook into list of children
- if (nsnull==firstImplicitColFrame)
- firstImplicitColFrame = colFrame;
- else
- prevColFrame->SetNextSibling(colFrame);
- prevColFrame = colFrame;
- }
- // hook new columns into col group child list
- if (nsnull==mFirstChild)
- mFirstChild = firstImplicitColFrame;
- else
- {
- nsIFrame *lastChild = mFirstChild;
- nsIFrame *nextChild = lastChild;
- while (nsnull!=nextChild)
+ // Process the newly added column frames
+ for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
+ // Set the preliminary values for the column frame
+ nsIContent* kid;
+ kidFrame->GetContent(kid);
+ // should use style to get this value
+ PRInt32 repeat=1;
+ nsIHTMLTableColElement* colContent = nsnull;
+ rv = kid->QueryInterface(kIHTMLTableColElementIID,
+ (void**) &colContent); // colContent: ADDREF++
+ NS_RELEASE(kid);
+ if (rv==NS_OK)
{
- lastChild = nextChild;
- nextChild->GetNextSibling(nextChild);
+ colContent->GetSpanValue(&repeat);
+ NS_RELEASE(colContent);
}
- lastChild->SetNextSibling(firstImplicitColFrame);
+ PRInt32 colIndex = mStartColIndex + mColCount;
+ ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
+ mColCount+= repeat;
+ ((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
+ tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame);
}
- }
- SetStyleContextForFirstPass(aPresContext);
+ // colgroup's span attribute is how many columns the group represents
+ // in the absence of any COL children
+ if (0==mColCount)
+ {
+ nsIFrame *firstImplicitColFrame=nsnull;
+ nsIFrame *prevColFrame=nsnull;
+ nsAutoString colTag;
+ nsHTMLAtoms::col->ToString(colTag);
+ mColCount = GetSpan();
+ for (PRInt32 colIndex=0; colIndexAppendChildTo((nsIContent*)col, PR_FALSE);
+ // Create a new col frame
+ nsIFrame* colFrame;
+ NS_NewTableColFrame(col, this, colFrame);
+
+ // Set its style context
+ nsIStyleContextPtr colStyleContext =
+ aPresContext.ResolveStyleContextFor(col, this, PR_TRUE);
+ colFrame->SetStyleContext(&aPresContext, colStyleContext);
+ colFrame->Init(aPresContext, nsnull);
+
+ // Set nsColFrame-specific information
+ PRInt32 absColIndex = mStartColIndex + colIndex;
+ ((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1);
+ ((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
+ tableFrame->AddColumnFrame((nsTableColFrame *)colFrame);
+
+ //hook into list of children
+ if (nsnull==firstImplicitColFrame)
+ firstImplicitColFrame = colFrame;
+ else
+ prevColFrame->SetNextSibling(colFrame);
+ prevColFrame = colFrame;
+ }
+ // hook new columns into col group child list
+ if (nsnull==mFirstChild)
+ mFirstChild = firstImplicitColFrame;
+ else
+ {
+ nsIFrame *lastChild = mFirstChild;
+ nsIFrame *nextChild = lastChild;
+ while (nsnull!=nextChild)
+ {
+ lastChild = nextChild;
+ nextChild->GetNextSibling(nextChild);
+ }
+ lastChild->SetNextSibling(firstImplicitColFrame);
+ }
+ }
+ SetStyleContextForFirstPass(aPresContext);
+ }
return rv;
}
@@ -233,54 +235,55 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPresContext)
{
// get the table frame
- nsIFrame* tableFrame=nsnull;
- GetGeometricParent(tableFrame);
-
- // get the style for the table frame
- nsStyleTable *tableStyle;
- tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
+ 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);
- // if COLS is set, then map it into the COL frames
- if (NS_STYLE_TABLE_COLS_NONE != tableStyle->mCols)
- {
- // set numCols to the number of columns effected by the COLS attribute
- PRInt32 numCols=0;
- if (NS_STYLE_TABLE_COLS_ALL == tableStyle->mCols)
- numCols = LengthOf(mFirstChild);
- else
- numCols = tableStyle->mCols;
-
- // for every column effected, set its width style
- PRInt32 colIndex=0;
- nsIFrame *colFrame=mFirstChild;
- while (nsnull!=colFrame)
+ // if COLS is set, then map it into the COL frames
+ if (NS_STYLE_TABLE_COLS_NONE != tableStyle->mCols)
{
- nsStyleDisplay * colDisplay=nsnull;
- colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
- if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
- {
- nsIStyleContextPtr colStyleContext;
- nsStylePosition * colPosition=nsnull;
- colFrame->GetStyleContext(&aPresContext, colStyleContext.AssignRef());
- colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
- if (colIndexmWidth = width;
- }
- else
- {
- colPosition->mWidth.SetCoordValue(0);
- }
- colStyleContext->RecalcAutomaticData(&aPresContext);
- colIndex++;
- }
- colFrame->GetNextSibling(colFrame);
- }
+ // set numCols to the number of columns effected by the COLS attribute
+ PRInt32 numCols=0;
+ if (NS_STYLE_TABLE_COLS_ALL == tableStyle->mCols)
+ numCols = LengthOf(mFirstChild);
+ else
+ numCols = tableStyle->mCols;
- mStyleContext->RecalcAutomaticData(&aPresContext);
+ // for every column effected, set its width style
+ PRInt32 colIndex=0;
+ nsIFrame *colFrame=mFirstChild;
+ while (nsnull!=colFrame)
+ {
+ nsStyleDisplay * colDisplay=nsnull;
+ colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
+ {
+ nsIStyleContextPtr colStyleContext;
+ nsStylePosition * colPosition=nsnull;
+ colFrame->GetStyleContext(&aPresContext, colStyleContext.AssignRef());
+ colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
+ if (colIndexmWidth = width;
+ }
+ else
+ {
+ colPosition->mWidth.SetCoordValue(0);
+ }
+ colStyleContext->RecalcAutomaticData(&aPresContext);
+ colIndex++;
+ }
+ colFrame->GetNextSibling(colFrame);
+ }
+ mStyleContext->RecalcAutomaticData(&aPresContext);
+ }
}
- return NS_OK;
+ return rv;
}
diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp
index dcf88de6ec8..64e775c30a1 100644
--- a/mozilla/layout/tables/nsTableFrame.cpp
+++ b/mozilla/layout/tables/nsTableFrame.cpp
@@ -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,11 +299,44 @@ 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 ******* */
/* return the next row group frame after aRowGroupFrame */
@@ -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();
- 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);
- }
+ NS_ASSERTION(nsnull!=cellMap, "GetRowCount null cellmap");
+ if (nsnull!=cellMap)
+ 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(0mDisplay))
- { // XXX: assumes content order
- firstRowGroupFrame = childFrame;
- if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame);
- break;
+ {
+ if (nsnull==firstRowGroupFrame)
+ {
+ firstRowGroupFrame = childFrame;
+ if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame);
+ }
}
- prevSibFrame = childFrame;
+ if (nsnull==firstRowGroupFrame)
+ prevSibFrame = childFrame;
childFrame->GetNextSibling(childFrame);
}
PRInt32 colCount = GetColCount();
@@ -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,11 +782,12 @@ 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
- firstRowGroupFrame = childFrame;
- break;
+ {
+ if (nsnull==firstRowGroupFrame)
+ firstRowGroupFrame = childFrame;
}
- prevSibFrame = childFrame;
+ if (nsnull==firstRowGroupFrame)
+ prevSibFrame = childFrame;
childFrame->GetNextSibling(childFrame);
}
if (actualColumns <= aColIndex)
@@ -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 (PR_TRUE==mIsInvariantWidth)
- result = PR_FALSE;
- // TODO: other cases...
+ if (eReflowReason_Incremental != aReflowState.reason)
+ { // incremental reflows always need to be reflowed (for now)
+ if (PR_TRUE==mIsInvariantWidth)
+ result = PR_FALSE;
+ // 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 (0FirstChild(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; colGroupIndexInitialize(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,95 +2938,95 @@ 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)
{
- mColCache = new ColumnInfoCache(mColCount);
- nsIFrame * childFrame = mFirstChild;
- while (nsnull!=childFrame)
- { // in this loop, we cache column info and set column style info from cells in first row
- const nsStyleDisplay *childDisplay;
- childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (PR_TRUE==gsDebugIR) printf("TIF BCB: clearing column cache and cell map column frame cache.\n");
+ mCellMap->ClearColumnCache();
+ delete mColCache;
+ }
- if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
- { // if it's a col group then get the columns and cache them in the CellMap
- nsTableColFrame *colFrame=nsnull;
- childFrame->FirstChild((nsIFrame *&)colFrame);
- while (nsnull!=colFrame)
- {
- mCellMap->AppendColumnFrame(colFrame);
- colFrame->GetNextSibling((nsIFrame *&)colFrame);
- }
+ mColCache = new ColumnInfoCache(mColCount);
+ nsIFrame * childFrame = mFirstChild;
+ while (nsnull!=childFrame)
+ { // in this loop, we cache column info and set column style info from cells in first row
+ const nsStyleDisplay *childDisplay;
+ childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ { // if it's a col group then get the columns and cache them in the CellMap
+ nsTableColFrame *colFrame=nsnull;
+ childFrame->FirstChild((nsIFrame *&)colFrame);
+ while (nsnull!=colFrame)
+ {
+ mCellMap->AppendColumnFrame(colFrame);
+ colFrame->GetNextSibling((nsIFrame *&)colFrame);
}
- else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
- { // if it's a row group, get the cells and set the column style if appropriate
- if (NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy)
- {
- nsIFrame *rowFrame;
- childFrame->FirstChild(rowFrame);
- while (nsnull!=rowFrame)
- {
- const nsStyleDisplay *rowDisplay;
- rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowDisplay));
- if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
- {
- nsIFrame *cellFrame;
- rowFrame->FirstChild(cellFrame);
- while (nsnull!=cellFrame)
- {
- /* this is the first time we are guaranteed to have both the cell frames
- * and the column frames, so it's a good time to
- * set the column style from the cell's width attribute (if this is the first row)
- */
- const nsStyleDisplay *cellDisplay;
- cellFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)cellDisplay));
- if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay)
- SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
- cellFrame->GetNextSibling(cellFrame);
- }
- }
- rowFrame->GetNextSibling(rowFrame);
- }
- }
- }
- childFrame->GetNextSibling(childFrame);
}
-
- // second time through, set column cache info for each column
- // we can't do this until the loop above has set the column style info from the cells in the first row
- childFrame = mFirstChild;
- while (nsnull!=childFrame)
- { // for every child, if it's a col group then get the columns
- const nsStyleDisplay *childDisplay;
- childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
- if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
+ { // if it's a row group, get the cells and set the column style if appropriate
+ if (NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy)
{
- nsTableColFrame *colFrame=nsnull;
- childFrame->FirstChild((nsIFrame *&)colFrame);
- while (nsnull!=colFrame)
- { // for every column, create an entry in the column cache
- // assumes that the col style has been twiddled to account for first cell width attribute
- const nsStyleDisplay *colDisplay;
- colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
- if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
+ nsIFrame *rowFrame;
+ childFrame->FirstChild(rowFrame);
+ while (nsnull!=rowFrame)
+ {
+ const nsStyleDisplay *rowDisplay;
+ rowFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)rowDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay)
{
- const nsStylePosition* colPosition;
- colFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)colPosition));
- mColCache->AddColumnInfo(colPosition->mWidth.GetUnit(), colFrame->GetColumnIndex());
+ nsIFrame *cellFrame;
+ rowFrame->FirstChild(cellFrame);
+ while (nsnull!=cellFrame)
+ {
+ /* this is the first time we are guaranteed to have both the cell frames
+ * and the column frames, so it's a good time to
+ * set the column style from the cell's width attribute (if this is the first row)
+ */
+ const nsStyleDisplay *cellDisplay;
+ cellFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)cellDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay)
+ SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)cellFrame, (nsTableRowFrame *)rowFrame);
+ cellFrame->GetNextSibling(cellFrame);
+ }
}
- colFrame->GetNextSibling((nsIFrame *&)colFrame);
+ rowFrame->GetNextSibling(rowFrame);
}
}
- else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay))
- { // XXX: assumes content order
- break; // once we hit a row group, we're done
- }
- childFrame->GetNextSibling(childFrame);
}
+ childFrame->GetNextSibling(childFrame);
+ }
+
+ // second time through, set column cache info for each column
+ // we can't do this until the loop above has set the column style info from the cells in the first row
+ childFrame = mFirstChild;
+ while (nsnull!=childFrame)
+ { // for every child, if it's a col group then get the columns
+ const nsStyleDisplay *childDisplay;
+ childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
+ {
+ nsTableColFrame *colFrame=nsnull;
+ childFrame->FirstChild((nsIFrame *&)colFrame);
+ while (nsnull!=colFrame)
+ { // for every column, create an entry in the column cache
+ // assumes that the col style has been twiddled to account for first cell width attribute
+ const nsStyleDisplay *colDisplay;
+ colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
+ {
+ const nsStylePosition* colPosition;
+ colFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)colPosition));
+ mColCache->AddColumnInfo(colPosition->mWidth.GetUnit(), colFrame->GetColumnIndex());
+ }
+ colFrame->GetNextSibling((nsIFrame *&)colFrame);
+ }
+ }
+ childFrame->GetNextSibling(childFrame);
}
}
@@ -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;
+ }
+ rv = childFrame->GetNextSibling(childFrame);
+ }
break;
- result = aOutFrame->GetContentParent((nsIFrame *&)aOutFrame);
+ }
+ 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;
}
diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h
index db2c20038a2..af7c9a5bb8f 100644
--- a/mozilla/layout/tables/nsTableFrame.h
+++ b/mozilla/layout/tables/nsTableFrame.h
@@ -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
diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp
index fa7585144e5..f002487dfdb 100644
--- a/mozilla/layout/tables/nsTableOuterFrame.cpp
+++ b/mozilla/layout/tables/nsTableOuterFrame.cpp
@@ -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;
}
diff --git a/mozilla/layout/tables/nsTableOuterFrame.h b/mozilla/layout/tables/nsTableOuterFrame.h
index 539d6013569..316601f159e 100644
--- a/mozilla/layout/tables/nsTableOuterFrame.h
+++ b/mozilla/layout/tables/nsTableOuterFrame.h
@@ -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,
diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp
index 22742db37c0..14d07ef3cec 100644
--- a/mozilla/layout/tables/nsTableRowFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowFrame.cpp
@@ -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,45 +101,62 @@ NS_IMETHODIMP
nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
mFirstChild = aChildList;
- nsTableFrame* table = nsnull;
- nsresult result;
+ return NS_OK;
+}
- result = nsTableFrame::GetTableFrame(this, table);
- if ((NS_OK==result) && (table != nsnull))
+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)
{
- SetRowIndex(table->GetNextAvailRowIndex());
- PRInt32 colIndex = 0;
- for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame))
+ result = nsTableFrame::GetTableFrame(this, table);
+ if ((NS_OK==result) && (table != nsnull))
{
- const nsStyleDisplay *kidDisplay;
- kidFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
- if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
+ 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))
{
- // what column does this cell belong to?
- colIndex = table->GetNextAvailColIndex(mRowIndex, colIndex);
- /* for style context optimization, set the content's column index if possible.
- * this can only be done if we really have an nsTableCell.
- * other tags mapped to table cell display won't benefit from this optimization
- * see nsHTMLStyleSheet::RulesMatching
- */
- nsIContent* cell;
- kidFrame->GetContent(cell);
- nsIHTMLTableCellElement *cellContent = nsnull;
- nsresult rv = cell->QueryInterface(kIHTMLTableCellElementIID,
- (void **)&cellContent); // cellContent: REFCNT++
- NS_RELEASE(cell);
- if (NS_SUCCEEDED(rv))
- { // we know it's a table cell
- cellContent->SetColIndex(colIndex);
- if (gsDebug) printf("%p : set cell content %p to col index = %d\n", this, cellContent, colIndex);
- NS_RELEASE(cellContent);
- }
+ const nsStyleDisplay *kidDisplay;
+ kidFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)kidDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
+ {
+ // what column does this cell belong to?
+ colIndex = table->GetNextAvailColIndex(mRowIndex, colIndex);
+ /* for style context optimization, set the content's column index if possible.
+ * this can only be done if we really have an nsTableCell.
+ * other tags mapped to table cell display won't benefit from this optimization
+ * see nsHTMLStyleSheet::RulesMatching
+ */
+ nsIContent* cell;
+ kidFrame->GetContent(cell);
+ nsIHTMLTableCellElement *cellContent = nsnull;
+ nsresult rv = cell->QueryInterface(kIHTMLTableCellElementIID,
+ (void **)&cellContent); // cellContent: REFCNT++
+ NS_RELEASE(cell);
+ if (NS_SUCCEEDED(rv))
+ { // we know it's a table cell
+ cellContent->SetColIndex(colIndex);
+ if (gsDebug) printf("%p : set cell content %p to col index = %d\n", this, cellContent, colIndex);
+ NS_RELEASE(cellContent);
+ }
- // this sets the frame's notion of it's column index
- ((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
- if (gsDebug) printf("%p : set cell frame %p to col index = %d\n", this, kidFrame, colIndex);
- // add the cell frame to the table's cell map
- table->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild);
+ // this sets the frame's notion of it's column index
+ ((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
+ if (gsDebug) printf("%p : set cell frame %p to col index = %d\n", this, kidFrame, colIndex);
+ // add the cell frame to the table's cell map
+ table->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild);
+ }
}
}
}
@@ -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; colIndexGetColumnWidth(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; numColSpanGetColumnWidth(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,162 +793,417 @@ 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)
+
+
+NS_METHOD nsTableRowFrame::IncrementalReflow(nsIPresContext& aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ RowReflowState& aReflowState,
+ nsReflowStatus& aStatus)
{
- nsresult status;
+ if (PR_TRUE==gsDebugIR) printf("\nTRF IR: IncrementalReflow\n");
+ nsresult rv = NS_OK;
- // 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;
- }
-
- // Get the next frame in the reflow chain
- nsIFrame* kidFrame;
- aState.reflowState.reflowCommand->GetNext(kidFrame);
-
- // Recover our reflow state
- nscoord maxCellTopMargin, maxCellBottomMargin;
- RecoverState(aPresContext, aState, kidFrame, maxCellTopMargin, maxCellBottomMargin);
-
- // Get the frame's margins
- nsMargin kidMargin;
- aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
- if (kidMargin.top > maxCellTopMargin)
- maxCellTopMargin = kidMargin.top;
- if (kidMargin.bottom > maxCellBottomMargin)
- maxCellBottomMargin = kidMargin.bottom;
-
- // 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));
- nscoord availWidth = 0;
- for (PRInt32 numColSpan = 0; numColSpan < cellColSpan; numColSpan++)
+ // 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))
{
- availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
- if (0GetNext(nextFrame);
+ rv = IR_TargetIsChild(aPresContext, aDesiredSize, aReflowState, aStatus, nextFrame);
}
}
-
- // Always let the cell be as high as it wants. We ignore the height that's
- // passed in and always place the entire row. Let the row group decide
- // whether we fit or wehther the entire row is pushed
- nsSize kidAvailSize(availWidth, NS_UNCONSTRAINEDSIZE);
-
- // Pass along the reflow command
- nsSize kidMaxElementSize;
- nsHTMLReflowMetrics desiredSize(&kidMaxElementSize);
- nsHTMLReflowState kidReflowState(aPresContext, kidFrame, aState.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);
-
- // Now do the regular pass 1 reflow and gather the max width and max element
- // size.
- // XXX It would be nice if we could skip this step and the next step if the
- // column width isn't dependent on the max cell width...
- kidReflowState.reason = eReflowReason_Resize;
- kidReflowState.reflowCommand = nsnull;
- kidReflowState.maxSize.width = NS_UNCONSTRAINEDSIZE;
- ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, status);
- if (gsDebug)
- printf ("TR %p for cell %p Incremental Reflow: desired=%d, MES=%d\n",
- this, kidFrame, 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?
- if (kidMaxElementSize.width>desiredSize.width)
- desiredSize.width = kidMaxElementSize.width;
- if (kidMaxElementSize.height>desiredSize.height)
- desiredSize.height = kidMaxElementSize.height;
- ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(desiredSize);
- ((nsTableCellFrame *)kidFrame)->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);
-
- // 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
- // widths have changed. If so, we just bail and return a status indicating
- // what happened and let the table reflow all the table cells...
- nscoord specifiedHeight = 0;
- nscoord cellHeight = desiredSize.height;
- nsIStyleContextPtr kidSC;
- kidFrame->GetStyleContext(&aPresContext, kidSC.AssignRef());
- const nsStylePosition* kidPosition = (const nsStylePosition*)
- kidSC->GetStyleData(eStyleStruct_Position);
- switch (kidPosition->mHeight.GetUnit()) {
- case eStyleUnit_Coord:
- specifiedHeight = kidPosition->mHeight.GetCoordValue();
- break;
-
- case eStyleUnit_Inherit:
- // XXX for now, do nothing
- default:
- case eStyleUnit_Auto:
- break;
- }
- if (specifiedHeight>cellHeight)
- cellHeight = specifiedHeight;
-
- nscoord cellWidth = desiredSize.width;
- // begin special Nav4 compatibility code
- if (0==cellWidth)
- {
- cellWidth = aState.tableFrame->GetColumnWidth(cellColIndex);
- }
- // end special Nav4 compatibility code
-
- // Now place the child
- nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
-
- PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
- &kidMaxElementSize);
-
- SetMaxChildHeight(aState.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;
-
- 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;
+ return rv;
}
+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, aReflowState, aNextFrame, maxCellTopMargin, maxCellBottomMargin);
+
+ // Get the frame's margins
+ nsMargin kidMargin;
+ aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)aNextFrame, kidMargin);
+ if (kidMargin.top > maxCellTopMargin)
+ maxCellTopMargin = kidMargin.top;
+ if (kidMargin.bottom > maxCellBottomMargin)
+ maxCellBottomMargin = kidMargin.bottom;
+
+ // At this point, we know the column widths. Get the available width
+ // from the known column widths
+ 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 += aReflowState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
+ if (0desiredSize.width)
+ desiredSize.width = kidMaxElementSize.width;
+ if (kidMaxElementSize.height>desiredSize.height)
+ desiredSize.height = kidMaxElementSize.height;
+ ((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;
+ 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
+ // widths have changed. If so, we just bail and return a status indicating
+ // what happened and let the table reflow all the table cells...
+ nscoord specifiedHeight = 0;
+ nscoord cellHeight = desiredSize.height;
+ nsIStyleContextPtr kidSC;
+ aNextFrame->GetStyleContext(&aPresContext, kidSC.AssignRef());
+ const nsStylePosition* kidPosition = (const nsStylePosition*)
+ kidSC->GetStyleData(eStyleStruct_Position);
+ switch (kidPosition->mHeight.GetUnit()) {
+ case eStyleUnit_Coord:
+ specifiedHeight = kidPosition->mHeight.GetCoordValue();
+ break;
+
+ case eStyleUnit_Inherit:
+ // XXX for now, do nothing
+ default:
+ case eStyleUnit_Auto:
+ break;
+ }
+ if (specifiedHeight>cellHeight)
+ cellHeight = specifiedHeight;
+
+ nscoord cellWidth = desiredSize.width;
+ // begin special Nav4 compatibility code
+ if (0==cellWidth)
+ {
+ cellWidth = aReflowState.tableFrame->GetColumnWidth(cellColIndex);
+ }
+ // end special Nav4 compatibility code
+
+ // Now place the child
+ nsRect kidRect (aReflowState.x, kidMargin.top, cellWidth, cellHeight);
+
+ PlaceChild(aPresContext, aReflowState, aNextFrame, kidRect, aDesiredSize.maxElementSize,
+ &kidMaxElementSize);
+
+ 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 = 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,
+ 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
diff --git a/mozilla/layout/tables/nsTableRowFrame.h b/mozilla/layout/tables/nsTableRowFrame.h
index 43e6d0cd3f8..51d6d09debc 100644
--- a/mozilla/layout/tables/nsTableRowFrame.h
+++ b/mozilla/layout/tables/nsTableRowFrame.h
@@ -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
diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp
index b485bfec9c6..09df6333da1 100644
--- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp
@@ -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,
diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.h b/mozilla/layout/tables/nsTableRowGroupFrame.h
index 309f7afa04a..302619e9315 100644
--- a/mozilla/layout/tables/nsTableRowGroupFrame.h
+++ b/mozilla/layout/tables/nsTableRowGroupFrame.h
@@ -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: