зеркало из https://github.com/mozilla/pjs.git
Bug 257916. Move history scroll position save and restore from nsScrollBoxFrame to nsHTML/XULScrollFrame. +sr=dbaron(rubber-stamp)
This commit is contained in:
Родитель
ce80d8481f
Коммит
cdaf90f7e4
|
@ -3511,14 +3511,8 @@ PresShell::EndLoad(nsIDocument *aDocument)
|
|||
CallQueryInterface(scrollFrame, &scrollableFrame);
|
||||
NS_ASSERTION(scrollableFrame, "RootScrollFrame is not scrollable?");
|
||||
if (scrollableFrame) {
|
||||
// XXX We shouldn't depend on the scrolling guts here. Make this
|
||||
// go away!
|
||||
nsIFrame* scrollBoxFrame = scrollFrame->GetFirstChild(nsnull);
|
||||
|
||||
if (scrollBoxFrame) {
|
||||
FrameManager()->RestoreFrameStateFor(scrollBoxFrame, historyState,
|
||||
nsIStatefulFrame::eDocumentScrollState);
|
||||
}
|
||||
FrameManager()->RestoreFrameStateFor(scrollFrame, historyState,
|
||||
nsIStatefulFrame::eDocumentScrollState);
|
||||
scrollableFrame->ScrollToRestoredPosition();
|
||||
}
|
||||
}
|
||||
|
@ -4503,13 +4497,8 @@ PresShell::CaptureHistoryState(nsILayoutHistoryState** aState, PRBool aLeavingPa
|
|||
if (aLeavingPage) {
|
||||
nsIFrame* scrollFrame = GetRootScrollFrame(rootFrame);
|
||||
if (scrollFrame) {
|
||||
// XXX We shouldn't depend on the scrolling guts here. Make this
|
||||
// go away!
|
||||
nsIFrame* scrollBoxFrame = scrollFrame->GetFirstChild(nsnull);
|
||||
if (scrollBoxFrame) {
|
||||
FrameManager()->CaptureFrameStateFor(scrollBoxFrame, historyState,
|
||||
nsIStatefulFrame::eDocumentScrollState);
|
||||
}
|
||||
FrameManager()->CaptureFrameStateFor(scrollFrame, historyState,
|
||||
nsIStatefulFrame::eDocumentScrollState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -294,6 +294,7 @@ nsListControlFrame::nsListControlFrame(nsIPresShell* aShell,
|
|||
mIsAllFramesHere = PR_FALSE;
|
||||
mHasBeenInitialized = PR_FALSE;
|
||||
mNeedToReset = PR_TRUE;
|
||||
mPostChildrenLoadedReset = PR_FALSE;
|
||||
|
||||
mCacheSize.width = -1;
|
||||
mCacheSize.height = -1;
|
||||
|
@ -558,129 +559,9 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|||
*aInstancePtr = (void *)((nsISelectControlFrame*)this);
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) {
|
||||
*aInstancePtr =
|
||||
NS_STATIC_CAST(void*,NS_STATIC_CAST(nsIStatefulFrame*,this));
|
||||
return NS_OK;
|
||||
}
|
||||
return nsHTMLScrollFrame::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIStatefulFrame
|
||||
// These methods were originally in the nsScrollFrame superclass,
|
||||
// but were moved here when nsListControlFrame switched to use
|
||||
// nsHTMLScrollFrame.
|
||||
//----------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::SaveState(nsPresContext* aPresContext,
|
||||
nsIPresState** aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsCOMPtr<nsIPresState> state;
|
||||
nsresult res = NS_OK;
|
||||
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
|
||||
nscoord x = 0, y = 0;
|
||||
if (scrollingView) {
|
||||
scrollingView->GetScrollPosition(x, y);
|
||||
}
|
||||
|
||||
// Don't save scroll position if we are at (0,0)
|
||||
if (x || y) {
|
||||
nsIView* child = nsnull;
|
||||
scrollingView->GetScrolledView(child);
|
||||
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
|
||||
|
||||
nsRect childRect = child->GetBounds();
|
||||
|
||||
res = NS_NewPresState(getter_AddRefs(state));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset =
|
||||
do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID, &res);
|
||||
if (xoffset) {
|
||||
res = xoffset->SetData(x);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), xoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset =
|
||||
do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID, &res);
|
||||
if (yoffset) {
|
||||
res = yoffset->SetData(y);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), yoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> width =
|
||||
do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID, &res);
|
||||
if (width) {
|
||||
res = width->SetData(childRect.width);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("width"), width);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> height =
|
||||
do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID, &res);
|
||||
if (height) {
|
||||
res = height->SetData(childRect.height);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("height"), height);
|
||||
}
|
||||
*aState = state;
|
||||
NS_ADDREF(*aState);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::RestoreState(nsPresContext* aPresContext,
|
||||
nsIPresState* aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), getter_AddRefs(xoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), getter_AddRefs(yoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("width"), getter_AddRefs(width));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("height"), getter_AddRefs(height));
|
||||
|
||||
nsresult res = NS_ERROR_NULL_POINTER;
|
||||
if (xoffset && yoffset) {
|
||||
PRInt32 x,y,w,h;
|
||||
res = xoffset->GetData(&x);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = yoffset->GetData(&y);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = width->GetData(&w);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = height->GetData(&h);
|
||||
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
if (scrollingView) {
|
||||
nsIView* child = nsnull;
|
||||
nsRect childRect(0,0,0,0);
|
||||
if (NS_SUCCEEDED(scrollingView->GetScrolledView(child)) && child) {
|
||||
childRect = child->GetBounds();
|
||||
}
|
||||
x = (int)(((float)childRect.width / w) * x);
|
||||
y = (int)(((float)childRect.height / h) * y);
|
||||
|
||||
scrollingView->ScrollTo(x,y,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
NS_IMETHODIMP nsListControlFrame::GetAccessible(nsIAccessible** aAccessible)
|
||||
{
|
||||
|
@ -1885,7 +1766,7 @@ nsListControlFrame::MouseClicked(nsPresContext* aPresContext)
|
|||
NS_IMETHODIMP
|
||||
nsListControlFrame::OnContentReset()
|
||||
{
|
||||
ResetList();
|
||||
ResetList(PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1894,7 +1775,7 @@ nsListControlFrame::OnContentReset()
|
|||
// those values as determined by the original HTML
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
nsListControlFrame::ResetList()
|
||||
nsListControlFrame::ResetList(PRBool aAllowScrolling)
|
||||
{
|
||||
REFLOW_DEBUG_MSG("LBX::ResetList\n");
|
||||
|
||||
|
@ -1904,14 +1785,18 @@ nsListControlFrame::ResetList()
|
|||
return;
|
||||
}
|
||||
|
||||
// Scroll to the selected index
|
||||
PRInt32 indexToSelect = kNothingSelected;
|
||||
if (aAllowScrolling) {
|
||||
mPostChildrenLoadedReset = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement(do_QueryInterface(mContent));
|
||||
NS_ASSERTION(selectElement, "No select element!");
|
||||
if (selectElement) {
|
||||
selectElement->GetSelectedIndex(&indexToSelect);
|
||||
ScrollToIndex(indexToSelect);
|
||||
// Scroll to the selected index
|
||||
PRInt32 indexToSelect = kNothingSelected;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement(do_QueryInterface(mContent));
|
||||
NS_ASSERTION(selectElement, "No select element!");
|
||||
if (selectElement) {
|
||||
selectElement->GetSelectedIndex(&indexToSelect);
|
||||
ScrollToIndex(indexToSelect);
|
||||
}
|
||||
}
|
||||
|
||||
mStartSelectionIndex = kNothingSelected;
|
||||
|
@ -2095,7 +1980,7 @@ nsListControlFrame::DoneAddingChildren(PRBool aIsDone)
|
|||
// if all the frames are now present we can initalize
|
||||
if (CheckIfAllFramesHere()) {
|
||||
mHasBeenInitialized = PR_TRUE;
|
||||
ResetList();
|
||||
ResetList(PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2129,6 +2014,7 @@ nsListControlFrame::AddOption(nsPresContext* aPresContext, PRInt32 aIndex)
|
|||
|
||||
// Make sure we scroll to the selected option as needed
|
||||
mNeedToReset = PR_TRUE;
|
||||
mPostChildrenLoadedReset = mIsAllContentHere;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2139,6 +2025,7 @@ nsListControlFrame::RemoveOption(nsPresContext* aPresContext, PRInt32 aIndex)
|
|||
// Need to reset if we're a dropdown
|
||||
if (IsInDropDownMode()) {
|
||||
mNeedToReset = PR_TRUE;
|
||||
mPostChildrenLoadedReset = mIsAllContentHere;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2444,7 +2331,16 @@ nsListControlFrame::DidReflow(nsPresContext* aPresContext,
|
|||
|
||||
if (mNeedToReset) {
|
||||
mNeedToReset = PR_FALSE;
|
||||
ResetList();
|
||||
// Suppress scrolling to the selected element if we restored
|
||||
// scroll history state AND the list contents have not changed
|
||||
// since we loaded all the children AND nothing else forced us
|
||||
// to scroll by calling ResetList(PR_TRUE). The latter two conditions
|
||||
// are folded into mPostChildrenLoadedReset.
|
||||
//
|
||||
// The idea is that we want scroll history restoration to trump ResetList
|
||||
// scrolling to the selected element, when the ResetList was probably only
|
||||
// caused by content loading normally.
|
||||
ResetList(!DidHistoryRestore() || mPostChildrenLoadedReset);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -2841,6 +2737,8 @@ nsresult
|
|||
nsListControlFrame::ScrollToIndex(PRInt32 aIndex)
|
||||
{
|
||||
if (aIndex < 0) {
|
||||
// XXX shouldn't we just do nothing if we're asked to scroll to
|
||||
// kNothingSelected?
|
||||
return ScrollToFrame(nsnull);
|
||||
} else {
|
||||
nsCOMPtr<nsIContent> content = getter_AddRefs(GetOptionContent(aIndex));
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#include "nsIFormControlFrame.h"
|
||||
#include "nsIListControlFrame.h"
|
||||
#include "nsISelectControlFrame.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIPresState.h"
|
||||
#include "nsIContent.h"
|
||||
|
@ -77,7 +76,6 @@ class nsListEventListener;
|
|||
class nsListControlFrame : public nsHTMLScrollFrame,
|
||||
public nsIFormControlFrame,
|
||||
public nsIListControlFrame,
|
||||
public nsIStatefulFrame,
|
||||
public nsISelectControlFrame
|
||||
{
|
||||
public:
|
||||
|
@ -190,10 +188,6 @@ public:
|
|||
NS_IMETHOD GetDummyFrame(nsIFrame** aFrame);
|
||||
NS_IMETHOD SetDummyFrame(nsIFrame* aFrame);
|
||||
|
||||
//nsIStatefulFrame
|
||||
NS_IMETHOD SaveState(nsPresContext* aPresContext, nsIPresState** aState);
|
||||
NS_IMETHOD RestoreState(nsPresContext* aPresContext, nsIPresState* aState);
|
||||
|
||||
// mouse event listeners
|
||||
nsresult MouseDown(nsIDOMEvent* aMouseEvent);
|
||||
nsresult MouseUp(nsIDOMEvent* aMouseEvent);
|
||||
|
@ -231,7 +225,7 @@ protected:
|
|||
PRBool IsClickingInCombobox(nsIDOMEvent* aMouseEvent);
|
||||
void AdjustIndexForDisabledOpt(PRInt32 aStartIndex, PRInt32 &anNewIndex,
|
||||
PRInt32 aNumOptions, PRInt32 aDoAdjustInc, PRInt32 aDoAdjustIncNext);
|
||||
virtual void ResetList();
|
||||
virtual void ResetList(PRBool aAllowScrolling);
|
||||
|
||||
nsListControlFrame(nsIPresShell* aShell, nsIDocument* aDocument);
|
||||
virtual ~nsListControlFrame();
|
||||
|
@ -282,6 +276,7 @@ protected:
|
|||
PRPackedBool mIsAllFramesHere;
|
||||
PRPackedBool mHasBeenInitialized;
|
||||
PRPackedBool mNeedToReset;
|
||||
PRPackedBool mPostChildrenLoadedReset;
|
||||
|
||||
PRPackedBool mOverrideReflowOpt;
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsIAccessibilityService.h"
|
||||
#endif
|
||||
|
@ -606,6 +607,7 @@ NS_INTERFACE_MAP_BEGIN(nsHTMLScrollFrame)
|
|||
#endif
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollableFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollableViewProvider)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStatefulFrame)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
|
||||
//----------nsXULScrollFrame-------------------------------------------
|
||||
|
@ -1119,6 +1121,7 @@ NS_INTERFACE_MAP_BEGIN(nsXULScrollFrame)
|
|||
#endif
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollableFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollableViewProvider)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStatefulFrame)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
|
||||
|
||||
|
@ -1133,16 +1136,16 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsBoxFrame* aOuter)
|
|||
mOnePixel(20),
|
||||
mOuter(aOuter),
|
||||
mMaxElementWidth(0),
|
||||
mRestoreRect(-1, -1, -1, -1),
|
||||
mLastPos(-1, -1),
|
||||
mLastDir(-1),
|
||||
mNeverHasVerticalScrollbar(PR_FALSE),
|
||||
mNeverHasHorizontalScrollbar(PR_FALSE),
|
||||
mHasVerticalScrollbar(PR_FALSE),
|
||||
mHasHorizontalScrollbar(PR_FALSE),
|
||||
mFirstPass(PR_FALSE),
|
||||
mIsRoot(PR_FALSE),
|
||||
mNeverReflowed(PR_TRUE),
|
||||
mViewInitiatedScroll(PR_FALSE),
|
||||
mFrameInitiatedScroll(PR_FALSE)
|
||||
mFrameInitiatedScroll(PR_FALSE),
|
||||
mDidHistoryRestore(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1208,10 +1211,65 @@ nsGfxScrollFrameInner::GetScrollbarStylesFromFrame() const
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* this code is resposible for restoring the scroll position back to some
|
||||
* saved positon. if the user has not moved the scroll position manually
|
||||
* we keep scrolling down until we get to our orignally position. keep in
|
||||
* mind that content could incrementally be coming in. we only want to stop
|
||||
* when we reach our new position.
|
||||
*/
|
||||
void
|
||||
nsGfxScrollFrameInner::ScrollToRestoredPosition()
|
||||
{
|
||||
NS_STATIC_CAST(nsScrollBoxFrame*, mScrollAreaBox)->ScrollToRestoredPosition();
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
if (!scrollingView) {
|
||||
return;
|
||||
}
|
||||
if (mRestoreRect.y == -1 || mLastPos.x == -1 || mLastPos.y == -1) {
|
||||
return;
|
||||
}
|
||||
// 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.
|
||||
nscoord x = 0;
|
||||
nscoord y = 0;
|
||||
scrollingView->GetScrollPosition(x, y);
|
||||
|
||||
// if we didn't move, we still need to restore
|
||||
if (x == mLastPos.x && y == mLastPos.y) {
|
||||
nsRect childRect(0, 0, 0, 0);
|
||||
nsIView* child = nsnull;
|
||||
nsresult rv = scrollingView->GetScrolledView(child);
|
||||
if (NS_SUCCEEDED(rv) && child)
|
||||
childRect = child->GetBounds();
|
||||
|
||||
PRInt32 cx, cy, x, y;
|
||||
scrollingView->GetScrollPosition(cx,cy);
|
||||
|
||||
x = (int)
|
||||
(((float)childRect.width / mRestoreRect.width) * mRestoreRect.x);
|
||||
y = (int)
|
||||
(((float)childRect.height / mRestoreRect.height) * mRestoreRect.y);
|
||||
|
||||
// if our position is greater than the scroll position, scroll.
|
||||
// remember that we could be incrementally loading so we may enter
|
||||
// and scroll many times.
|
||||
if (y > cy || x > cx) {
|
||||
scrollingView->ScrollTo(x, y, 0);
|
||||
// scrollpostion goes from twips to pixels. this fixes any roundoff
|
||||
// problems.
|
||||
scrollingView->GetScrollPosition(mLastPos.x, mLastPos.y);
|
||||
} else {
|
||||
// if we reached the position then stop
|
||||
mRestoreRect.y = -1;
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
}
|
||||
} else {
|
||||
// user moved the position, so we won't need to restore
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2032,6 +2090,8 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
|
|||
}
|
||||
}
|
||||
|
||||
ScrollToRestoredPosition();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2135,3 +2195,111 @@ nsGfxScrollFrameInner::GetIntegerAttribute(nsIBox* aBox, nsIAtom* atom, PRInt32
|
|||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIPresState>
|
||||
nsGfxScrollFrameInner::SaveState()
|
||||
{
|
||||
nsCOMPtr<nsIScrollbarMediator> mediator;
|
||||
nsIFrame* first = GetScrolledFrame();
|
||||
mediator = do_QueryInterface(first);
|
||||
if (mediator) {
|
||||
// Child manages its own scrolling. Bail.
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
PRInt32 x,y;
|
||||
scrollingView->GetScrollPosition(x,y);
|
||||
// Don't save scroll position if we are at (0,0)
|
||||
if (!x && !y) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIView* child = nsnull;
|
||||
scrollingView->GetScrolledView(child);
|
||||
if (!child) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsRect childRect = child->GetBounds();
|
||||
nsCOMPtr<nsIPresState> state;
|
||||
nsresult rv = NS_NewPresState(getter_AddRefs(state));
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(xoffset));
|
||||
if (xoffset) {
|
||||
rv = xoffset->SetData(x);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), xoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(yoffset));
|
||||
if (yoffset) {
|
||||
rv = yoffset->SetData(y);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), yoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(width));
|
||||
if (width) {
|
||||
rv = width->SetData(childRect.width);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("width"), width);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(height));
|
||||
if (height) {
|
||||
rv = height->SetData(childRect.height);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("height"), height);
|
||||
}
|
||||
nsIPresState* result = state;
|
||||
NS_ADDREF(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::RestoreState(nsIPresState* aState)
|
||||
{
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), getter_AddRefs(xoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), getter_AddRefs(yoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("width"), getter_AddRefs(width));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("height"), getter_AddRefs(height));
|
||||
|
||||
if (xoffset && yoffset) {
|
||||
PRInt32 x,y,w,h;
|
||||
nsresult rv = xoffset->GetData(&x);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = yoffset->GetData(&y);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = width->GetData(&w);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = height->GetData(&h);
|
||||
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
mRestoreRect.SetRect(-1, -1, -1, -1);
|
||||
|
||||
// don't do it now, store it later and do it in layout.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mRestoreRect.SetRect(x, y, w, h);
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
if (scrollingView) {
|
||||
scrollingView->GetScrollPosition(mLastPos.x, mLastPos.y);
|
||||
mDidHistoryRestore = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "nsBoxFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIScrollPositionListener.h"
|
||||
#include "nsIPresState.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
|
||||
class nsISupportsArray;
|
||||
class nsIScrollableView;
|
||||
|
@ -110,6 +112,9 @@ public:
|
|||
|
||||
void ScrollToRestoredPosition();
|
||||
|
||||
already_AddRefed<nsIPresState> SaveState();
|
||||
void RestoreState(nsIPresState* aState);
|
||||
|
||||
nsIFrame* GetScrolledFrame() const {
|
||||
nsIBox* childBox;
|
||||
nsIFrame* frame;
|
||||
|
@ -136,6 +141,9 @@ public:
|
|||
nsBoxFrame* mOuter;
|
||||
nscoord mMaxElementWidth;
|
||||
|
||||
nsRect mRestoreRect;
|
||||
nsPoint mLastPos;
|
||||
|
||||
// The last dir value we saw in AddHorizontalScrollbar. Use PRInt16
|
||||
// so we can fit all the possible values of a PRUint8 and have a -1
|
||||
// value that indicates "not set")
|
||||
|
@ -146,11 +154,9 @@ public:
|
|||
|
||||
PRPackedBool mHasVerticalScrollbar;
|
||||
PRPackedBool mHasHorizontalScrollbar;
|
||||
PRPackedBool mFirstPass;
|
||||
PRPackedBool mIsRoot;
|
||||
PRPackedBool mNeverReflowed;
|
||||
PRPackedBool mViewInitiatedScroll;
|
||||
PRPackedBool mFrameInitiatedScroll;
|
||||
PRPackedBool mDidHistoryRestore;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -164,7 +170,8 @@ public:
|
|||
*/
|
||||
class nsHTMLScrollFrame : public nsBoxFrame,
|
||||
public nsIScrollableFrame,
|
||||
public nsIAnonymousContentCreator {
|
||||
public nsIAnonymousContentCreator,
|
||||
public nsIStatefulFrame {
|
||||
public:
|
||||
friend nsresult NS_NewHTMLScrollFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
|
||||
PRBool aIsRoot);
|
||||
|
@ -248,6 +255,18 @@ public:
|
|||
|
||||
virtual void CurPosAttributeChanged(nsIContent* aChild, PRInt32 aModType);
|
||||
|
||||
// nsIStatefulFrame
|
||||
NS_IMETHOD SaveState(nsPresContext* aPresContext, nsIPresState** aState) {
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
*aState = mInner.SaveState().get();
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD RestoreState(nsPresContext* aPresContext, nsIPresState* aState) {
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
mInner.RestoreState(aState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual void ScrollToRestoredPosition() {
|
||||
mInner.ScrollToRestoredPosition();
|
||||
}
|
||||
|
@ -269,6 +288,8 @@ public:
|
|||
|
||||
virtual nsresult GetContentOf(nsIContent** aContent);
|
||||
|
||||
PRBool DidHistoryRestore() { return mInner.mDidHistoryRestore; }
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
|
||||
#endif
|
||||
|
@ -293,7 +314,8 @@ private:
|
|||
*/
|
||||
class nsXULScrollFrame : public nsBoxFrame,
|
||||
public nsIScrollableFrame,
|
||||
public nsIAnonymousContentCreator {
|
||||
public nsIAnonymousContentCreator,
|
||||
public nsIStatefulFrame {
|
||||
public:
|
||||
friend nsresult NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
|
||||
PRBool aIsRoot);
|
||||
|
@ -377,6 +399,18 @@ public:
|
|||
|
||||
virtual void CurPosAttributeChanged(nsIContent* aChild, PRInt32 aModType);
|
||||
|
||||
// nsIStatefulFrame
|
||||
NS_IMETHOD SaveState(nsPresContext* aPresContext, nsIPresState** aState) {
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
*aState = mInner.SaveState().get();
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD RestoreState(nsPresContext* aPresContext, nsIPresState* aState) {
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
mInner.RestoreState(aState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual void ScrollToRestoredPosition() {
|
||||
mInner.ScrollToRestoredPosition();
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsIAccessibilityService.h"
|
||||
#endif
|
||||
|
@ -606,6 +607,7 @@ NS_INTERFACE_MAP_BEGIN(nsHTMLScrollFrame)
|
|||
#endif
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollableFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollableViewProvider)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStatefulFrame)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
|
||||
//----------nsXULScrollFrame-------------------------------------------
|
||||
|
@ -1119,6 +1121,7 @@ NS_INTERFACE_MAP_BEGIN(nsXULScrollFrame)
|
|||
#endif
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollableFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollableViewProvider)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStatefulFrame)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
|
||||
|
||||
|
||||
|
@ -1133,16 +1136,16 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsBoxFrame* aOuter)
|
|||
mOnePixel(20),
|
||||
mOuter(aOuter),
|
||||
mMaxElementWidth(0),
|
||||
mRestoreRect(-1, -1, -1, -1),
|
||||
mLastPos(-1, -1),
|
||||
mLastDir(-1),
|
||||
mNeverHasVerticalScrollbar(PR_FALSE),
|
||||
mNeverHasHorizontalScrollbar(PR_FALSE),
|
||||
mHasVerticalScrollbar(PR_FALSE),
|
||||
mHasHorizontalScrollbar(PR_FALSE),
|
||||
mFirstPass(PR_FALSE),
|
||||
mIsRoot(PR_FALSE),
|
||||
mNeverReflowed(PR_TRUE),
|
||||
mViewInitiatedScroll(PR_FALSE),
|
||||
mFrameInitiatedScroll(PR_FALSE)
|
||||
mFrameInitiatedScroll(PR_FALSE),
|
||||
mDidHistoryRestore(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1208,10 +1211,65 @@ nsGfxScrollFrameInner::GetScrollbarStylesFromFrame() const
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* this code is resposible for restoring the scroll position back to some
|
||||
* saved positon. if the user has not moved the scroll position manually
|
||||
* we keep scrolling down until we get to our orignally position. keep in
|
||||
* mind that content could incrementally be coming in. we only want to stop
|
||||
* when we reach our new position.
|
||||
*/
|
||||
void
|
||||
nsGfxScrollFrameInner::ScrollToRestoredPosition()
|
||||
{
|
||||
NS_STATIC_CAST(nsScrollBoxFrame*, mScrollAreaBox)->ScrollToRestoredPosition();
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
if (!scrollingView) {
|
||||
return;
|
||||
}
|
||||
if (mRestoreRect.y == -1 || mLastPos.x == -1 || mLastPos.y == -1) {
|
||||
return;
|
||||
}
|
||||
// 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.
|
||||
nscoord x = 0;
|
||||
nscoord y = 0;
|
||||
scrollingView->GetScrollPosition(x, y);
|
||||
|
||||
// if we didn't move, we still need to restore
|
||||
if (x == mLastPos.x && y == mLastPos.y) {
|
||||
nsRect childRect(0, 0, 0, 0);
|
||||
nsIView* child = nsnull;
|
||||
nsresult rv = scrollingView->GetScrolledView(child);
|
||||
if (NS_SUCCEEDED(rv) && child)
|
||||
childRect = child->GetBounds();
|
||||
|
||||
PRInt32 cx, cy, x, y;
|
||||
scrollingView->GetScrollPosition(cx,cy);
|
||||
|
||||
x = (int)
|
||||
(((float)childRect.width / mRestoreRect.width) * mRestoreRect.x);
|
||||
y = (int)
|
||||
(((float)childRect.height / mRestoreRect.height) * mRestoreRect.y);
|
||||
|
||||
// if our position is greater than the scroll position, scroll.
|
||||
// remember that we could be incrementally loading so we may enter
|
||||
// and scroll many times.
|
||||
if (y > cy || x > cx) {
|
||||
scrollingView->ScrollTo(x, y, 0);
|
||||
// scrollpostion goes from twips to pixels. this fixes any roundoff
|
||||
// problems.
|
||||
scrollingView->GetScrollPosition(mLastPos.x, mLastPos.y);
|
||||
} else {
|
||||
// if we reached the position then stop
|
||||
mRestoreRect.y = -1;
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
}
|
||||
} else {
|
||||
// user moved the position, so we won't need to restore
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2032,6 +2090,8 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
|
|||
}
|
||||
}
|
||||
|
||||
ScrollToRestoredPosition();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2135,3 +2195,111 @@ nsGfxScrollFrameInner::GetIntegerAttribute(nsIBox* aBox, nsIAtom* atom, PRInt32
|
|||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIPresState>
|
||||
nsGfxScrollFrameInner::SaveState()
|
||||
{
|
||||
nsCOMPtr<nsIScrollbarMediator> mediator;
|
||||
nsIFrame* first = GetScrolledFrame();
|
||||
mediator = do_QueryInterface(first);
|
||||
if (mediator) {
|
||||
// Child manages its own scrolling. Bail.
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
PRInt32 x,y;
|
||||
scrollingView->GetScrollPosition(x,y);
|
||||
// Don't save scroll position if we are at (0,0)
|
||||
if (!x && !y) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIView* child = nsnull;
|
||||
scrollingView->GetScrolledView(child);
|
||||
if (!child) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsRect childRect = child->GetBounds();
|
||||
nsCOMPtr<nsIPresState> state;
|
||||
nsresult rv = NS_NewPresState(getter_AddRefs(state));
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(xoffset));
|
||||
if (xoffset) {
|
||||
rv = xoffset->SetData(x);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), xoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(yoffset));
|
||||
if (yoffset) {
|
||||
rv = yoffset->SetData(y);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), yoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(width));
|
||||
if (width) {
|
||||
rv = width->SetData(childRect.width);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("width"), width);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(height));
|
||||
if (height) {
|
||||
rv = height->SetData(childRect.height);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("height"), height);
|
||||
}
|
||||
nsIPresState* result = state;
|
||||
NS_ADDREF(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::RestoreState(nsIPresState* aState)
|
||||
{
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), getter_AddRefs(xoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), getter_AddRefs(yoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("width"), getter_AddRefs(width));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("height"), getter_AddRefs(height));
|
||||
|
||||
if (xoffset && yoffset) {
|
||||
PRInt32 x,y,w,h;
|
||||
nsresult rv = xoffset->GetData(&x);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = yoffset->GetData(&y);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = width->GetData(&w);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = height->GetData(&h);
|
||||
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
mRestoreRect.SetRect(-1, -1, -1, -1);
|
||||
|
||||
// don't do it now, store it later and do it in layout.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mRestoreRect.SetRect(x, y, w, h);
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
if (scrollingView) {
|
||||
scrollingView->GetScrollPosition(mLastPos.x, mLastPos.y);
|
||||
mDidHistoryRestore = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "nsBoxFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIScrollPositionListener.h"
|
||||
#include "nsIPresState.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
|
||||
class nsISupportsArray;
|
||||
class nsIScrollableView;
|
||||
|
@ -110,6 +112,9 @@ public:
|
|||
|
||||
void ScrollToRestoredPosition();
|
||||
|
||||
already_AddRefed<nsIPresState> SaveState();
|
||||
void RestoreState(nsIPresState* aState);
|
||||
|
||||
nsIFrame* GetScrolledFrame() const {
|
||||
nsIBox* childBox;
|
||||
nsIFrame* frame;
|
||||
|
@ -136,6 +141,9 @@ public:
|
|||
nsBoxFrame* mOuter;
|
||||
nscoord mMaxElementWidth;
|
||||
|
||||
nsRect mRestoreRect;
|
||||
nsPoint mLastPos;
|
||||
|
||||
// The last dir value we saw in AddHorizontalScrollbar. Use PRInt16
|
||||
// so we can fit all the possible values of a PRUint8 and have a -1
|
||||
// value that indicates "not set")
|
||||
|
@ -146,11 +154,9 @@ public:
|
|||
|
||||
PRPackedBool mHasVerticalScrollbar;
|
||||
PRPackedBool mHasHorizontalScrollbar;
|
||||
PRPackedBool mFirstPass;
|
||||
PRPackedBool mIsRoot;
|
||||
PRPackedBool mNeverReflowed;
|
||||
PRPackedBool mViewInitiatedScroll;
|
||||
PRPackedBool mFrameInitiatedScroll;
|
||||
PRPackedBool mDidHistoryRestore;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -164,7 +170,8 @@ public:
|
|||
*/
|
||||
class nsHTMLScrollFrame : public nsBoxFrame,
|
||||
public nsIScrollableFrame,
|
||||
public nsIAnonymousContentCreator {
|
||||
public nsIAnonymousContentCreator,
|
||||
public nsIStatefulFrame {
|
||||
public:
|
||||
friend nsresult NS_NewHTMLScrollFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
|
||||
PRBool aIsRoot);
|
||||
|
@ -248,6 +255,18 @@ public:
|
|||
|
||||
virtual void CurPosAttributeChanged(nsIContent* aChild, PRInt32 aModType);
|
||||
|
||||
// nsIStatefulFrame
|
||||
NS_IMETHOD SaveState(nsPresContext* aPresContext, nsIPresState** aState) {
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
*aState = mInner.SaveState().get();
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD RestoreState(nsPresContext* aPresContext, nsIPresState* aState) {
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
mInner.RestoreState(aState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual void ScrollToRestoredPosition() {
|
||||
mInner.ScrollToRestoredPosition();
|
||||
}
|
||||
|
@ -269,6 +288,8 @@ public:
|
|||
|
||||
virtual nsresult GetContentOf(nsIContent** aContent);
|
||||
|
||||
PRBool DidHistoryRestore() { return mInner.mDidHistoryRestore; }
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
|
||||
#endif
|
||||
|
@ -293,7 +314,8 @@ private:
|
|||
*/
|
||||
class nsXULScrollFrame : public nsBoxFrame,
|
||||
public nsIScrollableFrame,
|
||||
public nsIAnonymousContentCreator {
|
||||
public nsIAnonymousContentCreator,
|
||||
public nsIStatefulFrame {
|
||||
public:
|
||||
friend nsresult NS_NewXULScrollFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
|
||||
PRBool aIsRoot);
|
||||
|
@ -377,6 +399,18 @@ public:
|
|||
|
||||
virtual void CurPosAttributeChanged(nsIContent* aChild, PRInt32 aModType);
|
||||
|
||||
// nsIStatefulFrame
|
||||
NS_IMETHOD SaveState(nsPresContext* aPresContext, nsIPresState** aState) {
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
*aState = mInner.SaveState().get();
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD RestoreState(nsPresContext* aPresContext, nsIPresState* aState) {
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
mInner.RestoreState(aState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual void ScrollToRestoredPosition() {
|
||||
mInner.ScrollToRestoredPosition();
|
||||
}
|
||||
|
|
|
@ -3511,14 +3511,8 @@ PresShell::EndLoad(nsIDocument *aDocument)
|
|||
CallQueryInterface(scrollFrame, &scrollableFrame);
|
||||
NS_ASSERTION(scrollableFrame, "RootScrollFrame is not scrollable?");
|
||||
if (scrollableFrame) {
|
||||
// XXX We shouldn't depend on the scrolling guts here. Make this
|
||||
// go away!
|
||||
nsIFrame* scrollBoxFrame = scrollFrame->GetFirstChild(nsnull);
|
||||
|
||||
if (scrollBoxFrame) {
|
||||
FrameManager()->RestoreFrameStateFor(scrollBoxFrame, historyState,
|
||||
nsIStatefulFrame::eDocumentScrollState);
|
||||
}
|
||||
FrameManager()->RestoreFrameStateFor(scrollFrame, historyState,
|
||||
nsIStatefulFrame::eDocumentScrollState);
|
||||
scrollableFrame->ScrollToRestoredPosition();
|
||||
}
|
||||
}
|
||||
|
@ -4503,13 +4497,8 @@ PresShell::CaptureHistoryState(nsILayoutHistoryState** aState, PRBool aLeavingPa
|
|||
if (aLeavingPage) {
|
||||
nsIFrame* scrollFrame = GetRootScrollFrame(rootFrame);
|
||||
if (scrollFrame) {
|
||||
// XXX We shouldn't depend on the scrolling guts here. Make this
|
||||
// go away!
|
||||
nsIFrame* scrollBoxFrame = scrollFrame->GetFirstChild(nsnull);
|
||||
if (scrollBoxFrame) {
|
||||
FrameManager()->CaptureFrameStateFor(scrollBoxFrame, historyState,
|
||||
nsIStatefulFrame::eDocumentScrollState);
|
||||
}
|
||||
FrameManager()->CaptureFrameStateFor(scrollFrame, historyState,
|
||||
nsIStatefulFrame::eDocumentScrollState);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -294,6 +294,7 @@ nsListControlFrame::nsListControlFrame(nsIPresShell* aShell,
|
|||
mIsAllFramesHere = PR_FALSE;
|
||||
mHasBeenInitialized = PR_FALSE;
|
||||
mNeedToReset = PR_TRUE;
|
||||
mPostChildrenLoadedReset = PR_FALSE;
|
||||
|
||||
mCacheSize.width = -1;
|
||||
mCacheSize.height = -1;
|
||||
|
@ -558,129 +559,9 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|||
*aInstancePtr = (void *)((nsISelectControlFrame*)this);
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) {
|
||||
*aInstancePtr =
|
||||
NS_STATIC_CAST(void*,NS_STATIC_CAST(nsIStatefulFrame*,this));
|
||||
return NS_OK;
|
||||
}
|
||||
return nsHTMLScrollFrame::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIStatefulFrame
|
||||
// These methods were originally in the nsScrollFrame superclass,
|
||||
// but were moved here when nsListControlFrame switched to use
|
||||
// nsHTMLScrollFrame.
|
||||
//----------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::SaveState(nsPresContext* aPresContext,
|
||||
nsIPresState** aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsCOMPtr<nsIPresState> state;
|
||||
nsresult res = NS_OK;
|
||||
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
|
||||
nscoord x = 0, y = 0;
|
||||
if (scrollingView) {
|
||||
scrollingView->GetScrollPosition(x, y);
|
||||
}
|
||||
|
||||
// Don't save scroll position if we are at (0,0)
|
||||
if (x || y) {
|
||||
nsIView* child = nsnull;
|
||||
scrollingView->GetScrolledView(child);
|
||||
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
|
||||
|
||||
nsRect childRect = child->GetBounds();
|
||||
|
||||
res = NS_NewPresState(getter_AddRefs(state));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset =
|
||||
do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID, &res);
|
||||
if (xoffset) {
|
||||
res = xoffset->SetData(x);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), xoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset =
|
||||
do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID, &res);
|
||||
if (yoffset) {
|
||||
res = yoffset->SetData(y);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), yoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> width =
|
||||
do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID, &res);
|
||||
if (width) {
|
||||
res = width->SetData(childRect.width);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("width"), width);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> height =
|
||||
do_CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID, &res);
|
||||
if (height) {
|
||||
res = height->SetData(childRect.height);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("height"), height);
|
||||
}
|
||||
*aState = state;
|
||||
NS_ADDREF(*aState);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsListControlFrame::RestoreState(nsPresContext* aPresContext,
|
||||
nsIPresState* aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), getter_AddRefs(xoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), getter_AddRefs(yoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("width"), getter_AddRefs(width));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("height"), getter_AddRefs(height));
|
||||
|
||||
nsresult res = NS_ERROR_NULL_POINTER;
|
||||
if (xoffset && yoffset) {
|
||||
PRInt32 x,y,w,h;
|
||||
res = xoffset->GetData(&x);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = yoffset->GetData(&y);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = width->GetData(&w);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = height->GetData(&h);
|
||||
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
nsIScrollableView* scrollingView = GetScrollableView();
|
||||
if (scrollingView) {
|
||||
nsIView* child = nsnull;
|
||||
nsRect childRect(0,0,0,0);
|
||||
if (NS_SUCCEEDED(scrollingView->GetScrolledView(child)) && child) {
|
||||
childRect = child->GetBounds();
|
||||
}
|
||||
x = (int)(((float)childRect.width / w) * x);
|
||||
y = (int)(((float)childRect.height / h) * y);
|
||||
|
||||
scrollingView->ScrollTo(x,y,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
NS_IMETHODIMP nsListControlFrame::GetAccessible(nsIAccessible** aAccessible)
|
||||
{
|
||||
|
@ -1885,7 +1766,7 @@ nsListControlFrame::MouseClicked(nsPresContext* aPresContext)
|
|||
NS_IMETHODIMP
|
||||
nsListControlFrame::OnContentReset()
|
||||
{
|
||||
ResetList();
|
||||
ResetList(PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1894,7 +1775,7 @@ nsListControlFrame::OnContentReset()
|
|||
// those values as determined by the original HTML
|
||||
//---------------------------------------------------------
|
||||
void
|
||||
nsListControlFrame::ResetList()
|
||||
nsListControlFrame::ResetList(PRBool aAllowScrolling)
|
||||
{
|
||||
REFLOW_DEBUG_MSG("LBX::ResetList\n");
|
||||
|
||||
|
@ -1904,14 +1785,18 @@ nsListControlFrame::ResetList()
|
|||
return;
|
||||
}
|
||||
|
||||
// Scroll to the selected index
|
||||
PRInt32 indexToSelect = kNothingSelected;
|
||||
if (aAllowScrolling) {
|
||||
mPostChildrenLoadedReset = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement(do_QueryInterface(mContent));
|
||||
NS_ASSERTION(selectElement, "No select element!");
|
||||
if (selectElement) {
|
||||
selectElement->GetSelectedIndex(&indexToSelect);
|
||||
ScrollToIndex(indexToSelect);
|
||||
// Scroll to the selected index
|
||||
PRInt32 indexToSelect = kNothingSelected;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement(do_QueryInterface(mContent));
|
||||
NS_ASSERTION(selectElement, "No select element!");
|
||||
if (selectElement) {
|
||||
selectElement->GetSelectedIndex(&indexToSelect);
|
||||
ScrollToIndex(indexToSelect);
|
||||
}
|
||||
}
|
||||
|
||||
mStartSelectionIndex = kNothingSelected;
|
||||
|
@ -2095,7 +1980,7 @@ nsListControlFrame::DoneAddingChildren(PRBool aIsDone)
|
|||
// if all the frames are now present we can initalize
|
||||
if (CheckIfAllFramesHere()) {
|
||||
mHasBeenInitialized = PR_TRUE;
|
||||
ResetList();
|
||||
ResetList(PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2129,6 +2014,7 @@ nsListControlFrame::AddOption(nsPresContext* aPresContext, PRInt32 aIndex)
|
|||
|
||||
// Make sure we scroll to the selected option as needed
|
||||
mNeedToReset = PR_TRUE;
|
||||
mPostChildrenLoadedReset = mIsAllContentHere;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2139,6 +2025,7 @@ nsListControlFrame::RemoveOption(nsPresContext* aPresContext, PRInt32 aIndex)
|
|||
// Need to reset if we're a dropdown
|
||||
if (IsInDropDownMode()) {
|
||||
mNeedToReset = PR_TRUE;
|
||||
mPostChildrenLoadedReset = mIsAllContentHere;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2444,7 +2331,16 @@ nsListControlFrame::DidReflow(nsPresContext* aPresContext,
|
|||
|
||||
if (mNeedToReset) {
|
||||
mNeedToReset = PR_FALSE;
|
||||
ResetList();
|
||||
// Suppress scrolling to the selected element if we restored
|
||||
// scroll history state AND the list contents have not changed
|
||||
// since we loaded all the children AND nothing else forced us
|
||||
// to scroll by calling ResetList(PR_TRUE). The latter two conditions
|
||||
// are folded into mPostChildrenLoadedReset.
|
||||
//
|
||||
// The idea is that we want scroll history restoration to trump ResetList
|
||||
// scrolling to the selected element, when the ResetList was probably only
|
||||
// caused by content loading normally.
|
||||
ResetList(!DidHistoryRestore() || mPostChildrenLoadedReset);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -2841,6 +2737,8 @@ nsresult
|
|||
nsListControlFrame::ScrollToIndex(PRInt32 aIndex)
|
||||
{
|
||||
if (aIndex < 0) {
|
||||
// XXX shouldn't we just do nothing if we're asked to scroll to
|
||||
// kNothingSelected?
|
||||
return ScrollToFrame(nsnull);
|
||||
} else {
|
||||
nsCOMPtr<nsIContent> content = getter_AddRefs(GetOptionContent(aIndex));
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#include "nsIFormControlFrame.h"
|
||||
#include "nsIListControlFrame.h"
|
||||
#include "nsISelectControlFrame.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIPresState.h"
|
||||
#include "nsIContent.h"
|
||||
|
@ -77,7 +76,6 @@ class nsListEventListener;
|
|||
class nsListControlFrame : public nsHTMLScrollFrame,
|
||||
public nsIFormControlFrame,
|
||||
public nsIListControlFrame,
|
||||
public nsIStatefulFrame,
|
||||
public nsISelectControlFrame
|
||||
{
|
||||
public:
|
||||
|
@ -190,10 +188,6 @@ public:
|
|||
NS_IMETHOD GetDummyFrame(nsIFrame** aFrame);
|
||||
NS_IMETHOD SetDummyFrame(nsIFrame* aFrame);
|
||||
|
||||
//nsIStatefulFrame
|
||||
NS_IMETHOD SaveState(nsPresContext* aPresContext, nsIPresState** aState);
|
||||
NS_IMETHOD RestoreState(nsPresContext* aPresContext, nsIPresState* aState);
|
||||
|
||||
// mouse event listeners
|
||||
nsresult MouseDown(nsIDOMEvent* aMouseEvent);
|
||||
nsresult MouseUp(nsIDOMEvent* aMouseEvent);
|
||||
|
@ -231,7 +225,7 @@ protected:
|
|||
PRBool IsClickingInCombobox(nsIDOMEvent* aMouseEvent);
|
||||
void AdjustIndexForDisabledOpt(PRInt32 aStartIndex, PRInt32 &anNewIndex,
|
||||
PRInt32 aNumOptions, PRInt32 aDoAdjustInc, PRInt32 aDoAdjustIncNext);
|
||||
virtual void ResetList();
|
||||
virtual void ResetList(PRBool aAllowScrolling);
|
||||
|
||||
nsListControlFrame(nsIPresShell* aShell, nsIDocument* aDocument);
|
||||
virtual ~nsListControlFrame();
|
||||
|
@ -282,6 +276,7 @@ protected:
|
|||
PRPackedBool mIsAllFramesHere;
|
||||
PRPackedBool mHasBeenInitialized;
|
||||
PRPackedBool mNeedToReset;
|
||||
PRPackedBool mPostChildrenLoadedReset;
|
||||
|
||||
PRPackedBool mOverrideReflowOpt;
|
||||
|
||||
|
|
|
@ -84,9 +84,7 @@ NS_NewScrollBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsScrollBoxFrame::nsScrollBoxFrame(nsIPresShell* aShell):nsBoxFrame(aShell), mVerticalOverflow(PR_FALSE), mHorizontalOverflow(PR_FALSE),
|
||||
mRestoreRect(-1, -1, -1, -1),
|
||||
mLastPos(-1, -1)
|
||||
nsScrollBoxFrame::nsScrollBoxFrame(nsIPresShell* aShell):nsBoxFrame(aShell), mVerticalOverflow(PR_FALSE), mHorizontalOverflow(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -438,76 +436,9 @@ 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
|
||||
* we keep scrolling down until we get to our orignally position. keep in
|
||||
* 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 (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.
|
||||
nsIScrollableView* scrollingView;
|
||||
CallQueryInterface(view, &scrollingView);
|
||||
if (scrollingView) {
|
||||
nscoord x = 0;
|
||||
nscoord y = 0;
|
||||
scrollingView->GetScrollPosition(x, y);
|
||||
|
||||
// if we didn't move, we still need to restore
|
||||
if ((x == mLastPos.x) && (y == mLastPos.y)) {
|
||||
nsRect childRect(0, 0, 0, 0);
|
||||
nsIView* child = nsnull;
|
||||
nsresult rv = scrollingView->GetScrolledView(child);
|
||||
if (NS_SUCCEEDED(rv) && child)
|
||||
childRect = child->GetBounds();
|
||||
|
||||
PRInt32 cx, cy, x, y;
|
||||
scrollingView->GetScrollPosition(cx,cy);
|
||||
|
||||
x = (int)
|
||||
(((float)childRect.width / mRestoreRect.width) * mRestoreRect.x);
|
||||
y = (int)
|
||||
(((float)childRect.height / mRestoreRect.height) * mRestoreRect.y);
|
||||
|
||||
// if our position is greater than the scroll position, scroll.
|
||||
// remember that we could be incrementally loading so we may enter
|
||||
// and scroll many times.
|
||||
if ((y > cy) || (x > cx)) {
|
||||
scrollingView->ScrollTo(x, y, 0);
|
||||
// scrollpostion goes from twips to pixels. this fixes any roundoff
|
||||
// problems.
|
||||
scrollingView->GetScrollPosition(mLastPos.x, mLastPos.y);
|
||||
}
|
||||
else {
|
||||
// if we reached the position then stop
|
||||
mRestoreRect.y = -1;
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// user moved the position, so we won't need to restore
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollBoxFrame::PostScrollPortEvent(nsIPresShell* aShell, PRBool aOverflow, nsScrollPortEvent::orientType aType)
|
||||
{
|
||||
|
@ -638,140 +569,9 @@ nsScrollBoxFrame::Release(void)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIStatefulFrame
|
||||
//----------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::SaveState(nsPresContext* aPresContext,
|
||||
nsIPresState** aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
|
||||
nsCOMPtr<nsIScrollbarMediator> mediator;
|
||||
nsIFrame* first = mFrames.FirstChild();
|
||||
mediator = do_QueryInterface(first);
|
||||
if (mediator) {
|
||||
// Child manages its own scrolling. Bail.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresState> state;
|
||||
nsresult res = NS_OK;
|
||||
|
||||
nsIView* view = GetView();
|
||||
NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
|
||||
|
||||
PRInt32 x,y;
|
||||
nsIScrollableView* scrollingView;
|
||||
res = CallQueryInterface(view, &scrollingView);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
scrollingView->GetScrollPosition(x,y);
|
||||
|
||||
// Don't save scroll position if we are at (0,0)
|
||||
if (x || y) {
|
||||
|
||||
nsIView* child = nsnull;
|
||||
scrollingView->GetScrolledView(child);
|
||||
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
|
||||
|
||||
nsRect childRect = child->GetBounds();
|
||||
|
||||
res = NS_NewPresState(getter_AddRefs(state));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(xoffset));
|
||||
if (xoffset) {
|
||||
res = xoffset->SetData(x);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), xoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(yoffset));
|
||||
if (yoffset) {
|
||||
res = yoffset->SetData(y);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), yoffset);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(width));
|
||||
if (width) {
|
||||
res = width->SetData(childRect.width);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("width"), width);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_CONTRACTID,
|
||||
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(height));
|
||||
if (height) {
|
||||
res = height->SetData(childRect.height);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
state->SetStatePropertyAsSupports(NS_LITERAL_STRING("height"), height);
|
||||
}
|
||||
*aState = state;
|
||||
NS_ADDREF(*aState);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsScrollBoxFrame::RestoreState(nsPresContext* aPresContext,
|
||||
nsIPresState* aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
|
||||
nsCOMPtr<nsISupportsPRInt32> xoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> yoffset;
|
||||
nsCOMPtr<nsISupportsPRInt32> width;
|
||||
nsCOMPtr<nsISupportsPRInt32> height;
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("x-offset"), getter_AddRefs(xoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("y-offset"), getter_AddRefs(yoffset));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("width"), getter_AddRefs(width));
|
||||
aState->GetStatePropertyAsSupports(NS_LITERAL_STRING("height"), getter_AddRefs(height));
|
||||
|
||||
nsresult res = NS_ERROR_NULL_POINTER;
|
||||
if (xoffset && yoffset) {
|
||||
PRInt32 x,y,w,h;
|
||||
res = xoffset->GetData(&x);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = yoffset->GetData(&y);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = width->GetData(&w);
|
||||
if (NS_SUCCEEDED(res))
|
||||
res = height->GetData(&h);
|
||||
|
||||
mLastPos.x = -1;
|
||||
mLastPos.y = -1;
|
||||
mRestoreRect.SetRect(-1, -1, -1, -1);
|
||||
|
||||
// don't do it now, store it later and do it in layout.
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
mRestoreRect.SetRect(x, y, w, h);
|
||||
nsIView* view = GetView();
|
||||
if (!view)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIScrollableView* scrollingView;
|
||||
CallQueryInterface(view, &scrollingView);
|
||||
if (scrollingView)
|
||||
scrollingView->GetScrollPosition(mLastPos.x, mLastPos.y);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsScrollBoxFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIBox)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStatefulFrame)
|
||||
#ifdef NS_DEBUG
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFrameDebug)
|
||||
#endif
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
* Scroll frames don't support incremental changes, i.e. you can't replace
|
||||
* or remove the scrolled frame
|
||||
*/
|
||||
class nsScrollBoxFrame : public nsBoxFrame, public nsIStatefulFrame {
|
||||
class nsScrollBoxFrame : public nsBoxFrame {
|
||||
public:
|
||||
friend nsresult NS_NewScrollBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
|
@ -124,8 +124,6 @@ public:
|
|||
|
||||
virtual nsIView* GetMouseCapturer() const;
|
||||
|
||||
void ScrollToRestoredPosition();
|
||||
|
||||
protected:
|
||||
nsScrollBoxFrame(nsIPresShell* aShell);
|
||||
|
||||
|
@ -137,17 +135,11 @@ protected:
|
|||
nsIFrame* aParent,
|
||||
nsIView** aParentView);
|
||||
|
||||
//nsIStatefulFrame
|
||||
NS_IMETHOD SaveState(nsPresContext* aPresContext, nsIPresState** aState);
|
||||
NS_IMETHOD RestoreState(nsPresContext* aPresContext, nsIPresState* aState);
|
||||
|
||||
private:
|
||||
nsresult CreateScrollingView(nsPresContext* aPresContext);
|
||||
PRPackedBool mVerticalOverflow;
|
||||
PRPackedBool mHorizontalOverflow;
|
||||
nsRect mRestoreRect;
|
||||
nsPoint mLastPos;
|
||||
|
||||
|
||||
protected:
|
||||
virtual PRBool NeedsClipWidget();
|
||||
virtual void PostScrollPortEvent(nsIPresShell* aShell, PRBool aOverflow, nsScrollPortEvent::orientType aType);
|
||||
|
|
Загрузка…
Ссылка в новой задаче