- Added setter for history state to nsIPresShell

- Added capture/restore frame state methods to nsIFrameManager
- Added a getter for state type to nsIStatefulFrame.
- Changed the save/restore method parameters  in nsIStateful frame
  so that only the frame state gets passed to the stateful frame.
- Implemented all the new interface methods in the respective implementation classes.
This commit is contained in:
nisheeth%netscape.com 1999-08-31 14:35:50 +00:00
parent 18b5e04d18
commit dfd7b5d559
9 changed files with 281 additions and 86 deletions

View File

@ -30,6 +30,9 @@
#ifdef NS_DEBUG
#include "nsLayoutAtoms.h"
#endif
#include "nsILayoutHistoryState.h"
#include "nsIStatefulFrame.h"
#include "nsIContent.h"
// Class IID's
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
@ -134,6 +137,10 @@ public:
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
NS_IMETHOD CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
NS_IMETHOD RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
private:
nsIPresShell* mPresShell; // weak link, because the pres shell owns us
nsIStyleSet* mStyleSet; // weak link. pres shell holds a reference
@ -557,6 +564,109 @@ FrameManager::CantRenderReplacedElement(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{
nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame);
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.
nsCOMPtr<nsIContent> content;
rv = aFrame->GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)) {
PRUint32 ID;
rv = content->GetContentID(&ID);
if (NS_SUCCEEDED(rv)) {
PRInt32 type = NS_HISTORY_STATE_TYPE_NONE;
rv = statefulFrame->GetStateType(&type);
if (NS_SUCCEEDED(rv)) {
nsISupports* frameState;
rv = statefulFrame->SaveState(&frameState);
if (NS_SUCCEEDED(rv)) {
rv = aState->AddState(ID, frameState, type);
}
}
}
}
}
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// Capture frame state for the first child
nsIFrame* child = nsnull;
rv = aFrame->FirstChild(nsnull, &child);
if (NS_SUCCEEDED(rv) && nsnull != child) {
rv = CaptureFrameState(child, aState);
}
// Capture frame state for the next sibling
nsIFrame* sibling = nsnull;
rv = aFrame->GetNextSibling(&sibling);
if (NS_SUCCEEDED(rv) && nsnull != sibling) {
rv = CaptureFrameState(sibling, aState);
}
return rv;
}
NS_IMETHODIMP
FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{
nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame);
if (nsnull != statefulFrame) {
// If so, get the content ID, state type and the frame state and
// ask the frame object to restore its state.
nsCOMPtr<nsIContent> content;
rv = aFrame->GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)) {
PRUint32 ID;
rv = content->GetContentID(&ID);
if (NS_SUCCEEDED(rv)) {
PRInt32 type = NS_HISTORY_STATE_TYPE_NONE;
rv = statefulFrame->GetStateType(&type);
if (NS_SUCCEEDED(rv)) {
nsISupports* frameState = nsnull;
rv = aState->GetState(ID, &frameState, type);
if (NS_SUCCEEDED(rv) && nsnull != frameState) {
rv = statefulFrame->RestoreState(frameState);
}
}
}
}
}
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// Capture frame state for the first child
nsIFrame* child = nsnull;
rv = aFrame->FirstChild(nsnull, &child);
if (NS_SUCCEEDED(rv) && nsnull != child) {
rv = RestoreFrameState(child, aState);
}
// Capture frame state for the next sibling
nsIFrame* sibling = nsnull;
rv = aFrame->GetNextSibling(&sibling);
if (NS_SUCCEEDED(rv) && nsnull != sibling) {
rv = RestoreFrameState(sibling, aState);
}
return rv;
}
//----------------------------------------------------------------------
static PLHashNumber

View File

