From 46dc14a9bbff84ee700cebe41e9549aa8c9f2185 Mon Sep 17 00:00:00 2001 From: "karnaze%netscape.com" Date: Sun, 17 Jan 1999 23:35:56 +0000 Subject: [PATCH] scrollable row groups git-svn-id: svn://10.0.0.236/trunk@17941 18797224-902f-48f8-a5cc-f745e15eee43 --- .../html/style/src/nsHTMLStyleSheet.cpp | 65 +++++++++++++++++-- .../html/style/src/nsHTMLStyleSheet.cpp | 65 +++++++++++++++++-- .../layout/html/table/src/nsTableFrame.cpp | 39 +++++++++-- mozilla/layout/html/table/src/nsTableFrame.h | 6 ++ .../html/table/src/nsTableRowGroupFrame.cpp | 33 +++++++++- mozilla/layout/style/nsHTMLStyleSheet.cpp | 65 +++++++++++++++++-- mozilla/layout/tables/nsTableFrame.cpp | 39 +++++++++-- mozilla/layout/tables/nsTableFrame.h | 6 ++ .../layout/tables/nsTableRowGroupFrame.cpp | 33 +++++++++- .../webshell/tests/viewer/samples/test4.html | 22 +++++++ 10 files changed, 341 insertions(+), 32 deletions(-) diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp index df2215c1c38..90f93a6901b 100644 --- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp @@ -395,6 +395,13 @@ protected: nsAbsoluteItems& aAboluteItems, nsIFrame*& aNewFrame); + nsresult ConstructTableRowGroupFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewScrollFrame, + nsIFrame*& aNewFrame); + nsresult ConstructTableCellFrame(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParentFrame, @@ -1099,6 +1106,50 @@ HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent, nsIFrame*& aFrame) return rv; } +nsresult +HTMLStyleSheetImpl::ConstructTableRowGroupFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewScrollFrame, + nsIFrame*& aNewFrame) +{ + const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + if (IsScrollable(aPresContext, styleDisplay)) { + // Create a scroll frame + NS_NewScrollFrame(aNewScrollFrame); + + + // Initialize it + aNewScrollFrame->Init(*aPresContext, aContent, aParent, aStyleContext); + + // The scroll frame gets the original style context, and the scrolled + // frame gets a SCROLLED-CONTENT pseudo element style context that + // inherits the background properties + nsIStyleContext* scrolledPseudoStyle = aPresContext->ResolvePseudoStyleContextFor + (aContent, nsHTMLAtoms::scrolledContentPseudo, aStyleContext); + + // Create an area container for the frame + NS_NewTableRowGroupFrame(aNewFrame); + + // Initialize the frame and force it to have a view + aNewFrame->Init(*aPresContext, aContent, aNewScrollFrame, scrolledPseudoStyle); + nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, aNewFrame, + scrolledPseudoStyle, PR_TRUE); + NS_RELEASE(scrolledPseudoStyle); + + aNewScrollFrame->SetInitialChildList(*aPresContext, nsnull, aNewFrame); + } else { + NS_NewTableRowGroupFrame(aNewFrame); + aNewFrame->Init(*aPresContext, aContent, aParent, aStyleContext); + aNewScrollFrame = nsnull; + } + + return NS_OK; +} + nsresult HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, nsIContent* aContent, @@ -1146,7 +1197,8 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, aContent->ChildAt(i, childContent); if (nsnull != childContent) { - nsIFrame* frame = nsnull; + nsIFrame* frame = nsnull; + nsIFrame* scrollFrame = nsnull; nsIStyleContext* childStyleContext; // Resolve the style context @@ -1176,8 +1228,8 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP: case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP: case NS_STYLE_DISPLAY_TABLE_ROW_GROUP: - NS_NewTableRowGroupFrame(frame); - frame->Init(*aPresContext, childContent, innerFrame, childStyleContext); + ConstructTableRowGroupFrame(aPresContext, childContent, innerFrame, + childStyleContext, scrollFrame, frame); break; case NS_STYLE_DISPLAY_TABLE_ROW: @@ -1284,12 +1336,13 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, frame->SetInitialChildList(*aPresContext, nsnull, grandChildList); // Link the frame into the child list + nsIFrame* outerMostFrame = (nsnull == scrollFrame) ? frame : scrollFrame; if (nsnull == lastChildFrame) { - innerChildList = frame; + innerChildList = outerMostFrame; } else { - lastChildFrame->SetNextSibling(frame); + lastChildFrame->SetNextSibling(outerMostFrame); } - lastChildFrame = frame; + lastChildFrame = outerMostFrame; } NS_RELEASE(childStyleContext); diff --git a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp index df2215c1c38..90f93a6901b 100644 --- a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -395,6 +395,13 @@ protected: nsAbsoluteItems& aAboluteItems, nsIFrame*& aNewFrame); + nsresult ConstructTableRowGroupFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewScrollFrame, + nsIFrame*& aNewFrame); + nsresult ConstructTableCellFrame(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParentFrame, @@ -1099,6 +1106,50 @@ HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent, nsIFrame*& aFrame) return rv; } +nsresult +HTMLStyleSheetImpl::ConstructTableRowGroupFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewScrollFrame, + nsIFrame*& aNewFrame) +{ + const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + if (IsScrollable(aPresContext, styleDisplay)) { + // Create a scroll frame + NS_NewScrollFrame(aNewScrollFrame); + + + // Initialize it + aNewScrollFrame->Init(*aPresContext, aContent, aParent, aStyleContext); + + // The scroll frame gets the original style context, and the scrolled + // frame gets a SCROLLED-CONTENT pseudo element style context that + // inherits the background properties + nsIStyleContext* scrolledPseudoStyle = aPresContext->ResolvePseudoStyleContextFor + (aContent, nsHTMLAtoms::scrolledContentPseudo, aStyleContext); + + // Create an area container for the frame + NS_NewTableRowGroupFrame(aNewFrame); + + // Initialize the frame and force it to have a view + aNewFrame->Init(*aPresContext, aContent, aNewScrollFrame, scrolledPseudoStyle); + nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, aNewFrame, + scrolledPseudoStyle, PR_TRUE); + NS_RELEASE(scrolledPseudoStyle); + + aNewScrollFrame->SetInitialChildList(*aPresContext, nsnull, aNewFrame); + } else { + NS_NewTableRowGroupFrame(aNewFrame); + aNewFrame->Init(*aPresContext, aContent, aParent, aStyleContext); + aNewScrollFrame = nsnull; + } + + return NS_OK; +} + nsresult HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, nsIContent* aContent, @@ -1146,7 +1197,8 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, aContent->ChildAt(i, childContent); if (nsnull != childContent) { - nsIFrame* frame = nsnull; + nsIFrame* frame = nsnull; + nsIFrame* scrollFrame = nsnull; nsIStyleContext* childStyleContext; // Resolve the style context @@ -1176,8 +1228,8 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP: case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP: case NS_STYLE_DISPLAY_TABLE_ROW_GROUP: - NS_NewTableRowGroupFrame(frame); - frame->Init(*aPresContext, childContent, innerFrame, childStyleContext); + ConstructTableRowGroupFrame(aPresContext, childContent, innerFrame, + childStyleContext, scrollFrame, frame); break; case NS_STYLE_DISPLAY_TABLE_ROW: @@ -1284,12 +1336,13 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, frame->SetInitialChildList(*aPresContext, nsnull, grandChildList); // Link the frame into the child list + nsIFrame* outerMostFrame = (nsnull == scrollFrame) ? frame : scrollFrame; if (nsnull == lastChildFrame) { - innerChildList = frame; + innerChildList = outerMostFrame; } else { - lastChildFrame->SetNextSibling(frame); + lastChildFrame->SetNextSibling(outerMostFrame); } - lastChildFrame = frame; + lastChildFrame = outerMostFrame; } NS_RELEASE(childStyleContext); diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index 0d92d853310..5032d7767fe 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -42,6 +42,7 @@ #include "nsHTMLIIDs.h" #include "nsIReflowCommand.h" #include "nsLayoutAtoms.h" +#include "nsIDeviceContext.h" #ifdef NS_DEBUG static PRBool gsDebug = PR_FALSE; @@ -266,7 +267,8 @@ nsTableFrame::nsTableFrame() mColumnWidthsValid(PR_FALSE), mColumnCacheValid(PR_FALSE), mCellMapValid(PR_TRUE), - mIsInvariantWidth(PR_FALSE) + mIsInvariantWidth(PR_FALSE), + mHasScrollableRowGroup(PR_FALSE) { mEffectiveColCount = -1; // -1 means uninitialized mColumnWidthsSet=PR_FALSE; @@ -338,7 +340,7 @@ nsTableFrame::SetInitialChildList(nsIPresContext& aPresContext, mFrames.SetFrames(childFrame); else prevMainChild->SetNextSibling(childFrame); - rv = DidAppendRowGroup((nsTableRowGroupFrame*)childFrame); + rv = DidAppendRowGroup(GetRowGroupFrameFor(childFrame, childDisplay)); prevMainChild = childFrame; } else if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) @@ -2705,7 +2707,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, else if (IsRowGroup(childDisplay->mDisplay)) { rv = IR_RowGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus, - (nsTableRowGroupFrame*)objectFrame, PR_FALSE); + GetRowGroupFrameFor(objectFrame, childDisplay), PR_FALSE); } else { @@ -2724,7 +2726,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, else if (IsRowGroup(childDisplay->mDisplay)) { rv = IR_RowGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, - (nsTableRowGroupFrame*)objectFrame); + GetRowGroupFrameFor(objectFrame, childDisplay)); } else { // no optimization to be done for Unknown frame types, so just reuse the Inserted method @@ -2750,7 +2752,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, else if (IsRowGroup(childDisplay->mDisplay)) { rv = IR_RowGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus, - (nsTableRowGroupFrame*)objectFrame); + GetRowGroupFrameFor(objectFrame, childDisplay)); } else { @@ -3015,7 +3017,7 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext, // account for the cells in the rows that are children of aAppendedFrame // this will add the content of the rowgroup to the cell map - rv = DidAppendRowGroup((nsTableRowGroupFrame*)aAppendedFrame); + rv = DidAppendRowGroup(aAppendedFrame); if (NS_FAILED(rv)) return rv; @@ -3597,6 +3599,15 @@ void nsTableFrame::SetTableWidth(nsIPresContext& aPresContext) printf ("%p: setting table rect to %d, %d after adding insets %d, %d\n", this, tableSize.width, tableSize.height, rightInset, leftInset); } + + // account for scroll bars. XXX needs optimization/caching + if (mHasScrollableRowGroup) { + float sbWidth, sbHeight; + nsIDeviceContext* dc = aPresContext.GetDeviceContext(); + dc->GetScrollBarDimensions(sbWidth, sbHeight); + NS_RELEASE(dc); + tableSize.width += NSToCoordRound(sbWidth); + } SetRect(tableSize); } @@ -4911,3 +4922,19 @@ nsTableFrame::GetFrameName(nsString& aResult) const { return MakeFrameName("Table", aResult); } + +// XXX make this a macro if it becomes an issue +nsTableRowGroupFrame* +nsTableFrame::GetRowGroupFrameFor(nsIFrame* aFrame, const nsStyleDisplay* aDisplay) +{ + if ((NS_STYLE_OVERFLOW_SCROLL == aDisplay->mOverflow) || + (NS_STYLE_OVERFLOW_AUTO == aDisplay->mOverflow)) { + mHasScrollableRowGroup = PR_TRUE; + nsIFrame* child = nsnull; + aFrame->FirstChild(nsnull, child); + return (nsTableRowGroupFrame*)child; + } else { + return (nsTableRowGroupFrame*)aFrame; + } +} + diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h index 2e3d46ceb60..80093e9865f 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.h +++ b/mozilla/layout/html/table/src/nsTableFrame.h @@ -599,6 +599,11 @@ protected: */ virtual PRInt32 GetSpecifiedColumnCount (); + /** + * Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame + */ + nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame, const nsStyleDisplay* aDisplay); + public: /* ----- Cell Map public methods ----- */ /** returns the number of rows in this table. @@ -681,6 +686,7 @@ private: PRBool mColumnCacheValid; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated PRBool mCellMapValid; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change + PRBool mHasScrollableRowGroup; // PR_TRUE if any section has overflow == "auto" or "scroll" PRInt32 mColCount; // the number of columns in this table PRInt32 mEffectiveColCount; // the number of columns in this table adjusted for weird table attributes nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp index 4b594ef71a9..e13b8fed522 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -28,6 +28,8 @@ #include "nsIPtr.h" #include "nsIReflowCommand.h" #include "nsHTMLIIDs.h" +#include "nsIDeviceContext.h" +#include "nsHTMLAtoms.h" #ifdef NS_DEBUG static PRBool gsDebug = PR_FALSE; @@ -86,7 +88,6 @@ struct RowGroupReflowState { - /* ----------- nsTableRowGroupFrame ---------- */ NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount) @@ -487,6 +488,7 @@ NS_METHOD nsTableRowGroupFrame::PullUpChildren(nsIPresContext& aPresContext RowGroupReflowState& aReflowState, nsReflowStatus& aStatus) { +// XXX if this code is activated then fix the nsRowGroupFrame cast, it might be an nsScrollFrame nsTableRowGroupFrame* nextInFlow = (nsTableRowGroupFrame*)mNextInFlow; nsSize kidMaxElementSize; nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull; @@ -962,6 +964,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext, // XXX We need to figure out what to do about this... #if 0 + // XXX if this code is activated then fix PullUpChildren to not case nsRowGroupFrame, it might be an nsScrollFrame // Did we successfully reflow our mapped children? if (NS_FRAME_COMPLETE==aStatus) { // Try and pull-up some children from a next-in-flow @@ -973,6 +976,33 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext, aDesiredSize.width = aReflowState.availableWidth; aDesiredSize.height = state.y; + // account for scroll bars. XXX needs optimization/caching + if (nsnull != aDesiredSize.maxElementSize) { + nsIAtom* pseudoTag; + + mStyleContext->GetPseudoType(pseudoTag); + if (pseudoTag == nsHTMLAtoms::scrolledContentPseudo) { + nsIFrame* scrollFrame; + GetParent(scrollFrame); + const nsStyleDisplay *display; + scrollFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display)); + if ((NS_STYLE_OVERFLOW_SCROLL == display->mOverflow) || + (NS_STYLE_OVERFLOW_AUTO == display->mOverflow)) { + float sbWidth, sbHeight; + nsIDeviceContext* dc = aPresContext.GetDeviceContext(); + + dc->GetScrollBarDimensions(sbWidth, sbHeight); + NS_RELEASE(dc); + aDesiredSize.maxElementSize->width += NSToCoordRound(sbWidth); + // If scrollbars are always visible then add in the hor sb height + if (NS_STYLE_OVERFLOW_SCROLL == display->mOverflow) { + aDesiredSize.maxElementSize->height += NSToCoordRound(sbHeight); + } + } + } + NS_IF_RELEASE(pseudoTag); + } + // shrink wrap rows to height of tallest cell in that row if (eReflowReason_Initial != aReflowState.reason) { CalculateRowHeights(aPresContext, aDesiredSize, aReflowState); @@ -1319,6 +1349,7 @@ NS_METHOD nsTableRowGroupFrame::IR_StyleChanged(nsIPresContext& aPresContex return rv; } +// XXX this doesn't handle scrolling, it that is even possible in this context NS_METHOD nsTableRowGroupFrame::CreateContinuingFrame(nsIPresContext& aPresContext, nsIFrame* aParent, diff --git a/mozilla/layout/style/nsHTMLStyleSheet.cpp b/mozilla/layout/style/nsHTMLStyleSheet.cpp index df2215c1c38..90f93a6901b 100644 --- a/mozilla/layout/style/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLStyleSheet.cpp @@ -395,6 +395,13 @@ protected: nsAbsoluteItems& aAboluteItems, nsIFrame*& aNewFrame); + nsresult ConstructTableRowGroupFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewScrollFrame, + nsIFrame*& aNewFrame); + nsresult ConstructTableCellFrame(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParentFrame, @@ -1099,6 +1106,50 @@ HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent, nsIFrame*& aFrame) return rv; } +nsresult +HTMLStyleSheetImpl::ConstructTableRowGroupFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewScrollFrame, + nsIFrame*& aNewFrame) +{ + const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + if (IsScrollable(aPresContext, styleDisplay)) { + // Create a scroll frame + NS_NewScrollFrame(aNewScrollFrame); + + + // Initialize it + aNewScrollFrame->Init(*aPresContext, aContent, aParent, aStyleContext); + + // The scroll frame gets the original style context, and the scrolled + // frame gets a SCROLLED-CONTENT pseudo element style context that + // inherits the background properties + nsIStyleContext* scrolledPseudoStyle = aPresContext->ResolvePseudoStyleContextFor + (aContent, nsHTMLAtoms::scrolledContentPseudo, aStyleContext); + + // Create an area container for the frame + NS_NewTableRowGroupFrame(aNewFrame); + + // Initialize the frame and force it to have a view + aNewFrame->Init(*aPresContext, aContent, aNewScrollFrame, scrolledPseudoStyle); + nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, aNewFrame, + scrolledPseudoStyle, PR_TRUE); + NS_RELEASE(scrolledPseudoStyle); + + aNewScrollFrame->SetInitialChildList(*aPresContext, nsnull, aNewFrame); + } else { + NS_NewTableRowGroupFrame(aNewFrame); + aNewFrame->Init(*aPresContext, aContent, aParent, aStyleContext); + aNewScrollFrame = nsnull; + } + + return NS_OK; +} + nsresult HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, nsIContent* aContent, @@ -1146,7 +1197,8 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, aContent->ChildAt(i, childContent); if (nsnull != childContent) { - nsIFrame* frame = nsnull; + nsIFrame* frame = nsnull; + nsIFrame* scrollFrame = nsnull; nsIStyleContext* childStyleContext; // Resolve the style context @@ -1176,8 +1228,8 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP: case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP: case NS_STYLE_DISPLAY_TABLE_ROW_GROUP: - NS_NewTableRowGroupFrame(frame); - frame->Init(*aPresContext, childContent, innerFrame, childStyleContext); + ConstructTableRowGroupFrame(aPresContext, childContent, innerFrame, + childStyleContext, scrollFrame, frame); break; case NS_STYLE_DISPLAY_TABLE_ROW: @@ -1284,12 +1336,13 @@ HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, frame->SetInitialChildList(*aPresContext, nsnull, grandChildList); // Link the frame into the child list + nsIFrame* outerMostFrame = (nsnull == scrollFrame) ? frame : scrollFrame; if (nsnull == lastChildFrame) { - innerChildList = frame; + innerChildList = outerMostFrame; } else { - lastChildFrame->SetNextSibling(frame); + lastChildFrame->SetNextSibling(outerMostFrame); } - lastChildFrame = frame; + lastChildFrame = outerMostFrame; } NS_RELEASE(childStyleContext); diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 0d92d853310..5032d7767fe 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -42,6 +42,7 @@ #include "nsHTMLIIDs.h" #include "nsIReflowCommand.h" #include "nsLayoutAtoms.h" +#include "nsIDeviceContext.h" #ifdef NS_DEBUG static PRBool gsDebug = PR_FALSE; @@ -266,7 +267,8 @@ nsTableFrame::nsTableFrame() mColumnWidthsValid(PR_FALSE), mColumnCacheValid(PR_FALSE), mCellMapValid(PR_TRUE), - mIsInvariantWidth(PR_FALSE) + mIsInvariantWidth(PR_FALSE), + mHasScrollableRowGroup(PR_FALSE) { mEffectiveColCount = -1; // -1 means uninitialized mColumnWidthsSet=PR_FALSE; @@ -338,7 +340,7 @@ nsTableFrame::SetInitialChildList(nsIPresContext& aPresContext, mFrames.SetFrames(childFrame); else prevMainChild->SetNextSibling(childFrame); - rv = DidAppendRowGroup((nsTableRowGroupFrame*)childFrame); + rv = DidAppendRowGroup(GetRowGroupFrameFor(childFrame, childDisplay)); prevMainChild = childFrame; } else if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) @@ -2705,7 +2707,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, else if (IsRowGroup(childDisplay->mDisplay)) { rv = IR_RowGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus, - (nsTableRowGroupFrame*)objectFrame, PR_FALSE); + GetRowGroupFrameFor(objectFrame, childDisplay), PR_FALSE); } else { @@ -2724,7 +2726,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, else if (IsRowGroup(childDisplay->mDisplay)) { rv = IR_RowGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, - (nsTableRowGroupFrame*)objectFrame); + GetRowGroupFrameFor(objectFrame, childDisplay)); } else { // no optimization to be done for Unknown frame types, so just reuse the Inserted method @@ -2750,7 +2752,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, else if (IsRowGroup(childDisplay->mDisplay)) { rv = IR_RowGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus, - (nsTableRowGroupFrame*)objectFrame); + GetRowGroupFrameFor(objectFrame, childDisplay)); } else { @@ -3015,7 +3017,7 @@ NS_METHOD nsTableFrame::IR_RowGroupAppended(nsIPresContext& aPresContext, // account for the cells in the rows that are children of aAppendedFrame // this will add the content of the rowgroup to the cell map - rv = DidAppendRowGroup((nsTableRowGroupFrame*)aAppendedFrame); + rv = DidAppendRowGroup(aAppendedFrame); if (NS_FAILED(rv)) return rv; @@ -3597,6 +3599,15 @@ void nsTableFrame::SetTableWidth(nsIPresContext& aPresContext) printf ("%p: setting table rect to %d, %d after adding insets %d, %d\n", this, tableSize.width, tableSize.height, rightInset, leftInset); } + + // account for scroll bars. XXX needs optimization/caching + if (mHasScrollableRowGroup) { + float sbWidth, sbHeight; + nsIDeviceContext* dc = aPresContext.GetDeviceContext(); + dc->GetScrollBarDimensions(sbWidth, sbHeight); + NS_RELEASE(dc); + tableSize.width += NSToCoordRound(sbWidth); + } SetRect(tableSize); } @@ -4911,3 +4922,19 @@ nsTableFrame::GetFrameName(nsString& aResult) const { return MakeFrameName("Table", aResult); } + +// XXX make this a macro if it becomes an issue +nsTableRowGroupFrame* +nsTableFrame::GetRowGroupFrameFor(nsIFrame* aFrame, const nsStyleDisplay* aDisplay) +{ + if ((NS_STYLE_OVERFLOW_SCROLL == aDisplay->mOverflow) || + (NS_STYLE_OVERFLOW_AUTO == aDisplay->mOverflow)) { + mHasScrollableRowGroup = PR_TRUE; + nsIFrame* child = nsnull; + aFrame->FirstChild(nsnull, child); + return (nsTableRowGroupFrame*)child; + } else { + return (nsTableRowGroupFrame*)aFrame; + } +} + diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index 2e3d46ceb60..80093e9865f 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -599,6 +599,11 @@ protected: */ virtual PRInt32 GetSpecifiedColumnCount (); + /** + * Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame + */ + nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame, const nsStyleDisplay* aDisplay); + public: /* ----- Cell Map public methods ----- */ /** returns the number of rows in this table. @@ -681,6 +686,7 @@ private: PRBool mColumnCacheValid; // PR_TRUE if column cache info is still legit, PR_FALSE if it needs to be recalculated PRBool mCellMapValid; // PR_TRUE if cell map data is still legit, PR_FALSE if it needs to be recalculated PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change + PRBool mHasScrollableRowGroup; // PR_TRUE if any section has overflow == "auto" or "scroll" PRInt32 mColCount; // the number of columns in this table PRInt32 mEffectiveColCount; // the number of columns in this table adjusted for weird table attributes nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp index 4b594ef71a9..e13b8fed522 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp @@ -28,6 +28,8 @@ #include "nsIPtr.h" #include "nsIReflowCommand.h" #include "nsHTMLIIDs.h" +#include "nsIDeviceContext.h" +#include "nsHTMLAtoms.h" #ifdef NS_DEBUG static PRBool gsDebug = PR_FALSE; @@ -86,7 +88,6 @@ struct RowGroupReflowState { - /* ----------- nsTableRowGroupFrame ---------- */ NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount) @@ -487,6 +488,7 @@ NS_METHOD nsTableRowGroupFrame::PullUpChildren(nsIPresContext& aPresContext RowGroupReflowState& aReflowState, nsReflowStatus& aStatus) { +// XXX if this code is activated then fix the nsRowGroupFrame cast, it might be an nsScrollFrame nsTableRowGroupFrame* nextInFlow = (nsTableRowGroupFrame*)mNextInFlow; nsSize kidMaxElementSize; nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull; @@ -962,6 +964,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext, // XXX We need to figure out what to do about this... #if 0 + // XXX if this code is activated then fix PullUpChildren to not case nsRowGroupFrame, it might be an nsScrollFrame // Did we successfully reflow our mapped children? if (NS_FRAME_COMPLETE==aStatus) { // Try and pull-up some children from a next-in-flow @@ -973,6 +976,33 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext, aDesiredSize.width = aReflowState.availableWidth; aDesiredSize.height = state.y; + // account for scroll bars. XXX needs optimization/caching + if (nsnull != aDesiredSize.maxElementSize) { + nsIAtom* pseudoTag; + + mStyleContext->GetPseudoType(pseudoTag); + if (pseudoTag == nsHTMLAtoms::scrolledContentPseudo) { + nsIFrame* scrollFrame; + GetParent(scrollFrame); + const nsStyleDisplay *display; + scrollFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display)); + if ((NS_STYLE_OVERFLOW_SCROLL == display->mOverflow) || + (NS_STYLE_OVERFLOW_AUTO == display->mOverflow)) { + float sbWidth, sbHeight; + nsIDeviceContext* dc = aPresContext.GetDeviceContext(); + + dc->GetScrollBarDimensions(sbWidth, sbHeight); + NS_RELEASE(dc); + aDesiredSize.maxElementSize->width += NSToCoordRound(sbWidth); + // If scrollbars are always visible then add in the hor sb height + if (NS_STYLE_OVERFLOW_SCROLL == display->mOverflow) { + aDesiredSize.maxElementSize->height += NSToCoordRound(sbHeight); + } + } + } + NS_IF_RELEASE(pseudoTag); + } + // shrink wrap rows to height of tallest cell in that row if (eReflowReason_Initial != aReflowState.reason) { CalculateRowHeights(aPresContext, aDesiredSize, aReflowState); @@ -1319,6 +1349,7 @@ NS_METHOD nsTableRowGroupFrame::IR_StyleChanged(nsIPresContext& aPresContex return rv; } +// XXX this doesn't handle scrolling, it that is even possible in this context NS_METHOD nsTableRowGroupFrame::CreateContinuingFrame(nsIPresContext& aPresContext, nsIFrame* aParent, diff --git a/mozilla/webshell/tests/viewer/samples/test4.html b/mozilla/webshell/tests/viewer/samples/test4.html index 6be7e2fd915..6fbfc8d9853 100644 --- a/mozilla/webshell/tests/viewer/samples/test4.html +++ b/mozilla/webshell/tests/viewer/samples/test4.html @@ -148,5 +148,27 @@ layout. This should be long enough. column widths and collapsing borders. +
+ + + + + + + + + + + + + +
HEADER +
cell-00cell-01 +
cell-10cell-11 +
cell-20cell-21 +
cell-30cell-31 +
FOOTER +
Table 5 has a scrolling tbody.
+