diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp index f43a071509e..2c9e40e08bf 100644 --- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp @@ -267,16 +267,14 @@ protected: PRInt32 aAttrCount, nsIHTMLAttributes*& aAttributes); - NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsIAtom* aTag, - nsIStyleContext* aStyleContext, - nsIFrame*& aFrameSubTree); - nsIFrame* ConstructRootFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIStyleContext* aStyleContext); + nsIContent* aContent); + + nsIFrame* ConstructTableFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIStyleContext* aStyleContext, + nsIFrame*& aChildList); nsresult ProcessChildren(nsIPresContext* aPresContext, nsIFrame* aFrame, @@ -538,11 +536,15 @@ PRInt32 HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, nsTableColFrame* colFrame; nsIFrame* colGroupFrame; + // XXX CONSTRUCTION. + // Unfortunately the table's children haven't been added yet... +#if 0 ((nsTableFrame*)tableFrame)->GetColumnFrame(colIndex, colFrame); colFrame->GetContentParent(colGroupFrame); matchCount += AppendRulesFrom(colGroupFrame, aPresContext, backstopInsertPoint, aResults); matchCount += AppendRulesFrom(colFrame, aPresContext, backstopInsertPoint, aResults); +#endif NS_RELEASE(cell); // cell: REFCNT-- } matchCount += AppendRulesFrom(rowGroupFrame, aPresContext, backstopInsertPoint, aResults); @@ -964,16 +966,123 @@ HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent, } nsIFrame* -HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIStyleContext* aStyleContext) +HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIStyleContext* aStyleContext, + nsIFrame*& aChildList) +{ + nsIFrame* outerFrame; + nsIFrame* innerFrame; + nsIFrame* innerChildList = nsnull; + nsIFrame* captionFrame = nsnull; + + // Create an anonymous table outer frame which holds the caption and the + // table frame + NS_NewTableOuterFrame(aContent, aParentFrame, outerFrame); + + // Create the inner table frame + NS_NewTableFrame(aContent, outerFrame, innerFrame); + aChildList = innerFrame; + + // Have the inner table frame use the same style context as the outer table frame + innerFrame->SetStyleContext(aPresContext, aStyleContext); + + // Iterate the child content + nsIFrame* lastChildFrame = nsnull; + PRInt32 count; + aContent->ChildCount(count); + for (PRInt32 i = 0; i < count; i++) { + nsIContent* childContent; + aContent->ChildAt(i, childContent); + + if (nsnull != childContent) { + nsIFrame* frame = nsnull; + nsIStyleContext* childStyleContext; + + // Resolve the style context + childStyleContext = aPresContext->ResolveStyleContextFor(childContent, outerFrame); + + // See how it should be displayed + const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*) + childStyleContext->GetStyleData(eStyleStruct_Display); + + switch (styleDisplay->mDisplay) { + case NS_STYLE_DISPLAY_TABLE_CAPTION: + // Have we already created a caption? If so, ignore this caption + if (nsnull == captionFrame) { + NS_NewBodyFrame(childContent, outerFrame, captionFrame); + captionFrame->SetStyleContext(aPresContext, childStyleContext); + + // Process the caption's child content and initialize it + nsIFrame* captionChildList; + ProcessChildren(aPresContext, captionFrame, childContent, captionChildList); + captionFrame->Init(*aPresContext, captionChildList); + + // Prepend the caption frame to the outer frame's child list + captionFrame->SetNextSibling(innerFrame); + aChildList = captionFrame; + } + break; + + case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP: + case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP: + case NS_STYLE_DISPLAY_TABLE_ROW_GROUP: + NS_NewTableRowGroupFrame(childContent, innerFrame, frame); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN: + NS_NewTableColFrame(childContent, innerFrame, frame); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP: + NS_NewTableColGroupFrame(childContent, innerFrame, frame); + break; + + default: + // XXX For the time being ignore everything else. We should deal with + // things like table cells and create anonymous frames... + break; + } + + // If it's not a caption frame then set the style context, and link the + // frame into the inner frame's child list + if (nsnull != frame) { + frame->SetStyleContext(aPresContext, childStyleContext); + + // Process the children and initialize the frame + nsIFrame* childChildList; + ProcessChildren(aPresContext, frame, childContent, childChildList); + frame->Init(*aPresContext, childChildList); + + // Link the frame into the child list + if (nsnull == lastChildFrame) { + innerChildList = frame; + } else { + lastChildFrame->SetNextSibling(frame); + } + lastChildFrame = frame; + } + + NS_RELEASE(childStyleContext); + NS_RELEASE(childContent); + } + } + + // Initialize the inner table with its child list + innerFrame->Init(*aPresContext, innerChildList); + + return outerFrame; +} + +nsIFrame* +HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, + nsIContent* aContent) { nsIFrame* rootFrame; - nsIFrame* childList; - // Create the root frame and set its style context + // Create the root frame NS_NewHTMLFrame(aContent, nsnull, rootFrame); - rootFrame->SetStyleContext(aPresContext, aStyleContext); // Bind root frame to root view (and root window) nsIPresShell* presShell = aPresContext->GetShell(); @@ -985,23 +1094,33 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, rootFrame->SetView(rootView); NS_RELEASE(viewManager); - // Process the children and initialize the frame - ProcessChildren(aPresContext, rootFrame, aContent, childList); - rootFrame->Init(*aPresContext, childList); - return rootFrame; } NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParentFrame, - nsIAtom* aTag, - nsIStyleContext* aStyleContext, nsIFrame*& aFrameSubTree) { + // Get the tag + nsIAtom* tag; + aContent->GetTag(tag); + + // Resolve the style context. + // XXX Cheesy hack for text + nsIStyleContext* styleContext; + if (nsnull == tag) { + styleContext = aPresContext->ResolvePseudoStyleContextFor(nsHTMLAtoms::text, aParentFrame); + } else { + styleContext = aPresContext->ResolveStyleContextFor(aContent, aParentFrame); + } + + // Initialize OUT parameter aFrameSubTree = nsnull; // Create a frame. + nsIFrame* frame = nsnull; + nsIFrame* childList = nsnull; if (nsnull == aParentFrame) { // This should only be the case for the root content object. #ifdef NS_DEBUG @@ -1017,90 +1136,67 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, #endif // Construct the root frame object - aFrameSubTree = ConstructRootFrame(aPresContext, aContent, aStyleContext); + frame = ConstructRootFrame(aPresContext, aContent); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); } else { - nsIFrame* frame = nsnull; - nsIFrame* childList = nsnull; nsresult rv = NS_OK; // Handle specific frame types - if (nsnull == aTag) { + if (nsnull == tag) { rv = NS_NewTextFrame(aContent, aParentFrame, frame); } - else if (nsHTMLAtoms::applet == aTag) { + else if (nsHTMLAtoms::img == tag) { + rv = NS_NewImageFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::hr == tag) { + rv = NS_NewHRFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::br == tag) { + rv = NS_NewBRFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::wbr == tag) { + rv = NS_NewWBRFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::input == tag) { + rv = CreateInputFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::textarea == tag) { + rv = NS_NewInputTextFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::select == tag) { + rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::applet == tag) { rv = NS_NewObjectFrame(aContent, aParentFrame, frame); } - else if (nsHTMLAtoms::body == aTag) { + else if (nsHTMLAtoms::embed == tag) { + rv = NS_NewObjectFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::object == tag) { + rv = NS_NewObjectFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::body == tag) { rv = NS_NewBodyFrame(aContent, aParentFrame, frame); // Process the child content rv = ProcessChildren(aPresContext, frame, aContent, childList); } - else if (nsHTMLAtoms::frameset == aTag) { + else if (nsHTMLAtoms::frameset == tag) { rv = NS_NewHTMLFramesetFrame(aContent, aParentFrame, frame); } - else if (nsHTMLAtoms::br == aTag) { - rv = NS_NewBRFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::embed == aTag) { - rv = NS_NewObjectFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::hr == aTag) { - rv = NS_NewHRFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::img == aTag) { - rv = NS_NewImageFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::object == aTag) { - rv = NS_NewObjectFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::spacer == aTag) { - rv = NS_NewSpacerFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::wbr == aTag) { - rv = NS_NewWBRFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::input == aTag) { - rv = CreateInputFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::textarea == aTag) { - rv = NS_NewInputTextFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::select == aTag) { - rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::iframe == aTag) { + else if (nsHTMLAtoms::iframe == tag) { rv = NS_NewHTMLFrameOuterFrame(aContent, aParentFrame, frame); } - - // the table content frames... - else if (nsHTMLAtoms::caption == aTag) { - rv = NS_NewBodyFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::table == aTag) { - rv = NS_NewTableOuterFrame(aContent, aParentFrame, frame); - } - else if ((nsHTMLAtoms::tbody == aTag) || - (nsHTMLAtoms::thead == aTag) || - (nsHTMLAtoms::tfoot == aTag)) { - rv = NS_NewTableRowGroupFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::tr == aTag) { - rv = NS_NewTableRowFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::colgroup == aTag) { - rv = NS_NewTableColGroupFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::col == aTag) { - rv = NS_NewTableColFrame(aContent, aParentFrame, frame); - } - else if ((nsHTMLAtoms::td == aTag) || - (nsHTMLAtoms::th == aTag)) { - rv = NS_NewTableCellFrame(aContent, aParentFrame, frame); + else if (nsHTMLAtoms::spacer == tag) { + rv = NS_NewSpacerFrame(aContent, aParentFrame, frame); } if (NS_OK != rv) { + NS_RELEASE(styleContext); + NS_IF_RELEASE(tag); return rv; } @@ -1111,10 +1207,9 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, // When there is no explicit frame to create, assume it's a // container and let style dictate the rest. const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*) - aStyleContext->GetStyleData(eStyleStruct_Display); + styleContext->GetStyleData(eStyleStruct_Display); // Use style to choose what kind of frame to create - nsresult rv; switch (styleDisplay->mDisplay) { case NS_STYLE_DISPLAY_BLOCK: case NS_STYLE_DISPLAY_LIST_ITEM: @@ -1131,53 +1226,78 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, ProcessChildren(aPresContext, frame, aContent, childList); break; + case NS_STYLE_DISPLAY_TABLE: + frame = ConstructTableFrame(aPresContext, aContent, aParentFrame, + styleContext, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_ROW_GROUP: + case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP: + 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 + rv = NS_NewTableRowGroupFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN: + // XXX We should check for being inside of a table column group... + rv = NS_NewTableColFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP: + // XXX We should check for being inside of a table... + rv = NS_NewTableColGroupFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_ROW: + // XXX We should check for being inside of a table row group... + rv = NS_NewTableRowFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_CELL: + // XXX We should check for being inside of a table row frame... + rv = NS_NewTableCellFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + default: // Don't create any frame for content that's not displayed... break; } if (NS_OK != rv) { + NS_RELEASE(styleContext); + NS_IF_RELEASE(tag); return rv; } } + } - if (nsnull != frame) { - // Set the style context - frame->SetStyleContext(aPresContext, aStyleContext); - - // Initialize the frame giving it its child list - frame->Init(*aPresContext, childList); - } - aFrameSubTree = frame; + // If we created a frame then set its style context and initialize it + // passing it the child list + if (nsnull != frame) { + frame->SetStyleContext(aPresContext, styleContext); + frame->Init(*aPresContext, childList); } - - return NS_OK; -} - -NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsIFrame*& aFrameSubTree) -{ - // Get the tag - nsIAtom* tag; - aContent->GetTag(tag); - - // Resolve the style context. - // XXX Cheesy hack for text - nsIStyleContext* styleContext; - if (nsnull == tag) { - styleContext = aPresContext->ResolvePseudoStyleContextFor(nsHTMLAtoms::text, aParentFrame); - } else { - styleContext = aPresContext->ResolveStyleContextFor(aContent, aParentFrame); - } - - nsresult result = ConstructFrame(aPresContext, aContent, aParentFrame, - tag, styleContext, aFrameSubTree); + aFrameSubTree = frame; NS_RELEASE(styleContext); NS_IF_RELEASE(tag); - return result; + return NS_OK; } NS_IMETHODIMP HTMLStyleSheetImpl::ContentAppended(nsIPresContext* aPresContext, diff --git a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp index f43a071509e..2c9e40e08bf 100644 --- a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -267,16 +267,14 @@ protected: PRInt32 aAttrCount, nsIHTMLAttributes*& aAttributes); - NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsIAtom* aTag, - nsIStyleContext* aStyleContext, - nsIFrame*& aFrameSubTree); - nsIFrame* ConstructRootFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIStyleContext* aStyleContext); + nsIContent* aContent); + + nsIFrame* ConstructTableFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIStyleContext* aStyleContext, + nsIFrame*& aChildList); nsresult ProcessChildren(nsIPresContext* aPresContext, nsIFrame* aFrame, @@ -538,11 +536,15 @@ PRInt32 HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, nsTableColFrame* colFrame; nsIFrame* colGroupFrame; + // XXX CONSTRUCTION. + // Unfortunately the table's children haven't been added yet... +#if 0 ((nsTableFrame*)tableFrame)->GetColumnFrame(colIndex, colFrame); colFrame->GetContentParent(colGroupFrame); matchCount += AppendRulesFrom(colGroupFrame, aPresContext, backstopInsertPoint, aResults); matchCount += AppendRulesFrom(colFrame, aPresContext, backstopInsertPoint, aResults); +#endif NS_RELEASE(cell); // cell: REFCNT-- } matchCount += AppendRulesFrom(rowGroupFrame, aPresContext, backstopInsertPoint, aResults); @@ -964,16 +966,123 @@ HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent, } nsIFrame* -HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIStyleContext* aStyleContext) +HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIStyleContext* aStyleContext, + nsIFrame*& aChildList) +{ + nsIFrame* outerFrame; + nsIFrame* innerFrame; + nsIFrame* innerChildList = nsnull; + nsIFrame* captionFrame = nsnull; + + // Create an anonymous table outer frame which holds the caption and the + // table frame + NS_NewTableOuterFrame(aContent, aParentFrame, outerFrame); + + // Create the inner table frame + NS_NewTableFrame(aContent, outerFrame, innerFrame); + aChildList = innerFrame; + + // Have the inner table frame use the same style context as the outer table frame + innerFrame->SetStyleContext(aPresContext, aStyleContext); + + // Iterate the child content + nsIFrame* lastChildFrame = nsnull; + PRInt32 count; + aContent->ChildCount(count); + for (PRInt32 i = 0; i < count; i++) { + nsIContent* childContent; + aContent->ChildAt(i, childContent); + + if (nsnull != childContent) { + nsIFrame* frame = nsnull; + nsIStyleContext* childStyleContext; + + // Resolve the style context + childStyleContext = aPresContext->ResolveStyleContextFor(childContent, outerFrame); + + // See how it should be displayed + const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*) + childStyleContext->GetStyleData(eStyleStruct_Display); + + switch (styleDisplay->mDisplay) { + case NS_STYLE_DISPLAY_TABLE_CAPTION: + // Have we already created a caption? If so, ignore this caption + if (nsnull == captionFrame) { + NS_NewBodyFrame(childContent, outerFrame, captionFrame); + captionFrame->SetStyleContext(aPresContext, childStyleContext); + + // Process the caption's child content and initialize it + nsIFrame* captionChildList; + ProcessChildren(aPresContext, captionFrame, childContent, captionChildList); + captionFrame->Init(*aPresContext, captionChildList); + + // Prepend the caption frame to the outer frame's child list + captionFrame->SetNextSibling(innerFrame); + aChildList = captionFrame; + } + break; + + case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP: + case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP: + case NS_STYLE_DISPLAY_TABLE_ROW_GROUP: + NS_NewTableRowGroupFrame(childContent, innerFrame, frame); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN: + NS_NewTableColFrame(childContent, innerFrame, frame); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP: + NS_NewTableColGroupFrame(childContent, innerFrame, frame); + break; + + default: + // XXX For the time being ignore everything else. We should deal with + // things like table cells and create anonymous frames... + break; + } + + // If it's not a caption frame then set the style context, and link the + // frame into the inner frame's child list + if (nsnull != frame) { + frame->SetStyleContext(aPresContext, childStyleContext); + + // Process the children and initialize the frame + nsIFrame* childChildList; + ProcessChildren(aPresContext, frame, childContent, childChildList); + frame->Init(*aPresContext, childChildList); + + // Link the frame into the child list + if (nsnull == lastChildFrame) { + innerChildList = frame; + } else { + lastChildFrame->SetNextSibling(frame); + } + lastChildFrame = frame; + } + + NS_RELEASE(childStyleContext); + NS_RELEASE(childContent); + } + } + + // Initialize the inner table with its child list + innerFrame->Init(*aPresContext, innerChildList); + + return outerFrame; +} + +nsIFrame* +HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, + nsIContent* aContent) { nsIFrame* rootFrame; - nsIFrame* childList; - // Create the root frame and set its style context + // Create the root frame NS_NewHTMLFrame(aContent, nsnull, rootFrame); - rootFrame->SetStyleContext(aPresContext, aStyleContext); // Bind root frame to root view (and root window) nsIPresShell* presShell = aPresContext->GetShell(); @@ -985,23 +1094,33 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, rootFrame->SetView(rootView); NS_RELEASE(viewManager); - // Process the children and initialize the frame - ProcessChildren(aPresContext, rootFrame, aContent, childList); - rootFrame->Init(*aPresContext, childList); - return rootFrame; } NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParentFrame, - nsIAtom* aTag, - nsIStyleContext* aStyleContext, nsIFrame*& aFrameSubTree) { + // Get the tag + nsIAtom* tag; + aContent->GetTag(tag); + + // Resolve the style context. + // XXX Cheesy hack for text + nsIStyleContext* styleContext; + if (nsnull == tag) { + styleContext = aPresContext->ResolvePseudoStyleContextFor(nsHTMLAtoms::text, aParentFrame); + } else { + styleContext = aPresContext->ResolveStyleContextFor(aContent, aParentFrame); + } + + // Initialize OUT parameter aFrameSubTree = nsnull; // Create a frame. + nsIFrame* frame = nsnull; + nsIFrame* childList = nsnull; if (nsnull == aParentFrame) { // This should only be the case for the root content object. #ifdef NS_DEBUG @@ -1017,90 +1136,67 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, #endif // Construct the root frame object - aFrameSubTree = ConstructRootFrame(aPresContext, aContent, aStyleContext); + frame = ConstructRootFrame(aPresContext, aContent); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); } else { - nsIFrame* frame = nsnull; - nsIFrame* childList = nsnull; nsresult rv = NS_OK; // Handle specific frame types - if (nsnull == aTag) { + if (nsnull == tag) { rv = NS_NewTextFrame(aContent, aParentFrame, frame); } - else if (nsHTMLAtoms::applet == aTag) { + else if (nsHTMLAtoms::img == tag) { + rv = NS_NewImageFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::hr == tag) { + rv = NS_NewHRFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::br == tag) { + rv = NS_NewBRFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::wbr == tag) { + rv = NS_NewWBRFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::input == tag) { + rv = CreateInputFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::textarea == tag) { + rv = NS_NewInputTextFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::select == tag) { + rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::applet == tag) { rv = NS_NewObjectFrame(aContent, aParentFrame, frame); } - else if (nsHTMLAtoms::body == aTag) { + else if (nsHTMLAtoms::embed == tag) { + rv = NS_NewObjectFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::object == tag) { + rv = NS_NewObjectFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::body == tag) { rv = NS_NewBodyFrame(aContent, aParentFrame, frame); // Process the child content rv = ProcessChildren(aPresContext, frame, aContent, childList); } - else if (nsHTMLAtoms::frameset == aTag) { + else if (nsHTMLAtoms::frameset == tag) { rv = NS_NewHTMLFramesetFrame(aContent, aParentFrame, frame); } - else if (nsHTMLAtoms::br == aTag) { - rv = NS_NewBRFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::embed == aTag) { - rv = NS_NewObjectFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::hr == aTag) { - rv = NS_NewHRFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::img == aTag) { - rv = NS_NewImageFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::object == aTag) { - rv = NS_NewObjectFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::spacer == aTag) { - rv = NS_NewSpacerFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::wbr == aTag) { - rv = NS_NewWBRFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::input == aTag) { - rv = CreateInputFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::textarea == aTag) { - rv = NS_NewInputTextFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::select == aTag) { - rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::iframe == aTag) { + else if (nsHTMLAtoms::iframe == tag) { rv = NS_NewHTMLFrameOuterFrame(aContent, aParentFrame, frame); } - - // the table content frames... - else if (nsHTMLAtoms::caption == aTag) { - rv = NS_NewBodyFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::table == aTag) { - rv = NS_NewTableOuterFrame(aContent, aParentFrame, frame); - } - else if ((nsHTMLAtoms::tbody == aTag) || - (nsHTMLAtoms::thead == aTag) || - (nsHTMLAtoms::tfoot == aTag)) { - rv = NS_NewTableRowGroupFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::tr == aTag) { - rv = NS_NewTableRowFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::colgroup == aTag) { - rv = NS_NewTableColGroupFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::col == aTag) { - rv = NS_NewTableColFrame(aContent, aParentFrame, frame); - } - else if ((nsHTMLAtoms::td == aTag) || - (nsHTMLAtoms::th == aTag)) { - rv = NS_NewTableCellFrame(aContent, aParentFrame, frame); + else if (nsHTMLAtoms::spacer == tag) { + rv = NS_NewSpacerFrame(aContent, aParentFrame, frame); } if (NS_OK != rv) { + NS_RELEASE(styleContext); + NS_IF_RELEASE(tag); return rv; } @@ -1111,10 +1207,9 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, // When there is no explicit frame to create, assume it's a // container and let style dictate the rest. const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*) - aStyleContext->GetStyleData(eStyleStruct_Display); + styleContext->GetStyleData(eStyleStruct_Display); // Use style to choose what kind of frame to create - nsresult rv; switch (styleDisplay->mDisplay) { case NS_STYLE_DISPLAY_BLOCK: case NS_STYLE_DISPLAY_LIST_ITEM: @@ -1131,53 +1226,78 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, ProcessChildren(aPresContext, frame, aContent, childList); break; + case NS_STYLE_DISPLAY_TABLE: + frame = ConstructTableFrame(aPresContext, aContent, aParentFrame, + styleContext, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_ROW_GROUP: + case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP: + 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 + rv = NS_NewTableRowGroupFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN: + // XXX We should check for being inside of a table column group... + rv = NS_NewTableColFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP: + // XXX We should check for being inside of a table... + rv = NS_NewTableColGroupFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_ROW: + // XXX We should check for being inside of a table row group... + rv = NS_NewTableRowFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_CELL: + // XXX We should check for being inside of a table row frame... + rv = NS_NewTableCellFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + default: // Don't create any frame for content that's not displayed... break; } if (NS_OK != rv) { + NS_RELEASE(styleContext); + NS_IF_RELEASE(tag); return rv; } } + } - if (nsnull != frame) { - // Set the style context - frame->SetStyleContext(aPresContext, aStyleContext); - - // Initialize the frame giving it its child list - frame->Init(*aPresContext, childList); - } - aFrameSubTree = frame; + // If we created a frame then set its style context and initialize it + // passing it the child list + if (nsnull != frame) { + frame->SetStyleContext(aPresContext, styleContext); + frame->Init(*aPresContext, childList); } - - return NS_OK; -} - -NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsIFrame*& aFrameSubTree) -{ - // Get the tag - nsIAtom* tag; - aContent->GetTag(tag); - - // Resolve the style context. - // XXX Cheesy hack for text - nsIStyleContext* styleContext; - if (nsnull == tag) { - styleContext = aPresContext->ResolvePseudoStyleContextFor(nsHTMLAtoms::text, aParentFrame); - } else { - styleContext = aPresContext->ResolveStyleContextFor(aContent, aParentFrame); - } - - nsresult result = ConstructFrame(aPresContext, aContent, aParentFrame, - tag, styleContext, aFrameSubTree); + aFrameSubTree = frame; NS_RELEASE(styleContext); NS_IF_RELEASE(tag); - return result; + return NS_OK; } NS_IMETHODIMP HTMLStyleSheetImpl::ContentAppended(nsIPresContext* aPresContext, diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp index 430d9cfc851..b355ef0e598 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp @@ -73,6 +73,29 @@ nsTableCellFrame::~nsTableCellFrame() { } +NS_IMETHODIMP +nsTableCellFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + // Create body pseudo frame + NS_NewBodyFrame(mContent, this, mFirstChild); + mChildCount = 1; + + // Resolve style and set the style context + nsIStyleContext* styleContext = + aPresContext.ResolveStyleContextFor(mContent, this); // styleContext: ADDREF++ + mFirstChild->SetStyleContext(&aPresContext, styleContext); + NS_RELEASE(styleContext); // styleContext: ADDREF-- + + // Set the geometric and content parent for each of the child frames + for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) { + frame->SetGeometricParent(mFirstChild); + frame->SetContentParent(mFirstChild); + } + + // Queue up the frames for the block frame + return mFirstChild->Init(aPresContext, aChildList); +} + NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.h b/mozilla/layout/html/table/src/nsTableCellFrame.h index 68e7a9080ae..074aed091b6 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.h +++ b/mozilla/layout/html/table/src/nsTableCellFrame.h @@ -58,6 +58,8 @@ public: // nsISupports NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); diff --git a/mozilla/layout/html/table/src/nsTableColFrame.cpp b/mozilla/layout/html/table/src/nsTableColFrame.cpp index 03b9065ddc6..2c7755bee33 100644 --- a/mozilla/layout/html/table/src/nsTableColFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColFrame.cpp @@ -32,7 +32,6 @@ static const PRBool gsDebug = PR_FALSE; static const PRBool gsNoisyRefs = PR_FALSE; #endif - nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsFrame(aContent, aParentFrame) { diff --git a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp index eab3e1bd890..9c1e72bab3c 100644 --- a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp @@ -35,7 +35,6 @@ static NS_DEFINE_IID(kIHTMLTableColElementIID, NS_IHTMLTABLECOLELEMENT_IID); static PRBool gsDebug = PR_FALSE; - nsTableColGroupFrame::nsTableColGroupFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsContainerFrame(aContent, aParentFrame) @@ -47,6 +46,57 @@ nsTableColGroupFrame::~nsTableColGroupFrame() { } +nsresult +nsTableColGroupFrame::AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + nsIFrame* lastChild; + LastChild(lastChild); + + // Append the new frames to the child list + if (nsnull == lastChild) { + mFirstChild = aChildList; + } else { + lastChild->SetNextSibling(aChildList); + } + mChildCount += LengthOf(aChildList); + + // 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); + PRInt32 repeat=1; + nsIHTMLTableColElement* colContent = nsnull; + nsresult 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; + + // Set nsColFrame-specific information + ((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex); + nsIFrame* tableFrame=nsnull; + GetGeometricParent(tableFrame); + ((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame); + + SetStyleContextForFirstPass(&aPresContext, colIndex); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsTableColGroupFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + return AppendNewFrames(aPresContext, aChildList); +} + NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) @@ -72,6 +122,8 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext, nsIFrame* kidFrame = nsnull; nsIFrame* prevKidFrame; + // XXX CONSTRUCTION +#if 0 LastChild(prevKidFrame); // XXX remember this... PRInt32 kidIndex = 0; // index of the content child we are currently working on PRInt32 colIndex = 0; // number of content children that are columns, normally same as kidIndex @@ -155,6 +207,38 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext, colIndex++; // if this wasn't a column, we would not have gotten this far kidIndex++; } +#else + if (eReflowReason_Incremental == aReflowState.reason) { + NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command"); + + // Get the type of reflow command + nsIReflowCommand::ReflowType reflowCmdType; + aReflowState.reflowCommand->GetType(reflowCmdType); + + // Currently we only expect appended reflow commands + NS_ASSERTION(nsIReflowCommand::FrameAppended == reflowCmdType, + "unexpected reflow command"); + + // Get the new column frames + nsIFrame* childList; + aReflowState.reflowCommand->GetChildFrame(childList); + + // Append them to the child list + AppendNewFrames(aPresContext, childList); + } + + for (kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) { + // Give the child frame a chance to reflow, even though we know it'll have 0 size + nsReflowMetrics kidSize(nsnull); + // XXX Use a valid reason... + nsReflowState kidReflowState(kidFrame, aReflowState, nsSize(0,0), eReflowReason_Initial); + kidFrame->WillReflow(aPresContext); + nsReflowStatus status = ReflowChild(kidFrame,&aPresContext, kidSize, + kidReflowState); + // note that DidReflow is called as the result of some ancestor firing off a DidReflow above me + kidFrame->SetRect(nsRect(0,0,0,0)); + } +#endif aDesiredSize.width=0; aDesiredSize.height=0; if (nsnull!=aDesiredSize.maxElementSize) diff --git a/mozilla/layout/html/table/src/nsTableColGroupFrame.h b/mozilla/layout/html/table/src/nsTableColGroupFrame.h index bf9498c96ad..eabb45a8365 100644 --- a/mozilla/layout/html/table/src/nsTableColGroupFrame.h +++ b/mozilla/layout/html/table/src/nsTableColGroupFrame.h @@ -43,6 +43,8 @@ public: nsIFrame* aParentFrame, nsIFrame*& aResult); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); @@ -83,6 +85,7 @@ protected: NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext, PRInt32 aColIndex); + nsresult AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList); PRInt32 mColCount; diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index c8e4ebbfd5e..964bee7e61a 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -258,7 +258,6 @@ void ColumnInfoCache::GetColumnsByType(const nsStyleUnit aType, /* --------------------- nsTableFrame -------------------- */ - nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsContainerFrame(aContent, aParentFrame), mCellMap(nsnull), @@ -287,6 +286,14 @@ nsTableFrame::~nsTableFrame() delete mColCache; } +NS_IMETHODIMP +nsTableFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + mFirstChild = aChildList; + mChildCount = LengthOf(mFirstChild); + return NS_OK; +} + /* ****** CellMap methods ******* */ /* return the next row group frame after aRowGroupFrame */ @@ -708,9 +715,13 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex, lastColGroupFrame->GetContent((nsIContent *&)lastColGroup); // ADDREF b: lastColGroup++ } + // XXX It would be better to do this in the style code while constructing + // the table's frames nsAutoString colTag; nsHTMLAtoms::col->ToString(colTag); PRInt32 excessColumns = aColIndex - actualColumns; + nsIFrame* firstNewColFrame = nsnull; + nsIFrame* lastNewColFrame = nsnull; for ( ; excessColumns >= 0; excessColumns--) { nsIHTMLContent *col=nsnull; @@ -718,10 +729,49 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex, rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++ //XXX mark the col implicit lastColGroup->AppendChildTo((nsIContent*)col, PR_FALSE); + + // Create a new col frame + nsIFrame* colFrame; + NS_NewTableColFrame(col, lastColGroupFrame, colFrame); + + // Set its style context + nsIStyleContextPtr colStyleContext = + aPresContext->ResolveStyleContextFor(col, lastColGroupFrame, PR_TRUE); + colFrame->SetStyleContext(aPresContext, colStyleContext); + + // XXX Don't release this style context (or we'll end up with a double-free).\ + // This code is doing what nsTableColGroupFrame::Reflow() does... + //NS_RELEASE(colStyleContext); + + // Add it to our list + if (nsnull == lastNewColFrame) { + firstNewColFrame = colFrame; + } else { + lastNewColFrame->SetNextSibling(colFrame); + } + lastNewColFrame = colFrame; NS_RELEASE(col); // ADDREF: col-- } NS_RELEASE(lastColGroup); // ADDREF: lastColGroup-- - lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, aReflowState, aStatus); + + // New reflow the new column frames + nsIFrame* firstChild; + lastColGroupFrame->FirstChild(firstChild); + if (nsnull == firstChild) { + lastColGroupFrame->Init(*aPresContext, firstNewColFrame); + lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, aReflowState, aStatus); + } else { + // 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; + lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus); + } } } @@ -1513,6 +1563,8 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext, nsReflowReason reflowReason = aReflowState.reason; nsIContent * prevKid; // do NOT hold a reference for this temp pointer! + // XXX CONSTRUCTION +#if 0 /* assumes that Table's children are in the following order: * Captions * ColGroups, in order @@ -1620,6 +1672,49 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext, break; } } +#else + for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) { + nsSize maxKidElementSize(0,0); + nsReflowState kidReflowState(kidFrame, aReflowState, availSize); + + PRInt32 yCoord = y; + if (NS_UNCONSTRAINEDSIZE!=yCoord) + yCoord+= topInset; + kidFrame->WillReflow(*aPresContext); + kidFrame->MoveTo(leftInset, yCoord); + result = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState); + + // Place the child since some of its content fit in us. + if (PR_TRUE==gsDebugNT) { + printf ("%p: reflow of row group returned desired=%d,%d, max-element=%d,%d\n", + this, kidSize.width, kidSize.height, kidMaxSize.width, kidMaxSize.height); + } + kidFrame->SetRect(nsRect(leftInset, yCoord, + kidSize.width, kidSize.height)); + if (NS_UNCONSTRAINEDSIZE==kidSize.height) + y = NS_UNCONSTRAINEDSIZE; + else + y += kidSize.height; + if (kidMaxSize.width > maxSize.width) { + maxSize.width = kidMaxSize.width; + } + if (kidMaxSize.height > maxSize.height) { + maxSize.height = kidMaxSize.height; + } + + if (NS_FRAME_IS_NOT_COMPLETE(result)) { + // If the child didn't finish layout then it means that it used + // up all of our available space (or needs us to split). + mLastContentIsComplete = PR_FALSE; + break; + } + } + if (NS_FRAME_IS_NOT_COMPLETE(result)) { + // If the child didn't finish layout then it means that it used + // up all of our available space (or needs us to split). + mLastContentIsComplete = PR_FALSE; + } +#endif BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus); // Recalculate Layout Dependencies @@ -1703,11 +1798,14 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, } else if (NextChildOffset() < numKids) { // Try and pull-up some children from a next-in-flow if (PullUpChildren(aPresContext, state, aDesiredSize.maxElementSize)) { + // XXX CONSTRUCTION. WE SHOULD NEVER HAVE UNMAPPED CHILDREN... +#if 0 // If we still have unmapped children then create some new frames mContent->ChildCount(numKids); if (NextChildOffset() < numKids) { status = ReflowUnmappedChildren(aPresContext, state, aDesiredSize.maxElementSize); } +#endif } else { // We were unable to pull-up all the existing frames from the // next in flow diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h index ac6d6b09d77..f78adb07f81 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.h +++ b/mozilla/layout/html/table/src/nsTableFrame.h @@ -86,6 +86,8 @@ public: const nsReflowState& aReflowState, nscoord& aSpecifiedTableWidth); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp index 7ce83d1e2ff..e391f076b30 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp @@ -94,7 +94,6 @@ struct OuterTableReflowState { /* ----------- nsTableOuterFrame ---------- */ - /** */ nsTableOuterFrame::nsTableOuterFrame(nsIContent* aContent, nsIFrame* aParentFrame) @@ -106,6 +105,25 @@ nsTableOuterFrame::nsTableOuterFrame(nsIContent* aContent, nsIFrame* aParentFram { } +NS_IMETHODIMP nsTableOuterFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + mFirstChild = aChildList; + mChildCount = LengthOf(mFirstChild); + + // Set our internal member data + if (1 == mChildCount) { + mInnerTableFrame = (nsTableFrame*)mFirstChild; + } else { + mCaptionFrame = mFirstChild; + + nsIFrame* f; + mFirstChild->GetNextSibling(f); + mInnerTableFrame = (nsTableFrame*)f; + } + + return NS_OK; +} + NS_METHOD nsTableOuterFrame::Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) @@ -403,12 +421,15 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext, // Set up our kids. They're already present, on an overflow list, // or there are none so we'll create them now MoveOverflowToChildList(); + // XXX CONSTRUCTION +#if 0 if (nsnull == mFirstChild) { nsresult result = CreateChildFrames(&aPresContext); if (NS_OK != result) { return result; } } +#endif // Lay out the caption and get its maximum element size if (nsnull != mCaptionFrame) { diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.h b/mozilla/layout/html/table/src/nsTableOuterFrame.h index 5e13f6bcd70..f0b484a3ea1 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.h +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.h @@ -50,6 +50,8 @@ public: nsIFrame* aParentFrame, nsIFrame*& aResult); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp index 2045307a9f1..929cfc647c7 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp @@ -97,6 +97,14 @@ nsTableRowFrame::~nsTableRowFrame() { } +NS_IMETHODIMP +nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + mFirstChild = aChildList; + mChildCount = LengthOf(mFirstChild); + return NS_OK; +} + /** * Post-reflow hook. This is where the table row does its post-processing */ @@ -538,6 +546,8 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, nsresult result = NS_OK; PRBool isFirst=PR_TRUE; + // XXX CONSTRUCTION +#if 0 for (;;) { // what row am I? // to handle rows with no cells, this block must be done before the "Get the next content object" block @@ -685,6 +695,112 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, NS_ASSERTION(len == mChildCount, "bad child count"); #endif } +#else + // 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); + + // Get the child's margins + nsMargin margin; + nscoord topMargin = 0; + + if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK) + { + topMargin = margin.top; + } + + 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); + 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); + if (gsDebug) + printf ("TR %p for cell %p Initial Reflow: desired=%d, MES=%d\n", + this, kidFrame, kidSize.width, kidMaxElementSize.width); + //XXX: this is a hack, shouldn't it be the case that a min size is + // never larger than a desired size? + if (kidMaxElementSize.width>kidSize.width) + kidSize.width = kidMaxElementSize.width; + if (kidMaxElementSize.height>kidSize.height) + kidSize.height = kidMaxElementSize.height; + ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize); + ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize); + NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "unexpected child reflow status"); + + if (gsDebug) + { + printf("reflow of cell returned result = %s with desired=%d,%d, min = %d,%d\n", + NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete", + kidSize.width, kidSize.height, + kidMaxElementSize.width, kidMaxElementSize.height); + } + + // Place the child + x += margin.left; + nsRect kidRect(x, topMargin, kidSize.width, kidSize.height); + PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize, + &kidMaxElementSize); + x += kidSize.width + margin.right; + } + + SetMaxChildHeight(aState.maxCellHeight, maxTopMargin, maxBottomMargin); // remember height of tallest child who doesn't have a row span + + // Return our desired size + aDesiredSize.width = x; + aDesiredSize.height = aState.maxCellVertSpace; +#endif return result; } @@ -960,7 +1076,10 @@ nsTableRowFrame::Reflow(nsIPresContext& aPresContext, switch (aReflowState.reason) { case eReflowReason_Initial: + // XXX CONSTRUCTION +#if 0 NS_ASSERTION(nsnull == mFirstChild, "unexpected reflow reason"); +#endif result = InitialReflow(aPresContext, state, aDesiredSize); GetMinRowSpan(tableFrame); FixMinCellHeight(tableFrame); diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.h b/mozilla/layout/html/table/src/nsTableRowFrame.h index 395d852b083..4d8ebfd820e 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.h +++ b/mozilla/layout/html/table/src/nsTableRowFrame.h @@ -53,6 +53,8 @@ public: nsIFrame* aParentFrame, nsIFrame*& aResult); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp index eff4da2972b..fd038827eae 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -127,6 +127,22 @@ NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount) return NS_OK; } +NS_IMETHODIMP +nsTableRowGroupFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + mFirstChild = aChildList; + mChildCount = LengthOf(mFirstChild); + + // XXX TEMP CODE UNTIL nsContainerFrame GOES AWAY... + nsIFrame* lastChild; + LastChild(lastChild); + if (nsnull != lastChild) { + lastChild->GetContentIndex(mLastContentOffset); + } + + return NS_OK; +} + NS_METHOD nsTableRowGroupFrame::Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) @@ -321,8 +337,8 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon } // Reflow the child into the available space - nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize, - eReflowReason_Resize); + nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize); + // XXX CONSTRUCTION eReflowReason_Resize); kidFrame->WillReflow(*aPresContext); kidFrame->MoveTo(kidMargin.left, aState.y + topMargin); if (gsDebug) printf("%p RG reflowing child %d (frame=%p) with avail width = %d\n", @@ -1155,10 +1171,13 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext, } else if (NextChildOffset() < numKids) { // Try and pull-up some children from a next-in-flow if (PullUpChildren(&aPresContext, state, aDesiredSize.maxElementSize)) { + // XXX CONSTRUCTION. WE SHOULD NEVER HAVE UNMAPPED CHILDREN... +#if 0 // If we still have unmapped children then create some new frames if (NextChildOffset() < numKids) { aStatus = ReflowUnmappedChildren(&aPresContext, state, aDesiredSize.maxElementSize); } +#endif } else { // We were unable to pull-up all the existing frames from the // next in flow diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.h b/mozilla/layout/html/table/src/nsTableRowGroupFrame.h index b97305c3407..7c73aa6a959 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.h +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.h @@ -51,6 +51,8 @@ public: nsIFrame* aParentFrame, nsIFrame*& aResult); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, diff --git a/mozilla/layout/style/nsHTMLStyleSheet.cpp b/mozilla/layout/style/nsHTMLStyleSheet.cpp index f43a071509e..2c9e40e08bf 100644 --- a/mozilla/layout/style/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLStyleSheet.cpp @@ -267,16 +267,14 @@ protected: PRInt32 aAttrCount, nsIHTMLAttributes*& aAttributes); - NS_IMETHOD ConstructFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsIAtom* aTag, - nsIStyleContext* aStyleContext, - nsIFrame*& aFrameSubTree); - nsIFrame* ConstructRootFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIStyleContext* aStyleContext); + nsIContent* aContent); + + nsIFrame* ConstructTableFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIStyleContext* aStyleContext, + nsIFrame*& aChildList); nsresult ProcessChildren(nsIPresContext* aPresContext, nsIFrame* aFrame, @@ -538,11 +536,15 @@ PRInt32 HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext, nsTableColFrame* colFrame; nsIFrame* colGroupFrame; + // XXX CONSTRUCTION. + // Unfortunately the table's children haven't been added yet... +#if 0 ((nsTableFrame*)tableFrame)->GetColumnFrame(colIndex, colFrame); colFrame->GetContentParent(colGroupFrame); matchCount += AppendRulesFrom(colGroupFrame, aPresContext, backstopInsertPoint, aResults); matchCount += AppendRulesFrom(colFrame, aPresContext, backstopInsertPoint, aResults); +#endif NS_RELEASE(cell); // cell: REFCNT-- } matchCount += AppendRulesFrom(rowGroupFrame, aPresContext, backstopInsertPoint, aResults); @@ -964,16 +966,123 @@ HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent, } nsIFrame* -HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIStyleContext* aStyleContext) +HTMLStyleSheetImpl::ConstructTableFrame(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIStyleContext* aStyleContext, + nsIFrame*& aChildList) +{ + nsIFrame* outerFrame; + nsIFrame* innerFrame; + nsIFrame* innerChildList = nsnull; + nsIFrame* captionFrame = nsnull; + + // Create an anonymous table outer frame which holds the caption and the + // table frame + NS_NewTableOuterFrame(aContent, aParentFrame, outerFrame); + + // Create the inner table frame + NS_NewTableFrame(aContent, outerFrame, innerFrame); + aChildList = innerFrame; + + // Have the inner table frame use the same style context as the outer table frame + innerFrame->SetStyleContext(aPresContext, aStyleContext); + + // Iterate the child content + nsIFrame* lastChildFrame = nsnull; + PRInt32 count; + aContent->ChildCount(count); + for (PRInt32 i = 0; i < count; i++) { + nsIContent* childContent; + aContent->ChildAt(i, childContent); + + if (nsnull != childContent) { + nsIFrame* frame = nsnull; + nsIStyleContext* childStyleContext; + + // Resolve the style context + childStyleContext = aPresContext->ResolveStyleContextFor(childContent, outerFrame); + + // See how it should be displayed + const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*) + childStyleContext->GetStyleData(eStyleStruct_Display); + + switch (styleDisplay->mDisplay) { + case NS_STYLE_DISPLAY_TABLE_CAPTION: + // Have we already created a caption? If so, ignore this caption + if (nsnull == captionFrame) { + NS_NewBodyFrame(childContent, outerFrame, captionFrame); + captionFrame->SetStyleContext(aPresContext, childStyleContext); + + // Process the caption's child content and initialize it + nsIFrame* captionChildList; + ProcessChildren(aPresContext, captionFrame, childContent, captionChildList); + captionFrame->Init(*aPresContext, captionChildList); + + // Prepend the caption frame to the outer frame's child list + captionFrame->SetNextSibling(innerFrame); + aChildList = captionFrame; + } + break; + + case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP: + case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP: + case NS_STYLE_DISPLAY_TABLE_ROW_GROUP: + NS_NewTableRowGroupFrame(childContent, innerFrame, frame); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN: + NS_NewTableColFrame(childContent, innerFrame, frame); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP: + NS_NewTableColGroupFrame(childContent, innerFrame, frame); + break; + + default: + // XXX For the time being ignore everything else. We should deal with + // things like table cells and create anonymous frames... + break; + } + + // If it's not a caption frame then set the style context, and link the + // frame into the inner frame's child list + if (nsnull != frame) { + frame->SetStyleContext(aPresContext, childStyleContext); + + // Process the children and initialize the frame + nsIFrame* childChildList; + ProcessChildren(aPresContext, frame, childContent, childChildList); + frame->Init(*aPresContext, childChildList); + + // Link the frame into the child list + if (nsnull == lastChildFrame) { + innerChildList = frame; + } else { + lastChildFrame->SetNextSibling(frame); + } + lastChildFrame = frame; + } + + NS_RELEASE(childStyleContext); + NS_RELEASE(childContent); + } + } + + // Initialize the inner table with its child list + innerFrame->Init(*aPresContext, innerChildList); + + return outerFrame; +} + +nsIFrame* +HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, + nsIContent* aContent) { nsIFrame* rootFrame; - nsIFrame* childList; - // Create the root frame and set its style context + // Create the root frame NS_NewHTMLFrame(aContent, nsnull, rootFrame); - rootFrame->SetStyleContext(aPresContext, aStyleContext); // Bind root frame to root view (and root window) nsIPresShell* presShell = aPresContext->GetShell(); @@ -985,23 +1094,33 @@ HTMLStyleSheetImpl::ConstructRootFrame(nsIPresContext* aPresContext, rootFrame->SetView(rootView); NS_RELEASE(viewManager); - // Process the children and initialize the frame - ProcessChildren(aPresContext, rootFrame, aContent, childList); - rootFrame->Init(*aPresContext, childList); - return rootFrame; } NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParentFrame, - nsIAtom* aTag, - nsIStyleContext* aStyleContext, nsIFrame*& aFrameSubTree) { + // Get the tag + nsIAtom* tag; + aContent->GetTag(tag); + + // Resolve the style context. + // XXX Cheesy hack for text + nsIStyleContext* styleContext; + if (nsnull == tag) { + styleContext = aPresContext->ResolvePseudoStyleContextFor(nsHTMLAtoms::text, aParentFrame); + } else { + styleContext = aPresContext->ResolveStyleContextFor(aContent, aParentFrame); + } + + // Initialize OUT parameter aFrameSubTree = nsnull; // Create a frame. + nsIFrame* frame = nsnull; + nsIFrame* childList = nsnull; if (nsnull == aParentFrame) { // This should only be the case for the root content object. #ifdef NS_DEBUG @@ -1017,90 +1136,67 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, #endif // Construct the root frame object - aFrameSubTree = ConstructRootFrame(aPresContext, aContent, aStyleContext); + frame = ConstructRootFrame(aPresContext, aContent); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); } else { - nsIFrame* frame = nsnull; - nsIFrame* childList = nsnull; nsresult rv = NS_OK; // Handle specific frame types - if (nsnull == aTag) { + if (nsnull == tag) { rv = NS_NewTextFrame(aContent, aParentFrame, frame); } - else if (nsHTMLAtoms::applet == aTag) { + else if (nsHTMLAtoms::img == tag) { + rv = NS_NewImageFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::hr == tag) { + rv = NS_NewHRFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::br == tag) { + rv = NS_NewBRFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::wbr == tag) { + rv = NS_NewWBRFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::input == tag) { + rv = CreateInputFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::textarea == tag) { + rv = NS_NewInputTextFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::select == tag) { + rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::applet == tag) { rv = NS_NewObjectFrame(aContent, aParentFrame, frame); } - else if (nsHTMLAtoms::body == aTag) { + else if (nsHTMLAtoms::embed == tag) { + rv = NS_NewObjectFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::object == tag) { + rv = NS_NewObjectFrame(aContent, aParentFrame, frame); + } + else if (nsHTMLAtoms::body == tag) { rv = NS_NewBodyFrame(aContent, aParentFrame, frame); // Process the child content rv = ProcessChildren(aPresContext, frame, aContent, childList); } - else if (nsHTMLAtoms::frameset == aTag) { + else if (nsHTMLAtoms::frameset == tag) { rv = NS_NewHTMLFramesetFrame(aContent, aParentFrame, frame); } - else if (nsHTMLAtoms::br == aTag) { - rv = NS_NewBRFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::embed == aTag) { - rv = NS_NewObjectFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::hr == aTag) { - rv = NS_NewHRFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::img == aTag) { - rv = NS_NewImageFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::object == aTag) { - rv = NS_NewObjectFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::spacer == aTag) { - rv = NS_NewSpacerFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::wbr == aTag) { - rv = NS_NewWBRFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::input == aTag) { - rv = CreateInputFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::textarea == aTag) { - rv = NS_NewInputTextFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::select == aTag) { - rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::iframe == aTag) { + else if (nsHTMLAtoms::iframe == tag) { rv = NS_NewHTMLFrameOuterFrame(aContent, aParentFrame, frame); } - - // the table content frames... - else if (nsHTMLAtoms::caption == aTag) { - rv = NS_NewBodyFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::table == aTag) { - rv = NS_NewTableOuterFrame(aContent, aParentFrame, frame); - } - else if ((nsHTMLAtoms::tbody == aTag) || - (nsHTMLAtoms::thead == aTag) || - (nsHTMLAtoms::tfoot == aTag)) { - rv = NS_NewTableRowGroupFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::tr == aTag) { - rv = NS_NewTableRowFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::colgroup == aTag) { - rv = NS_NewTableColGroupFrame(aContent, aParentFrame, frame); - } - else if (nsHTMLAtoms::col == aTag) { - rv = NS_NewTableColFrame(aContent, aParentFrame, frame); - } - else if ((nsHTMLAtoms::td == aTag) || - (nsHTMLAtoms::th == aTag)) { - rv = NS_NewTableCellFrame(aContent, aParentFrame, frame); + else if (nsHTMLAtoms::spacer == tag) { + rv = NS_NewSpacerFrame(aContent, aParentFrame, frame); } if (NS_OK != rv) { + NS_RELEASE(styleContext); + NS_IF_RELEASE(tag); return rv; } @@ -1111,10 +1207,9 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, // When there is no explicit frame to create, assume it's a // container and let style dictate the rest. const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*) - aStyleContext->GetStyleData(eStyleStruct_Display); + styleContext->GetStyleData(eStyleStruct_Display); // Use style to choose what kind of frame to create - nsresult rv; switch (styleDisplay->mDisplay) { case NS_STYLE_DISPLAY_BLOCK: case NS_STYLE_DISPLAY_LIST_ITEM: @@ -1131,53 +1226,78 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, ProcessChildren(aPresContext, frame, aContent, childList); break; + case NS_STYLE_DISPLAY_TABLE: + frame = ConstructTableFrame(aPresContext, aContent, aParentFrame, + styleContext, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_ROW_GROUP: + case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP: + 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 + rv = NS_NewTableRowGroupFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN: + // XXX We should check for being inside of a table column group... + rv = NS_NewTableColFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP: + // XXX We should check for being inside of a table... + rv = NS_NewTableColGroupFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_ROW: + // XXX We should check for being inside of a table row group... + rv = NS_NewTableRowFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + + case NS_STYLE_DISPLAY_TABLE_CELL: + // XXX We should check for being inside of a table row frame... + rv = NS_NewTableCellFrame(aContent, aParentFrame, frame); + + // Process the child content + ProcessChildren(aPresContext, frame, aContent, childList); + break; + default: // Don't create any frame for content that's not displayed... break; } if (NS_OK != rv) { + NS_RELEASE(styleContext); + NS_IF_RELEASE(tag); return rv; } } + } - if (nsnull != frame) { - // Set the style context - frame->SetStyleContext(aPresContext, aStyleContext); - - // Initialize the frame giving it its child list - frame->Init(*aPresContext, childList); - } - aFrameSubTree = frame; + // If we created a frame then set its style context and initialize it + // passing it the child list + if (nsnull != frame) { + frame->SetStyleContext(aPresContext, styleContext); + frame->Init(*aPresContext, childList); } - - return NS_OK; -} - -NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsIFrame*& aFrameSubTree) -{ - // Get the tag - nsIAtom* tag; - aContent->GetTag(tag); - - // Resolve the style context. - // XXX Cheesy hack for text - nsIStyleContext* styleContext; - if (nsnull == tag) { - styleContext = aPresContext->ResolvePseudoStyleContextFor(nsHTMLAtoms::text, aParentFrame); - } else { - styleContext = aPresContext->ResolveStyleContextFor(aContent, aParentFrame); - } - - nsresult result = ConstructFrame(aPresContext, aContent, aParentFrame, - tag, styleContext, aFrameSubTree); + aFrameSubTree = frame; NS_RELEASE(styleContext); NS_IF_RELEASE(tag); - return result; + return NS_OK; } NS_IMETHODIMP HTMLStyleSheetImpl::ContentAppended(nsIPresContext* aPresContext, diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index 430d9cfc851..b355ef0e598 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -73,6 +73,29 @@ nsTableCellFrame::~nsTableCellFrame() { } +NS_IMETHODIMP +nsTableCellFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + // Create body pseudo frame + NS_NewBodyFrame(mContent, this, mFirstChild); + mChildCount = 1; + + // Resolve style and set the style context + nsIStyleContext* styleContext = + aPresContext.ResolveStyleContextFor(mContent, this); // styleContext: ADDREF++ + mFirstChild->SetStyleContext(&aPresContext, styleContext); + NS_RELEASE(styleContext); // styleContext: ADDREF-- + + // Set the geometric and content parent for each of the child frames + for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) { + frame->SetGeometricParent(mFirstChild); + frame->SetContentParent(mFirstChild); + } + + // Queue up the frames for the block frame + return mFirstChild->Init(aPresContext, aChildList); +} + NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) diff --git a/mozilla/layout/tables/nsTableCellFrame.h b/mozilla/layout/tables/nsTableCellFrame.h index 68e7a9080ae..074aed091b6 100644 --- a/mozilla/layout/tables/nsTableCellFrame.h +++ b/mozilla/layout/tables/nsTableCellFrame.h @@ -58,6 +58,8 @@ public: // nsISupports NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); diff --git a/mozilla/layout/tables/nsTableColFrame.cpp b/mozilla/layout/tables/nsTableColFrame.cpp index 03b9065ddc6..2c7755bee33 100644 --- a/mozilla/layout/tables/nsTableColFrame.cpp +++ b/mozilla/layout/tables/nsTableColFrame.cpp @@ -32,7 +32,6 @@ static const PRBool gsDebug = PR_FALSE; static const PRBool gsNoisyRefs = PR_FALSE; #endif - nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsFrame(aContent, aParentFrame) { diff --git a/mozilla/layout/tables/nsTableColGroupFrame.cpp b/mozilla/layout/tables/nsTableColGroupFrame.cpp index eab3e1bd890..9c1e72bab3c 100644 --- a/mozilla/layout/tables/nsTableColGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableColGroupFrame.cpp @@ -35,7 +35,6 @@ static NS_DEFINE_IID(kIHTMLTableColElementIID, NS_IHTMLTABLECOLELEMENT_IID); static PRBool gsDebug = PR_FALSE; - nsTableColGroupFrame::nsTableColGroupFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsContainerFrame(aContent, aParentFrame) @@ -47,6 +46,57 @@ nsTableColGroupFrame::~nsTableColGroupFrame() { } +nsresult +nsTableColGroupFrame::AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + nsIFrame* lastChild; + LastChild(lastChild); + + // Append the new frames to the child list + if (nsnull == lastChild) { + mFirstChild = aChildList; + } else { + lastChild->SetNextSibling(aChildList); + } + mChildCount += LengthOf(aChildList); + + // 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); + PRInt32 repeat=1; + nsIHTMLTableColElement* colContent = nsnull; + nsresult 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; + + // Set nsColFrame-specific information + ((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex); + nsIFrame* tableFrame=nsnull; + GetGeometricParent(tableFrame); + ((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame); + + SetStyleContextForFirstPass(&aPresContext, colIndex); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsTableColGroupFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + return AppendNewFrames(aPresContext, aChildList); +} + NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) @@ -72,6 +122,8 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext, nsIFrame* kidFrame = nsnull; nsIFrame* prevKidFrame; + // XXX CONSTRUCTION +#if 0 LastChild(prevKidFrame); // XXX remember this... PRInt32 kidIndex = 0; // index of the content child we are currently working on PRInt32 colIndex = 0; // number of content children that are columns, normally same as kidIndex @@ -155,6 +207,38 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext, colIndex++; // if this wasn't a column, we would not have gotten this far kidIndex++; } +#else + if (eReflowReason_Incremental == aReflowState.reason) { + NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command"); + + // Get the type of reflow command + nsIReflowCommand::ReflowType reflowCmdType; + aReflowState.reflowCommand->GetType(reflowCmdType); + + // Currently we only expect appended reflow commands + NS_ASSERTION(nsIReflowCommand::FrameAppended == reflowCmdType, + "unexpected reflow command"); + + // Get the new column frames + nsIFrame* childList; + aReflowState.reflowCommand->GetChildFrame(childList); + + // Append them to the child list + AppendNewFrames(aPresContext, childList); + } + + for (kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) { + // Give the child frame a chance to reflow, even though we know it'll have 0 size + nsReflowMetrics kidSize(nsnull); + // XXX Use a valid reason... + nsReflowState kidReflowState(kidFrame, aReflowState, nsSize(0,0), eReflowReason_Initial); + kidFrame->WillReflow(aPresContext); + nsReflowStatus status = ReflowChild(kidFrame,&aPresContext, kidSize, + kidReflowState); + // note that DidReflow is called as the result of some ancestor firing off a DidReflow above me + kidFrame->SetRect(nsRect(0,0,0,0)); + } +#endif aDesiredSize.width=0; aDesiredSize.height=0; if (nsnull!=aDesiredSize.maxElementSize) diff --git a/mozilla/layout/tables/nsTableColGroupFrame.h b/mozilla/layout/tables/nsTableColGroupFrame.h index bf9498c96ad..eabb45a8365 100644 --- a/mozilla/layout/tables/nsTableColGroupFrame.h +++ b/mozilla/layout/tables/nsTableColGroupFrame.h @@ -43,6 +43,8 @@ public: nsIFrame* aParentFrame, nsIFrame*& aResult); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); @@ -83,6 +85,7 @@ protected: NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext, PRInt32 aColIndex); + nsresult AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList); PRInt32 mColCount; diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index c8e4ebbfd5e..964bee7e61a 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -258,7 +258,6 @@ void ColumnInfoCache::GetColumnsByType(const nsStyleUnit aType, /* --------------------- nsTableFrame -------------------- */ - nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsContainerFrame(aContent, aParentFrame), mCellMap(nsnull), @@ -287,6 +286,14 @@ nsTableFrame::~nsTableFrame() delete mColCache; } +NS_IMETHODIMP +nsTableFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + mFirstChild = aChildList; + mChildCount = LengthOf(mFirstChild); + return NS_OK; +} + /* ****** CellMap methods ******* */ /* return the next row group frame after aRowGroupFrame */ @@ -708,9 +715,13 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex, lastColGroupFrame->GetContent((nsIContent *&)lastColGroup); // ADDREF b: lastColGroup++ } + // XXX It would be better to do this in the style code while constructing + // the table's frames nsAutoString colTag; nsHTMLAtoms::col->ToString(colTag); PRInt32 excessColumns = aColIndex - actualColumns; + nsIFrame* firstNewColFrame = nsnull; + nsIFrame* lastNewColFrame = nsnull; for ( ; excessColumns >= 0; excessColumns--) { nsIHTMLContent *col=nsnull; @@ -718,10 +729,49 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex, rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++ //XXX mark the col implicit lastColGroup->AppendChildTo((nsIContent*)col, PR_FALSE); + + // Create a new col frame + nsIFrame* colFrame; + NS_NewTableColFrame(col, lastColGroupFrame, colFrame); + + // Set its style context + nsIStyleContextPtr colStyleContext = + aPresContext->ResolveStyleContextFor(col, lastColGroupFrame, PR_TRUE); + colFrame->SetStyleContext(aPresContext, colStyleContext); + + // XXX Don't release this style context (or we'll end up with a double-free).\ + // This code is doing what nsTableColGroupFrame::Reflow() does... + //NS_RELEASE(colStyleContext); + + // Add it to our list + if (nsnull == lastNewColFrame) { + firstNewColFrame = colFrame; + } else { + lastNewColFrame->SetNextSibling(colFrame); + } + lastNewColFrame = colFrame; NS_RELEASE(col); // ADDREF: col-- } NS_RELEASE(lastColGroup); // ADDREF: lastColGroup-- - lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, aReflowState, aStatus); + + // New reflow the new column frames + nsIFrame* firstChild; + lastColGroupFrame->FirstChild(firstChild); + if (nsnull == firstChild) { + lastColGroupFrame->Init(*aPresContext, firstNewColFrame); + lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, aReflowState, aStatus); + } else { + // 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; + lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus); + } } } @@ -1513,6 +1563,8 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext, nsReflowReason reflowReason = aReflowState.reason; nsIContent * prevKid; // do NOT hold a reference for this temp pointer! + // XXX CONSTRUCTION +#if 0 /* assumes that Table's children are in the following order: * Captions * ColGroups, in order @@ -1620,6 +1672,49 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext, break; } } +#else + for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) { + nsSize maxKidElementSize(0,0); + nsReflowState kidReflowState(kidFrame, aReflowState, availSize); + + PRInt32 yCoord = y; + if (NS_UNCONSTRAINEDSIZE!=yCoord) + yCoord+= topInset; + kidFrame->WillReflow(*aPresContext); + kidFrame->MoveTo(leftInset, yCoord); + result = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState); + + // Place the child since some of its content fit in us. + if (PR_TRUE==gsDebugNT) { + printf ("%p: reflow of row group returned desired=%d,%d, max-element=%d,%d\n", + this, kidSize.width, kidSize.height, kidMaxSize.width, kidMaxSize.height); + } + kidFrame->SetRect(nsRect(leftInset, yCoord, + kidSize.width, kidSize.height)); + if (NS_UNCONSTRAINEDSIZE==kidSize.height) + y = NS_UNCONSTRAINEDSIZE; + else + y += kidSize.height; + if (kidMaxSize.width > maxSize.width) { + maxSize.width = kidMaxSize.width; + } + if (kidMaxSize.height > maxSize.height) { + maxSize.height = kidMaxSize.height; + } + + if (NS_FRAME_IS_NOT_COMPLETE(result)) { + // If the child didn't finish layout then it means that it used + // up all of our available space (or needs us to split). + mLastContentIsComplete = PR_FALSE; + break; + } + } + if (NS_FRAME_IS_NOT_COMPLETE(result)) { + // If the child didn't finish layout then it means that it used + // up all of our available space (or needs us to split). + mLastContentIsComplete = PR_FALSE; + } +#endif BuildColumnCache(aPresContext, aDesiredSize, aReflowState, aStatus); // Recalculate Layout Dependencies @@ -1703,11 +1798,14 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, } else if (NextChildOffset() < numKids) { // Try and pull-up some children from a next-in-flow if (PullUpChildren(aPresContext, state, aDesiredSize.maxElementSize)) { + // XXX CONSTRUCTION. WE SHOULD NEVER HAVE UNMAPPED CHILDREN... +#if 0 // If we still have unmapped children then create some new frames mContent->ChildCount(numKids); if (NextChildOffset() < numKids) { status = ReflowUnmappedChildren(aPresContext, state, aDesiredSize.maxElementSize); } +#endif } else { // We were unable to pull-up all the existing frames from the // next in flow diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index ac6d6b09d77..f78adb07f81 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -86,6 +86,8 @@ public: const nsReflowState& aReflowState, nscoord& aSpecifiedTableWidth); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp index 7ce83d1e2ff..e391f076b30 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.cpp +++ b/mozilla/layout/tables/nsTableOuterFrame.cpp @@ -94,7 +94,6 @@ struct OuterTableReflowState { /* ----------- nsTableOuterFrame ---------- */ - /** */ nsTableOuterFrame::nsTableOuterFrame(nsIContent* aContent, nsIFrame* aParentFrame) @@ -106,6 +105,25 @@ nsTableOuterFrame::nsTableOuterFrame(nsIContent* aContent, nsIFrame* aParentFram { } +NS_IMETHODIMP nsTableOuterFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + mFirstChild = aChildList; + mChildCount = LengthOf(mFirstChild); + + // Set our internal member data + if (1 == mChildCount) { + mInnerTableFrame = (nsTableFrame*)mFirstChild; + } else { + mCaptionFrame = mFirstChild; + + nsIFrame* f; + mFirstChild->GetNextSibling(f); + mInnerTableFrame = (nsTableFrame*)f; + } + + return NS_OK; +} + NS_METHOD nsTableOuterFrame::Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) @@ -403,12 +421,15 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext, // Set up our kids. They're already present, on an overflow list, // or there are none so we'll create them now MoveOverflowToChildList(); + // XXX CONSTRUCTION +#if 0 if (nsnull == mFirstChild) { nsresult result = CreateChildFrames(&aPresContext); if (NS_OK != result) { return result; } } +#endif // Lay out the caption and get its maximum element size if (nsnull != mCaptionFrame) { diff --git a/mozilla/layout/tables/nsTableOuterFrame.h b/mozilla/layout/tables/nsTableOuterFrame.h index 5e13f6bcd70..f0b484a3ea1 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.h +++ b/mozilla/layout/tables/nsTableOuterFrame.h @@ -50,6 +50,8 @@ public: nsIFrame* aParentFrame, nsIFrame*& aResult); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp index 2045307a9f1..929cfc647c7 100644 --- a/mozilla/layout/tables/nsTableRowFrame.cpp +++ b/mozilla/layout/tables/nsTableRowFrame.cpp @@ -97,6 +97,14 @@ nsTableRowFrame::~nsTableRowFrame() { } +NS_IMETHODIMP +nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + mFirstChild = aChildList; + mChildCount = LengthOf(mFirstChild); + return NS_OK; +} + /** * Post-reflow hook. This is where the table row does its post-processing */ @@ -538,6 +546,8 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, nsresult result = NS_OK; PRBool isFirst=PR_TRUE; + // XXX CONSTRUCTION +#if 0 for (;;) { // what row am I? // to handle rows with no cells, this block must be done before the "Get the next content object" block @@ -685,6 +695,112 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, NS_ASSERTION(len == mChildCount, "bad child count"); #endif } +#else + // 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); + + // Get the child's margins + nsMargin margin; + nscoord topMargin = 0; + + if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK) + { + topMargin = margin.top; + } + + 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); + 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); + if (gsDebug) + printf ("TR %p for cell %p Initial Reflow: desired=%d, MES=%d\n", + this, kidFrame, kidSize.width, kidMaxElementSize.width); + //XXX: this is a hack, shouldn't it be the case that a min size is + // never larger than a desired size? + if (kidMaxElementSize.width>kidSize.width) + kidSize.width = kidMaxElementSize.width; + if (kidMaxElementSize.height>kidSize.height) + kidSize.height = kidMaxElementSize.height; + ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize); + ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize); + NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "unexpected child reflow status"); + + if (gsDebug) + { + printf("reflow of cell returned result = %s with desired=%d,%d, min = %d,%d\n", + NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete", + kidSize.width, kidSize.height, + kidMaxElementSize.width, kidMaxElementSize.height); + } + + // Place the child + x += margin.left; + nsRect kidRect(x, topMargin, kidSize.width, kidSize.height); + PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize, + &kidMaxElementSize); + x += kidSize.width + margin.right; + } + + SetMaxChildHeight(aState.maxCellHeight, maxTopMargin, maxBottomMargin); // remember height of tallest child who doesn't have a row span + + // Return our desired size + aDesiredSize.width = x; + aDesiredSize.height = aState.maxCellVertSpace; +#endif return result; } @@ -960,7 +1076,10 @@ nsTableRowFrame::Reflow(nsIPresContext& aPresContext, switch (aReflowState.reason) { case eReflowReason_Initial: + // XXX CONSTRUCTION +#if 0 NS_ASSERTION(nsnull == mFirstChild, "unexpected reflow reason"); +#endif result = InitialReflow(aPresContext, state, aDesiredSize); GetMinRowSpan(tableFrame); FixMinCellHeight(tableFrame); diff --git a/mozilla/layout/tables/nsTableRowFrame.h b/mozilla/layout/tables/nsTableRowFrame.h index 395d852b083..4d8ebfd820e 100644 --- a/mozilla/layout/tables/nsTableRowFrame.h +++ b/mozilla/layout/tables/nsTableRowFrame.h @@ -53,6 +53,8 @@ public: nsIFrame* aParentFrame, nsIFrame*& aResult); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp index eff4da2972b..fd038827eae 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp @@ -127,6 +127,22 @@ NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount) return NS_OK; } +NS_IMETHODIMP +nsTableRowGroupFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + mFirstChild = aChildList; + mChildCount = LengthOf(mFirstChild); + + // XXX TEMP CODE UNTIL nsContainerFrame GOES AWAY... + nsIFrame* lastChild; + LastChild(lastChild); + if (nsnull != lastChild) { + lastChild->GetContentIndex(mLastContentOffset); + } + + return NS_OK; +} + NS_METHOD nsTableRowGroupFrame::Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) @@ -321,8 +337,8 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon } // Reflow the child into the available space - nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize, - eReflowReason_Resize); + nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize); + // XXX CONSTRUCTION eReflowReason_Resize); kidFrame->WillReflow(*aPresContext); kidFrame->MoveTo(kidMargin.left, aState.y + topMargin); if (gsDebug) printf("%p RG reflowing child %d (frame=%p) with avail width = %d\n", @@ -1155,10 +1171,13 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext, } else if (NextChildOffset() < numKids) { // Try and pull-up some children from a next-in-flow if (PullUpChildren(&aPresContext, state, aDesiredSize.maxElementSize)) { + // XXX CONSTRUCTION. WE SHOULD NEVER HAVE UNMAPPED CHILDREN... +#if 0 // If we still have unmapped children then create some new frames if (NextChildOffset() < numKids) { aStatus = ReflowUnmappedChildren(&aPresContext, state, aDesiredSize.maxElementSize); } +#endif } else { // We were unable to pull-up all the existing frames from the // next in flow diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.h b/mozilla/layout/tables/nsTableRowGroupFrame.h index b97305c3407..7c73aa6a959 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.h +++ b/mozilla/layout/tables/nsTableRowGroupFrame.h @@ -51,6 +51,8 @@ public: nsIFrame* aParentFrame, nsIFrame*& aResult); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext,