From 56a1f1002d9bd3b7f6d95573d06116322aeb22be Mon Sep 17 00:00:00 2001 From: "roc+%cs.cmu.edu" Date: Fri, 23 Jul 2004 21:39:47 +0000 Subject: [PATCH] Bug 217120. Always make an attempt to scroll to history position after restoring scroll position in EndLoad, just in case no reflows happen again. r+sr=dbaron git-svn-id: svn://10.0.0.236/trunk@159746 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/nsPresShell.cpp | 7 +++++++ .../layout/base/public/nsIScrollableFrame.h | 9 +++++++++ mozilla/layout/generic/nsGfxScrollFrame.cpp | 10 +++++++++- mozilla/layout/generic/nsGfxScrollFrame.h | 10 ++++++++++ mozilla/layout/generic/nsIScrollableFrame.h | 9 +++++++++ .../layout/html/base/src/nsGfxScrollFrame.cpp | 10 +++++++++- .../layout/html/base/src/nsGfxScrollFrame.h | 10 ++++++++++ mozilla/layout/html/base/src/nsPresShell.cpp | 7 +++++++ .../layout/xul/base/src/nsScrollBoxFrame.cpp | 20 ++++++++++--------- .../layout/xul/base/src/nsScrollBoxFrame.h | 2 ++ 10 files changed, 83 insertions(+), 11 deletions(-) diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index c015b49fb47..a7c57957407 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -3639,6 +3639,13 @@ PresShell::EndLoad(nsIDocument *aDocument) GetRootScrollFrame(mPresContext, rootFrame, &scrollFrame); if (scrollFrame) { FrameManager()->RestoreFrameStateFor(scrollFrame, historyState, nsIStatefulFrame::eDocumentScrollState); + + nsIScrollableFrame* scrollableFrame; + CallQueryInterface(scrollFrame, &scrollableFrame); + NS_ASSERTION(scrollableFrame, "RootScrollFrame is not scrollable?"); + if (scrollableFrame) { + scrollableFrame->ScrollToRestoredPosition(); + } } } diff --git a/mozilla/layout/base/public/nsIScrollableFrame.h b/mozilla/layout/base/public/nsIScrollableFrame.h index 7ad07b3f290..35f9a33ba8a 100644 --- a/mozilla/layout/base/public/nsIScrollableFrame.h +++ b/mozilla/layout/base/public/nsIScrollableFrame.h @@ -134,6 +134,15 @@ public: NS_IMETHOD CurPosAttributeChanged(nsIPresContext* aPresContext, nsIContent* aChild, PRInt32 aModType) = 0; + + /** + * This tells the scroll frame to try scrolling to the scroll + * position that was restored from the history. This must be called + * at least once after state has been restored. It is called by the + * scrolled frame itself during reflow, but sometimes state can be + * restored after reflows are done... + */ + virtual void ScrollToRestoredPosition() = 0; }; #endif diff --git a/mozilla/layout/generic/nsGfxScrollFrame.cpp b/mozilla/layout/generic/nsGfxScrollFrame.cpp index c4e2f49fda3..2eea2043dc2 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.cpp +++ b/mozilla/layout/generic/nsGfxScrollFrame.cpp @@ -49,6 +49,7 @@ #include "nsHTMLContainerFrame.h" #include "nsWidgetsCID.h" #include "nsGfxScrollFrame.h" +#include "nsScrollBoxFrame.h" #include "nsLayoutAtoms.h" #include "nsXULAtoms.h" #include "nsHTMLAtoms.h" @@ -1244,7 +1245,14 @@ nsGfxScrollFrameInner::GetScrollPreference() const } } -void nsGfxScrollFrameInner::ReloadChildFrames() +void +nsGfxScrollFrameInner::ScrollToRestoredPosition() +{ + NS_STATIC_CAST(nsScrollBoxFrame*, mScrollAreaBox)->ScrollToRestoredPosition(); +} + +void +nsGfxScrollFrameInner::ReloadChildFrames() { mScrollAreaBox = nsnull; mHScrollbarBox = nsnull; diff --git a/mozilla/layout/generic/nsGfxScrollFrame.h b/mozilla/layout/generic/nsGfxScrollFrame.h index fe94df56851..264da4fd665 100644 --- a/mozilla/layout/generic/nsGfxScrollFrame.h +++ b/mozilla/layout/generic/nsGfxScrollFrame.h @@ -112,6 +112,8 @@ public: nsIScrollableView* GetScrollableView() const; + void ScrollToRestoredPosition(); + nsIFrame* GetScrolledFrame() const { nsIBox* childBox; nsIFrame* frame; @@ -256,6 +258,10 @@ public: NS_IMETHOD GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref* aScrollPreference) const; + virtual void ScrollToRestoredPosition() { + mInner.ScrollToRestoredPosition(); + } + virtual nsMargin GetActualScrollbarSizes() const; virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const; @@ -383,6 +389,10 @@ public: NS_IMETHOD GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref* aScrollPreference) const; + virtual void ScrollToRestoredPosition() { + mInner.ScrollToRestoredPosition(); + } + virtual nsMargin GetActualScrollbarSizes() const; virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const; diff --git a/mozilla/layout/generic/nsIScrollableFrame.h b/mozilla/layout/generic/nsIScrollableFrame.h index 7ad07b3f290..35f9a33ba8a 100644 --- a/mozilla/layout/generic/nsIScrollableFrame.h +++ b/mozilla/layout/generic/nsIScrollableFrame.h @@ -134,6 +134,15 @@ public: NS_IMETHOD CurPosAttributeChanged(nsIPresContext* aPresContext, nsIContent* aChild, PRInt32 aModType) = 0; + + /** + * This tells the scroll frame to try scrolling to the scroll + * position that was restored from the history. This must be called + * at least once after state has been restored. It is called by the + * scrolled frame itself during reflow, but sometimes state can be + * restored after reflows are done... + */ + virtual void ScrollToRestoredPosition() = 0; }; #endif diff --git a/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp b/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp index c4e2f49fda3..2eea2043dc2 100644 --- a/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp +++ b/mozilla/layout/html/base/src/nsGfxScrollFrame.cpp @@ -49,6 +49,7 @@ #include "nsHTMLContainerFrame.h" #include "nsWidgetsCID.h" #include "nsGfxScrollFrame.h" +#include "nsScrollBoxFrame.h" #include "nsLayoutAtoms.h" #include "nsXULAtoms.h" #include "nsHTMLAtoms.h" @@ -1244,7 +1245,14 @@ nsGfxScrollFrameInner::GetScrollPreference() const } } -void nsGfxScrollFrameInner::ReloadChildFrames() +void +nsGfxScrollFrameInner::ScrollToRestoredPosition() +{ + NS_STATIC_CAST(nsScrollBoxFrame*, mScrollAreaBox)->ScrollToRestoredPosition(); +} + +void +nsGfxScrollFrameInner::ReloadChildFrames() { mScrollAreaBox = nsnull; mHScrollbarBox = nsnull; diff --git a/mozilla/layout/html/base/src/nsGfxScrollFrame.h b/mozilla/layout/html/base/src/nsGfxScrollFrame.h index fe94df56851..264da4fd665 100644 --- a/mozilla/layout/html/base/src/nsGfxScrollFrame.h +++ b/mozilla/layout/html/base/src/nsGfxScrollFrame.h @@ -112,6 +112,8 @@ public: nsIScrollableView* GetScrollableView() const; + void ScrollToRestoredPosition(); + nsIFrame* GetScrolledFrame() const { nsIBox* childBox; nsIFrame* frame; @@ -256,6 +258,10 @@ public: NS_IMETHOD GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref* aScrollPreference) const; + virtual void ScrollToRestoredPosition() { + mInner.ScrollToRestoredPosition(); + } + virtual nsMargin GetActualScrollbarSizes() const; virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const; @@ -383,6 +389,10 @@ public: NS_IMETHOD GetScrollPreference(nsIPresContext* aPresContext, nsScrollPref* aScrollPreference) const; + virtual void ScrollToRestoredPosition() { + mInner.ScrollToRestoredPosition(); + } + virtual nsMargin GetActualScrollbarSizes() const; virtual nsMargin GetDesiredScrollbarSizes(nsBoxLayoutState* aState); virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const; diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index c015b49fb47..a7c57957407 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -3639,6 +3639,13 @@ PresShell::EndLoad(nsIDocument *aDocument) GetRootScrollFrame(mPresContext, rootFrame, &scrollFrame); if (scrollFrame) { FrameManager()->RestoreFrameStateFor(scrollFrame, historyState, nsIStatefulFrame::eDocumentScrollState); + + nsIScrollableFrame* scrollableFrame; + CallQueryInterface(scrollFrame, &scrollableFrame); + NS_ASSERTION(scrollableFrame, "RootScrollFrame is not scrollable?"); + if (scrollableFrame) { + scrollableFrame->ScrollToRestoredPosition(); + } } } diff --git a/mozilla/layout/xul/base/src/nsScrollBoxFrame.cpp b/mozilla/layout/xul/base/src/nsScrollBoxFrame.cpp index 13e993b32a8..fcd20fc8344 100644 --- a/mozilla/layout/xul/base/src/nsScrollBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsScrollBoxFrame.cpp @@ -438,6 +438,11 @@ nsScrollBoxFrame::DoLayout(nsBoxLayoutState& aState) PostScrollPortEvent(shell, mHorizontalOverflow, nsScrollPortEvent::horizontal); } + ScrollToRestoredPosition(); + + return NS_OK; +} + /** * this code is resposible for restoring the scroll position back to some * saved positon. if the user has not moved the scroll position manually @@ -445,17 +450,16 @@ nsScrollBoxFrame::DoLayout(nsBoxLayoutState& aState) * mind that content could incrementally be coming in. we only want to stop * when we reach our new position. */ +void +nsScrollBoxFrame::ScrollToRestoredPosition() +{ + nsIView* view = GetView(); + NS_ASSERTION(view, "Scrollbox must always have a view!"); - if ((mRestoreRect.y != -1) && - (mLastPos.x != -1) && - (mLastPos.y != -1)) { - + if (view && mRestoreRect.y != -1 && mLastPos.x != -1 && mLastPos.y != -1) { // make sure our scroll position did not change for where we last put // it. if it does then the user must have moved it, and we no longer // need to restore. - if (!view) - return NS_OK; // don't freak out if we have no view - nsIScrollableView* scrollingView; CallQueryInterface(view, &scrollingView); if (scrollingView) { @@ -502,8 +506,6 @@ nsScrollBoxFrame::DoLayout(nsBoxLayoutState& aState) } } } - - return NS_OK; } void diff --git a/mozilla/layout/xul/base/src/nsScrollBoxFrame.h b/mozilla/layout/xul/base/src/nsScrollBoxFrame.h index b96f8b6e2ec..4be38fe23a6 100644 --- a/mozilla/layout/xul/base/src/nsScrollBoxFrame.h +++ b/mozilla/layout/xul/base/src/nsScrollBoxFrame.h @@ -124,6 +124,8 @@ public: virtual nsIView* GetMouseCapturer() const; + void ScrollToRestoredPosition(); + protected: nsScrollBoxFrame(nsIPresShell* aShell);