diff --git a/layout/html/table/src/nsTableOuterFrame.cpp b/layout/html/table/src/nsTableOuterFrame.cpp index 9e7aa1fbd0fc..7c47af9cadbd 100644 --- a/layout/html/table/src/nsTableOuterFrame.cpp +++ b/layout/html/table/src/nsTableOuterFrame.cpp @@ -1273,9 +1273,23 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext, // pass along the reflow command to the inner table, requesting the same info in our flags nsHTMLReflowMetrics innerMet(aOuterMet.maxElementSize, aOuterMet.mFlags); + // If the incremental reflow command is a StyleChanged reflow and + // it's target is the current frame, then make sure we send + // StyleChange reflow reasons down to the children so that they + // don't over-optimize their reflow. + nsReflowReason ReflowReason = eReflowReason_Incremental; + nsIFrame* target = nsnull; + aOuterRS.reflowCommand->GetTarget(target); + if (this == target) { + nsIReflowCommand::ReflowType type; + aOuterRS.reflowCommand->GetType(type); + if (nsIReflowCommand::StyleChanged == type) { + ReflowReason = eReflowReason_StyleChange; + } + } nsresult rv = OuterReflowChild(aPresContext, mInnerTableFrame, aOuterRS, innerMet, nsnull, innerSize, innerMargin, innerMarginNoAuto, innerPadding, - eReflowReason_Incremental, aStatus); + ReflowReason, aStatus); if (NS_FAILED(rv)) return rv; nsPoint innerOrigin(0,0); @@ -1298,9 +1312,12 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext, nscoord availWidth = GetCaptionAvailWidth(aPresContext, mCaptionFrame, aOuterRS, &innerSize.width, &innerMarginNoAuto); nsReflowStatus capStatus; // don't let the caption cause incomplete + if (ReflowReason == eReflowReason_Incremental) { + ReflowReason = eReflowReason_Resize; + } rv = OuterReflowChild(aPresContext, mCaptionFrame, aOuterRS, captionMet, &availWidth, captionSize, captionMargin, captionMarginNoAuto, - ignorePadding, eReflowReason_Resize, capStatus); + ignorePadding, ReflowReason, capStatus); if (NS_FAILED(rv)) return rv; GetCaptionOrigin(aPresContext, captionSide, containSize, innerSize, diff --git a/layout/html/table/src/nsTableRowFrame.cpp b/layout/html/table/src/nsTableRowFrame.cpp index c03cf09aab77..6411bf884df7 100644 --- a/layout/html/table/src/nsTableRowFrame.cpp +++ b/layout/html/table/src/nsTableRowFrame.cpp @@ -901,6 +901,23 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, nsTableFrame* tableFirstInFlow = (nsTableFrame*)tableFrame->GetFirstInFlow(); PRBool isAutoLayout = tableFrame->IsAutoLayout(); PRBool needToNotifyTable = PR_TRUE; + // If the incremental reflow command is a StyleChanged reflow and + // it's target is the current frame, then make sure we send + // StyleChange reflow reasons down to the children so that they + // don't over-optimize their reflow. + + nsIFrame* target = nsnull; + PRBool notifyStyleChange = PR_FALSE; + if (eReflowReason_Incremental == aReflowState.reason) { + aReflowState.reflowCommand->GetTarget(target); + if (this == target) { + nsIReflowCommand::ReflowType type; + aReflowState.reflowCommand->GetType(type); + if (nsIReflowCommand::StyleChanged == type) { + notifyStyleChange = PR_TRUE; + } + } + } // Reflow each of our existing cell frames nsIFrame* kidFrame = iter.First(); while (kidFrame) { @@ -962,7 +979,8 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, (eReflowReason_StyleChange == aReflowState.reason) || isPaginated || (aReflowState.mFlags.mSpecialTableReflow && cellFrame->NeedSpecialReflow()) || - HasPctHeight()) { + HasPctHeight() || + notifyStyleChange ){ // Reflow the cell to fit the available width, height nsSize kidAvailSize(availColWidth, aReflowState.availableHeight); nsReflowReason reason = eReflowReason_Resize; @@ -977,6 +995,10 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, reason = eReflowReason_StyleChange; cellToWatch = PR_TRUE; } + else if (notifyStyleChange) { + reason = eReflowReason_StyleChange; + cellToWatch = PR_TRUE; + } if (cellToWatch) { cellFrame->DidSetStyleContext(aPresContext); // XXX check this if (!tablePrevInFlow && isAutoLayout) { @@ -1122,11 +1144,10 @@ nsTableRowFrame::IR_TargetIsMe(nsIPresContext* aPresContext, nsIReflowCommand::ReflowType type; aReflowState.reflowCommand->GetType(type); switch (type) { - case nsIReflowCommand::ReflowDirty: { + case nsIReflowCommand::ReflowDirty: // Reflow the dirty child frames. Typically this is newly added frames. rv = ReflowChildren(aPresContext, aDesiredSize, aReflowState, aTableFrame, aStatus, PR_TRUE); break; - } case nsIReflowCommand::StyleChanged : rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aTableFrame, aStatus); break; @@ -1154,6 +1175,7 @@ nsTableRowFrame::IR_StyleChanged(nsIPresContext* aPresContext, // 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 aTableFrame.SetNeedStrategyInit(PR_TRUE); + rv = ReflowChildren(aPresContext, aDesiredSize, aReflowState, aTableFrame, aStatus, PR_FALSE); return rv; } diff --git a/layout/html/table/src/nsTableRowGroupFrame.cpp b/layout/html/table/src/nsTableRowGroupFrame.cpp index 9a760bb82a03..6125cfde5089 100644 --- a/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -411,8 +411,25 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext, // it wants. We'll deal with splitting later after we've computed the row // heights, taking into account cells with row spans... kidAvailSize.height = NS_UNCONSTRAINEDSIZE; - nsReflowReason reason = (frameState & NS_FRAME_FIRST_REFLOW) - ? eReflowReason_Initial : aReflowState.reason; + // If the incremental reflow command is a StyleChanged reflow and + // it's target is the current frame, then make sure we send + // StyleChange reflow reasons down to the children so that they + // don't over-optimize their reflow. + nsIFrame* target = nsnull; + nsReflowReason reason = aReflowState.reason; + if (eReflowReason_Incremental == aReflowState.reason) { + aReflowState.reflowState.reflowCommand->GetTarget(target); + if (this == target) { + nsIReflowCommand::ReflowType type; + aReflowState.reflowState.reflowCommand->GetType(type); + if (nsIReflowCommand::StyleChanged == type) { + reason = eReflowReason_StyleChange; + } + } + } + if (frameState & NS_FRAME_FIRST_REFLOW) { + reason = eReflowReason_Initial; + } nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame, kidAvailSize, reason); @@ -1590,6 +1607,12 @@ nsTableRowGroupFrame::IR_StyleChanged(nsIPresContext* aPresContext, // 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 aReflowState.tableFrame->SetNeedStrategyInit(PR_TRUE); + nsRowGroupReflowState state(aReflowState); + nsTableRowFrame* firstRowReflowed; + rv = ReflowChildren(aPresContext, aDesiredSize, state, aStatus, + nsnull, PR_FALSE, &firstRowReflowed); + CalculateRowHeights(aPresContext, aDesiredSize, aReflowState.reflowState, firstRowReflowed); + return rv; } diff --git a/layout/tables/nsTableOuterFrame.cpp b/layout/tables/nsTableOuterFrame.cpp index 9e7aa1fbd0fc..7c47af9cadbd 100644 --- a/layout/tables/nsTableOuterFrame.cpp +++ b/layout/tables/nsTableOuterFrame.cpp @@ -1273,9 +1273,23 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext, // pass along the reflow command to the inner table, requesting the same info in our flags nsHTMLReflowMetrics innerMet(aOuterMet.maxElementSize, aOuterMet.mFlags); + // If the incremental reflow command is a StyleChanged reflow and + // it's target is the current frame, then make sure we send + // StyleChange reflow reasons down to the children so that they + // don't over-optimize their reflow. + nsReflowReason ReflowReason = eReflowReason_Incremental; + nsIFrame* target = nsnull; + aOuterRS.reflowCommand->GetTarget(target); + if (this == target) { + nsIReflowCommand::ReflowType type; + aOuterRS.reflowCommand->GetType(type); + if (nsIReflowCommand::StyleChanged == type) { + ReflowReason = eReflowReason_StyleChange; + } + } nsresult rv = OuterReflowChild(aPresContext, mInnerTableFrame, aOuterRS, innerMet, nsnull, innerSize, innerMargin, innerMarginNoAuto, innerPadding, - eReflowReason_Incremental, aStatus); + ReflowReason, aStatus); if (NS_FAILED(rv)) return rv; nsPoint innerOrigin(0,0); @@ -1298,9 +1312,12 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext, nscoord availWidth = GetCaptionAvailWidth(aPresContext, mCaptionFrame, aOuterRS, &innerSize.width, &innerMarginNoAuto); nsReflowStatus capStatus; // don't let the caption cause incomplete + if (ReflowReason == eReflowReason_Incremental) { + ReflowReason = eReflowReason_Resize; + } rv = OuterReflowChild(aPresContext, mCaptionFrame, aOuterRS, captionMet, &availWidth, captionSize, captionMargin, captionMarginNoAuto, - ignorePadding, eReflowReason_Resize, capStatus); + ignorePadding, ReflowReason, capStatus); if (NS_FAILED(rv)) return rv; GetCaptionOrigin(aPresContext, captionSide, containSize, innerSize, diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index c03cf09aab77..6411bf884df7 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -901,6 +901,23 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, nsTableFrame* tableFirstInFlow = (nsTableFrame*)tableFrame->GetFirstInFlow(); PRBool isAutoLayout = tableFrame->IsAutoLayout(); PRBool needToNotifyTable = PR_TRUE; + // If the incremental reflow command is a StyleChanged reflow and + // it's target is the current frame, then make sure we send + // StyleChange reflow reasons down to the children so that they + // don't over-optimize their reflow. + + nsIFrame* target = nsnull; + PRBool notifyStyleChange = PR_FALSE; + if (eReflowReason_Incremental == aReflowState.reason) { + aReflowState.reflowCommand->GetTarget(target); + if (this == target) { + nsIReflowCommand::ReflowType type; + aReflowState.reflowCommand->GetType(type); + if (nsIReflowCommand::StyleChanged == type) { + notifyStyleChange = PR_TRUE; + } + } + } // Reflow each of our existing cell frames nsIFrame* kidFrame = iter.First(); while (kidFrame) { @@ -962,7 +979,8 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, (eReflowReason_StyleChange == aReflowState.reason) || isPaginated || (aReflowState.mFlags.mSpecialTableReflow && cellFrame->NeedSpecialReflow()) || - HasPctHeight()) { + HasPctHeight() || + notifyStyleChange ){ // Reflow the cell to fit the available width, height nsSize kidAvailSize(availColWidth, aReflowState.availableHeight); nsReflowReason reason = eReflowReason_Resize; @@ -977,6 +995,10 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, reason = eReflowReason_StyleChange; cellToWatch = PR_TRUE; } + else if (notifyStyleChange) { + reason = eReflowReason_StyleChange; + cellToWatch = PR_TRUE; + } if (cellToWatch) { cellFrame->DidSetStyleContext(aPresContext); // XXX check this if (!tablePrevInFlow && isAutoLayout) { @@ -1122,11 +1144,10 @@ nsTableRowFrame::IR_TargetIsMe(nsIPresContext* aPresContext, nsIReflowCommand::ReflowType type; aReflowState.reflowCommand->GetType(type); switch (type) { - case nsIReflowCommand::ReflowDirty: { + case nsIReflowCommand::ReflowDirty: // Reflow the dirty child frames. Typically this is newly added frames. rv = ReflowChildren(aPresContext, aDesiredSize, aReflowState, aTableFrame, aStatus, PR_TRUE); break; - } case nsIReflowCommand::StyleChanged : rv = IR_StyleChanged(aPresContext, aDesiredSize, aReflowState, aTableFrame, aStatus); break; @@ -1154,6 +1175,7 @@ nsTableRowFrame::IR_StyleChanged(nsIPresContext* aPresContext, // 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 aTableFrame.SetNeedStrategyInit(PR_TRUE); + rv = ReflowChildren(aPresContext, aDesiredSize, aReflowState, aTableFrame, aStatus, PR_FALSE); return rv; } diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 9a760bb82a03..6125cfde5089 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -411,8 +411,25 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext, // it wants. We'll deal with splitting later after we've computed the row // heights, taking into account cells with row spans... kidAvailSize.height = NS_UNCONSTRAINEDSIZE; - nsReflowReason reason = (frameState & NS_FRAME_FIRST_REFLOW) - ? eReflowReason_Initial : aReflowState.reason; + // If the incremental reflow command is a StyleChanged reflow and + // it's target is the current frame, then make sure we send + // StyleChange reflow reasons down to the children so that they + // don't over-optimize their reflow. + nsIFrame* target = nsnull; + nsReflowReason reason = aReflowState.reason; + if (eReflowReason_Incremental == aReflowState.reason) { + aReflowState.reflowState.reflowCommand->GetTarget(target); + if (this == target) { + nsIReflowCommand::ReflowType type; + aReflowState.reflowState.reflowCommand->GetType(type); + if (nsIReflowCommand::StyleChanged == type) { + reason = eReflowReason_StyleChange; + } + } + } + if (frameState & NS_FRAME_FIRST_REFLOW) { + reason = eReflowReason_Initial; + } nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame, kidAvailSize, reason); @@ -1590,6 +1607,12 @@ nsTableRowGroupFrame::IR_StyleChanged(nsIPresContext* aPresContext, // 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 aReflowState.tableFrame->SetNeedStrategyInit(PR_TRUE); + nsRowGroupReflowState state(aReflowState); + nsTableRowFrame* firstRowReflowed; + rv = ReflowChildren(aPresContext, aDesiredSize, state, aStatus, + nsnull, PR_FALSE, &firstRowReflowed); + CalculateRowHeights(aPresContext, aDesiredSize, aReflowState.reflowState, firstRowReflowed); + return rv; }