Split nsIContentViewer::destroy into close and destroy so we can trigger teardown both at the beginning and at the end of paint suppression. Move the PresShell's teardown from its destructor into EndObservingDocument so it happens at the end of paint suppression. b=80203,89626 r=hyatt sr=waterson

This commit is contained in:
dbaron%fas.harvard.edu 2001-07-25 04:30:59 +00:00
Родитель 718bf64106
Коммит 08b178d117
10 изменённых файлов: 375 добавлений и 361 удалений

Просмотреть файл

@ -372,30 +372,7 @@ public:
NS_DECL_ISUPPORTS
// nsIContentViewer interface...
NS_IMETHOD Init(nsIWidget* aParentWidget,
nsIDeviceContext* aDeviceContext,
const nsRect& aBounds);
NS_IMETHOD SetContainer(nsISupports* aContainer);
NS_IMETHOD GetContainer(nsISupports** aContainerResult);
NS_IMETHOD LoadStart(nsISupports* aDoc);
NS_IMETHOD LoadComplete(nsresult aStatus);
NS_IMETHOD Unload(void);
NS_IMETHOD Destroy(void);
NS_IMETHOD Stop(void);
NS_IMETHOD GetDOMDocument(nsIDOMDocument **aResult);
NS_IMETHOD SetDOMDocument(nsIDOMDocument *aDocument);
NS_IMETHOD GetBounds(nsRect& aResult);
NS_IMETHOD SetBounds(const nsRect& aBounds);
NS_IMETHOD GetPreviousViewer(nsIContentViewer** aResult);
NS_IMETHOD SetPreviousViewer(nsIContentViewer* aViewer);
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
NS_IMETHOD Show();
NS_IMETHOD Hide();
NS_IMETHOD Validate();
NS_IMETHOD SetEnableRendering(PRBool aOn);
NS_IMETHOD GetEnableRendering(PRBool* aResult);
NS_DECL_NSICONTENTVIEWER
// nsIDocumentViewer interface...
NS_IMETHOD SetUAStyleSheet(nsIStyleSheet* aUAStyleSheet);
@ -845,6 +822,14 @@ NS_IMPL_ISUPPORTS5(DocumentViewerImpl,
DocumentViewerImpl::~DocumentViewerImpl()
{
NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Close");
if (mDocument)
Close();
NS_ASSERTION(!mPresShell, "User did not call nsIContentViewer::Destroy");
if (mPresShell)
Destroy();
if (mPagePrintTimer != nsnull) {
mPagePrintTimer->Stop();
delete mPagePrintTimer;
@ -854,10 +839,8 @@ DocumentViewerImpl::~DocumentViewerImpl()
mPrt->OnEndPrinting(NS_ERROR_FAILURE);
delete mPrt;
}
// Revoke pending invalidate events
NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Destroy");
if (mDocument)
Destroy();
// XXX(?) Revoke pending invalidate events
// clear weak references before we go away
if (mPresContext) {
@ -870,10 +853,6 @@ DocumentViewerImpl::~DocumentViewerImpl()
// stop everything but the chrome.
mPresContext->Stop();
}
// Avoid leaking the old viewer.
if (mPreviousViewer)
SetPreviousViewer(nsnull);
}
/*
@ -1166,13 +1145,19 @@ DocumentViewerImpl::Unload()
}
NS_IMETHODIMP
DocumentViewerImpl::Destroy()
DocumentViewerImpl::Close()
{
// All callers are supposed to call destroy to break circular
// All callers are supposed to call close to break circular
// references. If we do this stuff in the destructor, the
// destructor might never be called (especially if we're being
// used from JS.
// Close is also needed to disable scripts during paint suppression,
// since we transfer the existing global object to the new document
// that is loaded. In the future, the global object may become a proxy
// for an object that can be switched in and out so that we don't need
// to disable scripts during paint suppression.
nsresult rv;
if (mDocument) {
@ -1194,6 +1179,24 @@ DocumentViewerImpl::Destroy()
}
}
mDocument = nsnull;
return NS_OK;
}
NS_IMETHODIMP
DocumentViewerImpl::Destroy()
{
// All callers are supposed to call destroy to break circular
// references. If we do this stuff in the destructor, the
// destructor might never be called (especially if we're being
// used from JS.
// Avoid leaking the old viewer.
if (mPreviousViewer) {
mPreviousViewer->Destroy();
mPreviousViewer = nsnull;
}
if (mDeviceContext)
mDeviceContext->FlushFontCache();
@ -1201,13 +1204,13 @@ DocumentViewerImpl::Destroy()
// Break circular reference (or something)
mPresShell->EndObservingDocument();
nsCOMPtr<nsISelection> selection;
rv = GetDocumentSelection(getter_AddRefs(selection));
nsresult rv = GetDocumentSelection(getter_AddRefs(selection));
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(selection));
if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener)
selPrivate->RemoveSelectionListener(mSelectionListener);
mPresShell = nsnull;
}
mDocument = nsnull;
return NS_OK;
}
@ -1370,17 +1373,13 @@ DocumentViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer)
NS_IMETHODIMP
DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
{
if (!aViewer) {
// Clearing it out.
mPreviousViewer = nsnull;
// NOTE: |Show| sets |mPreviousViewer| to null without calling this
// function.
if (aViewer) {
NS_ASSERTION(!mPreviousViewer,
"can't set previous viewer when there already is one");
// Now we can show, but only if we aren't dead already (which
// can occasionally happen when one page moves to another during the onload
// handler.)
if (mDocument)
Show();
}
else {
// In a multiple chaining situation (which occurs when running a thrashing
// test like i-bench or jrgm's tests with no delay), we can build up a
// whole chain of viewers. In order to avoid this, we always set our previous
@ -1392,9 +1391,9 @@ DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
nsCOMPtr<nsIContentViewer> prevViewer;
aViewer->GetPreviousViewer(getter_AddRefs(prevViewer));
if (prevViewer) {
SetPreviousViewer(prevViewer);
prevViewer->SetPreviousViewer(nsnull);
return NS_OK;
aViewer->SetPreviousViewer(nsnull);
aViewer->Destroy();
return SetPreviousViewer(prevViewer);
}
}
@ -1432,6 +1431,17 @@ DocumentViewerImpl::Show(void)
{
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
NS_PRECONDITION(mWindow, "null window");
// We don't need the previous viewer anymore since we're not
// displaying it.
if (mPreviousViewer) {
// This little dance *may* only be to keep
// PresShell::EndObservingDocument happy, but I'm not sure.
nsCOMPtr<nsIContentViewer> prevViewer(mPreviousViewer);
mPreviousViewer = nsnull;
prevViewer->Destroy();
}
if (mWindow) {
mWindow->Show(PR_TRUE);
}

Просмотреть файл

@ -2451,6 +2451,7 @@ nsDocShell::Destroy()
docShellParentAsNode->RemoveChild(this);
if (mContentViewer) {
mContentViewer->Close();
mContentViewer->Destroy();
mContentViewer = nsnull;
}
@ -4105,7 +4106,7 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer)
}
}
mContentViewer->Destroy();
mContentViewer->Close();
aNewViewer->SetPreviousViewer(mContentViewer);
mContentViewer = nsnull;
}

Просмотреть файл

@ -27,7 +27,17 @@ interface nsIContentViewer : nsISupports
void loadComplete(in unsigned long aStatus);
void unload();
/**
* All users of a content viewer are responsible for calling both
* close() and destroy(), in that order.
*
* close() should be called when the load of a new page for the next
* content viewer begins, and destroy() should be called when the next
* content viewer replaces this one.
*/
void close();
void destroy();
void stop();
attribute nsIDOMDocument DOMDocument;
@ -35,8 +45,11 @@ interface nsIContentViewer : nsISupports
[noscript] void getBounds(in nsRectRef aBounds);
[noscript] void setBounds([const] in nsRectRef aBounds);
[noscript] void setPreviousViewer(in nsIContentViewer aViewer);
[noscript] nsIContentViewer getPreviousViewer();
/**
* The previous content viewer, which has been |close|d but not
* |destroy|ed.
*/
[noscript] attribute nsIContentViewer previousViewer;
void move(in long aX, in long aY);

Просмотреть файл

@ -372,30 +372,7 @@ public:
NS_DECL_ISUPPORTS
// nsIContentViewer interface...
NS_IMETHOD Init(nsIWidget* aParentWidget,
nsIDeviceContext* aDeviceContext,
const nsRect& aBounds);
NS_IMETHOD SetContainer(nsISupports* aContainer);
NS_IMETHOD GetContainer(nsISupports** aContainerResult);
NS_IMETHOD LoadStart(nsISupports* aDoc);
NS_IMETHOD LoadComplete(nsresult aStatus);
NS_IMETHOD Unload(void);
NS_IMETHOD Destroy(void);
NS_IMETHOD Stop(void);
NS_IMETHOD GetDOMDocument(nsIDOMDocument **aResult);
NS_IMETHOD SetDOMDocument(nsIDOMDocument *aDocument);
NS_IMETHOD GetBounds(nsRect& aResult);
NS_IMETHOD SetBounds(const nsRect& aBounds);
NS_IMETHOD GetPreviousViewer(nsIContentViewer** aResult);
NS_IMETHOD SetPreviousViewer(nsIContentViewer* aViewer);
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
NS_IMETHOD Show();
NS_IMETHOD Hide();
NS_IMETHOD Validate();
NS_IMETHOD SetEnableRendering(PRBool aOn);
NS_IMETHOD GetEnableRendering(PRBool* aResult);
NS_DECL_NSICONTENTVIEWER
// nsIDocumentViewer interface...
NS_IMETHOD SetUAStyleSheet(nsIStyleSheet* aUAStyleSheet);
@ -845,6 +822,14 @@ NS_IMPL_ISUPPORTS5(DocumentViewerImpl,
DocumentViewerImpl::~DocumentViewerImpl()
{
NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Close");
if (mDocument)
Close();
NS_ASSERTION(!mPresShell, "User did not call nsIContentViewer::Destroy");
if (mPresShell)
Destroy();
if (mPagePrintTimer != nsnull) {
mPagePrintTimer->Stop();
delete mPagePrintTimer;
@ -854,10 +839,8 @@ DocumentViewerImpl::~DocumentViewerImpl()
mPrt->OnEndPrinting(NS_ERROR_FAILURE);
delete mPrt;
}
// Revoke pending invalidate events
NS_ASSERTION(!mDocument, "User did not call nsIContentViewer::Destroy");
if (mDocument)
Destroy();
// XXX(?) Revoke pending invalidate events
// clear weak references before we go away
if (mPresContext) {
@ -870,10 +853,6 @@ DocumentViewerImpl::~DocumentViewerImpl()
// stop everything but the chrome.
mPresContext->Stop();
}
// Avoid leaking the old viewer.
if (mPreviousViewer)
SetPreviousViewer(nsnull);
}
/*
@ -1166,13 +1145,19 @@ DocumentViewerImpl::Unload()
}
NS_IMETHODIMP
DocumentViewerImpl::Destroy()
DocumentViewerImpl::Close()
{
// All callers are supposed to call destroy to break circular
// All callers are supposed to call close to break circular
// references. If we do this stuff in the destructor, the
// destructor might never be called (especially if we're being
// used from JS.
// Close is also needed to disable scripts during paint suppression,
// since we transfer the existing global object to the new document
// that is loaded. In the future, the global object may become a proxy
// for an object that can be switched in and out so that we don't need
// to disable scripts during paint suppression.
nsresult rv;
if (mDocument) {
@ -1194,6 +1179,24 @@ DocumentViewerImpl::Destroy()
}
}
mDocument = nsnull;
return NS_OK;
}
NS_IMETHODIMP
DocumentViewerImpl::Destroy()
{
// All callers are supposed to call destroy to break circular
// references. If we do this stuff in the destructor, the
// destructor might never be called (especially if we're being
// used from JS.
// Avoid leaking the old viewer.
if (mPreviousViewer) {
mPreviousViewer->Destroy();
mPreviousViewer = nsnull;
}
if (mDeviceContext)
mDeviceContext->FlushFontCache();
@ -1201,13 +1204,13 @@ DocumentViewerImpl::Destroy()
// Break circular reference (or something)
mPresShell->EndObservingDocument();
nsCOMPtr<nsISelection> selection;
rv = GetDocumentSelection(getter_AddRefs(selection));
nsresult rv = GetDocumentSelection(getter_AddRefs(selection));
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(selection));
if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener)
selPrivate->RemoveSelectionListener(mSelectionListener);
mPresShell = nsnull;
}
mDocument = nsnull;
return NS_OK;
}
@ -1370,17 +1373,13 @@ DocumentViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer)
NS_IMETHODIMP
DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
{
if (!aViewer) {
// Clearing it out.
mPreviousViewer = nsnull;
// NOTE: |Show| sets |mPreviousViewer| to null without calling this
// function.
if (aViewer) {
NS_ASSERTION(!mPreviousViewer,
"can't set previous viewer when there already is one");
// Now we can show, but only if we aren't dead already (which
// can occasionally happen when one page moves to another during the onload
// handler.)
if (mDocument)
Show();
}
else {
// In a multiple chaining situation (which occurs when running a thrashing
// test like i-bench or jrgm's tests with no delay), we can build up a
// whole chain of viewers. In order to avoid this, we always set our previous
@ -1392,9 +1391,9 @@ DocumentViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
nsCOMPtr<nsIContentViewer> prevViewer;
aViewer->GetPreviousViewer(getter_AddRefs(prevViewer));
if (prevViewer) {
SetPreviousViewer(prevViewer);
prevViewer->SetPreviousViewer(nsnull);
return NS_OK;
aViewer->SetPreviousViewer(nsnull);
aViewer->Destroy();
return SetPreviousViewer(prevViewer);
}
}
@ -1432,6 +1431,17 @@ DocumentViewerImpl::Show(void)
{
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
NS_PRECONDITION(mWindow, "null window");
// We don't need the previous viewer anymore since we're not
// displaying it.
if (mPreviousViewer) {
// This little dance *may* only be to keep
// PresShell::EndObservingDocument happy, but I'm not sure.
nsCOMPtr<nsIContentViewer> prevViewer(mPreviousViewer);
mPreviousViewer = nsnull;
prevViewer->Destroy();
}
if (mWindow) {
mWindow->Show(PR_TRUE);
}

Просмотреть файл

@ -1482,104 +1482,6 @@ PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr)
PresShell::~PresShell()
{
#ifdef MOZ_REFLOW_PERF
DumpReflows();
if (mReflowCountMgr) {
delete mReflowCountMgr;
mReflowCountMgr = nsnull;
}
#endif
// If our paint suppression timer is still active, kill it.
if (mPaintSuppressionTimer) {
mPaintSuppressionTimer->Cancel();
mPaintSuppressionTimer = nsnull;
}
nsCOMPtr<nsISupports> container;
mPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShell> cvc(do_QueryInterface(container));
if (cvc) {
nsCOMPtr<nsIContentViewer> cv;
cvc->GetContentViewer(getter_AddRefs(cv));
if (cv)
cv->SetPreviousViewer(nsnull);
}
}
// release our pref style sheet, if we have one still
ClearPreferenceStyleRules();
// if we allocated any stack memory free it.
FreeDynamicStack();
// free our table of anonymous content
ReleaseAnonymousContent();
mIsDestroying = PR_TRUE;
// Clobber weak leaks in case of re-entrancy during tear down
mHistoryState = nsnull;
// kill subshell map, if any. It holds only weak references
if (mSubShellMap)
{
delete mSubShellMap;
mSubShellMap = nsnull;
}
// release current event content and any content on event stack
NS_IF_RELEASE(mCurrentEventContent);
PRInt32 i, count = mCurrentEventContentStack.Count();
nsIContent* currentEventContent;
for (i = 0; i < count; i++) {
currentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(i);
NS_IF_RELEASE(currentEventContent);
}
if (mViewManager) {
// Disable paints during tear down of the frame tree
mViewManager->DisableRefresh();
mViewManager = nsnull;
}
// This shell must be removed from the document before the frame
// hierarchy is torn down to avoid finding deleted frames through
// this presshell while the frames are being torn down
if (mDocument) {
mDocument->DeleteShell(this);
}
// Destroy the frame manager. This will destroy the frame hierarchy
if (mFrameManager) {
mFrameManager->Destroy();
NS_RELEASE(mFrameManager);
}
// Let the style set do its cleanup.
mStyleSet->Shutdown();
// We hold a reference to the pres context, and it holds a weak link back
// to us. To avoid the pres context having a dangling reference, set its
// pres shell to NULL
if (mPresContext) {
mPresContext->SetShell(nsnull);
}
if (mViewEventListener) {
mViewEventListener->SetPresShell((nsIPresShell*)nsnull);
NS_RELEASE(mViewEventListener);
}
// Revoke pending reflow events
if (mPendingReflowEvent) {
mPendingReflowEvent = PR_FALSE;
mEventQueue->RevokeEvents(this);
}
KillResizeEventTimer();
}
/**
@ -2446,6 +2348,113 @@ PresShell::EndObservingDocument()
return NS_ERROR_UNEXPECTED;
mSelection->ShutDown();
}
#ifdef MOZ_REFLOW_PERF
DumpReflows();
if (mReflowCountMgr) {
delete mReflowCountMgr;
mReflowCountMgr = nsnull;
}
#endif
// If our paint suppression timer is still active, kill it.
if (mPaintSuppressionTimer) {
mPaintSuppressionTimer->Cancel();
mPaintSuppressionTimer = nsnull;
}
#ifdef DEBUG
{
nsCOMPtr<nsISupports> container;
mPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShell> cvc(do_QueryInterface(container));
if (cvc) {
nsCOMPtr<nsIContentViewer> cv;
cvc->GetContentViewer(getter_AddRefs(cv));
if (cv) {
nsCOMPtr<nsIContentViewer> prevViewer;
cv->GetPreviousViewer(getter_AddRefs(prevViewer));
NS_ASSERTION(!prevViewer, "still have a previous viewer!");
}
}
}
}
#endif
// release our pref style sheet, if we have one still
ClearPreferenceStyleRules();
// if we allocated any stack memory free it.
FreeDynamicStack();
// free our table of anonymous content
ReleaseAnonymousContent();
mIsDestroying = PR_TRUE;
// Clobber weak leaks in case of re-entrancy during tear down
mHistoryState = nsnull;
// kill subshell map, if any. It holds only weak references
if (mSubShellMap)
{
delete mSubShellMap;
mSubShellMap = nsnull;
}
// release current event content and any content on event stack
NS_IF_RELEASE(mCurrentEventContent);
PRInt32 i, count = mCurrentEventContentStack.Count();
nsIContent* currentEventContent;
for (i = 0; i < count; i++) {
currentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(i);
NS_IF_RELEASE(currentEventContent);
}
if (mViewManager) {
// Disable paints during tear down of the frame tree
mViewManager->DisableRefresh();
mViewManager = nsnull;
}
// This shell must be removed from the document before the frame
// hierarchy is torn down to avoid finding deleted frames through
// this presshell while the frames are being torn down
if (mDocument) {
mDocument->DeleteShell(this);
}
// Destroy the frame manager. This will destroy the frame hierarchy
if (mFrameManager) {
mFrameManager->Destroy();
NS_RELEASE(mFrameManager);
}
// Let the style set do its cleanup.
mStyleSet->Shutdown();
// We hold a reference to the pres context, and it holds a weak link back
// to us. To avoid the pres context having a dangling reference, set its
// pres shell to NULL
if (mPresContext) {
mPresContext->SetShell(nsnull);
}
if (mViewEventListener) {
mViewEventListener->SetPresShell((nsIPresShell*)nsnull);
NS_RELEASE(mViewEventListener);
}
// Revoke pending reflow events
if (mPendingReflowEvent) {
mPendingReflowEvent = PR_FALSE;
mEventQueue->RevokeEvents(this);
}
KillResizeEventTimer();
return NS_OK;
}
@ -4578,23 +4587,17 @@ PresShell::UnsuppressAndInvalidate()
focusController->SetSuppressFocus(PR_TRUE, "PresShell suppression on Web page loads");
nsCOMPtr<nsISupports> container;
nsCOMPtr<nsIContentViewer> cv;
nsCOMPtr<nsIDocumentViewer> dv;
mPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShell> cvc(do_QueryInterface(container));
if (cvc) {
nsCOMPtr<nsIContentViewer> cv;
cvc->GetContentViewer(getter_AddRefs(cv));
dv = do_QueryInterface(cv);
if (cv)
cv->Show();
}
}
if (dv)
dv->Show();
if (cv)
cv->SetPreviousViewer(nsnull);
mPaintingSuppressed = PR_FALSE;
nsIFrame* rootFrame;
mFrameManager->GetRootFrame(&rootFrame);

Просмотреть файл

@ -440,7 +440,7 @@ nsObjectFrame::Init(nsIPresContext* aPresContext,
nsCOMPtr<nsIContentViewer> cv;
cvc->GetContentViewer(getter_AddRefs(cv));
if (cv)
cv->SetPreviousViewer(nsnull);
cv->Show();
}
}

Просмотреть файл

@ -440,7 +440,7 @@ nsObjectFrame::Init(nsIPresContext* aPresContext,
nsCOMPtr<nsIContentViewer> cv;
cvc->GetContentViewer(getter_AddRefs(cv));
if (cv)
cv->SetPreviousViewer(nsnull);
cv->Show();
}
}

Просмотреть файл

@ -1482,104 +1482,6 @@ PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr)
PresShell::~PresShell()
{
#ifdef MOZ_REFLOW_PERF
DumpReflows();
if (mReflowCountMgr) {
delete mReflowCountMgr;
mReflowCountMgr = nsnull;
}
#endif
// If our paint suppression timer is still active, kill it.
if (mPaintSuppressionTimer) {
mPaintSuppressionTimer->Cancel();
mPaintSuppressionTimer = nsnull;
}
nsCOMPtr<nsISupports> container;
mPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShell> cvc(do_QueryInterface(container));
if (cvc) {
nsCOMPtr<nsIContentViewer> cv;
cvc->GetContentViewer(getter_AddRefs(cv));
if (cv)
cv->SetPreviousViewer(nsnull);
}
}
// release our pref style sheet, if we have one still
ClearPreferenceStyleRules();
// if we allocated any stack memory free it.
FreeDynamicStack();
// free our table of anonymous content
ReleaseAnonymousContent();
mIsDestroying = PR_TRUE;
// Clobber weak leaks in case of re-entrancy during tear down
mHistoryState = nsnull;
// kill subshell map, if any. It holds only weak references
if (mSubShellMap)
{
delete mSubShellMap;
mSubShellMap = nsnull;
}
// release current event content and any content on event stack
NS_IF_RELEASE(mCurrentEventContent);
PRInt32 i, count = mCurrentEventContentStack.Count();
nsIContent* currentEventContent;
for (i = 0; i < count; i++) {
currentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(i);
NS_IF_RELEASE(currentEventContent);
}
if (mViewManager) {
// Disable paints during tear down of the frame tree
mViewManager->DisableRefresh();
mViewManager = nsnull;
}
// This shell must be removed from the document before the frame
// hierarchy is torn down to avoid finding deleted frames through
// this presshell while the frames are being torn down
if (mDocument) {
mDocument->DeleteShell(this);
}
// Destroy the frame manager. This will destroy the frame hierarchy
if (mFrameManager) {
mFrameManager->Destroy();
NS_RELEASE(mFrameManager);
}
// Let the style set do its cleanup.
mStyleSet->Shutdown();
// We hold a reference to the pres context, and it holds a weak link back
// to us. To avoid the pres context having a dangling reference, set its
// pres shell to NULL
if (mPresContext) {
mPresContext->SetShell(nsnull);
}
if (mViewEventListener) {
mViewEventListener->SetPresShell((nsIPresShell*)nsnull);
NS_RELEASE(mViewEventListener);
}
// Revoke pending reflow events
if (mPendingReflowEvent) {
mPendingReflowEvent = PR_FALSE;
mEventQueue->RevokeEvents(this);
}
KillResizeEventTimer();
}
/**
@ -2446,6 +2348,113 @@ PresShell::EndObservingDocument()
return NS_ERROR_UNEXPECTED;
mSelection->ShutDown();
}
#ifdef MOZ_REFLOW_PERF
DumpReflows();
if (mReflowCountMgr) {
delete mReflowCountMgr;
mReflowCountMgr = nsnull;
}
#endif
// If our paint suppression timer is still active, kill it.
if (mPaintSuppressionTimer) {
mPaintSuppressionTimer->Cancel();
mPaintSuppressionTimer = nsnull;
}
#ifdef DEBUG
{
nsCOMPtr<nsISupports> container;
mPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShell> cvc(do_QueryInterface(container));
if (cvc) {
nsCOMPtr<nsIContentViewer> cv;
cvc->GetContentViewer(getter_AddRefs(cv));
if (cv) {
nsCOMPtr<nsIContentViewer> prevViewer;
cv->GetPreviousViewer(getter_AddRefs(prevViewer));
NS_ASSERTION(!prevViewer, "still have a previous viewer!");
}
}
}
}
#endif
// release our pref style sheet, if we have one still
ClearPreferenceStyleRules();
// if we allocated any stack memory free it.
FreeDynamicStack();
// free our table of anonymous content
ReleaseAnonymousContent();
mIsDestroying = PR_TRUE;
// Clobber weak leaks in case of re-entrancy during tear down
mHistoryState = nsnull;
// kill subshell map, if any. It holds only weak references
if (mSubShellMap)
{
delete mSubShellMap;
mSubShellMap = nsnull;
}
// release current event content and any content on event stack
NS_IF_RELEASE(mCurrentEventContent);
PRInt32 i, count = mCurrentEventContentStack.Count();
nsIContent* currentEventContent;
for (i = 0; i < count; i++) {
currentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(i);
NS_IF_RELEASE(currentEventContent);
}
if (mViewManager) {
// Disable paints during tear down of the frame tree
mViewManager->DisableRefresh();
mViewManager = nsnull;
}
// This shell must be removed from the document before the frame
// hierarchy is torn down to avoid finding deleted frames through
// this presshell while the frames are being torn down
if (mDocument) {
mDocument->DeleteShell(this);
}
// Destroy the frame manager. This will destroy the frame hierarchy
if (mFrameManager) {
mFrameManager->Destroy();
NS_RELEASE(mFrameManager);
}
// Let the style set do its cleanup.
mStyleSet->Shutdown();
// We hold a reference to the pres context, and it holds a weak link back
// to us. To avoid the pres context having a dangling reference, set its
// pres shell to NULL
if (mPresContext) {
mPresContext->SetShell(nsnull);
}
if (mViewEventListener) {
mViewEventListener->SetPresShell((nsIPresShell*)nsnull);
NS_RELEASE(mViewEventListener);
}
// Revoke pending reflow events
if (mPendingReflowEvent) {
mPendingReflowEvent = PR_FALSE;
mEventQueue->RevokeEvents(this);
}
KillResizeEventTimer();
return NS_OK;
}
@ -4578,23 +4587,17 @@ PresShell::UnsuppressAndInvalidate()
focusController->SetSuppressFocus(PR_TRUE, "PresShell suppression on Web page loads");
nsCOMPtr<nsISupports> container;
nsCOMPtr<nsIContentViewer> cv;
nsCOMPtr<nsIDocumentViewer> dv;
mPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShell> cvc(do_QueryInterface(container));
if (cvc) {
nsCOMPtr<nsIContentViewer> cv;
cvc->GetContentViewer(getter_AddRefs(cv));
dv = do_QueryInterface(cv);
if (cv)
cv->Show();
}
}
if (dv)
dv->Show();
if (cv)
cv->SetPreviousViewer(nsnull);
mPaintingSuppressed = PR_FALSE;
nsIFrame* rootFrame;
mFrameManager->GetRootFrame(&rootFrame);

Просмотреть файл

@ -169,28 +169,7 @@ public:
NS_IMETHOD StartLoad(nsIRequest* request, nsIStreamListener*& aResult);
// nsIContentViewer
NS_IMETHOD Init(nsIWidget* aParentWidget,
nsIDeviceContext* aDeviceContext,
const nsRect& aBounds);
NS_IMETHOD SetContainer(nsISupports* aContainer);
NS_IMETHOD GetContainer(nsISupports** aContainerResult);
NS_IMETHOD LoadStart(nsISupports* aDoc);
NS_IMETHOD LoadComplete(nsresult aStatus);
NS_IMETHOD Unload(void);
NS_IMETHOD Destroy(void);
NS_IMETHOD Stop(void);
NS_IMETHOD GetDOMDocument(nsIDOMDocument **aResult);
NS_IMETHOD SetDOMDocument(nsIDOMDocument *aDocument);
NS_IMETHOD GetBounds(nsRect& aResult);
NS_IMETHOD SetBounds(const nsRect& aBounds);
NS_IMETHOD GetPreviousViewer(nsIContentViewer** aViewer);
NS_IMETHOD SetPreviousViewer(nsIContentViewer* aViewer);
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
NS_IMETHOD Show();
NS_IMETHOD Hide();
NS_IMETHOD Validate();
NS_IMETHOD SetEnableRendering(PRBool aOn);
NS_IMETHOD GetEnableRendering(PRBool* aResult);
NS_DECL_NSICONTENTVIEWER
// nsIContentViewerEdit
NS_DECL_NSICONTENTVIEWEREDIT
@ -435,6 +414,12 @@ PluginViewerImpl::Unload(void)
return NS_OK;
}
NS_IMETHODIMP
PluginViewerImpl::Close(void)
{
return NS_OK;
}
NS_IMETHODIMP
PluginViewerImpl::Destroy(void)
{
@ -558,6 +543,8 @@ PluginViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer)
NS_IMETHODIMP
PluginViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
{
if (aViewer)
aViewer->Destroy();
return NS_OK;
}

Просмотреть файл

@ -169,28 +169,7 @@ public:
NS_IMETHOD StartLoad(nsIRequest* request, nsIStreamListener*& aResult);
// nsIContentViewer
NS_IMETHOD Init(nsIWidget* aParentWidget,
nsIDeviceContext* aDeviceContext,
const nsRect& aBounds);
NS_IMETHOD SetContainer(nsISupports* aContainer);
NS_IMETHOD GetContainer(nsISupports** aContainerResult);
NS_IMETHOD LoadStart(nsISupports* aDoc);
NS_IMETHOD LoadComplete(nsresult aStatus);
NS_IMETHOD Unload(void);
NS_IMETHOD Destroy(void);
NS_IMETHOD Stop(void);
NS_IMETHOD GetDOMDocument(nsIDOMDocument **aResult);
NS_IMETHOD SetDOMDocument(nsIDOMDocument *aDocument);
NS_IMETHOD GetBounds(nsRect& aResult);
NS_IMETHOD SetBounds(const nsRect& aBounds);
NS_IMETHOD GetPreviousViewer(nsIContentViewer** aViewer);
NS_IMETHOD SetPreviousViewer(nsIContentViewer* aViewer);
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
NS_IMETHOD Show();
NS_IMETHOD Hide();
NS_IMETHOD Validate();
NS_IMETHOD SetEnableRendering(PRBool aOn);
NS_IMETHOD GetEnableRendering(PRBool* aResult);
NS_DECL_NSICONTENTVIEWER
// nsIContentViewerEdit
NS_DECL_NSICONTENTVIEWEREDIT
@ -435,6 +414,12 @@ PluginViewerImpl::Unload(void)
return NS_OK;
}
NS_IMETHODIMP
PluginViewerImpl::Close(void)
{
return NS_OK;
}
NS_IMETHODIMP
PluginViewerImpl::Destroy(void)
{
@ -558,6 +543,8 @@ PluginViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer)
NS_IMETHODIMP
PluginViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
{
if (aViewer)
aViewer->Destroy();
return NS_OK;
}