@ -339,16 +339,10 @@ public:
// XXX selection
/**
* Get the history state for the current document
* Get and set the history state for the current document
*/
NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState) = 0;
/**
* Capture frame state for the frame subtree rooted at aFrame.
* aState is the document state storage object onto which each frame
* stores its state.
*/
NS_IMETHOD CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) = 0;
NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState) = 0;
/**
* See if reflow verification is enabled. To enable reflow verification add

View File

@ -63,7 +63,6 @@
#include "nsIFrameManager.h"
#include "nsISupportsPrimitives.h"
#include "nsILayoutHistoryState.h"
#include "nsIStatefulFrame.h"
// Drag & Drop, Clipboard
#include "nsWidgetsCID.h"
@ -176,8 +175,9 @@ public:
NS_IMETHOD GetFrameManager(nsIFrameManager** aFrameManager) const;
NS_IMETHOD DoCopy();
NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState);
NS_IMETHOD CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState);
//nsIViewObserver interface
@ -287,6 +287,7 @@ protected:
nsCOMPtr<nsIStyleSet> mStyleSet;
nsIFrame* mRootFrame;
nsIViewManager* mViewManager; // [WEAK] docViewer owns it so I don't have to
nsILayoutHistoryState* mHistoryState; // [WEAK] session history owns this
PRUint32 mUpdateCount;
nsVoidArray mReflowCommands;
PRUint32 mReflowLockCount;
@ -510,6 +511,8 @@ PresShell::Init(nsIDocument* aDocument,
mStyleSet = dont_QueryInterface(aStyleSet);
mHistoryState = nsnull;
nsresult result = nsComponentManager::CreateInstance(kFrameSelectionCID, nsnull,
nsIFrameSelection::GetIID(),
getter_AddRefs(mSelection));
@ -1574,43 +1577,16 @@ PresShell::GetHistoryState(nsILayoutHistoryState** aState)
rv = GetRootFrame(&rootFrame);
if (NS_FAILED(rv) || nsnull == rootFrame) return rv;
rv = CaptureFrameState(rootFrame, *aState);
rv = mFrameManager->CaptureFrameState(rootFrame, *aState);
return rv;
}
NS_IMETHODIMP
PresShell::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
PresShell::SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState)
{
nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame);
if (nsnull != statefulFrame) {
// If so, ask the frame to save its state
rv = statefulFrame->SaveState(aState);
}
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// Capture frame state for the first child
nsIFrame* child = nsnull;
rv = aFrame->FirstChild(nsnull, &child);
if (NS_SUCCEEDED(rv) && nsnull != child) {
rv = CaptureFrameState(child, aState);
}
// Capture frame state for the next sibling
nsIFrame* sibling = nsnull;
rv = aFrame->GetNextSibling(&sibling);
if (NS_SUCCEEDED(rv) && nsnull != sibling) {
rv = CaptureFrameState(sibling, aState);
}
return rv;
mHistoryState = aLayoutHistoryState;
return NS_OK;
}
NS_IMETHODIMP
@ -1663,6 +1639,17 @@ PresShell::ContentAppended(nsIDocument *aDocument,
{
EnterReflowLock();
nsresult rv = mStyleSet->ContentAppended(mPresContext, aContainer, aNewIndexInContainer);
if (NS_SUCCEEDED(rv) && nsnull != mHistoryState) {
// If history state has been set by session history, ask the frame manager
// to restore frame state for the frame hierarchy created for the chunk of
// content that just came in.
nsIFrame* frame = nsnull;
rv = GetPrimaryFrameFor(aContainer, &frame);
if (NS_SUCCEEDED(rv))
mFrameManager->RestoreFrameState(frame, mHistoryState);
}
ExitReflowLock();
return rv;
}

View File

@ -27,6 +27,7 @@ class nsIFrame;
class nsIPresContext;
class nsIPresShell;
class nsIStyleSet;
class nsILayoutHistoryState;
#define NS_IFRAMEMANAGER_IID \
{ 0xa6cf9107, 0x15b3, 0x11d2, \
@ -91,6 +92,14 @@ public:
// Notification that a frame is about to be destroyed. This allows any outstanding
// references to the frame to be cleaned up
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame) = 0;
/**
* Capture/restore frame state for the frame subtree rooted at aFrame.
* aState is the document state storage object onto which each frame
* stores its state.
*/
NS_IMETHOD CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) = 0;
NS_IMETHOD RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) = 0;
};
/**

View File

@ -339,16 +339,10 @@ public:
// XXX selection
/**
* Get the history state for the current document
* Get and set the history state for the current document
*/
NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState) = 0;
/**
* Capture frame state for the frame subtree rooted at aFrame.
* aState is the document state storage object onto which each frame
* stores its state.
*/
NS_IMETHOD CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState) = 0;
NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState) = 0;
/**
* See if reflow verification is enabled. To enable reflow verification add

View File

@ -13,8 +13,10 @@ class nsIStatefulFrame : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISTATEFULFRAME_IID)
NS_IMETHOD SaveState(nsILayoutHistoryState* aState) = 0;
NS_IMETHOD RestoreState(nsILayoutHistoryState* aState) = 0;
NS_IMETHOD GetStateType(PRInt32* aStateType) = 0;
NS_IMETHOD SaveState(nsISupports** aState) = 0;
NS_IMETHOD RestoreState(nsISupports* aState) = 0;
};
#endif /* _nsIStatefulFrame_h */

