From 03cad6390dd5cbdf6cab0c1997a14e9a7cb51144 Mon Sep 17 00:00:00 2001 From: "buster%netscape.com" Date: Fri, 30 Oct 1998 07:57:44 +0000 Subject: [PATCH] some extremely preliminary work for styleChanged incremental reflow --- .../html/content/src/nsHTMLTableElement.cpp | 2 +- content/html/style/src/nsHTMLStyleSheet.cpp | 13 ++++ .../html/content/src/nsHTMLTableElement.cpp | 2 +- layout/html/style/src/nsHTMLStyleSheet.cpp | 13 ++++ layout/html/table/src/nsTableCellFrame.cpp | 72 ++++++++++++++++++- layout/html/table/src/nsTableCellFrame.h | 5 ++ .../html/table/src/nsTableColGroupFrame.cpp | 38 +++++++++- layout/html/table/src/nsTableColGroupFrame.h | 6 ++ layout/html/table/src/nsTableFrame.cpp | 71 ++++++++++++++---- layout/html/table/src/nsTableFrame.h | 5 ++ layout/html/table/src/nsTableOuterFrame.cpp | 9 +-- layout/html/table/src/nsTableRowFrame.cpp | 59 +++++++++++++-- layout/html/table/src/nsTableRowFrame.h | 5 ++ .../html/table/src/nsTableRowGroupFrame.cpp | 48 +++++++++++-- layout/html/table/src/nsTableRowGroupFrame.h | 5 ++ layout/html/tests/TableIncrementalReflow.html | 59 +++++++++++++-- layout/style/nsHTMLStyleSheet.cpp | 13 ++++ layout/tables/nsTableCellFrame.cpp | 72 ++++++++++++++++++- layout/tables/nsTableCellFrame.h | 5 ++ layout/tables/nsTableColGroupFrame.cpp | 38 +++++++++- layout/tables/nsTableColGroupFrame.h | 6 ++ layout/tables/nsTableFrame.cpp | 71 ++++++++++++++---- layout/tables/nsTableFrame.h | 5 ++ layout/tables/nsTableOuterFrame.cpp | 9 +-- layout/tables/nsTableRowFrame.cpp | 59 +++++++++++++-- layout/tables/nsTableRowFrame.h | 5 ++ layout/tables/nsTableRowGroupFrame.cpp | 48 +++++++++++-- layout/tables/nsTableRowGroupFrame.h | 5 ++ 28 files changed, 667 insertions(+), 81 deletions(-) diff --git a/content/html/content/src/nsHTMLTableElement.cpp b/content/html/content/src/nsHTMLTableElement.cpp index 2a0083d25365..c3315edaac1c 100644 --- a/content/html/content/src/nsHTMLTableElement.cpp +++ b/content/html/content/src/nsHTMLTableElement.cpp @@ -167,7 +167,7 @@ NS_IMPL_STRING_ATTR(nsHTMLTableElement, CellSpacing, cellspacing, eSetAttrNotify NS_IMPL_STRING_ATTR(nsHTMLTableElement, Frame, frame, eSetAttrNotify_None) NS_IMPL_STRING_ATTR(nsHTMLTableElement, Rules, rules, eSetAttrNotify_None) NS_IMPL_STRING_ATTR(nsHTMLTableElement, Summary, summary, eSetAttrNotify_None) -NS_IMPL_STRING_ATTR(nsHTMLTableElement, Width, width, eSetAttrNotify_None) +NS_IMPL_STRING_ATTR(nsHTMLTableElement, Width, width, eSetAttrNotify_Reflow) NS_IMETHODIMP nsHTMLTableElement::GetCaption(nsIDOMHTMLTableCaptionElement** aValue) diff --git a/content/html/style/src/nsHTMLStyleSheet.cpp b/content/html/style/src/nsHTMLStyleSheet.cpp index 62f07846e0a5..906598f6385f 100644 --- a/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/content/html/style/src/nsHTMLStyleSheet.cpp @@ -2005,6 +2005,19 @@ HTMLStyleSheetImpl::AttributeChanged(nsIPresContext* aPresContext, render = PR_TRUE; } } + else if (tag == nsHTMLAtoms::caption || + tag == nsHTMLAtoms::table || + tag == nsHTMLAtoms::col || + tag == nsHTMLAtoms::colgroup || + tag == nsHTMLAtoms::tr || + tag == nsHTMLAtoms::tbody || + tag == nsHTMLAtoms::thead || + tag == nsHTMLAtoms::tfoot || + tag == nsHTMLAtoms::td || tag == nsHTMLAtoms::th) + { + restyle = PR_TRUE; + reflow = PR_TRUE; + } else { } diff --git a/layout/html/content/src/nsHTMLTableElement.cpp b/layout/html/content/src/nsHTMLTableElement.cpp index 2a0083d25365..c3315edaac1c 100644 --- a/layout/html/content/src/nsHTMLTableElement.cpp +++ b/layout/html/content/src/nsHTMLTableElement.cpp @@ -167,7 +167,7 @@ NS_IMPL_STRING_ATTR(nsHTMLTableElement, CellSpacing, cellspacing, eSetAttrNotify NS_IMPL_STRING_ATTR(nsHTMLTableElement, Frame, frame, eSetAttrNotify_None) NS_IMPL_STRING_ATTR(nsHTMLTableElement, Rules, rules, eSetAttrNotify_None) NS_IMPL_STRING_ATTR(nsHTMLTableElement, Summary, summary, eSetAttrNotify_None) -NS_IMPL_STRING_ATTR(nsHTMLTableElement, Width, width, eSetAttrNotify_None) +NS_IMPL_STRING_ATTR(nsHTMLTableElement, Width, width, eSetAttrNotify_Reflow) NS_IMETHODIMP nsHTMLTableElement::GetCaption(nsIDOMHTMLTableCaptionElement** aValue) diff --git a/layout/html/style/src/nsHTMLStyleSheet.cpp b/layout/html/style/src/nsHTMLStyleSheet.cpp index 62f07846e0a5..906598f6385f 100644 --- a/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -2005,6 +2005,19 @@ HTMLStyleSheetImpl::AttributeChanged(nsIPresContext* aPresContext, render = PR_TRUE; } } + else if (tag == nsHTMLAtoms::caption || + tag == nsHTMLAtoms::table || + tag == nsHTMLAtoms::col || + tag == nsHTMLAtoms::colgroup || + tag == nsHTMLAtoms::tr || + tag == nsHTMLAtoms::tbody || + tag == nsHTMLAtoms::thead || + tag == nsHTMLAtoms::tfoot || + tag == nsHTMLAtoms::td || tag == nsHTMLAtoms::th) + { + restyle = PR_TRUE; + reflow = PR_TRUE; + } else { } diff --git a/layout/html/table/src/nsTableCellFrame.cpp b/layout/html/table/src/nsTableCellFrame.cpp index e8e315136794..7301aeadac2a 100644 --- a/layout/html/table/src/nsTableCellFrame.cpp +++ b/layout/html/table/src/nsTableCellFrame.cpp @@ -111,9 +111,17 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext, nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myColor, 0, 0); - + + //XXX: this could be calculated once and remembered + // get border padding values + nsMargin borderPadding; + const nsStyleSpacing* cellSpacing; + GetStyleData(eStyleStruct_Spacing , ((nsStyleStruct *&)cellSpacing)); + cellSpacing->CalcBorderPaddingFor(this, borderPadding); + nscoord contentWidth = mPass1DesiredSize.width - (borderPadding.left+borderPadding.right); + nscoord contentHeight = mPass1DesiredSize.height - (borderPadding.top+borderPadding.bottom); // empty cells do not render their border - if (0!=mPass1DesiredSize.width || 0!=mPass1DesiredSize.height) + if (0width = 0; @@ -288,11 +298,33 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext& aPresContext, availSize.height -= topInset+bottomInset+margin.top+margin.bottom; // XXX Kipp added this hack - if (eReflowReason_Incremental == aReflowState.reason) { + if (eReflowReason_Incremental == aReflowState.reason) + { // XXX We *must* do this otherwise incremental reflow that's // passing through will not work right. nsIFrame* next; aReflowState.reflowCommand->GetNext(next); + + // if it is a StyleChanged reflow targeted at this cell frame, + // handle that here + // first determine if this frame is the target or not + nsIFrame *target=nsnull; + rv = aReflowState.reflowCommand->GetTarget(target); + if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target)) + { + if (this==target) + { + nsIReflowCommand::ReflowType type; + aReflowState.reflowCommand->GetType(type); + if (nsIReflowCommand::StyleChanged==type) + { + nsresult rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); + aStatus = NS_FRAME_COMPLETE; + return rv; + } + } + } + // if any of these conditions are not true, we just pass the reflow command down } // Try to reflow the child into the available space. It might not @@ -411,6 +443,40 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext& aPresContext, return NS_OK; } +NS_METHOD nsTableCellFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebug) printf("Cell IR: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + nsTableFrame* tableFrame=nsnull; + rv = nsTableFrame::GetTableFrame(this, tableFrame); + if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) + { + tableFrame->InvalidateCellMap(); + tableFrame->InvalidateFirstPassCache(); + } + + // we are obligated to pass along the reflow command to our children before doing anything else + /* + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState, + aReflowState.maxSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } + */ + return rv; +} + NS_METHOD nsTableCellFrame::CreateContinuingFrame(nsIPresContext& aPresContext, nsIFrame* aParent, diff --git a/layout/html/table/src/nsTableCellFrame.h b/layout/html/table/src/nsTableCellFrame.h index 3e314054a10b..14c27548d231 100644 --- a/layout/html/table/src/nsTableCellFrame.h +++ b/layout/html/table/src/nsTableCellFrame.h @@ -199,6 +199,11 @@ protected: void MapHTMLBorderStyle(nsIPresContext* aPresContext,nsStyleSpacing& aSpacingStyle, nscoord aBorderWidth); PRBool ConvertToPixelValue(nsHTMLValue& aValue, PRInt32 aDefault, PRInt32& aResult); + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + protected: /** the starting column for this cell */ diff --git a/layout/html/table/src/nsTableColGroupFrame.cpp b/layout/html/table/src/nsTableColGroupFrame.cpp index f2ead478ef8c..334cf34babc5 100644 --- a/layout/html/table/src/nsTableColGroupFrame.cpp +++ b/layout/html/table/src/nsTableColGroupFrame.cpp @@ -315,9 +315,7 @@ NS_METHOD nsTableColGroupFrame::IR_TargetIsMe(nsIPresContext& aPresCont break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TCGF IR: StyleChanged not implemented.\n"); + rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : @@ -457,6 +455,40 @@ NS_METHOD nsTableColGroupFrame::IR_ColRemoved(nsIPresContext& aPresCont return rv; } +NS_METHOD nsTableColGroupFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebugIR) printf("TIF IR: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + nsTableFrame* tableFrame=nsnull; + rv = nsTableFrame::GetTableFrame(this, tableFrame); + if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) + { + tableFrame->InvalidateColumnCache(); + tableFrame->InvalidateFirstPassCache(); + } + + /* + // we are obligated to pass along the reflow command to our children before doing anything else + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState, + aReflowState.maxSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } +*/ + return rv; +} + NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, diff --git a/layout/html/table/src/nsTableColGroupFrame.h b/layout/html/table/src/nsTableColGroupFrame.h index f81dc7f27dbc..8142dd81d514 100644 --- a/layout/html/table/src/nsTableColGroupFrame.h +++ b/layout/html/table/src/nsTableColGroupFrame.h @@ -140,6 +140,12 @@ protected: nsReflowStatus& aStatus, nsTableColFrame * aDeletedFrame); + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + NS_IMETHOD IR_TargetIsChild(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, diff --git a/layout/html/table/src/nsTableFrame.cpp b/layout/html/table/src/nsTableFrame.cpp index fd1abd59ff63..d5beb89f789d 100644 --- a/layout/html/table/src/nsTableFrame.cpp +++ b/layout/html/table/src/nsTableFrame.cpp @@ -1613,7 +1613,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext, if (PR_FALSE==IsFirstPassValid()) { if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: first pass is invalid, rebuilding...\n"); - rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, aReflowState.reason, PR_TRUE); + nsReflowReason reason = aReflowState.reason; + if (eReflowReason_Initial!=reason) + reason = eReflowReason_Resize; + rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, reason, PR_TRUE); if (NS_FAILED(rv)) return rv; needsRecalc=PR_TRUE; @@ -1749,6 +1752,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext, availSize, aReason); if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 1 of unknown frame %p of type %d with reason=%d\n", kidFrame, childDisplay->mDisplay, aReason); + // rv intentionally not set here ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); continue; } @@ -1920,12 +1924,15 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, aReflowState.reflowState.reflowCommand->GetType(type); nsIFrame *objectFrame; aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame); - const nsStyleDisplay *childDisplay; - objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); + const nsStyleDisplay *childDisplay=nsnull; + if (nsnull!=objectFrame) + objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); if (PR_TRUE==gsDebugIR) printf("TIF IR: IncrementalReflow_TargetIsMe with type=%d\n", type); switch (type) { case nsIReflowCommand::FrameInserted : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) { rv = IR_ColGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -1943,6 +1950,8 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::FrameAppended : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) { rv = IR_ColGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -1961,10 +1970,14 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, /* case nsIReflowCommand::FrameReplaced : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); */ case nsIReflowCommand::FrameRemoved : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) { rv = IR_ColGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -1982,9 +1995,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TIF IR: StyleChanged not implemented.\n"); + rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : @@ -2201,6 +2212,36 @@ NS_METHOD nsTableFrame::IR_ColGroupRemoved(nsIPresContext& aPresContext, return rv; } +NS_METHOD nsTableFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + InnerTableReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebugIR) printf("TIF IR: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + // if something like border changes, we need to do pass1 again + // but if something like width changes, we just need to do pass2 + InvalidateFirstPassCache(); + + // we are obligated to pass along the reflow command to our children before doing anything else + /* + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState.reflowState, + aReflowState.availSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } + */ + return rv; +} + NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, InnerTableReflowState& aReflowState, @@ -2446,7 +2487,6 @@ void nsTableFrame::PlaceChild(nsIPresContext& aPresContext, * @return true if we successfully reflowed all the mapped children and false * otherwise, e.g. we pushed children to the next in flow */ - // XXX: this interface should change to pass in aStatus, return nsresult NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, InnerTableReflowState& aReflowState, @@ -2891,6 +2931,7 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext, // then the width attribute also acts as the width attribute for the entire column // if the cell has a colspan, the width is used provisionally, divided equally among // the spanned columns + if (PR_TRUE==gsDebug) printf("TIF SetCSFromCell: cell %p in row %p\n", aCellFrame, aRowFrame); if ((nsnull!=aCellFrame) && (nsnull!=aRowFrame)) { // get the cell style info @@ -2901,23 +2942,23 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext, // compute the width per column spanned PRInt32 colSpan = GetEffectiveColSpan(aCellFrame->GetColIndex(), aCellFrame); if (PR_TRUE==gsDebug) - printf("for col %d with colspan %d\n",aCellFrame->GetColIndex(), colSpan); + printf("TIF SetCSFromCell: for col %d with colspan %d\n",aCellFrame->GetColIndex(), colSpan); for (PRInt32 i=0; iGetColIndex(), colFrame); if (PR_TRUE==gsDebug) - printf(" for col %d\n",i+aCellFrame->GetColIndex()); + printf("TIF SetCSFromCell: for col %d\n",i+aCellFrame->GetColIndex()); if (nsTableColFrame::eWIDTH_SOURCE_CELL != colFrame->GetWidthSource()) { if (PR_TRUE==gsDebug) - printf(" width not yet set from a cell...\n"); + printf("TIF SetCSFromCell: width not yet set from a cell...\n"); if ((1==colSpan) || (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN != colFrame->GetWidthSource())) { if (PR_TRUE==gsDebug) - printf(" colspan was 1 or width was not set from a span\n"); + printf("TIF SetCSFromCell: colspan was 1 or width was not set from a span\n"); // get the column style and set the width attribute nsIStyleContext *colSC; colFrame->GetStyleContext(&aPresContext, colSC); @@ -2929,27 +2970,27 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext, nscoord width = cellPosition->mWidth.GetCoordValue(); colPosition->mWidth.SetCoordValue(width/colSpan); if (PR_TRUE==gsDebug) - printf(" col fixed width set to %d ", (width/colSpan)); + printf("TIF SetCSFromCell: col fixed width set to %d ", (width/colSpan)); } else { float width = cellPosition->mWidth.GetPercentValue(); colPosition->mWidth.SetPercentValue(width/colSpan); if (PR_TRUE==gsDebug) - printf(" col percent width set to %d ", (width/colSpan)); + printf("TIF SetCSFromCell: col percent width set to %d ", (width/colSpan)); } // set the column width-set-type if (1==colSpan) { colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL); if (PR_TRUE==gsDebug) - printf(" source=cell\n"); + printf(" source = CELL\n"); } else { colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN); if (PR_TRUE==gsDebug) - printf(" source=cell_with_span\n"); + printf(" source = SPAN\n"); } } } diff --git a/layout/html/table/src/nsTableFrame.h b/layout/html/table/src/nsTableFrame.h index fdb62807cb2e..a318c528a39c 100644 --- a/layout/html/table/src/nsTableFrame.h +++ b/layout/html/table/src/nsTableFrame.h @@ -361,6 +361,11 @@ protected: InnerTableReflowState& aReflowState, nsReflowStatus& aStatus, nsTableRowGroupFrame * aDeletedFrame); + + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + InnerTableReflowState& aReflowState, + nsReflowStatus& aStatus); NS_IMETHOD AdjustSiblingsAfterReflow(nsIPresContext& aPresContext, InnerTableReflowState& aReflowState, diff --git a/layout/html/table/src/nsTableOuterFrame.cpp b/layout/html/table/src/nsTableOuterFrame.cpp index e065eb8b884c..478abd827bf2 100644 --- a/layout/html/table/src/nsTableOuterFrame.cpp +++ b/layout/html/table/src/nsTableOuterFrame.cpp @@ -345,7 +345,9 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext& aPres nsHTMLReflowState captionReflowState(aPresContext, mCaptionFrame, aReflowState.reflowState, nsSize(mRect.width, - aReflowState.reflowState.maxSize.height)); + aReflowState.reflowState.maxSize.height), + aReflowState.reflowState.reason); + captionReflowState.reflowCommand=aReflowState.reflowState.reflowCommand; rv = ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState, aStatus); if (PR_TRUE==gsDebugIR) printf("TOF IR: caption reflow returned %d with width=%d height=%d, minCaptionWidth=%d\n", rv, captionSize.width, captionSize.height, captionMES.width); @@ -485,9 +487,8 @@ nsresult nsTableOuterFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TOF IR: StyleChanged not implemented.\n"); + if (PR_TRUE==gsDebugIR) printf("TOF IR: calling inner table reflow.\n"); + rv = IR_InnerTableReflow(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : diff --git a/layout/html/table/src/nsTableRowFrame.cpp b/layout/html/table/src/nsTableRowFrame.cpp index 862db8ad1547..eadf0e37ec9b 100644 --- a/layout/html/table/src/nsTableRowFrame.cpp +++ b/layout/html/table/src/nsTableRowFrame.cpp @@ -687,15 +687,19 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, // Get the child's margins nsMargin margin; nscoord topMargin = 0; - if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK) { topMargin = margin.top; } - maxTopMargin = PR_MAX(margin.top, maxTopMargin); maxBottomMargin = PR_MAX(margin.bottom, maxBottomMargin); + // get border padding values + nsMargin borderPadding; + const nsStyleSpacing* cellSpacing; + kidFrame->GetStyleData(eStyleStruct_Spacing , ((nsStyleStruct *&)cellSpacing)); + cellSpacing->CalcBorderPaddingFor(kidFrame, borderPadding); + // 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 @@ -727,6 +731,9 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, kidSize.width = kidMaxElementSize.width; if (kidMaxElementSize.height>kidSize.height) kidSize.height = kidMaxElementSize.height; + kidSize.width += borderPadding.left+borderPadding.right; + kidSize.height += borderPadding.top+borderPadding.bottom; + kidMaxElementSize.SizeBy(borderPadding.left+borderPadding.right, borderPadding.top+borderPadding.bottom); ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize); ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "unexpected child reflow status"); @@ -900,12 +907,15 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext, aReflowState.reflowState.reflowCommand->GetType(type); nsIFrame *objectFrame; aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame); - const nsStyleDisplay *childDisplay; - objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); + const nsStyleDisplay *childDisplay=nsnull; + if (nsnull!=objectFrame) + objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); if (PR_TRUE==gsDebugIR) printf("TRF IR: IncrementalReflow_TargetIsMe with type=%d\n", type); switch (type) { case nsIReflowCommand::FrameInserted : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay) { rv = IR_CellInserted(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -918,6 +928,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::FrameAppended : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay) { rv = IR_CellAppended(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -935,6 +947,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext, */ case nsIReflowCommand::FrameRemoved : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay) { rv = IR_CellRemoved(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -947,9 +961,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TRF IR: StyleChanged not implemented.\n"); + rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : @@ -1122,6 +1134,39 @@ NS_METHOD nsTableRowFrame::IR_CellRemoved(nsIPresContext& aPresContext, return rv; } +NS_METHOD nsTableRowFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebugIR) printf("Row: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + nsTableFrame* tableFrame=nsnull; + rv = nsTableFrame::GetTableFrame(this, tableFrame); + if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) + { + tableFrame->InvalidateFirstPassCache(); + } + + /* + // we are obligated to pass along the reflow command to our children before doing anything else + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState.reflowState, + aReflowState.availSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } + */ + return rv; +} + NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, RowReflowState& aReflowState, diff --git a/layout/html/table/src/nsTableRowFrame.h b/layout/html/table/src/nsTableRowFrame.h index 65cc7aded299..788c5a2c35a3 100644 --- a/layout/html/table/src/nsTableRowFrame.h +++ b/layout/html/table/src/nsTableRowFrame.h @@ -178,6 +178,11 @@ protected: nsReflowStatus& aStatus, nsTableCellFrame * aDeletedFrame); + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowReflowState& aReflowState, + nsReflowStatus& aStatus); + // row-specific methods void GetMinRowSpan(nsTableFrame *aTableFrame); diff --git a/layout/html/table/src/nsTableRowGroupFrame.cpp b/layout/html/table/src/nsTableRowGroupFrame.cpp index 56611c5eef84..0f1eecc3f1dd 100644 --- a/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -900,12 +900,15 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext, aReflowState.reflowState.reflowCommand->GetType(type); nsIFrame *objectFrame; aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame); - const nsStyleDisplay *childDisplay; - objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); + const nsStyleDisplay *childDisplay=nsnull; + if (nsnull!=objectFrame) + objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); if (PR_TRUE==gsDebugIR) printf("TRGF IR: TargetIsMe with type=%d\n", type); switch (type) { case nsIReflowCommand::FrameInserted : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) { rv = IR_RowInserted(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -918,6 +921,8 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::FrameAppended : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) { rv = IR_RowAppended(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -935,6 +940,8 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext, */ case nsIReflowCommand::FrameRemoved : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) { rv = IR_RowRemoved(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -947,9 +954,7 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TRGF IR: StyleChanged not implemented.\n"); + rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : @@ -1178,6 +1183,39 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext& aPresConte return rv; } +NS_METHOD nsTableRowGroupFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowGroupReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebugIR) printf("TRGF: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + nsTableFrame* tableFrame=nsnull; + rv = nsTableFrame::GetTableFrame(this, tableFrame); + if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) + { + tableFrame->InvalidateFirstPassCache(); + } + + /* + // we are obligated to pass along the reflow command to our children before doing anything else + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState.reflowState, + aReflowState.availSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } + */ + return rv; +} + NS_METHOD nsTableRowGroupFrame::CreateContinuingFrame(nsIPresContext& aPresContext, nsIFrame* aParent, diff --git a/layout/html/table/src/nsTableRowGroupFrame.h b/layout/html/table/src/nsTableRowGroupFrame.h index 2967a9d947a7..16bb920c91fb 100644 --- a/layout/html/table/src/nsTableRowGroupFrame.h +++ b/layout/html/table/src/nsTableRowGroupFrame.h @@ -168,6 +168,11 @@ protected: nsReflowStatus& aStatus, nsTableRowFrame * aDeletedFrame); + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowGroupReflowState& aReflowState, + nsReflowStatus& aStatus); + NS_IMETHOD DidAppendRow(nsTableRowFrame *aRowFrame); PRBool NoRowsFollow(); diff --git a/layout/html/tests/TableIncrementalReflow.html b/layout/html/tests/TableIncrementalReflow.html index 44c6975b852c..2d3856ae54ac 100644 --- a/layout/html/tests/TableIncrementalReflow.html +++ b/layout/html/tests/TableIncrementalReflow.html @@ -17,12 +17,25 @@ function deleteCaption() { table.removeChild(caption); } +function changeCaptionStyle() { + var caption = document.getElementsByTagName("CAPTION")[0]; + caption.align="bottom"; + dump("SCRIPT: changed caption align to bottom\n"); +} + + +function changeTableStyle() { + var table = document.getElementsByTagName("TABLE")[0]; + table.width="600"; + dump("SCRIPT: changed table width to 600\n"); +} + function insertColGroup() { var table = document.getElementsByTagName("TABLE")[0]; var refColGroup = document.getElementsByTagName("COLGROUP")[0]; var colGroup = document.createElement("COLGROUP", null); - colGroup.width=200; + colGroup.width=100; colGroup.span=1; table.insertBefore(colGroup, refColGroup); dump("SCRIPT: inserted COLGROUP with span=1 width=200 as first colgroup in table\n"); @@ -44,6 +57,11 @@ function deleteColGroup() { dump("SCRIPT: deleted first COLGROUP\n"); } +function changeColGroupStyle() { + var colGroup = document.getElementsByTagName("COLGROUP")[0]; + colGroup.width="200"; + dump("SCRIPT: changed default width for first COLGROUP to 200\n"); +} function insertCol() { var table = document.getElementsByTagName("TABLE")[0]; @@ -69,6 +87,12 @@ function deleteCol() { dump("SCRIPT: deleted first COL in first COLGROUP\n"); } +function changeColStyle() { + var col = document.getElementsByTagName("COL")[0]; + col.width="200"; + dump("SCRIPT: changed default width for first COL to 200\n"); +} + function insertRowGroup() { var table = document.getElementsByTagName("TABLE")[0]; @@ -106,6 +130,13 @@ function deleteRowGroup() { dump("SCRIPT: deleted first ROWGROUP\n"); } +function changeRowGroupStyle() { + var rowGroup = document.getElementsByTagName("TBODY")[0]; + rowGroup.align="right"; + dump("SCRIPT: changed default align for first ROWGROUP to right\n"); +} + + function insertRow() { var rg = document.getElementsByTagName("TBODY")[0]; @@ -141,7 +172,11 @@ function deleteRow() { dump("SCRIPT: deleted first ROW in first ROWGROUP\n"); } - +function changeRowStyle() { + var row = document.getElementsByTagName("TR")[0]; + row.align="right"; + dump("SCRIPT: changed default align for first ROW to right\n"); +} function insertCell() { @@ -171,6 +206,12 @@ function deleteCell() { dump("SCRIPT: deleted first CELL in first ROW\n"); } +function changeCellStyle() { + var cell = document.getElementsByTagName("TD")[0]; + cell.width="right"; + dump("SCRIPT: changed align for first CELL to right\n"); +} + function AddALot() { dump("\nSCRIPT: starting AddALot\n"); var table = document.getElementsByTagName("TABLE")[0]; @@ -203,8 +244,8 @@ function AddALot() { -delete removes the first object of - +delete removes the first object of [type]. +
@@ -241,10 +282,18 @@ delete removes the first object of
- +
+ + + + + + + + diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 62f07846e0a5..906598f6385f 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -2005,6 +2005,19 @@ HTMLStyleSheetImpl::AttributeChanged(nsIPresContext* aPresContext, render = PR_TRUE; } } + else if (tag == nsHTMLAtoms::caption || + tag == nsHTMLAtoms::table || + tag == nsHTMLAtoms::col || + tag == nsHTMLAtoms::colgroup || + tag == nsHTMLAtoms::tr || + tag == nsHTMLAtoms::tbody || + tag == nsHTMLAtoms::thead || + tag == nsHTMLAtoms::tfoot || + tag == nsHTMLAtoms::td || tag == nsHTMLAtoms::th) + { + restyle = PR_TRUE; + reflow = PR_TRUE; + } else { } diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index e8e315136794..7301aeadac2a 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -111,9 +111,17 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext, nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myColor, 0, 0); - + + //XXX: this could be calculated once and remembered + // get border padding values + nsMargin borderPadding; + const nsStyleSpacing* cellSpacing; + GetStyleData(eStyleStruct_Spacing , ((nsStyleStruct *&)cellSpacing)); + cellSpacing->CalcBorderPaddingFor(this, borderPadding); + nscoord contentWidth = mPass1DesiredSize.width - (borderPadding.left+borderPadding.right); + nscoord contentHeight = mPass1DesiredSize.height - (borderPadding.top+borderPadding.bottom); // empty cells do not render their border - if (0!=mPass1DesiredSize.width || 0!=mPass1DesiredSize.height) + if (0width = 0; @@ -288,11 +298,33 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext& aPresContext, availSize.height -= topInset+bottomInset+margin.top+margin.bottom; // XXX Kipp added this hack - if (eReflowReason_Incremental == aReflowState.reason) { + if (eReflowReason_Incremental == aReflowState.reason) + { // XXX We *must* do this otherwise incremental reflow that's // passing through will not work right. nsIFrame* next; aReflowState.reflowCommand->GetNext(next); + + // if it is a StyleChanged reflow targeted at this cell frame, + // handle that here + // first determine if this frame is the target or not + nsIFrame *target=nsnull; + rv = aReflowState.reflowCommand->GetTarget(target); + if ((PR_TRUE==NS_SUCCEEDED(rv)) && (nsnull!=target)) + { + if (this==target) + { + nsIReflowCommand::ReflowType type; + aReflowState.reflowCommand->GetType(type); + if (nsIReflowCommand::StyleChanged==type) + { + nsresult rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); + aStatus = NS_FRAME_COMPLETE; + return rv; + } + } + } + // if any of these conditions are not true, we just pass the reflow command down } // Try to reflow the child into the available space. It might not @@ -411,6 +443,40 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext& aPresContext, return NS_OK; } +NS_METHOD nsTableCellFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebug) printf("Cell IR: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + nsTableFrame* tableFrame=nsnull; + rv = nsTableFrame::GetTableFrame(this, tableFrame); + if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) + { + tableFrame->InvalidateCellMap(); + tableFrame->InvalidateFirstPassCache(); + } + + // we are obligated to pass along the reflow command to our children before doing anything else + /* + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState, + aReflowState.maxSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } + */ + return rv; +} + NS_METHOD nsTableCellFrame::CreateContinuingFrame(nsIPresContext& aPresContext, nsIFrame* aParent, diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index 3e314054a10b..14c27548d231 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -199,6 +199,11 @@ protected: void MapHTMLBorderStyle(nsIPresContext* aPresContext,nsStyleSpacing& aSpacingStyle, nscoord aBorderWidth); PRBool ConvertToPixelValue(nsHTMLValue& aValue, PRInt32 aDefault, PRInt32& aResult); + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + protected: /** the starting column for this cell */ diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp index f2ead478ef8c..334cf34babc5 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -315,9 +315,7 @@ NS_METHOD nsTableColGroupFrame::IR_TargetIsMe(nsIPresContext& aPresCont break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TCGF IR: StyleChanged not implemented.\n"); + rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : @@ -457,6 +455,40 @@ NS_METHOD nsTableColGroupFrame::IR_ColRemoved(nsIPresContext& aPresCont return rv; } +NS_METHOD nsTableColGroupFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebugIR) printf("TIF IR: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + nsTableFrame* tableFrame=nsnull; + rv = nsTableFrame::GetTableFrame(this, tableFrame); + if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) + { + tableFrame->InvalidateColumnCache(); + tableFrame->InvalidateFirstPassCache(); + } + + /* + // we are obligated to pass along the reflow command to our children before doing anything else + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState, + aReflowState.maxSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } +*/ + return rv; +} + NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, diff --git a/layout/tables/nsTableColGroupFrame.h b/layout/tables/nsTableColGroupFrame.h index f81dc7f27dbc..8142dd81d514 100644 --- a/layout/tables/nsTableColGroupFrame.h +++ b/layout/tables/nsTableColGroupFrame.h @@ -140,6 +140,12 @@ protected: nsReflowStatus& aStatus, nsTableColFrame * aDeletedFrame); + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + NS_IMETHOD IR_TargetIsChild(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index fd1abd59ff63..d5beb89f789d 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1613,7 +1613,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext, if (PR_FALSE==IsFirstPassValid()) { if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: first pass is invalid, rebuilding...\n"); - rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, aReflowState.reason, PR_TRUE); + nsReflowReason reason = aReflowState.reason; + if (eReflowReason_Initial!=reason) + reason = eReflowReason_Resize; + rv = ResizeReflowPass1(aPresContext, aDesiredSize, aReflowState, aStatus, nsnull, reason, PR_TRUE); if (NS_FAILED(rv)) return rv; needsRecalc=PR_TRUE; @@ -1749,6 +1752,7 @@ NS_METHOD nsTableFrame::ResizeReflowPass1(nsIPresContext& aPresContext, availSize, aReason); if (PR_TRUE==gsDebugIR) printf("\nTIF IR: Reflow Pass 1 of unknown frame %p of type %d with reason=%d\n", kidFrame, childDisplay->mDisplay, aReason); + // rv intentionally not set here ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, aStatus); continue; } @@ -1920,12 +1924,15 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, aReflowState.reflowState.reflowCommand->GetType(type); nsIFrame *objectFrame; aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame); - const nsStyleDisplay *childDisplay; - objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); + const nsStyleDisplay *childDisplay=nsnull; + if (nsnull!=objectFrame) + objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); if (PR_TRUE==gsDebugIR) printf("TIF IR: IncrementalReflow_TargetIsMe with type=%d\n", type); switch (type) { case nsIReflowCommand::FrameInserted : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) { rv = IR_ColGroupInserted(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -1943,6 +1950,8 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::FrameAppended : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) { rv = IR_ColGroupAppended(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -1961,10 +1970,14 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, /* case nsIReflowCommand::FrameReplaced : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); */ case nsIReflowCommand::FrameRemoved : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == childDisplay->mDisplay) { rv = IR_ColGroupRemoved(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -1982,9 +1995,7 @@ NS_METHOD nsTableFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TIF IR: StyleChanged not implemented.\n"); + rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : @@ -2201,6 +2212,36 @@ NS_METHOD nsTableFrame::IR_ColGroupRemoved(nsIPresContext& aPresContext, return rv; } +NS_METHOD nsTableFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + InnerTableReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebugIR) printf("TIF IR: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + // if something like border changes, we need to do pass1 again + // but if something like width changes, we just need to do pass2 + InvalidateFirstPassCache(); + + // we are obligated to pass along the reflow command to our children before doing anything else + /* + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState.reflowState, + aReflowState.availSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } + */ + return rv; +} + NS_METHOD nsTableFrame::IR_RowGroupInserted(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, InnerTableReflowState& aReflowState, @@ -2446,7 +2487,6 @@ void nsTableFrame::PlaceChild(nsIPresContext& aPresContext, * @return true if we successfully reflowed all the mapped children and false * otherwise, e.g. we pushed children to the next in flow */ - // XXX: this interface should change to pass in aStatus, return nsresult NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, InnerTableReflowState& aReflowState, @@ -2891,6 +2931,7 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext, // then the width attribute also acts as the width attribute for the entire column // if the cell has a colspan, the width is used provisionally, divided equally among // the spanned columns + if (PR_TRUE==gsDebug) printf("TIF SetCSFromCell: cell %p in row %p\n", aCellFrame, aRowFrame); if ((nsnull!=aCellFrame) && (nsnull!=aRowFrame)) { // get the cell style info @@ -2901,23 +2942,23 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext, // compute the width per column spanned PRInt32 colSpan = GetEffectiveColSpan(aCellFrame->GetColIndex(), aCellFrame); if (PR_TRUE==gsDebug) - printf("for col %d with colspan %d\n",aCellFrame->GetColIndex(), colSpan); + printf("TIF SetCSFromCell: for col %d with colspan %d\n",aCellFrame->GetColIndex(), colSpan); for (PRInt32 i=0; iGetColIndex(), colFrame); if (PR_TRUE==gsDebug) - printf(" for col %d\n",i+aCellFrame->GetColIndex()); + printf("TIF SetCSFromCell: for col %d\n",i+aCellFrame->GetColIndex()); if (nsTableColFrame::eWIDTH_SOURCE_CELL != colFrame->GetWidthSource()) { if (PR_TRUE==gsDebug) - printf(" width not yet set from a cell...\n"); + printf("TIF SetCSFromCell: width not yet set from a cell...\n"); if ((1==colSpan) || (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN != colFrame->GetWidthSource())) { if (PR_TRUE==gsDebug) - printf(" colspan was 1 or width was not set from a span\n"); + printf("TIF SetCSFromCell: colspan was 1 or width was not set from a span\n"); // get the column style and set the width attribute nsIStyleContext *colSC; colFrame->GetStyleContext(&aPresContext, colSC); @@ -2929,27 +2970,27 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext & aPresContext, nscoord width = cellPosition->mWidth.GetCoordValue(); colPosition->mWidth.SetCoordValue(width/colSpan); if (PR_TRUE==gsDebug) - printf(" col fixed width set to %d ", (width/colSpan)); + printf("TIF SetCSFromCell: col fixed width set to %d ", (width/colSpan)); } else { float width = cellPosition->mWidth.GetPercentValue(); colPosition->mWidth.SetPercentValue(width/colSpan); if (PR_TRUE==gsDebug) - printf(" col percent width set to %d ", (width/colSpan)); + printf("TIF SetCSFromCell: col percent width set to %d ", (width/colSpan)); } // set the column width-set-type if (1==colSpan) { colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL); if (PR_TRUE==gsDebug) - printf(" source=cell\n"); + printf(" source = CELL\n"); } else { colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN); if (PR_TRUE==gsDebug) - printf(" source=cell_with_span\n"); + printf(" source = SPAN\n"); } } } diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index fdb62807cb2e..a318c528a39c 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -361,6 +361,11 @@ protected: InnerTableReflowState& aReflowState, nsReflowStatus& aStatus, nsTableRowGroupFrame * aDeletedFrame); + + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + InnerTableReflowState& aReflowState, + nsReflowStatus& aStatus); NS_IMETHOD AdjustSiblingsAfterReflow(nsIPresContext& aPresContext, InnerTableReflowState& aReflowState, diff --git a/layout/tables/nsTableOuterFrame.cpp b/layout/tables/nsTableOuterFrame.cpp index e065eb8b884c..478abd827bf2 100644 --- a/layout/tables/nsTableOuterFrame.cpp +++ b/layout/tables/nsTableOuterFrame.cpp @@ -345,7 +345,9 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext& aPres nsHTMLReflowState captionReflowState(aPresContext, mCaptionFrame, aReflowState.reflowState, nsSize(mRect.width, - aReflowState.reflowState.maxSize.height)); + aReflowState.reflowState.maxSize.height), + aReflowState.reflowState.reason); + captionReflowState.reflowCommand=aReflowState.reflowState.reflowCommand; rv = ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState, aStatus); if (PR_TRUE==gsDebugIR) printf("TOF IR: caption reflow returned %d with width=%d height=%d, minCaptionWidth=%d\n", rv, captionSize.width, captionSize.height, captionMES.width); @@ -485,9 +487,8 @@ nsresult nsTableOuterFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TOF IR: StyleChanged not implemented.\n"); + if (PR_TRUE==gsDebugIR) printf("TOF IR: calling inner table reflow.\n"); + rv = IR_InnerTableReflow(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index 862db8ad1547..eadf0e37ec9b 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -687,15 +687,19 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, // Get the child's margins nsMargin margin; nscoord topMargin = 0; - if (aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK) { topMargin = margin.top; } - maxTopMargin = PR_MAX(margin.top, maxTopMargin); maxBottomMargin = PR_MAX(margin.bottom, maxBottomMargin); + // get border padding values + nsMargin borderPadding; + const nsStyleSpacing* cellSpacing; + kidFrame->GetStyleData(eStyleStruct_Spacing , ((nsStyleStruct *&)cellSpacing)); + cellSpacing->CalcBorderPaddingFor(kidFrame, borderPadding); + // 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 @@ -727,6 +731,9 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, kidSize.width = kidMaxElementSize.width; if (kidMaxElementSize.height>kidSize.height) kidSize.height = kidMaxElementSize.height; + kidSize.width += borderPadding.left+borderPadding.right; + kidSize.height += borderPadding.top+borderPadding.bottom; + kidMaxElementSize.SizeBy(borderPadding.left+borderPadding.right, borderPadding.top+borderPadding.bottom); ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize); ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize); NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "unexpected child reflow status"); @@ -900,12 +907,15 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext, aReflowState.reflowState.reflowCommand->GetType(type); nsIFrame *objectFrame; aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame); - const nsStyleDisplay *childDisplay; - objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); + const nsStyleDisplay *childDisplay=nsnull; + if (nsnull!=objectFrame) + objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); if (PR_TRUE==gsDebugIR) printf("TRF IR: IncrementalReflow_TargetIsMe with type=%d\n", type); switch (type) { case nsIReflowCommand::FrameInserted : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay) { rv = IR_CellInserted(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -918,6 +928,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::FrameAppended : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay) { rv = IR_CellAppended(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -935,6 +947,8 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext, */ case nsIReflowCommand::FrameRemoved : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_CELL == childDisplay->mDisplay) { rv = IR_CellRemoved(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -947,9 +961,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TRF IR: StyleChanged not implemented.\n"); + rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : @@ -1122,6 +1134,39 @@ NS_METHOD nsTableRowFrame::IR_CellRemoved(nsIPresContext& aPresContext, return rv; } +NS_METHOD nsTableRowFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebugIR) printf("Row: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + nsTableFrame* tableFrame=nsnull; + rv = nsTableFrame::GetTableFrame(this, tableFrame); + if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) + { + tableFrame->InvalidateFirstPassCache(); + } + + /* + // we are obligated to pass along the reflow command to our children before doing anything else + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState.reflowState, + aReflowState.availSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } + */ + return rv; +} + NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, RowReflowState& aReflowState, diff --git a/layout/tables/nsTableRowFrame.h b/layout/tables/nsTableRowFrame.h index 65cc7aded299..788c5a2c35a3 100644 --- a/layout/tables/nsTableRowFrame.h +++ b/layout/tables/nsTableRowFrame.h @@ -178,6 +178,11 @@ protected: nsReflowStatus& aStatus, nsTableCellFrame * aDeletedFrame); + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowReflowState& aReflowState, + nsReflowStatus& aStatus); + // row-specific methods void GetMinRowSpan(nsTableFrame *aTableFrame); diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 56611c5eef84..0f1eecc3f1dd 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -900,12 +900,15 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext, aReflowState.reflowState.reflowCommand->GetType(type); nsIFrame *objectFrame; aReflowState.reflowState.reflowCommand->GetChildFrame(objectFrame); - const nsStyleDisplay *childDisplay; - objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); + const nsStyleDisplay *childDisplay=nsnull; + if (nsnull!=objectFrame) + objectFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)childDisplay)); if (PR_TRUE==gsDebugIR) printf("TRGF IR: TargetIsMe with type=%d\n", type); switch (type) { case nsIReflowCommand::FrameInserted : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) { rv = IR_RowInserted(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -918,6 +921,8 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::FrameAppended : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) { rv = IR_RowAppended(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -935,6 +940,8 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext, */ case nsIReflowCommand::FrameRemoved : + NS_ASSERTION(nsnull!=objectFrame, "bad objectFrame"); + NS_ASSERTION(nsnull!=childDisplay, "bad childDisplay"); if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) { rv = IR_RowRemoved(aPresContext, aDesiredSize, aReflowState, aStatus, @@ -947,9 +954,7 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsMe(nsIPresContext& aPresContext, break; case nsIReflowCommand::StyleChanged : - NS_NOTYETIMPLEMENTED("unimplemented reflow command type"); - rv = NS_ERROR_NOT_IMPLEMENTED; - if (PR_TRUE==gsDebugIR) printf("TRGF IR: StyleChanged not implemented.\n"); + rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aStatus); break; case nsIReflowCommand::ContentChanged : @@ -1178,6 +1183,39 @@ NS_METHOD nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext& aPresConte return rv; } +NS_METHOD nsTableRowGroupFrame::IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowGroupReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (PR_TRUE==gsDebugIR) printf("TRGF: IR_StyleChanged for frame %p\n", this); + nsresult rv = NS_OK; + // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here + // XXX: we can optimize this when we know which style attribute changed + nsTableFrame* tableFrame=nsnull; + rv = nsTableFrame::GetTableFrame(this, tableFrame); + if ((NS_SUCCEEDED(rv)) && (nsnull!=tableFrame)) + { + tableFrame->InvalidateFirstPassCache(); + } + + /* + // we are obligated to pass along the reflow command to our children before doing anything else + nsIFrame *childFrame = mFirstChild; + while (nsnull!=childFrame) + { + nsHTMLReflowState childReflowState(aPresContext, childFrame, aReflowState.reflowState, + aReflowState.availSize, eReflowReason_Incremental); + rv = ReflowChild(childFrame, aPresContext, aDesiredSize, childReflowState, aStatus); + if (NS_FAILED(rv)) + break; + // the returned desired size is irrelevant, because we'll do a resize reflow in a moment + childFrame->GetNextSibling(childFrame); + } + */ + return rv; +} + NS_METHOD nsTableRowGroupFrame::CreateContinuingFrame(nsIPresContext& aPresContext, nsIFrame* aParent, diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h index 2967a9d947a7..16bb920c91fb 100644 --- a/layout/tables/nsTableRowGroupFrame.h +++ b/layout/tables/nsTableRowGroupFrame.h @@ -168,6 +168,11 @@ protected: nsReflowStatus& aStatus, nsTableRowFrame * aDeletedFrame); + NS_IMETHOD IR_StyleChanged(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowGroupReflowState& aReflowState, + nsReflowStatus& aStatus); + NS_IMETHOD DidAppendRow(nsTableRowFrame *aRowFrame); PRBool NoRowsFollow();
cell content