From eeaf9cbeddfbf72c5bb6a272f581d1d18aa12322 Mon Sep 17 00:00:00 2001 From: "buster%netscape.com" Date: Thu, 12 Nov 1998 18:37:28 +0000 Subject: [PATCH] col and colgroup attribute handling colgroup pseudo frame for cols inserted directly into a table. More like this to come... git-svn-id: svn://10.0.0.236/trunk@14512 18797224-902f-48f8-a5cc-f745e15eee43 --- .../content/src/nsHTMLTableColElement.cpp | 13 +++- .../src/nsHTMLTableColGroupElement.cpp | 10 ++- .../html/style/src/nsHTMLStyleSheet.cpp | 35 +++++++++-- mozilla/layout/base/public/nsIStyleContext.h | 2 +- .../content/src/nsHTMLTableColElement.cpp | 13 +++- .../src/nsHTMLTableColGroupElement.cpp | 10 ++- .../html/style/src/nsHTMLStyleSheet.cpp | 35 +++++++++-- .../layout/html/table/src/nsTableColFrame.cpp | 8 ++- .../layout/html/table/src/nsTableColFrame.h | 14 +---- .../html/table/src/nsTableColGroupFrame.cpp | 63 +++++++++++++------ .../layout/html/table/src/nsTableFrame.cpp | 22 +++++-- mozilla/layout/style/nsHTMLStyleSheet.cpp | 35 +++++++++-- mozilla/layout/tables/nsTableColFrame.cpp | 8 ++- mozilla/layout/tables/nsTableColFrame.h | 14 +---- .../layout/tables/nsTableColGroupFrame.cpp | 63 +++++++++++++------ mozilla/layout/tables/nsTableFrame.cpp | 22 +++++-- 16 files changed, 276 insertions(+), 91 deletions(-) diff --git a/mozilla/content/html/content/src/nsHTMLTableColElement.cpp b/mozilla/content/html/content/src/nsHTMLTableColElement.cpp index b7fc21c38c9..11cef3b1f1e 100644 --- a/mozilla/content/html/content/src/nsHTMLTableColElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTableColElement.cpp @@ -165,7 +165,7 @@ nsHTMLTableColElement::StringToAttribute(nsIAtom* aAttribute, nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer); return NS_CONTENT_ATTR_HAS_VALUE; } - else if (aAttribute == nsHTMLAtoms::repeat) { + else if (aAttribute == nsHTMLAtoms::span) { nsGenericHTMLElement::ParseValue(aValue, 1, aResult, eHTMLUnit_Integer); return NS_CONTENT_ATTR_HAS_VALUE; } @@ -199,7 +199,7 @@ nsHTMLTableColElement::AttributeToString(nsIAtom* aAttribute, ch */ /* ignore attributes that are of standard types - choff, repeat, width + choff, span, width */ if (aAttribute == nsHTMLAtoms::align) { if (nsGenericHTMLElement::TableHAlignValueToString(aValue, aResult)) { @@ -260,7 +260,16 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes, textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); } + + // span: int + aAttributes->GetAttribute(nsHTMLAtoms::span, value); + if (value.GetUnit() == eHTMLUnit_Integer) + { + nsStyleTable *tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); + tableStyle->mSpan = value.GetIntValue(); + } } + nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext); } diff --git a/mozilla/content/html/content/src/nsHTMLTableColGroupElement.cpp b/mozilla/content/html/content/src/nsHTMLTableColGroupElement.cpp index 7b532aa89a3..9c92d1130bb 100644 --- a/mozilla/content/html/content/src/nsHTMLTableColGroupElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLTableColGroupElement.cpp @@ -154,7 +154,7 @@ nsHTMLTableColGroupElement::StringToAttribute(nsIAtom* aAttribute, nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer); return NS_CONTENT_ATTR_HAS_VALUE; } - else if (aAttribute == nsHTMLAtoms::repeat) { + else if (aAttribute == nsHTMLAtoms::span) { nsGenericHTMLElement::ParseValue(aValue, 1, aResult, eHTMLUnit_Integer); return NS_CONTENT_ATTR_HAS_VALUE; } @@ -249,6 +249,14 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes, textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); } + + // span: int + aAttributes->GetAttribute(nsHTMLAtoms::span, value); + if (value.GetUnit() == eHTMLUnit_Integer) + { + nsStyleTable *tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); + tableStyle->mSpan = value.GetIntValue(); + } } nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext); } diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp index bc89dad0dac..319482092a4 100644 --- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp @@ -962,6 +962,7 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, PRInt32 count; aContent->ChildCount(count); for (PRInt32 i = 0; i < count; i++) { + nsIFrame* grandChildList=nsnull; // to be used only when pseudoframes need to be created nsIContent* childContent; aContent->ChildAt(i, childContent); @@ -1000,8 +1001,28 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, break; case NS_STYLE_DISPLAY_TABLE_COLUMN: - NS_NewTableColFrame(childContent, innerFrame, frame); + { + //XXX: Peter - please code review and remove this comment when all is well. + // When we're done here, "frame" will be the pseudo colgroup frame and will be dealt with normally after the swtich. + // The the column itself will have already been dealt with + nsIStyleContext* colStyleContext; + nsIStyleContext* colGroupStyleContext; + colGroupStyleContext = aPresContext->ResolvePseudoStyleContextFor (childContent, + nsHTMLAtoms::columnPseudo, + aStyleContext); + nsStyleDisplay *colGroupDisplay = (nsStyleDisplay *)colGroupStyleContext->GetMutableStyleData(eStyleStruct_Display); + colGroupDisplay->mDisplay = NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP; + NS_NewTableColGroupFrame(childContent, innerFrame, frame); + childStyleContext = colGroupStyleContext; // the col group style context will get set to childStyleContext after the switch ends. + // need to resolve the style context for the column again to be sure it's a child of the colgroup style context + colStyleContext = aPresContext->ResolveStyleContextFor(childContent, colGroupStyleContext); + nsIFrame *colFrame; + NS_NewTableColFrame(childContent, frame, colFrame); + colFrame->SetInitialChildList(*aPresContext, nsnull, nsnull); + colFrame->SetStyleContext(aPresContext, colStyleContext); + grandChildList = colFrame; break; + } case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP: NS_NewTableColGroupFrame(childContent, innerFrame, frame); @@ -1019,9 +1040,13 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, frame->SetStyleContext(aPresContext, childStyleContext); // Process the children, and set the frame's initial child list - nsIFrame* childChildList; - ProcessChildren(aPresContext, frame, childContent, childChildList); - frame->SetInitialChildList(*aPresContext, nsnull, childChildList); + if (nsnull==grandChildList) + { + nsIFrame* childChildList; + ProcessChildren(aPresContext, frame, childContent, childChildList); + grandChildList = childChildList; + } + frame->SetInitialChildList(*aPresContext, nsnull, grandChildList); // Link the frame into the child list if (nsnull == lastChildFrame) { @@ -1329,6 +1354,8 @@ HTMLStyleSheetImpl::ConstructFrameByDisplayType(nsIPresContext* aPresContext, case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP: // XXX We should check for being inside of a table. If there's a missing // table then create an anonynmous table frame + // XXX: see ConstructTableFrame for a prototype of how this should be done, + // and propagate similar logic to other table elements { nsIFrame *parentFrame; rv = GetAdjustedParentFrame(aParentFrame, aDisplay->mDisplay, parentFrame); diff --git a/mozilla/layout/base/public/nsIStyleContext.h b/mozilla/layout/base/public/nsIStyleContext.h index c18b9890c0e..5b11561afdf 100644 --- a/mozilla/layout/base/public/nsIStyleContext.h +++ b/mozilla/layout/base/public/nsIStyleContext.h @@ -168,7 +168,7 @@ struct nsStyleTable: public nsStyleStruct { nsStyleCoord mCellPadding; // [reset] nsStyleCoord mCellSpacing; // [reset] PRInt32 mCols; // [reset] an integer if set, or see nsStyleConsts.h NS_STYLE_TABLE_COLS_* - PRInt32 mSpan; // [reset] the number of columns spanned by a colgroup + PRInt32 mSpan; // [reset] the number of columns spanned by a colgroup or col protected: nsStyleTable(void); diff --git a/mozilla/layout/html/content/src/nsHTMLTableColElement.cpp b/mozilla/layout/html/content/src/nsHTMLTableColElement.cpp index b7fc21c38c9..11cef3b1f1e 100644 --- a/mozilla/layout/html/content/src/nsHTMLTableColElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLTableColElement.cpp @@ -165,7 +165,7 @@ nsHTMLTableColElement::StringToAttribute(nsIAtom* aAttribute, nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer); return NS_CONTENT_ATTR_HAS_VALUE; } - else if (aAttribute == nsHTMLAtoms::repeat) { + else if (aAttribute == nsHTMLAtoms::span) { nsGenericHTMLElement::ParseValue(aValue, 1, aResult, eHTMLUnit_Integer); return NS_CONTENT_ATTR_HAS_VALUE; } @@ -199,7 +199,7 @@ nsHTMLTableColElement::AttributeToString(nsIAtom* aAttribute, ch */ /* ignore attributes that are of standard types - choff, repeat, width + choff, span, width */ if (aAttribute == nsHTMLAtoms::align) { if (nsGenericHTMLElement::TableHAlignValueToString(aValue, aResult)) { @@ -260,7 +260,16 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes, textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); } + + // span: int + aAttributes->GetAttribute(nsHTMLAtoms::span, value); + if (value.GetUnit() == eHTMLUnit_Integer) + { + nsStyleTable *tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); + tableStyle->mSpan = value.GetIntValue(); + } } + nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext); } diff --git a/mozilla/layout/html/content/src/nsHTMLTableColGroupElement.cpp b/mozilla/layout/html/content/src/nsHTMLTableColGroupElement.cpp index 7b532aa89a3..9c92d1130bb 100644 --- a/mozilla/layout/html/content/src/nsHTMLTableColGroupElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLTableColGroupElement.cpp @@ -154,7 +154,7 @@ nsHTMLTableColGroupElement::StringToAttribute(nsIAtom* aAttribute, nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer); return NS_CONTENT_ATTR_HAS_VALUE; } - else if (aAttribute == nsHTMLAtoms::repeat) { + else if (aAttribute == nsHTMLAtoms::span) { nsGenericHTMLElement::ParseValue(aValue, 1, aResult, eHTMLUnit_Integer); return NS_CONTENT_ATTR_HAS_VALUE; } @@ -249,6 +249,14 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes, textStyle = (nsStyleText*)aContext->GetMutableStyleData(eStyleStruct_Text); textStyle->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated); } + + // span: int + aAttributes->GetAttribute(nsHTMLAtoms::span, value); + if (value.GetUnit() == eHTMLUnit_Integer) + { + nsStyleTable *tableStyle = (nsStyleTable*)aContext->GetMutableStyleData(eStyleStruct_Table); + tableStyle->mSpan = value.GetIntValue(); + } } nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext); } diff --git a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp index bc89dad0dac..319482092a4 100644 --- a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -962,6 +962,7 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, PRInt32 count; aContent->ChildCount(count); for (PRInt32 i = 0; i < count; i++) { + nsIFrame* grandChildList=nsnull; // to be used only when pseudoframes need to be created nsIContent* childContent; aContent->ChildAt(i, childContent); @@ -1000,8 +1001,28 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, break; case NS_STYLE_DISPLAY_TABLE_COLUMN: - NS_NewTableColFrame(childContent, innerFrame, frame); + { + //XXX: Peter - please code review and remove this comment when all is well. + // When we're done here, "frame" will be the pseudo colgroup frame and will be dealt with normally after the swtich. + // The the column itself will have already been dealt with + nsIStyleContext* colStyleContext; + nsIStyleContext* colGroupStyleContext; + colGroupStyleContext = aPresContext->ResolvePseudoStyleContextFor (childContent, + nsHTMLAtoms::columnPseudo, + aStyleContext); + nsStyleDisplay *colGroupDisplay = (nsStyleDisplay *)colGroupStyleContext->GetMutableStyleData(eStyleStruct_Display); + colGroupDisplay->mDisplay = NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP; + NS_NewTableColGroupFrame(childContent, innerFrame, frame); + childStyleContext = colGroupStyleContext; // the col group style context will get set to childStyleContext after the switch ends. + // need to resolve the style context for the column again to be sure it's a child of the colgroup style context + colStyleContext = aPresContext->ResolveStyleContextFor(childContent, colGroupStyleContext); + nsIFrame *colFrame; + NS_NewTableColFrame(childContent, frame, colFrame); + colFrame->SetInitialChildList(*aPresContext, nsnull, nsnull); + colFrame->SetStyleContext(aPresContext, colStyleContext); + grandChildList = colFrame; break; + } case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP: NS_NewTableColGroupFrame(childContent, innerFrame, frame); @@ -1019,9 +1040,13 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, frame->SetStyleContext(aPresContext, childStyleContext); // Process the children, and set the frame's initial child list - nsIFrame* childChildList; - ProcessChildren(aPresContext, frame, childContent, childChildList); - frame->SetInitialChildList(*aPresContext, nsnull, childChildList); + if (nsnull==grandChildList) + { + nsIFrame* childChildList; + ProcessChildren(aPresContext, frame, childContent, childChildList); + grandChildList = childChildList; + } + frame->SetInitialChildList(*aPresContext, nsnull, grandChildList); // Link the frame into the child list if (nsnull == lastChildFrame) { @@ -1329,6 +1354,8 @@ HTMLStyleSheetImpl::ConstructFrameByDisplayType(nsIPresContext* aPresContext, case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP: // XXX We should check for being inside of a table. If there's a missing // table then create an anonynmous table frame + // XXX: see ConstructTableFrame for a prototype of how this should be done, + // and propagate similar logic to other table elements { nsIFrame *parentFrame; rv = GetAdjustedParentFrame(aParentFrame, aDisplay->mDisplay, parentFrame); diff --git a/mozilla/layout/html/table/src/nsTableColFrame.cpp b/mozilla/layout/html/table/src/nsTableColFrame.cpp index 3a1d8ce3b82..768a7817690 100644 --- a/mozilla/layout/html/table/src/nsTableColFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColFrame.cpp @@ -36,7 +36,6 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsFrame(aContent, aParentFrame) { mColIndex = 0; - mRepeat = 1; mMaxColWidth = 0; mMinColWidth = 0; mMaxEffectiveColWidth = 0; @@ -76,6 +75,13 @@ NS_METHOD nsTableColFrame::Reflow(nsIPresContext& aPresContext, return NS_OK; } +PRInt32 nsTableColFrame::GetSpan() +{ + nsStyleTable* tableStyle; + GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); + return tableStyle->mSpan; +} + /* ----- global methods ----- */ diff --git a/mozilla/layout/html/table/src/nsTableColFrame.h b/mozilla/layout/html/table/src/nsTableColFrame.h index 5697f06940b..b456f115a13 100644 --- a/mozilla/layout/html/table/src/nsTableColFrame.h +++ b/mozilla/layout/html/table/src/nsTableColFrame.h @@ -29,7 +29,7 @@ public: eWIDTH_SOURCE_CELL_WITH_SPAN=2 // a cell implicitly specified a width via colspan }; - void InitColFrame(PRInt32 aColIndex, PRInt32 aRepeat); + void InitColFrame(PRInt32 aColIndex); /** instantiate a new instance of nsTableColFrame. * @param aResult the new object is returned in this out-param @@ -56,7 +56,7 @@ public: virtual int GetColumnIndex (); /** return the number of the columns the col represents. always >= 0 */ - virtual int GetRepeat (); + virtual int GetSpan (); /** set the index of the column this content object represents. must be >= 0 */ virtual void SetColumnIndex (int aColIndex); @@ -96,8 +96,6 @@ protected: /** the starting index of the column (starting at 0) that this col object represents */ PRInt32 mColIndex; - /** the number of columns that the attributes of this column extend to */ - PRInt32 mRepeat; nscoord mMaxColWidth; nscoord mMinColWidth; @@ -112,21 +110,15 @@ protected: }; -inline void nsTableColFrame::InitColFrame(PRInt32 aColIndex, PRInt32 aRepeat) +inline void nsTableColFrame::InitColFrame(PRInt32 aColIndex) { NS_ASSERTION(0<=aColIndex, "bad col index param"); - NS_ASSERTION(0<=aRepeat, "bad repeat param"); - mColIndex = aColIndex; - mRepeat = aRepeat; } inline nsTableColFrame::GetColumnIndex() { return mColIndex; } -inline nsTableColFrame::GetRepeat() -{ return mRepeat; } - inline void nsTableColFrame::SetColumnIndex (int aColIndex) { mColIndex = aColIndex;} diff --git a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp index 232324fcded..113bded82db 100644 --- a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp @@ -67,24 +67,20 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi // Set the preliminary values for the column frame nsIContent* kid; kidFrame->GetContent(kid); - // should use style to get this value - PRInt32 repeat=1; - nsIHTMLTableColElement* colContent = nsnull; - rv = kid->QueryInterface(kIHTMLTableColElementIID, - (void**) &colContent); // colContent: ADDREF++ - NS_RELEASE(kid); - if (rv==NS_OK) - { - colContent->GetSpanValue(&repeat); - NS_RELEASE(colContent); - } + PRInt32 colIndex = mStartColIndex + mColCount; - ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat); - mColCount+= repeat; - tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame); + ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex); + PRInt32 repeat = ((nsTableColFrame *)(kidFrame))->GetSpan(); + mColCount += repeat; + for (PRInt32 i=0; iAddColumnFrame((nsTableColFrame *)kidFrame); + } } // colgroup's span attribute is how many columns the group represents // in the absence of any COL children + // Note that this is the correct, though perhaps unexpected, behavior for the span attribute. + // The spec says that if there are any COL children, the colgroup's span is ignored. if (0==mColCount) { nsIFrame *firstImplicitColFrame=nsnull; @@ -112,7 +108,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi // Set nsColFrame-specific information PRInt32 absColIndex = mStartColIndex + colIndex; - ((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1); + ((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex); ((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex); tableFrame->AddColumnFrame((nsTableColFrame *)colFrame); @@ -569,8 +565,39 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPre } colFrame->GetNextSibling(colFrame); } - mStyleContext->RecalcAutomaticData(&aPresContext); } + else + { + // propagate the colgroup width attribute down to the columns if they have no width of their own + nsStylePosition* position = (nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position); + if (eStyleUnit_Null!=position->mWidth.GetUnit()) + { + // now for every column that doesn't have it's own width, set the width style + nsIFrame *colFrame=mFirstChild; + while (nsnull!=colFrame) + { + nsStyleDisplay * colDisplay=nsnull; + colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay)); + if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) + { + nsIStyleContextPtr colStyleContext; + nsStylePosition * colPosition=nsnull; + colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct *&)colPosition); // get a read-only version of the style context + //XXX: how do I know this is auto because it's defaulted, vs. set explicitly to "auto"? + if (eStyleUnit_Auto==colPosition->mWidth.GetUnit()) + { + // notice how we defer getting a mutable style context until we're sure we really need one + colFrame->GetStyleContext(colStyleContext.AssignRef()); + colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position); + colPosition->mWidth = position->mWidth; + colStyleContext->RecalcAutomaticData(&aPresContext); + } + } + colFrame->GetNextSibling(colFrame); + } + } + } + //mStyleContext->RecalcAutomaticData(&aPresContext); } return rv; } @@ -592,7 +619,7 @@ int nsTableColGroupFrame::GetColumnCount () { nsTableColFrame *col = (nsTableColFrame *)childFrame; col->SetColumnIndex (mStartColIndex + mColCount); - mColCount += col->GetRepeat(); + mColCount += col->GetSpan(); } childFrame->GetNextSibling(childFrame); } @@ -643,7 +670,7 @@ nsTableColFrame * nsTableColGroupFrame::GetColumnAt (PRInt32 aColIndex) if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay) { nsTableColFrame *col = (nsTableColFrame *)childFrame; - count += col->GetRepeat(); + count += col->GetSpan(); if (aColIndex<=count) result = col; } diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index d7358b1eba1..e2bfb2c3ba8 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -649,6 +649,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext) childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) { + ((nsTableColGroupFrame*)childFrame)->SetStartColumnIndex(actualColumns); PRInt32 numCols = ((nsTableColGroupFrame*)childFrame)->GetColumnCount(); actualColumns += numCols; lastColGroupFrame = (nsTableColGroupFrame *)childFrame; @@ -2965,14 +2966,18 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext, childFrame->FirstChild(nsnull, (nsIFrame *&)colFrame); while (nsnull!=colFrame) { - nsTableColFrame *cachedColFrame = mCellMap->GetColumnFrame(colIndex); - if (nsnull==cachedColFrame) + PRInt32 repeat = colFrame->GetSpan(); + for (PRInt32 i=0; iAppendColumnFrame(colFrame); + nsTableColFrame *cachedColFrame = mCellMap->GetColumnFrame(colIndex+i); + if (nsnull==cachedColFrame) + { + if (gsDebug) printf("TIF BCB: adding column frame %p\n", colFrame); + mCellMap->AppendColumnFrame(colFrame); + } + colIndex++; } colFrame->GetNextSibling((nsIFrame *&)colFrame); - colIndex++; } } else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay)) @@ -3029,7 +3034,12 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext, { const nsStylePosition* colPosition; colFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)colPosition)); - mColCache->AddColumnInfo(colPosition->mWidth.GetUnit(), colFrame->GetColumnIndex()); + PRInt32 repeat = colFrame->GetSpan(); + colIndex = colFrame->GetColumnIndex(); + for (PRInt32 i=0; iAddColumnInfo(colPosition->mWidth.GetUnit(), colIndex+i); + } } colFrame->GetNextSibling((nsIFrame *&)colFrame); } diff --git a/mozilla/layout/style/nsHTMLStyleSheet.cpp b/mozilla/layout/style/nsHTMLStyleSheet.cpp index bc89dad0dac..319482092a4 100644 --- a/mozilla/layout/style/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLStyleSheet.cpp @@ -962,6 +962,7 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, PRInt32 count; aContent->ChildCount(count); for (PRInt32 i = 0; i < count; i++) { + nsIFrame* grandChildList=nsnull; // to be used only when pseudoframes need to be created nsIContent* childContent; aContent->ChildAt(i, childContent); @@ -1000,8 +1001,28 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, break; case NS_STYLE_DISPLAY_TABLE_COLUMN: - NS_NewTableColFrame(childContent, innerFrame, frame); + { + //XXX: Peter - please code review and remove this comment when all is well. + // When we're done here, "frame" will be the pseudo colgroup frame and will be dealt with normally after the swtich. + // The the column itself will have already been dealt with + nsIStyleContext* colStyleContext; + nsIStyleContext* colGroupStyleContext; + colGroupStyleContext = aPresContext->ResolvePseudoStyleContextFor (childContent, + nsHTMLAtoms::columnPseudo, + aStyleContext); + nsStyleDisplay *colGroupDisplay = (nsStyleDisplay *)colGroupStyleContext->GetMutableStyleData(eStyleStruct_Display); + colGroupDisplay->mDisplay = NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP; + NS_NewTableColGroupFrame(childContent, innerFrame, frame); + childStyleContext = colGroupStyleContext; // the col group style context will get set to childStyleContext after the switch ends. + // need to resolve the style context for the column again to be sure it's a child of the colgroup style context + colStyleContext = aPresContext->ResolveStyleContextFor(childContent, colGroupStyleContext); + nsIFrame *colFrame; + NS_NewTableColFrame(childContent, frame, colFrame); + colFrame->SetInitialChildList(*aPresContext, nsnull, nsnull); + colFrame->SetStyleContext(aPresContext, colStyleContext); + grandChildList = colFrame; break; + } case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP: NS_NewTableColGroupFrame(childContent, innerFrame, frame); @@ -1019,9 +1040,13 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, frame->SetStyleContext(aPresContext, childStyleContext); // Process the children, and set the frame's initial child list - nsIFrame* childChildList; - ProcessChildren(aPresContext, frame, childContent, childChildList); - frame->SetInitialChildList(*aPresContext, nsnull, childChildList); + if (nsnull==grandChildList) + { + nsIFrame* childChildList; + ProcessChildren(aPresContext, frame, childContent, childChildList); + grandChildList = childChildList; + } + frame->SetInitialChildList(*aPresContext, nsnull, grandChildList); // Link the frame into the child list if (nsnull == lastChildFrame) { @@ -1329,6 +1354,8 @@ HTMLStyleSheetImpl::ConstructFrameByDisplayType(nsIPresContext* aPresContext, case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP: // XXX We should check for being inside of a table. If there's a missing // table then create an anonynmous table frame + // XXX: see ConstructTableFrame for a prototype of how this should be done, + // and propagate similar logic to other table elements { nsIFrame *parentFrame; rv = GetAdjustedParentFrame(aParentFrame, aDisplay->mDisplay, parentFrame); diff --git a/mozilla/layout/tables/nsTableColFrame.cpp b/mozilla/layout/tables/nsTableColFrame.cpp index 3a1d8ce3b82..768a7817690 100644 --- a/mozilla/layout/tables/nsTableColFrame.cpp +++ b/mozilla/layout/tables/nsTableColFrame.cpp @@ -36,7 +36,6 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsFrame(aContent, aParentFrame) { mColIndex = 0; - mRepeat = 1; mMaxColWidth = 0; mMinColWidth = 0; mMaxEffectiveColWidth = 0; @@ -76,6 +75,13 @@ NS_METHOD nsTableColFrame::Reflow(nsIPresContext& aPresContext, return NS_OK; } +PRInt32 nsTableColFrame::GetSpan() +{ + nsStyleTable* tableStyle; + GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle); + return tableStyle->mSpan; +} + /* ----- global methods ----- */ diff --git a/mozilla/layout/tables/nsTableColFrame.h b/mozilla/layout/tables/nsTableColFrame.h index 5697f06940b..b456f115a13 100644 --- a/mozilla/layout/tables/nsTableColFrame.h +++ b/mozilla/layout/tables/nsTableColFrame.h @@ -29,7 +29,7 @@ public: eWIDTH_SOURCE_CELL_WITH_SPAN=2 // a cell implicitly specified a width via colspan }; - void InitColFrame(PRInt32 aColIndex, PRInt32 aRepeat); + void InitColFrame(PRInt32 aColIndex); /** instantiate a new instance of nsTableColFrame. * @param aResult the new object is returned in this out-param @@ -56,7 +56,7 @@ public: virtual int GetColumnIndex (); /** return the number of the columns the col represents. always >= 0 */ - virtual int GetRepeat (); + virtual int GetSpan (); /** set the index of the column this content object represents. must be >= 0 */ virtual void SetColumnIndex (int aColIndex); @@ -96,8 +96,6 @@ protected: /** the starting index of the column (starting at 0) that this col object represents */ PRInt32 mColIndex; - /** the number of columns that the attributes of this column extend to */ - PRInt32 mRepeat; nscoord mMaxColWidth; nscoord mMinColWidth; @@ -112,21 +110,15 @@ protected: }; -inline void nsTableColFrame::InitColFrame(PRInt32 aColIndex, PRInt32 aRepeat) +inline void nsTableColFrame::InitColFrame(PRInt32 aColIndex) { NS_ASSERTION(0<=aColIndex, "bad col index param"); - NS_ASSERTION(0<=aRepeat, "bad repeat param"); - mColIndex = aColIndex; - mRepeat = aRepeat; } inline nsTableColFrame::GetColumnIndex() { return mColIndex; } -inline nsTableColFrame::GetRepeat() -{ return mRepeat; } - inline void nsTableColFrame::SetColumnIndex (int aColIndex) { mColIndex = aColIndex;} diff --git a/mozilla/layout/tables/nsTableColGroupFrame.cpp b/mozilla/layout/tables/nsTableColGroupFrame.cpp index 232324fcded..113bded82db 100644 --- a/mozilla/layout/tables/nsTableColGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableColGroupFrame.cpp @@ -67,24 +67,20 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi // Set the preliminary values for the column frame nsIContent* kid; kidFrame->GetContent(kid); - // should use style to get this value - PRInt32 repeat=1; - nsIHTMLTableColElement* colContent = nsnull; - rv = kid->QueryInterface(kIHTMLTableColElementIID, - (void**) &colContent); // colContent: ADDREF++ - NS_RELEASE(kid); - if (rv==NS_OK) - { - colContent->GetSpanValue(&repeat); - NS_RELEASE(colContent); - } + PRInt32 colIndex = mStartColIndex + mColCount; - ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat); - mColCount+= repeat; - tableFrame->AddColumnFrame((nsTableColFrame *)kidFrame); + ((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex); + PRInt32 repeat = ((nsTableColFrame *)(kidFrame))->GetSpan(); + mColCount += repeat; + for (PRInt32 i=0; iAddColumnFrame((nsTableColFrame *)kidFrame); + } } // colgroup's span attribute is how many columns the group represents // in the absence of any COL children + // Note that this is the correct, though perhaps unexpected, behavior for the span attribute. + // The spec says that if there are any COL children, the colgroup's span is ignored. if (0==mColCount) { nsIFrame *firstImplicitColFrame=nsnull; @@ -112,7 +108,7 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi // Set nsColFrame-specific information PRInt32 absColIndex = mStartColIndex + colIndex; - ((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1); + ((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex); ((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex); tableFrame->AddColumnFrame((nsTableColFrame *)colFrame); @@ -569,8 +565,39 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext& aPre } colFrame->GetNextSibling(colFrame); } - mStyleContext->RecalcAutomaticData(&aPresContext); } + else + { + // propagate the colgroup width attribute down to the columns if they have no width of their own + nsStylePosition* position = (nsStylePosition*)mStyleContext->GetStyleData(eStyleStruct_Position); + if (eStyleUnit_Null!=position->mWidth.GetUnit()) + { + // now for every column that doesn't have it's own width, set the width style + nsIFrame *colFrame=mFirstChild; + while (nsnull!=colFrame) + { + nsStyleDisplay * colDisplay=nsnull; + colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay)); + if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) + { + nsIStyleContextPtr colStyleContext; + nsStylePosition * colPosition=nsnull; + colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct *&)colPosition); // get a read-only version of the style context + //XXX: how do I know this is auto because it's defaulted, vs. set explicitly to "auto"? + if (eStyleUnit_Auto==colPosition->mWidth.GetUnit()) + { + // notice how we defer getting a mutable style context until we're sure we really need one + colFrame->GetStyleContext(colStyleContext.AssignRef()); + colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position); + colPosition->mWidth = position->mWidth; + colStyleContext->RecalcAutomaticData(&aPresContext); + } + } + colFrame->GetNextSibling(colFrame); + } + } + } + //mStyleContext->RecalcAutomaticData(&aPresContext); } return rv; } @@ -592,7 +619,7 @@ int nsTableColGroupFrame::GetColumnCount () { nsTableColFrame *col = (nsTableColFrame *)childFrame; col->SetColumnIndex (mStartColIndex + mColCount); - mColCount += col->GetRepeat(); + mColCount += col->GetSpan(); } childFrame->GetNextSibling(childFrame); } @@ -643,7 +670,7 @@ nsTableColFrame * nsTableColGroupFrame::GetColumnAt (PRInt32 aColIndex) if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay) { nsTableColFrame *col = (nsTableColFrame *)childFrame; - count += col->GetRepeat(); + count += col->GetSpan(); if (aColIndex<=count) result = col; } diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index d7358b1eba1..e2bfb2c3ba8 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -649,6 +649,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext& aPresContext) childFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) { + ((nsTableColGroupFrame*)childFrame)->SetStartColumnIndex(actualColumns); PRInt32 numCols = ((nsTableColGroupFrame*)childFrame)->GetColumnCount(); actualColumns += numCols; lastColGroupFrame = (nsTableColGroupFrame *)childFrame; @@ -2965,14 +2966,18 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext, childFrame->FirstChild(nsnull, (nsIFrame *&)colFrame); while (nsnull!=colFrame) { - nsTableColFrame *cachedColFrame = mCellMap->GetColumnFrame(colIndex); - if (nsnull==cachedColFrame) + PRInt32 repeat = colFrame->GetSpan(); + for (PRInt32 i=0; iAppendColumnFrame(colFrame); + nsTableColFrame *cachedColFrame = mCellMap->GetColumnFrame(colIndex+i); + if (nsnull==cachedColFrame) + { + if (gsDebug) printf("TIF BCB: adding column frame %p\n", colFrame); + mCellMap->AppendColumnFrame(colFrame); + } + colIndex++; } colFrame->GetNextSibling((nsIFrame *&)colFrame); - colIndex++; } } else if (PR_TRUE==IsRowGroup(childDisplay->mDisplay)) @@ -3029,7 +3034,12 @@ void nsTableFrame::BuildColumnCache( nsIPresContext& aPresContext, { const nsStylePosition* colPosition; colFrame->GetStyleData(eStyleStruct_Position, ((nsStyleStruct *&)colPosition)); - mColCache->AddColumnInfo(colPosition->mWidth.GetUnit(), colFrame->GetColumnIndex()); + PRInt32 repeat = colFrame->GetSpan(); + colIndex = colFrame->GetColumnIndex(); + for (PRInt32 i=0; iAddColumnInfo(colPosition->mWidth.GetUnit(), colIndex+i); + } } colFrame->GetNextSibling((nsIFrame *&)colFrame); }