diff --git a/mozilla/content/base/src/nsStyleContext.cpp b/mozilla/content/base/src/nsStyleContext.cpp index ab298c598ac..1fb7105d955 100644 --- a/mozilla/content/base/src/nsStyleContext.cpp +++ b/mozilla/content/base/src/nsStyleContext.cpp @@ -549,7 +549,7 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre mRules = NS_STYLE_TABLE_RULES_NONE; mCellPadding.Reset(); mCellSpacing.Reset(); - mSpan=0; + mSpan=1; // values inherited if (nsnull!=aParent) mLayoutStrategy = aParent->mLayoutStrategy; diff --git a/mozilla/layout/base/src/nsStyleContext.cpp b/mozilla/layout/base/src/nsStyleContext.cpp index ab298c598ac..1fb7105d955 100644 --- a/mozilla/layout/base/src/nsStyleContext.cpp +++ b/mozilla/layout/base/src/nsStyleContext.cpp @@ -549,7 +549,7 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre mRules = NS_STYLE_TABLE_RULES_NONE; mCellPadding.Reset(); mCellSpacing.Reset(); - mSpan=0; + mSpan=1; // values inherited if (nsnull!=aParent) mLayoutStrategy = aParent->mLayoutStrategy; diff --git a/mozilla/layout/html/table/src/FixedTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/FixedTableLayoutStrategy.cpp index f6bfba434a1..e1fb21f2850 100644 --- a/mozilla/layout/html/table/src/FixedTableLayoutStrategy.cpp +++ b/mozilla/layout/html/table/src/FixedTableLayoutStrategy.cpp @@ -30,7 +30,7 @@ NS_DEF_PTR(nsIStyleContext); #ifdef NS_DEBUG -static PRBool gsDebug = PR_TRUE; +static PRBool gsDebug = PR_FALSE; #else static const PRBool gsDebug = PR_FALSE; #endif diff --git a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp index 2a270384cd3..9e9f416de9b 100644 --- a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp @@ -23,6 +23,8 @@ #include "nsIStyleContext.h" #include "nsStyleConsts.h" #include "nsIPresContext.h" +#include "nsIHTMLContent.h" +#include "nsHTMLParts.h" #include "nsIPtr.h" #include "nsHTMLAtoms.h" @@ -48,14 +50,18 @@ nsTableColGroupFrame::~nsTableColGroupFrame() 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; - nsresult rv = kid->QueryInterface(kIHTMLTableColElementIID, + rv = kid->QueryInterface(kIHTMLTableColElementIID, (void**) &colContent); // colContent: ADDREF++ NS_RELEASE(kid); if (rv==NS_OK) @@ -66,17 +72,67 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi PRInt32 colIndex = mStartColIndex + mColCount; ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat); mColCount+= repeat; - - // Set nsColFrame-specific information ((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex); - nsIFrame* tableFrame=nsnull; - GetGeometricParent(tableFrame); ((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame); - - SetStyleContextForFirstPass(&aPresContext, colIndex); } + // colgroup's span attribute is how many columns the group represents + // in the absence of any COL children + if (0==mColCount) + { + nsIFrame *firstImplicitCol=nsnull; + nsIFrame *prevColFrame=nsnull; + nsAutoString colTag; + nsHTMLAtoms::col->ToString(colTag); + mColCount = GetSpan(); + for (PRInt32 colIndex=0; colIndexAppendChildTo((nsIContent*)col, PR_FALSE); - return NS_OK; + // 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==firstImplicitCol) + firstImplicitCol = colFrame; + else + prevColFrame->SetNextSibling(colFrame); + prevColFrame = colFrame; + } + // hook new columns into col group child list + if (nsnull==mFirstChild) + mFirstChild = firstImplicitCol; + else + { + nsIFrame *lastChild = mFirstChild; + nsIFrame *nextChild = lastChild; + while (nsnull!=nextChild) + { + lastChild = nextChild; + nextChild->GetNextSibling(nextChild); + } + lastChild->SetNextSibling(firstImplicitCol); + } + } + SetStyleContextForFirstPass(&aPresContext); + + return rv; } nsresult @@ -97,7 +153,10 @@ nsTableColGroupFrame::AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aC NS_IMETHODIMP nsTableColGroupFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { - return AppendNewFrames(aPresContext, aChildList); + nsresult result = AppendNewFrames(aPresContext, aChildList); + if (NS_OK==result) + result = InitNewFrames(aPresContext, mFirstChild); + return result; } NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext, @@ -123,12 +182,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext, // create a frame and adjust it's style nsIFrame* kidFrame = nsnull; - if (eReflowReason_Initial == aReflowState.reason) { - // XXX Don't do this in the Init() member function, because the cell - // map hasn't been created yet.. - InitNewFrames(aPresContext, mFirstChild); - - } else if (eReflowReason_Incremental == aReflowState.reason) { + if (eReflowReason_Incremental == aReflowState.reason) { NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command"); // Get the type of reflow command @@ -172,18 +226,15 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext, } // Subclass hook for style post processing -NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext, - PRInt32 aColIndex) +NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext) { // get the table frame nsIFrame* tableFrame=nsnull; GetGeometricParent(tableFrame); - tableFrame->GetGeometricParent(tableFrame); // get the outer frame // get the style for the table frame - nsIStyleContextPtr tableSC; - tableFrame->GetStyleContext(aPresContext, tableSC.AssignRef()); - nsStyleTable *tableStyle = (nsStyleTable*)tableSC->GetStyleData(eStyleStruct_Table); + 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) @@ -197,32 +248,30 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre // for every column effected, set its width style PRInt32 colIndex=0; - nsIFrame *colFrame=nsnull; - nsIStyleContextPtr colStyleContext; - colFrame = FrameAt(mFirstChild, aColIndex); - if (nsnull!=colFrame) + nsIFrame *colFrame=mFirstChild; + while (nsnull!=colFrame) { - nsStylePosition * colPosition=nsnull; - colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef()); - colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position); - nsStyleCoord width (1, eStyleUnit_Proportional); - colPosition->mWidth = width; - colStyleContext->RecalcAutomaticData(aPresContext); - - // if there are more columns, there width is set to "minimum" - // XXX FIX USE OF LengthOf() and ChildAt()... - PRInt32 numChildFrames = LengthOf(mFirstChild); - for (; aColIndexGetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay)); + if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) { - colFrame = FrameAt(mFirstChild, colIndex); - if (nsnull==colFrame) - break; + nsIStyleContextPtr colStyleContext; nsStylePosition * colPosition=nsnull; colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef()); colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position); - colPosition->mWidth.SetCoordValue(0); + if (colIndexmWidth = width; + } + else + { + colPosition->mWidth.SetCoordValue(0); + } colStyleContext->RecalcAutomaticData(aPresContext); + colIndex++; } + colFrame->GetNextSibling(colFrame); } mStyleContext->RecalcAutomaticData(aPresContext); @@ -260,6 +309,18 @@ int nsTableColGroupFrame::GetColumnCount () return mColCount; } +PRInt32 nsTableColGroupFrame::GetSpan() +{ + PRInt32 span=1; + nsStyleTable* tableStyle=nsnull; + GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); + if (nsnull!=tableStyle) + { + span = tableStyle->mSpan; + } + return span; +} + /* ----- global methods ----- */ nsresult diff --git a/mozilla/layout/html/table/src/nsTableColGroupFrame.h b/mozilla/layout/html/table/src/nsTableColGroupFrame.h index 92727f48e68..108bdbbd51f 100644 --- a/mozilla/layout/html/table/src/nsTableColGroupFrame.h +++ b/mozilla/layout/html/table/src/nsTableColGroupFrame.h @@ -70,6 +70,9 @@ public: virtual void 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; protected: @@ -82,8 +85,7 @@ protected: * Since we need to know the full column structure before the COLS attribute * can be interpreted, we can't just use DidSetStyleContext */ - NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext, - PRInt32 aColIndex); + NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext); nsresult InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList); nsresult AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList); diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index 8f136cb0547..ebd7b7e5191 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -269,6 +269,7 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame) mIsInvariantWidth(PR_FALSE) { mEffectiveColCount = -1; // -1 means uninitialized + mCellMap = new nsCellMap(0, 0); } nsTableFrame::~nsTableFrame() @@ -290,6 +291,7 @@ NS_IMETHODIMP nsTableFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { mFirstChild = aChildList; + EnsureColumns(&aPresContext); return NS_OK; } @@ -610,13 +612,11 @@ void nsTableFrame::ResetCellMap () * add extra implicit columns to the content tree. */ -// XXX this and ENsureColumnsAt should be 1 method, with -1 for aColIndex meaning "do them all" -void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, - nsReflowMetrics& aDesiredSize, - const nsReflowState& aReflowState, - nsReflowStatus& aStatus) +// XXX this and EnsureColumnsAt should be 1 method, with -1 for aColIndex meaning "do them all" +void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext) { nsresult rv; + NS_PRECONDITION(nsnull!=mCellMap, "bad state: null cellmap"); // XXX sec should only be called on firstInFlow SetMinColSpanForTable(); if (nsnull==mCellMap) @@ -639,22 +639,29 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, PRInt32 numCols = ((nsTableColGroupFrame*)childFrame)->GetColumnCount(); actualColumns += numCols; lastColGroupFrame = (nsTableColGroupFrame *)childFrame; + if (PR_TRUE==gsDebug) printf("EC: found a col group %p\n", lastColGroupFrame); } else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay || NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay || NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay ) { firstRowGroupFrame = childFrame; + if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame); break; } prevSibFrame = childFrame; childFrame->GetNextSibling(childFrame); - } - if (actualColumns < GetColCount()) + } + PRInt32 colCount = GetColCount(); + if (PR_TRUE==gsDebug) printf("EC: actual = %d, colCount=%d\n", actualColumns, colCount); + if (actualColumns < colCount) { + PRBool lastColGroupNeedsInit=PR_FALSE; nsIHTMLContent *lastColGroup=nsnull; if (nsnull==lastColGroupFrame) { + lastColGroupNeedsInit=PR_TRUE; + if (PR_TRUE==gsDebug) printf("EC:creating colgroup\n", actualColumns, colCount); // create an implicit colgroup nsAutoString colGroupTag; nsHTMLAtoms::colgroup->ToString(colGroupTag); @@ -705,6 +712,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, nsIFrame* lastNewColFrame = nsnull; for ( ; excessColumns > 0; excessColumns--) { + if (PR_TRUE==gsDebug) printf("EC:creating col\n", actualColumns, colCount); nsIHTMLContent *col=nsnull; // create an implicit col rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++ @@ -719,6 +727,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, nsIStyleContextPtr colStyleContext = aPresContext->ResolveStyleContextFor(col, lastColGroupFrame, PR_TRUE); colFrame->SetStyleContext(aPresContext, colStyleContext); + colFrame->Init(*aPresContext, nsnull); // XXX Don't release this style context (or we'll end up with a double-free).\ // This code is doing what nsTableColGroupFrame::Reflow() does... @@ -733,20 +742,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, lastNewColFrame = colFrame; NS_RELEASE(col); // ADDREF: col-- } + if (PR_TRUE==lastColGroupNeedsInit) + lastColGroupFrame->Init(*aPresContext, firstNewColFrame); NS_RELEASE(lastColGroup); // ADDREF: lastColGroup-- - - // Generate an appended reflow command - // XXX This is really yucky... - nsIReflowCommand* reflowCmd; - - NS_NewHTMLReflowCommand(&reflowCmd, lastColGroupFrame, nsIReflowCommand::FrameAppended, - firstNewColFrame); - nsReflowState incrReflowState(lastColGroupFrame, aReflowState, aReflowState.maxSize); - incrReflowState.reflowCommand = reflowCmd; - incrReflowState.reason = eReflowReason_Incremental; - - // Reflow the frames - lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus); } } @@ -756,10 +754,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, */ // XXX should be nsresult, not void void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex, - nsIPresContext* aPresContext, - nsReflowMetrics& aDesiredSize, - const nsReflowState& aReflowState, - nsReflowStatus& aStatus) + nsIPresContext* aPresContext) { nsresult rv; PRInt32 actualColumns = 0; @@ -873,19 +868,6 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex, NS_RELEASE(col); // ADDREF: col-- } NS_RELEASE(lastColGroup); // ADDREF: lastColGroup-- - - // Generate an appended reflow command - // XXX This is really yucky... - nsIReflowCommand* reflowCmd; - - NS_NewHTMLReflowCommand(&reflowCmd, lastColGroupFrame, nsIReflowCommand::FrameAppended, - firstNewColFrame); - nsReflowState incrReflowState(lastColGroupFrame, aReflowState, aReflowState.maxSize); - incrReflowState.reflowCommand = reflowCmd; - incrReflowState.reason = eReflowReason_Incremental; - - // Reflow the frames - lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus); } } @@ -1584,10 +1566,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext, if (PR_TRUE==NeedsReflow(aReflowState.maxSize)) { if (PR_FALSE==IsFirstPassValid()) - { // we treat the table as if we've never seen the layout data before - if (mCellMap!=nsnull) - delete mCellMap; - mCellMap = new nsCellMap(0, 0); + { + // 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 mPass = kPASS_FIRST; aStatus = ResizeReflowPass1(&aPresContext, aDesiredSize, aReflowState, aStatus); // check result @@ -1685,7 +1667,7 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext, nsStyleTable* tableStyle; GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); - if (1||NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy) + if (NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy) { for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) { nsSize maxKidElementSize(0,0); @@ -1973,6 +1955,16 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext, nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull; PRBool result = PR_TRUE; + nsReflowReason reason; + nsStyleTable* tableStyle; + GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); + if (NS_STYLE_TABLE_LAYOUT_FIXED==tableStyle->mLayoutStrategy) + { + reason = aState.reflowState.reason; + } + else + reason = eReflowReason_Resize; + for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) { nsSize kidAvailSize(aState.availSize); nsReflowMetrics desiredSize(pKidMaxElementSize); @@ -2000,10 +1992,10 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext, if (PR_FALSE == aState.unconstrainedWidth) { kidAvailSize.width -= kidMargin.left + kidMargin.right; } - + // Reflow the child into the available space nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize, - eReflowReason_Resize); + reason); kidFrame->WillReflow(*aPresContext); nscoord x = aState.leftInset + kidMargin.left; nscoord y = aState.topInset + aState.y + topMargin; @@ -2514,7 +2506,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext, NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!"); nsStyleTable* tableStyle; GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); - EnsureColumns(aPresContext, aDesiredSize, aReflowState, aStatus); + EnsureColumns(aPresContext); if (nsnull==mColCache) { mColCache = new ColumnInfoCache(mColCount); diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h index bd697b7852e..5f0d17dc7e2 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.h +++ b/mozilla/layout/html/table/src/nsTableFrame.h @@ -211,10 +211,7 @@ public: * if not, create the needed col frames */ virtual void EnsureColumnFrameAt(PRInt32 aColIndex, - nsIPresContext* aPresContext, - nsReflowMetrics& aDesiredSize, - const nsReflowState& aReflowState, - nsReflowStatus& aStatus); + nsIPresContext* aPresContext); /** return the index of the next row that is not yet assigned. * If no row is initialized, 0 is returned. @@ -394,10 +391,7 @@ protected: * if the cell map says there are more columns than this, * add extra implicit columns to the content tree. */ - virtual void EnsureColumns (nsIPresContext* aPresContext, - nsReflowMetrics& aDesiredSize, - const nsReflowState& aReflowState, - nsReflowStatus& aStatus); + virtual void EnsureColumns (nsIPresContext* aPresContext); /** Set the min col span for every column in the table. Scans the whole table. */ virtual void SetMinColSpanForTable(); diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp index 66a112d7ce4..40daf18f3cd 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp @@ -100,9 +100,62 @@ NS_IMETHODIMP nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { mFirstChild = aChildList; + nsTableFrame* table = nsnull; + nsresult result; + + result = GetTableFrame((nsIFrame *&)table); + if ((NS_OK==result) && (table != nsnull)) + { + SetRowIndex(table->GetNextAvailRowIndex()); + 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); + } + // part of the style optimization is to ensure that the column frame for the cell exists + //table->EnsureColumnFrameAt(colIndex, &aPresContext); + + // 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); + } + } return NS_OK; } +NS_METHOD nsTableRowFrame::GetTableFrame(nsIFrame *& aFrame) +{ + nsresult result = GetContentParent(aFrame); + while ((NS_OK==result) && (nsnull!=aFrame)) + { + const nsStyleDisplay *display; + aFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display); + if (NS_STYLE_DISPLAY_TABLE == display->mDisplay) + break; + result = aFrame->GetContentParent(aFrame); + } + return result; +} + /** * Post-reflow hook. This is where the table row does its post-processing */ @@ -536,65 +589,28 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, nsReflowMetrics& aDesiredSize) { // Place our children, one at a time, until we are out of children - nsSize kidMaxElementSize; + nsSize kidMaxElementSize(0,0); PRInt32 kidIndex = 0; PRInt32 colIndex = 0; nsIFrame* prevKidFrame = nsnull; nscoord maxTopMargin = 0; nscoord maxBottomMargin = 0; nscoord x = 0; - nsresult result = NS_OK; PRBool isFirst=PR_TRUE; + PRBool tableLayoutStrategy=NS_STYLE_TABLE_LAYOUT_AUTO; + nsTableFrame* table = nsnull; + nsresult result = GetTableFrame((nsIFrame *&)table); + if ((NS_OK==result) && (table != nsnull)) + { + nsStyleTable* tableStyle; + table->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); + tableLayoutStrategy = tableStyle->mLayoutStrategy; + } + else + return NS_ERROR_UNEXPECTED; - // what row am I? - // to handle rows with no cells, this block must be done before the "Get the next content object" block - SetRowIndex(aState.tableFrame->GetNextAvailRowIndex()); - - for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) { - // what column does this cell belong to? - colIndex = aState.tableFrame->GetNextAvailColIndex(mRowIndex, colIndex); - if (gsDebug) printf("%p : next col index = %d\n", this, colIndex); - - // XXX CONSTRUCTION - // This code doesn't really belong here... - - /* 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); - } - // part of the style optimization is to ensure that the column frame for the cell exists - // we used to do this post-pass1, now we do it incrementally for the optimization - nsReflowStatus status; - aState.tableFrame->EnsureColumnFrameAt(colIndex, - &aPresContext, - aDesiredSize, - aState.reflowState, - status); - - // 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 - aState.tableFrame->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild); - - // Because we're not splittable always allow the child to be as high as - // it wants. The default available width is also unconstrained so we can - // get the child's maximum width - nsSize kidAvailSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); - + for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) + { // Get the child's margins nsMargin margin; nscoord topMargin = 0; @@ -606,16 +622,28 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, maxTopMargin = PR_MAX(margin.top, maxTopMargin); maxBottomMargin = PR_MAX(margin.bottom, maxBottomMargin); - - // Reflow the child. We always want back the max element size even if the - // caller doesn't ask for it, because the table needs it to compute column - // widths - nsReflowMetrics kidSize(&kidMaxElementSize); + + // Because we're not splittable always allow the child to be as high as + // it wants. The default available width is also unconstrained so we can + // get the child's maximum width + nsSize kidAvailSize; + nsReflowMetrics kidSize(nsnull); + if (NS_STYLE_TABLE_LAYOUT_AUTO==tableLayoutStrategy) + { + kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + kidSize.maxElementSize=&kidMaxElementSize; + } + else + { + PRInt32 colIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex(); + kidAvailSize.SizeTo(table->GetColumnWidth(colIndex), NS_UNCONSTRAINEDSIZE); + } + nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize, eReflowReason_Initial); kidFrame->WillReflow(aPresContext); if (gsDebug) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width); - status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState); + nsresult status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState); if (gsDebug) printf ("TR %p for cell %p Initial Reflow: desired=%d, MES=%d\n", this, kidFrame, kidSize.width, kidMaxElementSize.width); diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.h b/mozilla/layout/html/table/src/nsTableRowFrame.h index 4d8ebfd820e..dcc6c5930e1 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.h +++ b/mozilla/layout/html/table/src/nsTableRowFrame.h @@ -114,6 +114,9 @@ public: /** set this row's starting row index */ virtual void SetRowIndex (int aRowIndex); + /** get the row's enclosing table frame in a safe way */ + NS_IMETHOD GetTableFrame(nsIFrame *& aFrame); + NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const; protected: diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp index 733dd858401..3be083acece 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -553,7 +553,6 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext, return result; } -#include "nsIPresShell.h" /** */ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext, diff --git a/mozilla/layout/style/nsStyleContext.cpp b/mozilla/layout/style/nsStyleContext.cpp index ab298c598ac..1fb7105d955 100644 --- a/mozilla/layout/style/nsStyleContext.cpp +++ b/mozilla/layout/style/nsStyleContext.cpp @@ -549,7 +549,7 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre mRules = NS_STYLE_TABLE_RULES_NONE; mCellPadding.Reset(); mCellSpacing.Reset(); - mSpan=0; + mSpan=1; // values inherited if (nsnull!=aParent) mLayoutStrategy = aParent->mLayoutStrategy; diff --git a/mozilla/layout/tables/FixedTableLayoutStrategy.cpp b/mozilla/layout/tables/FixedTableLayoutStrategy.cpp index f6bfba434a1..e1fb21f2850 100644 --- a/mozilla/layout/tables/FixedTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/FixedTableLayoutStrategy.cpp @@ -30,7 +30,7 @@ NS_DEF_PTR(nsIStyleContext); #ifdef NS_DEBUG -static PRBool gsDebug = PR_TRUE; +static PRBool gsDebug = PR_FALSE; #else static const PRBool gsDebug = PR_FALSE; #endif diff --git a/mozilla/layout/tables/nsTableColGroupFrame.cpp b/mozilla/layout/tables/nsTableColGroupFrame.cpp index 2a270384cd3..9e9f416de9b 100644 --- a/mozilla/layout/tables/nsTableColGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableColGroupFrame.cpp @@ -23,6 +23,8 @@ #include "nsIStyleContext.h" #include "nsStyleConsts.h" #include "nsIPresContext.h" +#include "nsIHTMLContent.h" +#include "nsHTMLParts.h" #include "nsIPtr.h" #include "nsHTMLAtoms.h" @@ -48,14 +50,18 @@ nsTableColGroupFrame::~nsTableColGroupFrame() 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; - nsresult rv = kid->QueryInterface(kIHTMLTableColElementIID, + rv = kid->QueryInterface(kIHTMLTableColElementIID, (void**) &colContent); // colContent: ADDREF++ NS_RELEASE(kid); if (rv==NS_OK) @@ -66,17 +72,67 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi PRInt32 colIndex = mStartColIndex + mColCount; ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat); mColCount+= repeat; - - // Set nsColFrame-specific information ((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex); - nsIFrame* tableFrame=nsnull; - GetGeometricParent(tableFrame); ((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame); - - SetStyleContextForFirstPass(&aPresContext, colIndex); } + // colgroup's span attribute is how many columns the group represents + // in the absence of any COL children + if (0==mColCount) + { + nsIFrame *firstImplicitCol=nsnull; + nsIFrame *prevColFrame=nsnull; + nsAutoString colTag; + nsHTMLAtoms::col->ToString(colTag); + mColCount = GetSpan(); + for (PRInt32 colIndex=0; colIndexAppendChildTo((nsIContent*)col, PR_FALSE); - return NS_OK; + // 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==firstImplicitCol) + firstImplicitCol = colFrame; + else + prevColFrame->SetNextSibling(colFrame); + prevColFrame = colFrame; + } + // hook new columns into col group child list + if (nsnull==mFirstChild) + mFirstChild = firstImplicitCol; + else + { + nsIFrame *lastChild = mFirstChild; + nsIFrame *nextChild = lastChild; + while (nsnull!=nextChild) + { + lastChild = nextChild; + nextChild->GetNextSibling(nextChild); + } + lastChild->SetNextSibling(firstImplicitCol); + } + } + SetStyleContextForFirstPass(&aPresContext); + + return rv; } nsresult @@ -97,7 +153,10 @@ nsTableColGroupFrame::AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aC NS_IMETHODIMP nsTableColGroupFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { - return AppendNewFrames(aPresContext, aChildList); + nsresult result = AppendNewFrames(aPresContext, aChildList); + if (NS_OK==result) + result = InitNewFrames(aPresContext, mFirstChild); + return result; } NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext, @@ -123,12 +182,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext, // create a frame and adjust it's style nsIFrame* kidFrame = nsnull; - if (eReflowReason_Initial == aReflowState.reason) { - // XXX Don't do this in the Init() member function, because the cell - // map hasn't been created yet.. - InitNewFrames(aPresContext, mFirstChild); - - } else if (eReflowReason_Incremental == aReflowState.reason) { + if (eReflowReason_Incremental == aReflowState.reason) { NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command"); // Get the type of reflow command @@ -172,18 +226,15 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext, } // Subclass hook for style post processing -NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext, - PRInt32 aColIndex) +NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext) { // get the table frame nsIFrame* tableFrame=nsnull; GetGeometricParent(tableFrame); - tableFrame->GetGeometricParent(tableFrame); // get the outer frame // get the style for the table frame - nsIStyleContextPtr tableSC; - tableFrame->GetStyleContext(aPresContext, tableSC.AssignRef()); - nsStyleTable *tableStyle = (nsStyleTable*)tableSC->GetStyleData(eStyleStruct_Table); + 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) @@ -197,32 +248,30 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre // for every column effected, set its width style PRInt32 colIndex=0; - nsIFrame *colFrame=nsnull; - nsIStyleContextPtr colStyleContext; - colFrame = FrameAt(mFirstChild, aColIndex); - if (nsnull!=colFrame) + nsIFrame *colFrame=mFirstChild; + while (nsnull!=colFrame) { - nsStylePosition * colPosition=nsnull; - colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef()); - colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position); - nsStyleCoord width (1, eStyleUnit_Proportional); - colPosition->mWidth = width; - colStyleContext->RecalcAutomaticData(aPresContext); - - // if there are more columns, there width is set to "minimum" - // XXX FIX USE OF LengthOf() and ChildAt()... - PRInt32 numChildFrames = LengthOf(mFirstChild); - for (; aColIndexGetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay)); + if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) { - colFrame = FrameAt(mFirstChild, colIndex); - if (nsnull==colFrame) - break; + nsIStyleContextPtr colStyleContext; nsStylePosition * colPosition=nsnull; colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef()); colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position); - colPosition->mWidth.SetCoordValue(0); + if (colIndexmWidth = width; + } + else + { + colPosition->mWidth.SetCoordValue(0); + } colStyleContext->RecalcAutomaticData(aPresContext); + colIndex++; } + colFrame->GetNextSibling(colFrame); } mStyleContext->RecalcAutomaticData(aPresContext); @@ -260,6 +309,18 @@ int nsTableColGroupFrame::GetColumnCount () return mColCount; } +PRInt32 nsTableColGroupFrame::GetSpan() +{ + PRInt32 span=1; + nsStyleTable* tableStyle=nsnull; + GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); + if (nsnull!=tableStyle) + { + span = tableStyle->mSpan; + } + return span; +} + /* ----- global methods ----- */ nsresult diff --git a/mozilla/layout/tables/nsTableColGroupFrame.h b/mozilla/layout/tables/nsTableColGroupFrame.h index 92727f48e68..108bdbbd51f 100644 --- a/mozilla/layout/tables/nsTableColGroupFrame.h +++ b/mozilla/layout/tables/nsTableColGroupFrame.h @@ -70,6 +70,9 @@ public: virtual void 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; protected: @@ -82,8 +85,7 @@ protected: * Since we need to know the full column structure before the COLS attribute * can be interpreted, we can't just use DidSetStyleContext */ - NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext, - PRInt32 aColIndex); + NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext); nsresult InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList); nsresult AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList); diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 8f136cb0547..ebd7b7e5191 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -269,6 +269,7 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame) mIsInvariantWidth(PR_FALSE) { mEffectiveColCount = -1; // -1 means uninitialized + mCellMap = new nsCellMap(0, 0); } nsTableFrame::~nsTableFrame() @@ -290,6 +291,7 @@ NS_IMETHODIMP nsTableFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { mFirstChild = aChildList; + EnsureColumns(&aPresContext); return NS_OK; } @@ -610,13 +612,11 @@ void nsTableFrame::ResetCellMap () * add extra implicit columns to the content tree. */ -// XXX this and ENsureColumnsAt should be 1 method, with -1 for aColIndex meaning "do them all" -void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, - nsReflowMetrics& aDesiredSize, - const nsReflowState& aReflowState, - nsReflowStatus& aStatus) +// XXX this and EnsureColumnsAt should be 1 method, with -1 for aColIndex meaning "do them all" +void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext) { nsresult rv; + NS_PRECONDITION(nsnull!=mCellMap, "bad state: null cellmap"); // XXX sec should only be called on firstInFlow SetMinColSpanForTable(); if (nsnull==mCellMap) @@ -639,22 +639,29 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, PRInt32 numCols = ((nsTableColGroupFrame*)childFrame)->GetColumnCount(); actualColumns += numCols; lastColGroupFrame = (nsTableColGroupFrame *)childFrame; + if (PR_TRUE==gsDebug) printf("EC: found a col group %p\n", lastColGroupFrame); } else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay || NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay || NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay ) { firstRowGroupFrame = childFrame; + if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame); break; } prevSibFrame = childFrame; childFrame->GetNextSibling(childFrame); - } - if (actualColumns < GetColCount()) + } + PRInt32 colCount = GetColCount(); + if (PR_TRUE==gsDebug) printf("EC: actual = %d, colCount=%d\n", actualColumns, colCount); + if (actualColumns < colCount) { + PRBool lastColGroupNeedsInit=PR_FALSE; nsIHTMLContent *lastColGroup=nsnull; if (nsnull==lastColGroupFrame) { + lastColGroupNeedsInit=PR_TRUE; + if (PR_TRUE==gsDebug) printf("EC:creating colgroup\n", actualColumns, colCount); // create an implicit colgroup nsAutoString colGroupTag; nsHTMLAtoms::colgroup->ToString(colGroupTag); @@ -705,6 +712,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, nsIFrame* lastNewColFrame = nsnull; for ( ; excessColumns > 0; excessColumns--) { + if (PR_TRUE==gsDebug) printf("EC:creating col\n", actualColumns, colCount); nsIHTMLContent *col=nsnull; // create an implicit col rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++ @@ -719,6 +727,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, nsIStyleContextPtr colStyleContext = aPresContext->ResolveStyleContextFor(col, lastColGroupFrame, PR_TRUE); colFrame->SetStyleContext(aPresContext, colStyleContext); + colFrame->Init(*aPresContext, nsnull); // XXX Don't release this style context (or we'll end up with a double-free).\ // This code is doing what nsTableColGroupFrame::Reflow() does... @@ -733,20 +742,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, lastNewColFrame = colFrame; NS_RELEASE(col); // ADDREF: col-- } + if (PR_TRUE==lastColGroupNeedsInit) + lastColGroupFrame->Init(*aPresContext, firstNewColFrame); NS_RELEASE(lastColGroup); // ADDREF: lastColGroup-- - - // Generate an appended reflow command - // XXX This is really yucky... - nsIReflowCommand* reflowCmd; - - NS_NewHTMLReflowCommand(&reflowCmd, lastColGroupFrame, nsIReflowCommand::FrameAppended, - firstNewColFrame); - nsReflowState incrReflowState(lastColGroupFrame, aReflowState, aReflowState.maxSize); - incrReflowState.reflowCommand = reflowCmd; - incrReflowState.reason = eReflowReason_Incremental; - - // Reflow the frames - lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus); } } @@ -756,10 +754,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, */ // XXX should be nsresult, not void void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex, - nsIPresContext* aPresContext, - nsReflowMetrics& aDesiredSize, - const nsReflowState& aReflowState, - nsReflowStatus& aStatus) + nsIPresContext* aPresContext) { nsresult rv; PRInt32 actualColumns = 0; @@ -873,19 +868,6 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex, NS_RELEASE(col); // ADDREF: col-- } NS_RELEASE(lastColGroup); // ADDREF: lastColGroup-- - - // Generate an appended reflow command - // XXX This is really yucky... - nsIReflowCommand* reflowCmd; - - NS_NewHTMLReflowCommand(&reflowCmd, lastColGroupFrame, nsIReflowCommand::FrameAppended, - firstNewColFrame); - nsReflowState incrReflowState(lastColGroupFrame, aReflowState, aReflowState.maxSize); - incrReflowState.reflowCommand = reflowCmd; - incrReflowState.reason = eReflowReason_Incremental; - - // Reflow the frames - lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus); } } @@ -1584,10 +1566,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext, if (PR_TRUE==NeedsReflow(aReflowState.maxSize)) { if (PR_FALSE==IsFirstPassValid()) - { // we treat the table as if we've never seen the layout data before - if (mCellMap!=nsnull) - delete mCellMap; - mCellMap = new nsCellMap(0, 0); + { + // 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 mPass = kPASS_FIRST; aStatus = ResizeReflowPass1(&aPresContext, aDesiredSize, aReflowState, aStatus); // check result @@ -1685,7 +1667,7 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext, nsStyleTable* tableStyle; GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); - if (1||NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy) + if (NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy) { for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) { nsSize maxKidElementSize(0,0); @@ -1973,6 +1955,16 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext, nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull; PRBool result = PR_TRUE; + nsReflowReason reason; + nsStyleTable* tableStyle; + GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); + if (NS_STYLE_TABLE_LAYOUT_FIXED==tableStyle->mLayoutStrategy) + { + reason = aState.reflowState.reason; + } + else + reason = eReflowReason_Resize; + for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) { nsSize kidAvailSize(aState.availSize); nsReflowMetrics desiredSize(pKidMaxElementSize); @@ -2000,10 +1992,10 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext, if (PR_FALSE == aState.unconstrainedWidth) { kidAvailSize.width -= kidMargin.left + kidMargin.right; } - + // Reflow the child into the available space nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize, - eReflowReason_Resize); + reason); kidFrame->WillReflow(*aPresContext); nscoord x = aState.leftInset + kidMargin.left; nscoord y = aState.topInset + aState.y + topMargin; @@ -2514,7 +2506,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext, NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!"); nsStyleTable* tableStyle; GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); - EnsureColumns(aPresContext, aDesiredSize, aReflowState, aStatus); + EnsureColumns(aPresContext); if (nsnull==mColCache) { mColCache = new ColumnInfoCache(mColCount); diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index bd697b7852e..5f0d17dc7e2 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -211,10 +211,7 @@ public: * if not, create the needed col frames */ virtual void EnsureColumnFrameAt(PRInt32 aColIndex, - nsIPresContext* aPresContext, - nsReflowMetrics& aDesiredSize, - const nsReflowState& aReflowState, - nsReflowStatus& aStatus); + nsIPresContext* aPresContext); /** return the index of the next row that is not yet assigned. * If no row is initialized, 0 is returned. @@ -394,10 +391,7 @@ protected: * if the cell map says there are more columns than this, * add extra implicit columns to the content tree. */ - virtual void EnsureColumns (nsIPresContext* aPresContext, - nsReflowMetrics& aDesiredSize, - const nsReflowState& aReflowState, - nsReflowStatus& aStatus); + virtual void EnsureColumns (nsIPresContext* aPresContext); /** Set the min col span for every column in the table. Scans the whole table. */ virtual void SetMinColSpanForTable(); diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp index 66a112d7ce4..40daf18f3cd 100644 --- a/mozilla/layout/tables/nsTableRowFrame.cpp +++ b/mozilla/layout/tables/nsTableRowFrame.cpp @@ -100,9 +100,62 @@ NS_IMETHODIMP nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { mFirstChild = aChildList; + nsTableFrame* table = nsnull; + nsresult result; + + result = GetTableFrame((nsIFrame *&)table); + if ((NS_OK==result) && (table != nsnull)) + { + SetRowIndex(table->GetNextAvailRowIndex()); + 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); + } + // part of the style optimization is to ensure that the column frame for the cell exists + //table->EnsureColumnFrameAt(colIndex, &aPresContext); + + // 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); + } + } return NS_OK; } +NS_METHOD nsTableRowFrame::GetTableFrame(nsIFrame *& aFrame) +{ + nsresult result = GetContentParent(aFrame); + while ((NS_OK==result) && (nsnull!=aFrame)) + { + const nsStyleDisplay *display; + aFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display); + if (NS_STYLE_DISPLAY_TABLE == display->mDisplay) + break; + result = aFrame->GetContentParent(aFrame); + } + return result; +} + /** * Post-reflow hook. This is where the table row does its post-processing */ @@ -536,65 +589,28 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, nsReflowMetrics& aDesiredSize) { // Place our children, one at a time, until we are out of children - nsSize kidMaxElementSize; + nsSize kidMaxElementSize(0,0); PRInt32 kidIndex = 0; PRInt32 colIndex = 0; nsIFrame* prevKidFrame = nsnull; nscoord maxTopMargin = 0; nscoord maxBottomMargin = 0; nscoord x = 0; - nsresult result = NS_OK; PRBool isFirst=PR_TRUE; + PRBool tableLayoutStrategy=NS_STYLE_TABLE_LAYOUT_AUTO; + nsTableFrame* table = nsnull; + nsresult result = GetTableFrame((nsIFrame *&)table); + if ((NS_OK==result) && (table != nsnull)) + { + nsStyleTable* tableStyle; + table->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); + tableLayoutStrategy = tableStyle->mLayoutStrategy; + } + else + return NS_ERROR_UNEXPECTED; - // what row am I? - // to handle rows with no cells, this block must be done before the "Get the next content object" block - SetRowIndex(aState.tableFrame->GetNextAvailRowIndex()); - - for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) { - // what column does this cell belong to? - colIndex = aState.tableFrame->GetNextAvailColIndex(mRowIndex, colIndex); - if (gsDebug) printf("%p : next col index = %d\n", this, colIndex); - - // XXX CONSTRUCTION - // This code doesn't really belong here... - - /* 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); - } - // part of the style optimization is to ensure that the column frame for the cell exists - // we used to do this post-pass1, now we do it incrementally for the optimization - nsReflowStatus status; - aState.tableFrame->EnsureColumnFrameAt(colIndex, - &aPresContext, - aDesiredSize, - aState.reflowState, - status); - - // 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 - aState.tableFrame->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild); - - // Because we're not splittable always allow the child to be as high as - // it wants. The default available width is also unconstrained so we can - // get the child's maximum width - nsSize kidAvailSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); - + for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) + { // Get the child's margins nsMargin margin; nscoord topMargin = 0; @@ -606,16 +622,28 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, maxTopMargin = PR_MAX(margin.top, maxTopMargin); maxBottomMargin = PR_MAX(margin.bottom, maxBottomMargin); - - // Reflow the child. We always want back the max element size even if the - // caller doesn't ask for it, because the table needs it to compute column - // widths - nsReflowMetrics kidSize(&kidMaxElementSize); + + // Because we're not splittable always allow the child to be as high as + // it wants. The default available width is also unconstrained so we can + // get the child's maximum width + nsSize kidAvailSize; + nsReflowMetrics kidSize(nsnull); + if (NS_STYLE_TABLE_LAYOUT_AUTO==tableLayoutStrategy) + { + kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + kidSize.maxElementSize=&kidMaxElementSize; + } + else + { + PRInt32 colIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex(); + kidAvailSize.SizeTo(table->GetColumnWidth(colIndex), NS_UNCONSTRAINEDSIZE); + } + nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize, eReflowReason_Initial); kidFrame->WillReflow(aPresContext); if (gsDebug) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width); - status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState); + nsresult status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState); if (gsDebug) printf ("TR %p for cell %p Initial Reflow: desired=%d, MES=%d\n", this, kidFrame, kidSize.width, kidMaxElementSize.width); diff --git a/mozilla/layout/tables/nsTableRowFrame.h b/mozilla/layout/tables/nsTableRowFrame.h index 4d8ebfd820e..dcc6c5930e1 100644 --- a/mozilla/layout/tables/nsTableRowFrame.h +++ b/mozilla/layout/tables/nsTableRowFrame.h @@ -114,6 +114,9 @@ public: /** set this row's starting row index */ virtual void SetRowIndex (int aRowIndex); + /** get the row's enclosing table frame in a safe way */ + NS_IMETHOD GetTableFrame(nsIFrame *& aFrame); + NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const; protected: diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp index 733dd858401..3be083acece 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp @@ -553,7 +553,6 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext, return result; } -#include "nsIPresShell.h" /** */ void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,