diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp index 1c8c4b76fe2a..517696ecec76 100644 --- a/layout/generic/ReflowInput.cpp +++ b/layout/generic/ReflowInput.cpp @@ -522,9 +522,34 @@ void ReflowInput::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameType) { const WritingMode wm = mWritingMode; // just a shorthand + // We should report that we have a resize in the inline dimension if + // *either* the border-box size or the content-box size in that + // dimension has changed. It might not actually be necessary to do + // this if the border-box size has changed and the content-box size + // has not changed, but since we've historically used the flag to mean + // border-box size change, continue to do that. (It's possible for + // the content-box size to change without a border-box size change or + // a style change given (1) a fixed width (possibly fixed by max-width + // or min-width), (2) box-sizing:border-box or padding-box, and + // (3) percentage padding.) + // + // However, we don't actually have the information at this point to + // tell whether the content-box size has changed, since both style + // data and the UsedPaddingProperty() have already been updated. So, + // instead, we explicitly check for the case where it's possible for + // the content-box size to have changed without either (a) a change in + // the border-box size or (b) an nsChangeHint_NeedDirtyReflow change + // hint due to change in border or padding. Thus we test using the + // conditions from the previous paragraph, except without testing (1) + // since it's complicated to test properly and less likely to help + // with optimizing cases away. bool isIResize = + // is the border-box resizing? mFrame->ISize(wm) != - ComputedISize() + ComputedLogicalBorderPadding().IStartEnd(wm); + ComputedISize() + ComputedLogicalBorderPadding().IStartEnd(wm) || + // or is the content-box resizing? (see comment above) + (mStylePosition->mBoxSizing != StyleBoxSizing::Content && + mStylePadding->IsWidthDependent()); if ((mFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT) && nsLayoutUtils::FontSizeInflationEnabled(aPresContext)) { diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index dd62b077eca5..500a795c854b 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -336,6 +336,10 @@ nsStylePadding::CalcDifference(const nsStylePadding& aNewData) const // to force children to reflow so that we can reposition them, since their // offsets are from our frame bounds but our content rect's position within // those bounds is moving. + // FIXME: It would be good to return a weaker hint here that doesn't + // force reflow of all descendants, but the hint would need to force + // reflow of the frame's children (see how + // ReflowInput::InitResizeFlags initializes the inline-resize flag). return NS_STYLE_HINT_REFLOW & ~nsChangeHint_ClearDescendantIntrinsics; } @@ -470,8 +474,13 @@ nsStyleBorder::Destroy(nsPresContext* aContext) { nsChangeHint nsStyleBorder::CalcDifference(const nsStyleBorder& aNewData) const { - // XXXbz we should be able to return a more specific change hint for - // at least GetComputedBorder() differences... + // FIXME: XXXbz: As in nsStylePadding::CalcDifference, many of these + // differences should not need to clear descendant intrinsics. + // FIXME: It would be good to return a weaker hint for the + // GetComputedBorder() differences (and perhaps others) that doesn't + // force reflow of all descendants, but the hint would need to force + // reflow of the frame's children (see how + // ReflowInput::InitResizeFlags initializes the inline-resize flag). if (mTwipsPerPixel != aNewData.mTwipsPerPixel || GetComputedBorder() != aNewData.GetComputedBorder() || mFloatEdge != aNewData.mFloatEdge ||