View File

@ -13,8 +13,10 @@ class nsIStatefulFrame : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISTATEFULFRAME_IID)
NS_IMETHOD SaveState(nsILayoutHistoryState* aState) = 0;
NS_IMETHOD RestoreState(nsILayoutHistoryState* aState) = 0;
NS_IMETHOD GetStateType(PRInt32* aStateType) = 0;
NS_IMETHOD SaveState(nsISupports** aState) = 0;
NS_IMETHOD RestoreState(nsISupports* aState) = 0;
};
#endif /* _nsIStatefulFrame_h */

View File

@ -30,6 +30,9 @@
#ifdef NS_DEBUG
#include "nsLayoutAtoms.h"
#endif
#include "nsILayoutHistoryState.h"
#include "nsIStatefulFrame.h"
#include "nsIContent.h"
// Class IID's
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
@ -134,6 +137,10 @@ public:
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
NS_IMETHOD CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
NS_IMETHOD RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
private:
nsIPresShell* mPresShell; // weak link, because the pres shell owns us
nsIStyleSet* mStyleSet; // weak link. pres shell holds a reference
@ -557,6 +564,109 @@ FrameManager::CantRenderReplacedElement(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
FrameManager::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{
nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame);
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.
nsCOMPtr<nsIContent> content;
rv = aFrame->GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)) {
PRUint32 ID;
rv = content->GetContentID(&ID);
if (NS_SUCCEEDED(rv)) {
PRInt32 type = NS_HISTORY_STATE_TYPE_NONE;
rv = statefulFrame->GetStateType(&type);
if (NS_SUCCEEDED(rv)) {
nsISupports* frameState;
rv = statefulFrame->SaveState(&frameState);
if (NS_SUCCEEDED(rv)) {
rv = aState->AddState(ID, frameState, type);
}
}
}
}
}
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// Capture frame state for the first child
nsIFrame* child = nsnull;
rv = aFrame->FirstChild(nsnull, &child);
if (NS_SUCCEEDED(rv) && nsnull != child) {
rv = CaptureFrameState(child, aState);
}
// Capture frame state for the next sibling
nsIFrame* sibling = nsnull;
rv = aFrame->GetNextSibling(&sibling);
if (NS_SUCCEEDED(rv) && nsnull != sibling) {
rv = CaptureFrameState(sibling, aState);
}
return rv;
}
NS_IMETHODIMP
FrameManager::RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
{
nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame);
if (nsnull != statefulFrame) {
// If so, get the content ID, state type and the frame state and
// ask the frame object to restore its state.
nsCOMPtr<nsIContent> content;
rv = aFrame->GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)) {
PRUint32 ID;
rv = content->GetContentID(&ID);
if (NS_SUCCEEDED(rv)) {
PRInt32 type = NS_HISTORY_STATE_TYPE_NONE;
rv = statefulFrame->GetStateType(&type);
if (NS_SUCCEEDED(rv)) {
nsISupports* frameState = nsnull;
rv = aState->GetState(ID, &frameState, type);
if (NS_SUCCEEDED(rv) && nsnull != frameState) {
rv = statefulFrame->RestoreState(frameState);
}
}
}
}
}
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// Capture frame state for the first child
nsIFrame* child = nsnull;
rv = aFrame->FirstChild(nsnull, &child);
if (NS_SUCCEEDED(rv) && nsnull != child) {
rv = RestoreFrameState(child, aState);
}
// Capture frame state for the next sibling
nsIFrame* sibling = nsnull;
rv = aFrame->GetNextSibling(&sibling);
if (NS_SUCCEEDED(rv) && nsnull != sibling) {
rv = RestoreFrameState(sibling, aState);
}
return rv;
}
//----------------------------------------------------------------------
static PLHashNumber

