diff --git a/layout/html/table/src/nsTableColGroupFrame.cpp b/layout/html/table/src/nsTableColGroupFrame.cpp
index ffd056193bdd..454d90839d2d 100644
--- a/layout/html/table/src/nsTableColGroupFrame.cpp
+++ b/layout/html/table/src/nsTableColGroupFrame.cpp
@@ -316,6 +316,32 @@ int nsTableColGroupFrame::GetColumnCount ()
return mColCount;
}
+nsTableColFrame * nsTableColGroupFrame::GetFirstColumn()
+{
+ return GetNextColumn(nsnull);
+}
+
+nsTableColFrame * nsTableColGroupFrame::GetNextColumn(nsIFrame *aChildFrame)
+{
+ nsTableColFrame *result = nsnull;
+ nsIFrame *childFrame = aChildFrame;
+ if (nsnull==childFrame)
+ childFrame = mFirstChild;
+ while (nsnull!=childFrame)
+ {
+ const nsStyleDisplay *childDisplay;
+ childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay)
+ {
+ result = (nsTableColFrame *)childFrame;
+ break;
+ }
+ childFrame->GetNextSibling(childFrame);
+ }
+ return result;
+}
+
+
nsTableColFrame * nsTableColGroupFrame::GetColumnAt (PRInt32 aColIndex)
{
nsTableColFrame *result = nsnull;
@@ -349,6 +375,34 @@ PRInt32 nsTableColGroupFrame::GetSpan()
return span;
}
+/* this may be needed when IsSynthetic is properly implemented
+PRBool nsTableColGroupFrame::IsManufactured()
+{
+ PRBool result = PR_FALSE;
+ nsIFrame *firstCol = GetFirstColumn();
+ if (nsTableFrame::IsSynthetic(this) &&
+ ((nsnull==firstCol) || nsTableFrame::IsSynthetic(firstCol)))
+ result = PR_TRUE;
+ return result;
+}
+*/
+
+/** returns colcount because it is frequently used in the context of
+ * shuffling relative colgroup order, and it's convenient to not have to
+ * call GetColumnCount redundantly.
+ */
+PRInt32 nsTableColGroupFrame::SetStartColumnIndex (int aIndex)
+{
+ PRInt32 result = mColCount;
+ if (aIndex != mStartColIndex)
+ {
+ mStartColIndex = aIndex;
+ mColCount=0;
+ result = GetColumnCount(); // has the side effect of setting each column index based on new start index
+ }
+ return result;
+}
+
/* ----- global methods ----- */
nsresult
diff --git a/layout/html/table/src/nsTableColGroupFrame.h b/layout/html/table/src/nsTableColGroupFrame.h
index b8f0936703e3..7ee4e26d830b 100644
--- a/layout/html/table/src/nsTableColGroupFrame.h
+++ b/layout/html/table/src/nsTableColGroupFrame.h
@@ -66,18 +66,31 @@ public:
* if there are col children, count them (taking into account the span of each)
* else, check my own span attribute.
*/
- virtual PRInt32 GetColumnCount ();
+ virtual PRInt32 GetColumnCount();
- virtual nsTableColFrame * GetColumnAt (PRInt32 aColIndex);
+ virtual nsTableColFrame * GetFirstColumn();
- virtual PRInt32 GetStartColumnIndex ();
+ virtual nsTableColFrame * GetNextColumn(nsIFrame *aChildFrame);
+
+ virtual nsTableColFrame * GetColumnAt(PRInt32 aColIndex);
+
+ virtual PRInt32 GetStartColumnIndex();
- virtual void SetStartColumnIndex (PRInt32 aIndex);
+ /** sets mStartColIndex to aIndex.
+ * @return the col count
+ * has the side effect of setting all child COL indexes
+ */
+ virtual PRInt32 SetStartColumnIndex(PRInt32 aIndex);
/** helper method to get the span attribute for this colgroup */
PRInt32 GetSpan();
- NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const;
+ /** helper method returns PR_TRUE if this colgroup exists without any
+ * colgroup or col content in the table backing it.
+ */
+ //PRBool IsManufactured();
+
+ NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const;
protected:
@@ -104,11 +117,4 @@ protected:
inline int nsTableColGroupFrame::GetStartColumnIndex ()
{ return mStartColIndex;}
-inline void nsTableColGroupFrame::SetStartColumnIndex (int aIndex)
-{
- if (aIndex != mStartColIndex)
- mColCount = 0; // our index is being changed, trigger reset of col indicies, don't propogate back to table
- mStartColIndex = aIndex;
-}
-
#endif
diff --git a/layout/html/table/src/nsTableFrame.cpp b/layout/html/table/src/nsTableFrame.cpp
index 64e775c30a16..3c14a479f3b5 100644
--- a/layout/html/table/src/nsTableFrame.cpp
+++ b/layout/html/table/src/nsTableFrame.cpp
@@ -47,9 +47,6 @@ static PRBool gsDebug = PR_FALSE;
static PRBool gsDebugCLD = PR_FALSE;
static PRBool gsDebugNT = PR_FALSE;
static PRBool gsDebugIR = PR_FALSE;
-//#define NOISY
-//#define NOISY_FLOW
-//#ifdef NOISY_STYLE
#else
static const PRBool gsDebug = PR_FALSE;
static const PRBool gsDebugCLD = PR_FALSE;
@@ -197,35 +194,39 @@ ColumnInfoCache::~ColumnInfoCache()
void ColumnInfoCache::AddColumnInfo(const nsStyleUnit aType,
PRInt32 aColumnIndex)
{
- switch (aType)
+ // a table may have more COLs than actual columns, so we guard against that here
+ if (aColumnIndexInitialize(aDesiredSize.maxElementSize);
}
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
@@ -1882,12 +1886,12 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
{
rv = IR_ColGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame, PR_FALSE);
+ (nsTableColGroupFrame*)objectFrame, PR_FALSE);
}
else if (IsRowGroup(childDisplay->mDisplay))
{
rv = IR_RowGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame, PR_FALSE);
+ (nsTableRowGroupFrame*)objectFrame, PR_FALSE);
}
else
{
@@ -1899,11 +1903,13 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
case nsIReflowCommand::FrameAppended :
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
{
- rv = IR_ColGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
+ rv = IR_ColGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
+ (nsTableColGroupFrame*)objectFrame);
}
else if (IsRowGroup(childDisplay->mDisplay))
{
- rv = IR_RowGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
+ rv = IR_RowGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
+ (nsTableRowGroupFrame*)objectFrame);
}
else
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
@@ -1921,18 +1927,18 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
{
rv = IR_ColGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame);
+ (nsTableColGroupFrame*)objectFrame);
}
else if (IsRowGroup(childDisplay->mDisplay))
{
rv = IR_RowGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame);
+ (nsTableRowGroupFrame*)objectFrame);
}
else
{
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame);
+ objectFrame);
}
break;
@@ -1964,38 +1970,75 @@ NS_METHOD nsTableFrame::IR_ColGroupInserted(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aInsertedFrame,
+ nsTableColGroupFrame * aInsertedFrame,
PRBool aReplace)
{
- nsresult rv;
- /*
- 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 */
+ nsresult rv=NS_OK;
+ PRBool adjustStartingColIndex=PR_FALSE;
+ PRInt32 startingColIndex=0;
+ // find out what frame to insert aInsertedFrame after
+ nsIFrame *frameToInsertAfter=nsnull;
+ rv = aReflowState.reflowState.reflowCommand->GetPrevSiblingFrame(frameToInsertAfter);
+ // insert aInsertedFrame as the first child. Set its start col index to 0
+ if (nsnull==frameToInsertAfter)
+ {
+ aInsertedFrame->SetNextSibling(mFirstChild);
+ mFirstChild=aInsertedFrame;
+ startingColIndex += aInsertedFrame->SetStartColumnIndex(0);
+ adjustStartingColIndex=PR_TRUE;
+ }
+ nsIFrame *childFrame=mFirstChild;
+ nsIFrame *prevSib=nsnull;
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
+ {
+ if ((nsnull!=frameToInsertAfter) && (childFrame==frameToInsertAfter))
+ {
+ nsIFrame *nextSib=nsnull;
+ frameToInsertAfter->GetNextSibling(nextSib);
+ aInsertedFrame->SetNextSibling(nextSib);
+ frameToInsertAfter->SetNextSibling(aInsertedFrame);
+ // account for childFrame being a COLGROUP now
+ const nsStyleDisplay *display;
+ childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
+ {
+ if (PR_FALSE==adjustStartingColIndex) // we haven't gotten to aDeletedFrame yet
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
+ }
+ // skip ahead to aInsertedFrame, since we just handled the frame we inserted after
+ childFrame=aInsertedFrame;
+ adjustStartingColIndex=PR_TRUE; // now that we've inserted aInsertedFrame,
+ // start adjusting subsequent col groups' starting col index including aInsertedFrame
+ }
+ const nsStyleDisplay *display;
+ childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
+ {
+ if (PR_FALSE==adjustStartingColIndex) // we haven't gotten to aDeletedFrame yet
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
+ else // we've removed aDeletedFrame, now adjust the starting col index of all subsequent col groups
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
+ }
+ prevSib=childFrame;
+ rv = childFrame->GetNextSibling(childFrame);
+ }
+
+ InvalidateColumnCache();
+ //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_ColGroupAppended(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aAppendedFrame)
+ nsTableColGroupFrame * 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;
+ PRInt32 startingColIndex=0;
nsIFrame *childFrame=mFirstChild;
nsIFrame *lastChild=mFirstChild;
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
@@ -2004,7 +2047,7 @@ NS_METHOD nsTableFrame::IR_ColGroupAppended(nsIPresContext& aPresContext,
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
{
- colGroupList.AppendElement((void*)childFrame);
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
}
lastChild=childFrame;
rv = childFrame->GetNextSibling(childFrame);
@@ -2015,36 +2058,54 @@ NS_METHOD nsTableFrame::IR_ColGroupAppended(nsIPresContext& aPresContext,
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();
+ aAppendedFrame->SetStartColumnIndex(startingColIndex);
+
+#if 0
+
+we would only want to do this if manufactured col groups were invisible to the DOM. Since they
+currently are visible, they should behave just as if they were content-backed "real" colgroups
+If this decision is changed, the code below is a half-finished attempt to rationalize the situation.
+It requires having built a list of the colGroups before we get to this point.
+
+ // look at the last col group. If it is implicit, and it's cols are implicit, then
+ // it and its cols were manufactured for table layout.
+ // Delete it if possible, otherwise move it to the end of the list
+
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; colGroupIndexIsManufactured())
+ { // account for the new COLs that were added in aAppendedFrame
+ // first, try to delete the implicit colgroup
+
+ // if we couldn't delete it, move the implicit colgroup to the end of the list
+ // and adjust it's col indexes
+ nsIFrame *colGroupNextSib;
+ colGroup->GetNextSibling(colGroupNextSib);
+ childFrame=mFirstChild;
+ nsIFrame * prevSib=nsnull;
+ rv = NS_OK;
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
+ {
+ if (childFrame==colGroup)
{
- nsTableColGroupFrame *colGroup = (nsTableColGroupFrame *)(colGroupList.ElementAt(colGroupIndex));
- // XXX: here's where we yank colGroups if necessary
+ if (nsnull!=prevSib) // colGroup is in the middle of the list, remove it
+ prevSib->SetNextSibling(colGroupNextSib);
+ else // colGroup was the first child, so set it's next sib to first child
+ mFirstChild = colGroupNextSib;
+ aAppendedFrame->SetNextSibling(colGroup); // place colGroup at the end of the list
+ colGroup->SetNextSibling(nsnull);
+ break;
}
+ prevSib=childFrame;
+ rv = childFrame->GetNextSibling(childFrame);
}
}
}
+#endif
- //InvalidateFirstPassCache(); // for now, redo the first pass reflow
- // could probably just get away with mTableLayoutStrategy->Initialize(aMaxElementSize);
- mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
+
+ InvalidateColumnCache();
//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
@@ -2056,14 +2117,45 @@ NS_METHOD nsTableFrame::IR_ColGroupRemoved(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aDeletedFrame)
+ nsTableColGroupFrame * aDeletedFrame)
{
- nsresult rv;
- /*
- for every col in the colgroup (including implicit cols due to span attribute)
- an implicit col is created in the last implicit colgroup
- if there is no implicit colgroup, one is created at the end of the colgroup list
- */
+ nsresult rv=NS_OK;
+ PRBool adjustStartingColIndex=PR_FALSE;
+ PRInt32 startingColIndex=0;
+ nsIFrame *childFrame=mFirstChild;
+ nsIFrame *prevSib=nsnull;
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
+ {
+ if (childFrame==aDeletedFrame)
+ {
+ nsIFrame *deleteFrameNextSib=nsnull;
+ aDeletedFrame->GetNextSibling(deleteFrameNextSib);
+ if (nsnull!=prevSib)
+ prevSib->SetNextSibling(deleteFrameNextSib);
+ else
+ mFirstChild = deleteFrameNextSib;
+ childFrame=deleteFrameNextSib;
+ if (nsnull==childFrame)
+ break;
+ adjustStartingColIndex=PR_TRUE; // now that we've removed aDeletedFrame, start adjusting subsequent col groups' starting col index
+ }
+ const nsStyleDisplay *display;
+ childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
+ {
+ if (PR_FALSE==adjustStartingColIndex) // we haven't gotten to aDeletedFrame yet
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
+ else // we've removed aDeletedFrame, now adjust the starting col index of all subsequent col groups
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
+ }
+ prevSib=childFrame;
+ rv = childFrame->GetNextSibling(childFrame);
+ }
+
+ InvalidateColumnCache();
+ //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;
}
@@ -2071,7 +2163,7 @@ NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aInsertedFrame,
+ nsTableRowGroupFrame * aInsertedFrame,
PRBool aReplace)
{
nsresult rv;
@@ -2084,7 +2176,7 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aAppendedFrame)
+ nsTableRowGroupFrame * aAppendedFrame)
{
// hook aAppendedFrame into the child list
nsIFrame *lastChild = mFirstChild;
@@ -2115,7 +2207,7 @@ NS_METHOD nsTableFrame::IR_RowGroupRemoved(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aDeletedFrame)
+ nsTableRowGroupFrame * aDeletedFrame)
{
nsresult rv;
return rv;
@@ -2940,6 +3032,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
{
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
+ NS_ASSERTION(PR_FALSE==mColumnCacheValid, "column cache valid state should be PR_FALSE");
nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
EnsureColumns(aPresContext);
@@ -3028,6 +3121,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
}
childFrame->GetNextSibling(childFrame);
}
+ mColumnCacheValid=PR_TRUE;
}
PRBool nsTableFrame::IsFirstPassValid() const
@@ -3044,6 +3138,20 @@ void nsTableFrame::InvalidateFirstPassCache()
firstInFlow->mFirstPassValid=PR_FALSE;
}
+PRBool nsTableFrame::IsColumnCacheValid() const
+{
+ nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
+ NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
+ return firstInFlow->mColumnCacheValid;
+}
+
+void nsTableFrame::InvalidateColumnCache()
+{
+ nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
+ NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
+ firstInFlow->mColumnCacheValid=PR_FALSE;
+}
+
PRBool nsTableFrame::IsCellMapValid() const
{
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
diff --git a/layout/html/table/src/nsTableFrame.h b/layout/html/table/src/nsTableFrame.h
index cd8cbc57e5d4..05aacc6df15a 100644
--- a/layout/html/table/src/nsTableFrame.h
+++ b/layout/html/table/src/nsTableFrame.h
@@ -29,6 +29,7 @@ class nsTableCellFrame;
class nsTableColFrame;
class nsTableRowGroupFrame;
class nsTableRowFrame;
+class nsTableColGroupFrame;
class nsITableLayoutStrategy;
class nsHTMLValue;
class ColumnInfoCache;
@@ -317,39 +318,39 @@ protected:
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aInsertedFrame,
+ nsTableColGroupFrame * aInsertedFrame,
PRBool aReplace);
- NS_IMETHOD IR_ColGroupAppended(nsIPresContext& aPresContext,
+ NS_IMETHOD IR_ColGroupAppended(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aAppendedFrame);
+ nsTableColGroupFrame * aAppendedFrame);
NS_IMETHOD IR_ColGroupRemoved(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aDeletedFrame);
+ nsTableColGroupFrame * aDeletedFrame);
NS_IMETHOD IR_RowGroupInserted(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aInsertedFrame,
+ nsTableRowGroupFrame * aInsertedFrame,
PRBool aReplace);
NS_IMETHOD IR_RowGroupAppended(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aAppendedFrame);
+ nsTableRowGroupFrame * aAppendedFrame);
NS_IMETHOD IR_RowGroupRemoved(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aDeletedFrame);
+ nsTableRowGroupFrame * aDeletedFrame);
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -437,9 +438,14 @@ protected:
/** returns PR_TRUE if the cached pass 1 data is still valid */
virtual PRBool IsFirstPassValid() const;
+ /** returns PR_TRUE if the cached column info is still valid */
+ virtual PRBool IsColumnCacheValid() const;
+
public:
virtual void InvalidateFirstPassCache();
+ virtual void InvalidateColumnCache();
+
protected:
/** do post processing to setting up style information for the frame */
NS_IMETHOD DidSetStyleContext(nsIPresContext& aPresContext);
@@ -589,6 +595,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 mColumnCacheValid; // PR_TRUE if column cache info 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
diff --git a/layout/html/tests/TableIncrementalReflow.html b/layout/html/tests/TableIncrementalReflow.html
index 661966d27417..e363cda487b6 100644
--- a/layout/html/tests/TableIncrementalReflow.html
+++ b/layout/html/tests/TableIncrementalReflow.html
@@ -17,10 +17,24 @@ function deleteCaption() {
table.removeChild(caption);
}
+
function insertColGroup() {
var table = document.getElementsByTagName("TABLE")[0];
+ var refColGroup = document.getElementsByTagName("COLGROUP")[0];
var colGroup = document.createElement("COLGROUP", null);
+ colGroup.width=200;
+ colGroup.span=1;
+ table.insertBefore(colGroup, refColGroup);
+ dump("inserted COLGROUP with span=1 width=200 as first colgroup in table");
+}
+
+function appendColGroup() {
+ var table = document.getElementsByTagName("TABLE")[0];
+ var colGroup = document.createElement("COLGROUP", null);
+ colGroup.width=300;
+ colGroup.span=1;
table.appendChild(colGroup);
+ dump("appended COLGROUP with span=1 width=300");
}
function deleteColGroup() {
@@ -29,10 +43,22 @@ function deleteColGroup() {
table.removeChild(colGroup);
}
+
function insertCol() {
+ var table = document.getElementsByTagName("TABLE")[0];
+ var refCol = table.getElementsByTagName("COL")[0];
+ var col = document.createElement("COL", null);
+ col.width=200;
+ col.span=1;
+ table.insertBefore(col, refCol);
+ dump("inserted COL with span=1 width=200 as first col in first col group");
+}
+
+function appendCol() {
var table = document.getElementsByTagName("TABLE")[0];
var col = document.createElement("COL", null);
table.appendChild(col);
+ dump("appended COL with span=1 width=300");
}
function deleteCol() {
@@ -86,16 +112,20 @@ all delete buttons currently remove the first item of found
+
+
+
-
-
+
+
+
diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp
index ffd056193bdd..454d90839d2d 100644
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -316,6 +316,32 @@ int nsTableColGroupFrame::GetColumnCount ()
return mColCount;
}
+nsTableColFrame * nsTableColGroupFrame::GetFirstColumn()
+{
+ return GetNextColumn(nsnull);
+}
+
+nsTableColFrame * nsTableColGroupFrame::GetNextColumn(nsIFrame *aChildFrame)
+{
+ nsTableColFrame *result = nsnull;
+ nsIFrame *childFrame = aChildFrame;
+ if (nsnull==childFrame)
+ childFrame = mFirstChild;
+ while (nsnull!=childFrame)
+ {
+ const nsStyleDisplay *childDisplay;
+ childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay));
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay)
+ {
+ result = (nsTableColFrame *)childFrame;
+ break;
+ }
+ childFrame->GetNextSibling(childFrame);
+ }
+ return result;
+}
+
+
nsTableColFrame * nsTableColGroupFrame::GetColumnAt (PRInt32 aColIndex)
{
nsTableColFrame *result = nsnull;
@@ -349,6 +375,34 @@ PRInt32 nsTableColGroupFrame::GetSpan()
return span;
}
+/* this may be needed when IsSynthetic is properly implemented
+PRBool nsTableColGroupFrame::IsManufactured()
+{
+ PRBool result = PR_FALSE;
+ nsIFrame *firstCol = GetFirstColumn();
+ if (nsTableFrame::IsSynthetic(this) &&
+ ((nsnull==firstCol) || nsTableFrame::IsSynthetic(firstCol)))
+ result = PR_TRUE;
+ return result;
+}
+*/
+
+/** returns colcount because it is frequently used in the context of
+ * shuffling relative colgroup order, and it's convenient to not have to
+ * call GetColumnCount redundantly.
+ */
+PRInt32 nsTableColGroupFrame::SetStartColumnIndex (int aIndex)
+{
+ PRInt32 result = mColCount;
+ if (aIndex != mStartColIndex)
+ {
+ mStartColIndex = aIndex;
+ mColCount=0;
+ result = GetColumnCount(); // has the side effect of setting each column index based on new start index
+ }
+ return result;
+}
+
/* ----- global methods ----- */
nsresult
diff --git a/layout/tables/nsTableColGroupFrame.h b/layout/tables/nsTableColGroupFrame.h
index b8f0936703e3..7ee4e26d830b 100644
--- a/layout/tables/nsTableColGroupFrame.h
+++ b/layout/tables/nsTableColGroupFrame.h
@@ -66,18 +66,31 @@ public:
* if there are col children, count them (taking into account the span of each)
* else, check my own span attribute.
*/
- virtual PRInt32 GetColumnCount ();
+ virtual PRInt32 GetColumnCount();
- virtual nsTableColFrame * GetColumnAt (PRInt32 aColIndex);
+ virtual nsTableColFrame * GetFirstColumn();
- virtual PRInt32 GetStartColumnIndex ();
+ virtual nsTableColFrame * GetNextColumn(nsIFrame *aChildFrame);
+
+ virtual nsTableColFrame * GetColumnAt(PRInt32 aColIndex);
+
+ virtual PRInt32 GetStartColumnIndex();
- virtual void SetStartColumnIndex (PRInt32 aIndex);
+ /** sets mStartColIndex to aIndex.
+ * @return the col count
+ * has the side effect of setting all child COL indexes
+ */
+ virtual PRInt32 SetStartColumnIndex(PRInt32 aIndex);
/** helper method to get the span attribute for this colgroup */
PRInt32 GetSpan();
- NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const;
+ /** helper method returns PR_TRUE if this colgroup exists without any
+ * colgroup or col content in the table backing it.
+ */
+ //PRBool IsManufactured();
+
+ NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const;
protected:
@@ -104,11 +117,4 @@ protected:
inline int nsTableColGroupFrame::GetStartColumnIndex ()
{ return mStartColIndex;}
-inline void nsTableColGroupFrame::SetStartColumnIndex (int aIndex)
-{
- if (aIndex != mStartColIndex)
- mColCount = 0; // our index is being changed, trigger reset of col indicies, don't propogate back to table
- mStartColIndex = aIndex;
-}
-
#endif
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
index 64e775c30a16..3c14a479f3b5 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -47,9 +47,6 @@ static PRBool gsDebug = PR_FALSE;
static PRBool gsDebugCLD = PR_FALSE;
static PRBool gsDebugNT = PR_FALSE;
static PRBool gsDebugIR = PR_FALSE;
-//#define NOISY
-//#define NOISY_FLOW
-//#ifdef NOISY_STYLE
#else
static const PRBool gsDebug = PR_FALSE;
static const PRBool gsDebugCLD = PR_FALSE;
@@ -197,35 +194,39 @@ ColumnInfoCache::~ColumnInfoCache()
void ColumnInfoCache::AddColumnInfo(const nsStyleUnit aType,
PRInt32 aColumnIndex)
{
- switch (aType)
+ // a table may have more COLs than actual columns, so we guard against that here
+ if (aColumnIndexInitialize(aDesiredSize.maxElementSize);
}
BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus);
@@ -1882,12 +1886,12 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
{
rv = IR_ColGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame, PR_FALSE);
+ (nsTableColGroupFrame*)objectFrame, PR_FALSE);
}
else if (IsRowGroup(childDisplay->mDisplay))
{
rv = IR_RowGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame, PR_FALSE);
+ (nsTableRowGroupFrame*)objectFrame, PR_FALSE);
}
else
{
@@ -1899,11 +1903,13 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
case nsIReflowCommand::FrameAppended :
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
{
- rv = IR_ColGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
+ rv = IR_ColGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
+ (nsTableColGroupFrame*)objectFrame);
}
else if (IsRowGroup(childDisplay->mDisplay))
{
- rv = IR_RowGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, objectFrame);
+ rv = IR_RowGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus,
+ (nsTableRowGroupFrame*)objectFrame);
}
else
{ // no optimization to be done for Unknown frame types, so just reuse the Inserted method
@@ -1921,18 +1927,18 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext,
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay)
{
rv = IR_ColGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame);
+ (nsTableColGroupFrame*)objectFrame);
}
else if (IsRowGroup(childDisplay->mDisplay))
{
rv = IR_RowGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame);
+ (nsTableRowGroupFrame*)objectFrame);
}
else
{
rv = IR_UnknownFrameRemoved(aPresContext, aDesiredSize, aReflowState, aStatus,
- objectFrame);
+ objectFrame);
}
break;
@@ -1964,38 +1970,75 @@ NS_METHOD nsTableFrame::IR_ColGroupInserted(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aInsertedFrame,
+ nsTableColGroupFrame * aInsertedFrame,
PRBool aReplace)
{
- nsresult rv;
- /*
- 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 */
+ nsresult rv=NS_OK;
+ PRBool adjustStartingColIndex=PR_FALSE;
+ PRInt32 startingColIndex=0;
+ // find out what frame to insert aInsertedFrame after
+ nsIFrame *frameToInsertAfter=nsnull;
+ rv = aReflowState.reflowState.reflowCommand->GetPrevSiblingFrame(frameToInsertAfter);
+ // insert aInsertedFrame as the first child. Set its start col index to 0
+ if (nsnull==frameToInsertAfter)
+ {
+ aInsertedFrame->SetNextSibling(mFirstChild);
+ mFirstChild=aInsertedFrame;
+ startingColIndex += aInsertedFrame->SetStartColumnIndex(0);
+ adjustStartingColIndex=PR_TRUE;
+ }
+ nsIFrame *childFrame=mFirstChild;
+ nsIFrame *prevSib=nsnull;
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
+ {
+ if ((nsnull!=frameToInsertAfter) && (childFrame==frameToInsertAfter))
+ {
+ nsIFrame *nextSib=nsnull;
+ frameToInsertAfter->GetNextSibling(nextSib);
+ aInsertedFrame->SetNextSibling(nextSib);
+ frameToInsertAfter->SetNextSibling(aInsertedFrame);
+ // account for childFrame being a COLGROUP now
+ const nsStyleDisplay *display;
+ childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
+ {
+ if (PR_FALSE==adjustStartingColIndex) // we haven't gotten to aDeletedFrame yet
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
+ }
+ // skip ahead to aInsertedFrame, since we just handled the frame we inserted after
+ childFrame=aInsertedFrame;
+ adjustStartingColIndex=PR_TRUE; // now that we've inserted aInsertedFrame,
+ // start adjusting subsequent col groups' starting col index including aInsertedFrame
+ }
+ const nsStyleDisplay *display;
+ childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
+ {
+ if (PR_FALSE==adjustStartingColIndex) // we haven't gotten to aDeletedFrame yet
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
+ else // we've removed aDeletedFrame, now adjust the starting col index of all subsequent col groups
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
+ }
+ prevSib=childFrame;
+ rv = childFrame->GetNextSibling(childFrame);
+ }
+
+ InvalidateColumnCache();
+ //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_ColGroupAppended(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aAppendedFrame)
+ nsTableColGroupFrame * 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;
+ PRInt32 startingColIndex=0;
nsIFrame *childFrame=mFirstChild;
nsIFrame *lastChild=mFirstChild;
while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
@@ -2004,7 +2047,7 @@ NS_METHOD nsTableFrame::IR_ColGroupAppended(nsIPresContext& aPresContext,
childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
{
- colGroupList.AppendElement((void*)childFrame);
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
}
lastChild=childFrame;
rv = childFrame->GetNextSibling(childFrame);
@@ -2015,36 +2058,54 @@ NS_METHOD nsTableFrame::IR_ColGroupAppended(nsIPresContext& aPresContext,
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();
+ aAppendedFrame->SetStartColumnIndex(startingColIndex);
+
+#if 0
+
+we would only want to do this if manufactured col groups were invisible to the DOM. Since they
+currently are visible, they should behave just as if they were content-backed "real" colgroups
+If this decision is changed, the code below is a half-finished attempt to rationalize the situation.
+It requires having built a list of the colGroups before we get to this point.
+
+ // look at the last col group. If it is implicit, and it's cols are implicit, then
+ // it and its cols were manufactured for table layout.
+ // Delete it if possible, otherwise move it to the end of the list
+
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; colGroupIndexIsManufactured())
+ { // account for the new COLs that were added in aAppendedFrame
+ // first, try to delete the implicit colgroup
+
+ // if we couldn't delete it, move the implicit colgroup to the end of the list
+ // and adjust it's col indexes
+ nsIFrame *colGroupNextSib;
+ colGroup->GetNextSibling(colGroupNextSib);
+ childFrame=mFirstChild;
+ nsIFrame * prevSib=nsnull;
+ rv = NS_OK;
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
+ {
+ if (childFrame==colGroup)
{
- nsTableColGroupFrame *colGroup = (nsTableColGroupFrame *)(colGroupList.ElementAt(colGroupIndex));
- // XXX: here's where we yank colGroups if necessary
+ if (nsnull!=prevSib) // colGroup is in the middle of the list, remove it
+ prevSib->SetNextSibling(colGroupNextSib);
+ else // colGroup was the first child, so set it's next sib to first child
+ mFirstChild = colGroupNextSib;
+ aAppendedFrame->SetNextSibling(colGroup); // place colGroup at the end of the list
+ colGroup->SetNextSibling(nsnull);
+ break;
}
+ prevSib=childFrame;
+ rv = childFrame->GetNextSibling(childFrame);
}
}
}
+#endif
- //InvalidateFirstPassCache(); // for now, redo the first pass reflow
- // could probably just get away with mTableLayoutStrategy->Initialize(aMaxElementSize);
- mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
+
+ InvalidateColumnCache();
//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
@@ -2056,14 +2117,45 @@ NS_METHOD nsTableFrame::IR_ColGroupRemoved(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aDeletedFrame)
+ nsTableColGroupFrame * aDeletedFrame)
{
- nsresult rv;
- /*
- for every col in the colgroup (including implicit cols due to span attribute)
- an implicit col is created in the last implicit colgroup
- if there is no implicit colgroup, one is created at the end of the colgroup list
- */
+ nsresult rv=NS_OK;
+ PRBool adjustStartingColIndex=PR_FALSE;
+ PRInt32 startingColIndex=0;
+ nsIFrame *childFrame=mFirstChild;
+ nsIFrame *prevSib=nsnull;
+ while ((NS_SUCCEEDED(rv)) && (nsnull!=childFrame))
+ {
+ if (childFrame==aDeletedFrame)
+ {
+ nsIFrame *deleteFrameNextSib=nsnull;
+ aDeletedFrame->GetNextSibling(deleteFrameNextSib);
+ if (nsnull!=prevSib)
+ prevSib->SetNextSibling(deleteFrameNextSib);
+ else
+ mFirstChild = deleteFrameNextSib;
+ childFrame=deleteFrameNextSib;
+ if (nsnull==childFrame)
+ break;
+ adjustStartingColIndex=PR_TRUE; // now that we've removed aDeletedFrame, start adjusting subsequent col groups' starting col index
+ }
+ const nsStyleDisplay *display;
+ childFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
+ if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == display->mDisplay)
+ {
+ if (PR_FALSE==adjustStartingColIndex) // we haven't gotten to aDeletedFrame yet
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->GetColumnCount();
+ else // we've removed aDeletedFrame, now adjust the starting col index of all subsequent col groups
+ startingColIndex += ((nsTableColGroupFrame *)childFrame)->SetStartColumnIndex(startingColIndex);
+ }
+ prevSib=childFrame;
+ rv = childFrame->GetNextSibling(childFrame);
+ }
+
+ InvalidateColumnCache();
+ //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;
}
@@ -2071,7 +2163,7 @@ NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aInsertedFrame,
+ nsTableRowGroupFrame * aInsertedFrame,
PRBool aReplace)
{
nsresult rv;
@@ -2084,7 +2176,7 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aAppendedFrame)
+ nsTableRowGroupFrame * aAppendedFrame)
{
// hook aAppendedFrame into the child list
nsIFrame *lastChild = mFirstChild;
@@ -2115,7 +2207,7 @@ NS_METHOD nsTableFrame::IR_RowGroupRemoved(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aDeletedFrame)
+ nsTableRowGroupFrame * aDeletedFrame)
{
nsresult rv;
return rv;
@@ -2940,6 +3032,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
{
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
+ NS_ASSERTION(PR_FALSE==mColumnCacheValid, "column cache valid state should be PR_FALSE");
nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
EnsureColumns(aPresContext);
@@ -3028,6 +3121,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext,
}
childFrame->GetNextSibling(childFrame);
}
+ mColumnCacheValid=PR_TRUE;
}
PRBool nsTableFrame::IsFirstPassValid() const
@@ -3044,6 +3138,20 @@ void nsTableFrame::InvalidateFirstPassCache()
firstInFlow->mFirstPassValid=PR_FALSE;
}
+PRBool nsTableFrame::IsColumnCacheValid() const
+{
+ nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
+ NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
+ return firstInFlow->mColumnCacheValid;
+}
+
+void nsTableFrame::InvalidateColumnCache()
+{
+ nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
+ NS_ASSERTION(nsnull!=firstInFlow, "illegal state -- no first in flow");
+ firstInFlow->mColumnCacheValid=PR_FALSE;
+}
+
PRBool nsTableFrame::IsCellMapValid() const
{
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h
index cd8cbc57e5d4..05aacc6df15a 100644
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -29,6 +29,7 @@ class nsTableCellFrame;
class nsTableColFrame;
class nsTableRowGroupFrame;
class nsTableRowFrame;
+class nsTableColGroupFrame;
class nsITableLayoutStrategy;
class nsHTMLValue;
class ColumnInfoCache;
@@ -317,39 +318,39 @@ protected:
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aInsertedFrame,
+ nsTableColGroupFrame * aInsertedFrame,
PRBool aReplace);
- NS_IMETHOD IR_ColGroupAppended(nsIPresContext& aPresContext,
+ NS_IMETHOD IR_ColGroupAppended(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aAppendedFrame);
+ nsTableColGroupFrame * aAppendedFrame);
NS_IMETHOD IR_ColGroupRemoved(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aDeletedFrame);
+ nsTableColGroupFrame * aDeletedFrame);
NS_IMETHOD IR_RowGroupInserted(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aInsertedFrame,
+ nsTableRowGroupFrame * aInsertedFrame,
PRBool aReplace);
NS_IMETHOD IR_RowGroupAppended(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aAppendedFrame);
+ nsTableRowGroupFrame * aAppendedFrame);
NS_IMETHOD IR_RowGroupRemoved(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
InnerTableReflowState& aReflowState,
nsReflowStatus& aStatus,
- nsIFrame * aDeletedFrame);
+ nsTableRowGroupFrame * aDeletedFrame);
NS_IMETHOD IR_UnknownFrameInserted(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -437,9 +438,14 @@ protected:
/** returns PR_TRUE if the cached pass 1 data is still valid */
virtual PRBool IsFirstPassValid() const;
+ /** returns PR_TRUE if the cached column info is still valid */
+ virtual PRBool IsColumnCacheValid() const;
+
public:
virtual void InvalidateFirstPassCache();
+ virtual void InvalidateColumnCache();
+
protected:
/** do post processing to setting up style information for the frame */
NS_IMETHOD DidSetStyleContext(nsIPresContext& aPresContext);
@@ -589,6 +595,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 mColumnCacheValid; // PR_TRUE if column cache info 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