Loading docshell/base/nsDocShell.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -3128,7 +3128,7 @@ NS_IMETHODIMP nsDocShell::UpdateCurrentSessionHistory() if (NS_SUCCEEDED(rv) && shell) { nsCOMPtr<nsILayoutHistoryState> layoutState; rv = shell->CaptureHistoryState(getter_AddRefs(layoutState)); rv = shell->CaptureHistoryState(getter_AddRefs(layoutState), PR_TRUE); if (NS_SUCCEEDED(rv) && layoutState) { rv = entry->SetLayoutHistoryState(layoutState); Loading layout/base/nsFrameManager.cpp +66 −40 Original line number Diff line number Diff line Loading @@ -248,12 +248,22 @@ public: NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent, PRBool &aAffects); // Capture state from the entire frame heirarchy and store in aState NS_IMETHOD CaptureFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState); NS_IMETHOD RestoreFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState); // Add/restore state for one frame (special, global type, like scroll position) NS_IMETHOD CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID); NS_IMETHOD RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID); // Gets and sets properties on a given frame NS_IMETHOD GetFrameProperty(nsIFrame* aFrame, Loading Loading @@ -1477,8 +1487,10 @@ FrameManager::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent, return rv; } static nsresult CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState) // Capture state for a given frame. // Accept a content id here, in some cases we may not have content (scroll position) NS_IMETHODIMP FrameManager::CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID) { nsresult rv = NS_OK; NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in"); Loading @@ -1488,27 +1500,35 @@ CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHi nsIStatefulFrame* statefulFrame = nsnull; aFrame->QueryInterface(NS_GET_IID(nsIStatefulFrame), (void**) &statefulFrame); if (nsnull != statefulFrame) { // If so, get the content ID, state type and the state and // add an association between (ID, type) and (state) to the // history state storage object, aState. // If not given one, get the content ID PRUint32 ID = aID; if (nsIStatefulFrame::eNoID == ID) { nsCOMPtr<nsIContent> content; rv = aFrame->GetContent(getter_AddRefs(content)); if (NS_SUCCEEDED(rv)) { PRUint32 ID; if (NS_SUCCEEDED(rv) && content) { rv = content->GetContentID(&ID); } } if (NS_SUCCEEDED(rv) && ID) { // Must have ID (don't do anonymous content) // Get the state type nsIStatefulFrame::StateType type = nsIStatefulFrame::eNoType; rv = statefulFrame->GetStateType(aPresContext, &type); if (NS_SUCCEEDED(rv)) { // Get the state nsCOMPtr<nsIPresState> frameState; rv = statefulFrame->SaveState(aPresContext, getter_AddRefs(frameState)); if (NS_SUCCEEDED(rv)) { // add an association between (ID, type) and (state) to the // history state storage object, aState. rv = aState->AddState(ID, frameState, type); } } } } } return rv; } Loading Loading @@ -1539,8 +1559,10 @@ FrameManager::CaptureFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, return rv; } static nsresult RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState) // Restore state for a given frame. // Accept a content id here, in some cases we may not have content (scroll position) NS_IMETHODIMP FrameManager::RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID) { nsresult rv = NS_OK; NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in"); Loading @@ -1550,20 +1572,25 @@ RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHi nsIStatefulFrame* statefulFrame = nsnull; aFrame->QueryInterface(NS_GET_IID(nsIStatefulFrame), (void**) &statefulFrame); if (nsnull != statefulFrame) { // If so, get the content ID, state type and the frame state and // ask the frame object to restore its state. // If not given one, get the content ID PRUint32 ID = aID; if (nsIStatefulFrame::eNoID == ID) { nsCOMPtr<nsIContent> content; rv = aFrame->GetContent(getter_AddRefs(content)); if (NS_SUCCEEDED(rv)) { PRUint32 ID; if (NS_SUCCEEDED(rv) && content) { rv = content->GetContentID(&ID); } } if (NS_SUCCEEDED(rv) && ID) { // Must have ID (don't do anonymous content) nsIStatefulFrame::StateType type = nsIStatefulFrame::eNoType; rv = statefulFrame->GetStateType(aPresContext, &type); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIPresState> frameState; rv = aState->GetState(ID, getter_AddRefs(frameState), type); if (NS_SUCCEEDED(rv) && frameState) { // First restore the state. rv = statefulFrame->RestoreState(aPresContext, frameState); Loading @@ -1573,7 +1600,6 @@ RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHi } } } } return rv; } Loading layout/base/nsIPresShell.h +1 −1 Original line number Diff line number Diff line Loading @@ -369,7 +369,7 @@ public: * Get and set the history state for the current document */ NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState) = 0; NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState, PRBool aLeavingPage = PR_FALSE) = 0; NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState) = 0; NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState) = 0; Loading layout/base/nsPresShell.cpp +65 −2 Original line number Diff line number Diff line Loading @@ -642,7 +642,7 @@ public: NS_IMETHOD DoCopy(); NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState); NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState, PRBool aLeavingPage); NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState); NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState); Loading Loading @@ -1543,6 +1543,45 @@ PresShell::NotifyReflowObservers(const char *aData) return NS_OK; } static nsresult GetRootScrollFrame(nsIPresContext* aPresContext, nsIFrame* aRootFrame, nsIFrame** aScrollFrame) { // Frames: viewport->scroll->scrollport (Gfx) or viewport->scroll (Native) // Types: viewport->scroll->sroll viewport->scroll // Ensure root frame is a viewport frame *aScrollFrame = nsnull; nsIFrame* theFrame = nsnull; if (aRootFrame) { nsCOMPtr<nsIAtom> fType; aRootFrame->GetFrameType(getter_AddRefs(fType)); if (fType && (nsLayoutAtoms::viewportFrame == fType.get())) { // If child is scrollframe keep it (native) aRootFrame->FirstChild(aPresContext, nsnull, &theFrame); if (theFrame) { nsCOMPtr<nsIAtom> fType; theFrame->GetFrameType(getter_AddRefs(fType)); if (nsLayoutAtoms::scrollFrame == fType.get()) { *aScrollFrame = theFrame; // If the first child of that is scrollframe, use it instead (gfx) theFrame->FirstChild(aPresContext, nsnull, &theFrame); if (theFrame) { nsCOMPtr<nsIAtom> fType; theFrame->GetFrameType(getter_AddRefs(fType)); if (nsLayoutAtoms::scrollFrame == fType.get()) { *aScrollFrame = theFrame; } } } } } } return NS_OK; } NS_IMETHODIMP PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) { Loading Loading @@ -2237,6 +2276,18 @@ PresShell::BeginLoad(nsIDocument *aDocument) NS_IMETHODIMP PresShell::EndLoad(nsIDocument *aDocument) { // Restore frame state for the root scroll frame nsIFrame* rootFrame = nsnull; GetRootFrame(&rootFrame); if (rootFrame && mHistoryState) { nsIFrame* scrollFrame = nsnull; GetRootScrollFrame(mPresContext, rootFrame, &scrollFrame); if (scrollFrame) { mFrameManager->RestoreFrameStateFor(mPresContext, scrollFrame, mHistoryState, nsIStatefulFrame::eDocumentScrollState); } } #ifdef MOZ_PERF_METRICS // Dump reflow, style resolution and frame construction times here. MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::EndLoad(), this=%p\n", this)); Loading Loading @@ -2814,7 +2865,7 @@ PresShell::DoCopy() } NS_IMETHODIMP PresShell::CaptureHistoryState(nsILayoutHistoryState** aState) PresShell::CaptureHistoryState(nsILayoutHistoryState** aState, PRBool aLeavingPage) { nsresult rv = NS_OK; Loading @@ -2840,6 +2891,18 @@ PresShell::CaptureHistoryState(nsILayoutHistoryState** aState) nsIFrame* rootFrame = nsnull; rv = GetRootFrame(&rootFrame); if (NS_FAILED(rv) || nsnull == rootFrame) return rv; // Capture frame state for the root scroll frame // Don't capture state when first creating doc element heirarchy // As the scroll position is 0 and this will cause us to loose // our previously saved place! if (aLeavingPage) { nsIFrame* scrollFrame = nsnull; rv = GetRootScrollFrame(mPresContext, rootFrame, &scrollFrame); if (scrollFrame) { rv = mFrameManager->CaptureFrameStateFor(mPresContext, scrollFrame, mHistoryState, nsIStatefulFrame::eDocumentScrollState); } } rv = mFrameManager->CaptureFrameState(mPresContext, rootFrame, mHistoryState); Loading layout/base/public/nsIFrameManager.h +10 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "nslayout.h" #include "nsISupports.h" #include "nsIStatefulFrame.h" class nsIAtom; class nsIContent; Loading Loading @@ -165,6 +166,15 @@ public: NS_IMETHOD RestoreFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState) = 0; // Add/restore state for one frame (special, global type, like scroll position) NS_IMETHOD CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID) = 0; NS_IMETHOD RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID) = 0; /** * Gets a property value for a given frame. Loading Loading
docshell/base/nsDocShell.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -3128,7 +3128,7 @@ NS_IMETHODIMP nsDocShell::UpdateCurrentSessionHistory() if (NS_SUCCEEDED(rv) && shell) { nsCOMPtr<nsILayoutHistoryState> layoutState; rv = shell->CaptureHistoryState(getter_AddRefs(layoutState)); rv = shell->CaptureHistoryState(getter_AddRefs(layoutState), PR_TRUE); if (NS_SUCCEEDED(rv) && layoutState) { rv = entry->SetLayoutHistoryState(layoutState); Loading
layout/base/nsFrameManager.cpp +66 −40 Original line number Diff line number Diff line Loading @@ -248,12 +248,22 @@ public: NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent, PRBool &aAffects); // Capture state from the entire frame heirarchy and store in aState NS_IMETHOD CaptureFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState); NS_IMETHOD RestoreFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState); // Add/restore state for one frame (special, global type, like scroll position) NS_IMETHOD CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID); NS_IMETHOD RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID); // Gets and sets properties on a given frame NS_IMETHOD GetFrameProperty(nsIFrame* aFrame, Loading Loading @@ -1477,8 +1487,10 @@ FrameManager::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent, return rv; } static nsresult CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState) // Capture state for a given frame. // Accept a content id here, in some cases we may not have content (scroll position) NS_IMETHODIMP FrameManager::CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID) { nsresult rv = NS_OK; NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in"); Loading @@ -1488,27 +1500,35 @@ CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHi nsIStatefulFrame* statefulFrame = nsnull; aFrame->QueryInterface(NS_GET_IID(nsIStatefulFrame), (void**) &statefulFrame); if (nsnull != statefulFrame) { // If so, get the content ID, state type and the state and // add an association between (ID, type) and (state) to the // history state storage object, aState. // If not given one, get the content ID PRUint32 ID = aID; if (nsIStatefulFrame::eNoID == ID) { nsCOMPtr<nsIContent> content; rv = aFrame->GetContent(getter_AddRefs(content)); if (NS_SUCCEEDED(rv)) { PRUint32 ID; if (NS_SUCCEEDED(rv) && content) { rv = content->GetContentID(&ID); } } if (NS_SUCCEEDED(rv) && ID) { // Must have ID (don't do anonymous content) // Get the state type nsIStatefulFrame::StateType type = nsIStatefulFrame::eNoType; rv = statefulFrame->GetStateType(aPresContext, &type); if (NS_SUCCEEDED(rv)) { // Get the state nsCOMPtr<nsIPresState> frameState; rv = statefulFrame->SaveState(aPresContext, getter_AddRefs(frameState)); if (NS_SUCCEEDED(rv)) { // add an association between (ID, type) and (state) to the // history state storage object, aState. rv = aState->AddState(ID, frameState, type); } } } } } return rv; } Loading Loading @@ -1539,8 +1559,10 @@ FrameManager::CaptureFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, return rv; } static nsresult RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState) // Restore state for a given frame. // Accept a content id here, in some cases we may not have content (scroll position) NS_IMETHODIMP FrameManager::RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID) { nsresult rv = NS_OK; NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in"); Loading @@ -1550,20 +1572,25 @@ RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHi nsIStatefulFrame* statefulFrame = nsnull; aFrame->QueryInterface(NS_GET_IID(nsIStatefulFrame), (void**) &statefulFrame); if (nsnull != statefulFrame) { // If so, get the content ID, state type and the frame state and // ask the frame object to restore its state. // If not given one, get the content ID PRUint32 ID = aID; if (nsIStatefulFrame::eNoID == ID) { nsCOMPtr<nsIContent> content; rv = aFrame->GetContent(getter_AddRefs(content)); if (NS_SUCCEEDED(rv)) { PRUint32 ID; if (NS_SUCCEEDED(rv) && content) { rv = content->GetContentID(&ID); } } if (NS_SUCCEEDED(rv) && ID) { // Must have ID (don't do anonymous content) nsIStatefulFrame::StateType type = nsIStatefulFrame::eNoType; rv = statefulFrame->GetStateType(aPresContext, &type); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIPresState> frameState; rv = aState->GetState(ID, getter_AddRefs(frameState), type); if (NS_SUCCEEDED(rv) && frameState) { // First restore the state. rv = statefulFrame->RestoreState(aPresContext, frameState); Loading @@ -1573,7 +1600,6 @@ RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHi } } } } return rv; } Loading
layout/base/nsIPresShell.h +1 −1 Original line number Diff line number Diff line Loading @@ -369,7 +369,7 @@ public: * Get and set the history state for the current document */ NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState) = 0; NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState, PRBool aLeavingPage = PR_FALSE) = 0; NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState) = 0; NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState) = 0; Loading
layout/base/nsPresShell.cpp +65 −2 Original line number Diff line number Diff line Loading @@ -642,7 +642,7 @@ public: NS_IMETHOD DoCopy(); NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState); NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState, PRBool aLeavingPage); NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState); NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState); Loading Loading @@ -1543,6 +1543,45 @@ PresShell::NotifyReflowObservers(const char *aData) return NS_OK; } static nsresult GetRootScrollFrame(nsIPresContext* aPresContext, nsIFrame* aRootFrame, nsIFrame** aScrollFrame) { // Frames: viewport->scroll->scrollport (Gfx) or viewport->scroll (Native) // Types: viewport->scroll->sroll viewport->scroll // Ensure root frame is a viewport frame *aScrollFrame = nsnull; nsIFrame* theFrame = nsnull; if (aRootFrame) { nsCOMPtr<nsIAtom> fType; aRootFrame->GetFrameType(getter_AddRefs(fType)); if (fType && (nsLayoutAtoms::viewportFrame == fType.get())) { // If child is scrollframe keep it (native) aRootFrame->FirstChild(aPresContext, nsnull, &theFrame); if (theFrame) { nsCOMPtr<nsIAtom> fType; theFrame->GetFrameType(getter_AddRefs(fType)); if (nsLayoutAtoms::scrollFrame == fType.get()) { *aScrollFrame = theFrame; // If the first child of that is scrollframe, use it instead (gfx) theFrame->FirstChild(aPresContext, nsnull, &theFrame); if (theFrame) { nsCOMPtr<nsIAtom> fType; theFrame->GetFrameType(getter_AddRefs(fType)); if (nsLayoutAtoms::scrollFrame == fType.get()) { *aScrollFrame = theFrame; } } } } } } return NS_OK; } NS_IMETHODIMP PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) { Loading Loading @@ -2237,6 +2276,18 @@ PresShell::BeginLoad(nsIDocument *aDocument) NS_IMETHODIMP PresShell::EndLoad(nsIDocument *aDocument) { // Restore frame state for the root scroll frame nsIFrame* rootFrame = nsnull; GetRootFrame(&rootFrame); if (rootFrame && mHistoryState) { nsIFrame* scrollFrame = nsnull; GetRootScrollFrame(mPresContext, rootFrame, &scrollFrame); if (scrollFrame) { mFrameManager->RestoreFrameStateFor(mPresContext, scrollFrame, mHistoryState, nsIStatefulFrame::eDocumentScrollState); } } #ifdef MOZ_PERF_METRICS // Dump reflow, style resolution and frame construction times here. MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::EndLoad(), this=%p\n", this)); Loading Loading @@ -2814,7 +2865,7 @@ PresShell::DoCopy() } NS_IMETHODIMP PresShell::CaptureHistoryState(nsILayoutHistoryState** aState) PresShell::CaptureHistoryState(nsILayoutHistoryState** aState, PRBool aLeavingPage) { nsresult rv = NS_OK; Loading @@ -2840,6 +2891,18 @@ PresShell::CaptureHistoryState(nsILayoutHistoryState** aState) nsIFrame* rootFrame = nsnull; rv = GetRootFrame(&rootFrame); if (NS_FAILED(rv) || nsnull == rootFrame) return rv; // Capture frame state for the root scroll frame // Don't capture state when first creating doc element heirarchy // As the scroll position is 0 and this will cause us to loose // our previously saved place! if (aLeavingPage) { nsIFrame* scrollFrame = nsnull; rv = GetRootScrollFrame(mPresContext, rootFrame, &scrollFrame); if (scrollFrame) { rv = mFrameManager->CaptureFrameStateFor(mPresContext, scrollFrame, mHistoryState, nsIStatefulFrame::eDocumentScrollState); } } rv = mFrameManager->CaptureFrameState(mPresContext, rootFrame, mHistoryState); Loading
layout/base/public/nsIFrameManager.h +10 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include "nslayout.h" #include "nsISupports.h" #include "nsIStatefulFrame.h" class nsIAtom; class nsIContent; Loading Loading @@ -165,6 +166,15 @@ public: NS_IMETHOD RestoreFrameState(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState) = 0; // Add/restore state for one frame (special, global type, like scroll position) NS_IMETHOD CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID) = 0; NS_IMETHOD RestoreFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState, nsIStatefulFrame::SpecialStateID aID = nsIStatefulFrame::eNoID) = 0; /** * Gets a property value for a given frame. Loading