View File

@ -63,7 +63,6 @@
#include "nsIFrameManager.h"
#include "nsISupportsPrimitives.h"
#include "nsILayoutHistoryState.h"
#include "nsIStatefulFrame.h"
// Drag & Drop, Clipboard
#include "nsWidgetsCID.h"
@ -176,8 +175,9 @@ public:
NS_IMETHOD GetFrameManager(nsIFrameManager** aFrameManager) const;
NS_IMETHOD DoCopy();
NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState);
NS_IMETHOD CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState);
NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState);
//nsIViewObserver interface
@ -287,6 +287,7 @@ protected:
nsCOMPtr<nsIStyleSet> mStyleSet;
nsIFrame* mRootFrame;
nsIViewManager* mViewManager; // [WEAK] docViewer owns it so I don't have to
nsILayoutHistoryState* mHistoryState; // [WEAK] session history owns this
PRUint32 mUpdateCount;
nsVoidArray mReflowCommands;
PRUint32 mReflowLockCount;
@ -510,6 +511,8 @@ PresShell::Init(nsIDocument* aDocument,
mStyleSet = dont_QueryInterface(aStyleSet);
mHistoryState = nsnull;
nsresult result = nsComponentManager::CreateInstance(kFrameSelectionCID, nsnull,
nsIFrameSelection::GetIID(),
getter_AddRefs(mSelection));
@ -1574,43 +1577,16 @@ PresShell::GetHistoryState(nsILayoutHistoryState** aState)
rv = GetRootFrame(&rootFrame);
if (NS_FAILED(rv) || nsnull == rootFrame) return rv;
rv = CaptureFrameState(rootFrame, *aState);
rv = mFrameManager->CaptureFrameState(rootFrame, *aState);
return rv;
}
NS_IMETHODIMP
PresShell::CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState)
PresShell::SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState)
{
nsresult rv = NS_OK;
NS_PRECONDITION(nsnull != aFrame && nsnull != aState, "null parameters passed in");
// See if the frame is stateful.
nsCOMPtr<nsIStatefulFrame> statefulFrame = do_QueryInterface(aFrame);
if (nsnull != statefulFrame) {
// If so, ask the frame to save its state
rv = statefulFrame->SaveState(aState);
}
// XXX We are only going through the principal child list right now.
// Need to talk to Troy to find out about other kinds of
// child lists and whether they will contain stateful frames.
// Capture frame state for the first child
nsIFrame* child = nsnull;
rv = aFrame->FirstChild(nsnull, &child);
if (NS_SUCCEEDED(rv) && nsnull != child) {
rv = CaptureFrameState(child, aState);
}
// Capture frame state for the next sibling
nsIFrame* sibling = nsnull;
rv = aFrame->GetNextSibling(&sibling);
if (NS_SUCCEEDED(rv) && nsnull != sibling) {
rv = CaptureFrameState(sibling, aState);
}
return rv;
mHistoryState = aLayoutHistoryState;
return NS_OK;
}
NS_IMETHODIMP
@ -1663,6 +1639,17 @@ PresShell::ContentAppended(nsIDocument *aDocument,
{
EnterReflowLock();
nsresult rv = mStyleSet->ContentAppended(mPresContext, aContainer, aNewIndexInContainer);
if (NS_SUCCEEDED(rv) && nsnull != mHistoryState) {
// If history state has been set by session history, ask the frame manager
// to restore frame state for the frame hierarchy created for the chunk of
// content that just came in.
nsIFrame* frame = nsnull;
rv = GetPrimaryFrameFor(aContainer, &frame);
if (NS_SUCCEEDED(rv))
mFrameManager->RestoreFrameState(frame, mHistoryState);
}
ExitReflowLock();
return rv;
}