From b3478c6ec2d02cbd9043e9883dcb836aa1498e03 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Tue, 21 Mar 2017 02:12:41 +0100 Subject: [PATCH] Bug 1343795 - Hold a strong ref on the Selection while calling ScrollIntoView with SCROLL_DO_FLUSH. r=smaug MozReview-Commit-ID: 5C10dmT0bI9 --- layout/generic/Selection.h | 9 ++++++--- layout/generic/nsSelection.cpp | 9 +++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/layout/generic/Selection.h b/layout/generic/Selection.h index ef3ce0fda57d..bb3e3b6e49f9 100644 --- a/layout/generic/Selection.h +++ b/layout/generic/Selection.h @@ -101,12 +101,15 @@ public: enum { SCROLL_SYNCHRONOUS = 1<<1, SCROLL_FIRST_ANCESTOR_ONLY = 1<<2, - SCROLL_DO_FLUSH = 1<<3, + SCROLL_DO_FLUSH = 1<<3, // only matters if SCROLL_SYNCHRONOUS is passed too SCROLL_OVERFLOW_HIDDEN = 1<<5, SCROLL_FOR_CARET_MOVE = 1<<6 }; - // aDoFlush only matters if aIsSynchronous is true. If not, we'll just flush - // when the scroll event fires so we make sure to scroll to the right place. + // If aFlags doesn't contain SCROLL_SYNCHRONOUS, then we'll flush when + // the scroll event fires so we make sure to scroll to the right place. + // Otherwise, if SCROLL_DO_FLUSH is also in aFlags, then this method will + // flush layout and you MUST hold a strong ref on 'this' for the duration + // of this call. This might destroy arbitrary layout objects. nsresult ScrollIntoView(SelectionRegion aRegion, nsIPresShell::ScrollAxis aVertical = nsIPresShell::ScrollAxis(), diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index 58d18b46d64b..c1e213453933 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -1974,10 +1974,9 @@ nsFrameSelection::ScrollSelectionIntoView(SelectionType aSelectionType, // After ScrollSelectionIntoView(), the pending notifications might be // flushed and PresShell/PresContext/Frames may be dead. See bug 418470. - return mDomSelections[index]->ScrollIntoView(aRegion, - verticalScroll, - nsIPresShell::ScrollAxis(), - flags); + RefPtr sel = mDomSelections[index]; + return sel->ScrollIntoView(aRegion, verticalScroll, + nsIPresShell::ScrollAxis(), flags); } nsresult @@ -6171,6 +6170,8 @@ Selection::ScrollSelectionIntoViewEvent::Run() int32_t flags = Selection::SCROLL_DO_FLUSH | Selection::SCROLL_SYNCHRONOUS; + Selection* sel = mSelection; // workaround to satisfy static analysis + RefPtr kungFuDeathGrip(sel); mSelection->mScrollEvent.Forget(); mSelection->ScrollIntoView(mRegion, mVerticalScroll, mHorizontalScroll, mFlags | flags);