diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index a6945552b827..c9dc5d796cf2 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -2390,8 +2390,6 @@ nsChangeHint nsStyleDisplay::CalcDifference( const nsStyleDisplay& aNewData, const nsStylePosition& aOldPosition) const { if (mDisplay != aNewData.mDisplay || mContain != aNewData.mContain || (mFloat == StyleFloat::None) != (aNewData.mFloat == StyleFloat::None) || - mScrollBehavior != aNewData.mScrollBehavior || - mScrollSnapType != aNewData.mScrollSnapType || mTopLayer != aNewData.mTopLayer || mResize != aNewData.mResize) { return nsChangeHint_ReconstructFrame; } @@ -2447,6 +2445,13 @@ nsChangeHint nsStyleDisplay::CalcDifference( // FIXME: Bug 1530253 Support re-snapping when scroll-snap-align changes. hint |= nsChangeHint_NeutralChange; } + if (mScrollSnapType != aNewData.mScrollSnapType) { + // FIXME: Bug 1530253 Support re-snapping when scroll-snap-type changes. + hint |= nsChangeHint_RepaintFrame; + } + if (mScrollBehavior != aNewData.mScrollBehavior) { + hint |= nsChangeHint_NeutralChange; + } if (mOverflowX != aNewData.mOverflowX || mOverflowY != aNewData.mOverflowY) { const bool isScrollable = IsScrollableOverflow(); @@ -2492,22 +2497,6 @@ nsChangeHint nsStyleDisplay::CalcDifference( } } - /* Note: When mScrollBehavior or mScrollSnapType are changed, - * nsChangeHint_NeutralChange is not sufficient to enter - * nsCSSFrameConstructor::PropagateScrollToViewport. By using the same hint as - * used when the overflow css property changes, nsChangeHint_ReconstructFrame, - * PropagateScrollToViewport will be called. - * - * The scroll-behavior css property is not expected to change often (the - * CSSOM-View DOM methods are likely to be used in those cases); however, - * if this does become common perhaps a faster-path might be worth while. - * - * FIXME(emilio): Can we do what we do for overflow changes? - * - * FIXME(emilio): These properties no longer propagate from the body to the - * viewport. - */ - if (mFloat != aNewData.mFloat) { // Changing which side we're floating on (float:none was handled above). hint |= nsChangeHint_ReflowHintsForFloatAreaChange; diff --git a/layout/style/test/test_dynamic_change_causing_reflow.html b/layout/style/test/test_dynamic_change_causing_reflow.html index 3fc67391f7e0..b047847f02d6 100644 --- a/layout/style/test/test_dynamic_change_causing_reflow.html +++ b/layout/style/test/test_dynamic_change_causing_reflow.html @@ -410,6 +410,78 @@ const gTestcases = [ expectConstruction: true, expectReflow: true, }, + // changing scroll-behavior should not cause reflow or frame construction + { + elem: document.documentElement, + /* beforeStyle: implicitly 'scroll-behavior: auto' */ + afterStyle: "scroll-behavior: smooth", + expectConstruction: false, + expectReflow: false, + }, + { + elem: document.documentElement, + beforeStyle: "scroll-behavior: smooth", + afterStyle: "scroll-behavior: auto", + expectConstruction: false, + expectReflow: false, + }, + { + elem: document.body, + /* beforeStyle: implicitly 'scroll-behavior: auto' */ + afterStyle: "scroll-behavior: smooth", + expectConstruction: false, + expectReflow: false, + }, + { + elem: document.body, + beforeStyle: "scroll-behavior: smooth", + afterStyle: "scroll-behavior: auto", + expectConstruction: false, + expectReflow: false, + }, + // changing scroll-snap-type should not cause reflow or frame construction + { + elem: document.documentElement, + /* beforeStyle: implicitly 'scroll-snap-type: none' */ + afterStyle: "scroll-snap-type: y mandatory", + expectConstruction: false, + expectReflow: false, + }, + { + elem: document.documentElement, + /* beforeStyle: implicitly 'scroll-snap-type: none' */ + afterStyle: "scroll-snap-type: x proximity", + expectConstruction: false, + expectReflow: false, + }, + { + elem: document.documentElement, + beforeStyle: "scroll-snap-type: y mandatory", + afterStyle: "scroll-snap-type: none", + expectConstruction: false, + expectReflow: false, + }, + { + elem: document.body, + /* beforeStyle: implicitly 'scroll-snap-type: none' */ + afterStyle: "scroll-snap-type: y mandatory", + expectConstruction: false, + expectReflow: false, + }, + { + elem: document.body, + /* beforeStyle: implicitly 'scroll-snap-type: none' */ + afterStyle: "scroll-snap-type: x proximity", + expectConstruction: false, + expectReflow: false, + }, + { + elem: document.body, + beforeStyle: "scroll-snap-type: y mandatory", + afterStyle: "scroll-snap-type: none", + expectConstruction: false, + expectReflow: false, + }, ]; // Helper function to let us call either "is" or "isnot" & assemble