From d50c80150f505fc8f6c6b85d07c2913378b9ef7e Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 25 May 2017 13:39:44 -0400 Subject: [PATCH] Bug 1364360 part 3. Don't flush layout when setting scrollTop to 0. r=ehsan --- dom/base/Element.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 8d60587347d1..f194e5bcf22c 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -855,7 +855,15 @@ Element::ScrollTop() void Element::SetScrollTop(int32_t aScrollTop) { - nsIScrollableFrame* sf = GetScrollFrame(); + // When aScrollTop is 0, we don't need to flush layout to scroll to that + // point; we know 0 is always in range. At least we think so... But we do + // need to flush frames so we ensure we find the right scrollable frame if + // there is one. + // + // If aScrollTop is nonzero, we need to flush layout because we need to figure + // out what our real scrollTopMax is. + FlushType flushType = aScrollTop == 0 ? FlushType::Frames : FlushType::Layout; + nsIScrollableFrame* sf = GetScrollFrame(nullptr, flushType); if (sf) { nsIScrollableFrame::ScrollMode scrollMode = nsIScrollableFrame::INSTANT; if (sf->GetScrollbarStyles().mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_SMOOTH) { @@ -877,6 +885,9 @@ Element::ScrollLeft() void Element::SetScrollLeft(int32_t aScrollLeft) { + // We can't assume things here based on the value of aScrollLeft, because + // depending on our direction and layout 0 may or may not be in our scroll + // range. So we need to flush layout no matter what. nsIScrollableFrame* sf = GetScrollFrame(); if (sf) { nsIScrollableFrame::ScrollMode scrollMode = nsIScrollableFrame::INSTANT;