Fix for 76495. r=danm, sr=rpotts

This commit is contained in:
hyatt%netscape.com 2001-05-01 22:54:11 +00:00
parent dddabd000c
commit 9ac35d4459
10 changed files with 178 additions and 56 deletions

View File

@ -3275,7 +3275,8 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(newGlobal);
nsCOMPtr<nsPIDOMWindow> oldWindow = do_QueryInterface(oldGlobal);
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
if (newWindow)
newWindow->GetRootFocusController(getter_AddRefs(newFocusController));
oldWindow->GetRootFocusController(getter_AddRefs(oldFocusController));
if(oldFocusController && oldFocusController != newFocusController)
oldFocusController->SetSuppressFocus(PR_TRUE, "SendFocusBlur Window Switch #2");

View File

@ -177,18 +177,19 @@ nsDocShell::~nsDocShell()
NS_IMETHODIMP
nsDocShell::DestroyChildren()
{
PRInt32 i, n = mChildren.Count();
nsCOMPtr<nsIDocShellTreeItem> shell;
for (i = 0; i < n; i++) {
shell = dont_AddRef((nsIDocShellTreeItem *) mChildren.ElementAt(i));
if (!NS_WARN_IF_FALSE(shell, "docshell has null child"))
shell->SetParent(nsnull);
nsCOMPtr<nsIBaseWindow> shellWin(do_QueryInterface(shell));
if (shellWin)
shellWin->Destroy();
}
mChildren.Clear();
return NS_OK;
PRInt32 i, n = mChildren.Count();
nsCOMPtr<nsIDocShellTreeItem> shell;
for (i = 0; i < n; i++) {
shell = dont_AddRef((nsIDocShellTreeItem *) mChildren.ElementAt(i));
if (!NS_WARN_IF_FALSE(shell, "docshell has null child"))
shell->SetParent(nsnull);
shell->SetTreeOwner(nsnull);
// just clear out the array. When the nsFrameFrame that holds the subshell is
// destroyed, then the Destroy() method of that subshell will actually get
// called.
}
mChildren.Clear();
return NS_OK;
}
//*****************************************************************************
@ -3233,28 +3234,8 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer)
// Stop any activity that may be happening in the old document before
// releasing it...
mContentViewer->Stop();
// Try to extract the default background color from the old
// view manager, so we can use it for the next document.
nsCOMPtr<nsIDocumentViewer> docviewer =
do_QueryInterface(mContentViewer);
if (docviewer) {
nsCOMPtr<nsIPresShell> shell;
docviewer->GetPresShell(*getter_AddRefs(shell));
if (shell) {
nsCOMPtr<nsIViewManager> vm;
shell->GetViewManager(getter_AddRefs(vm));
if (vm) {
vm->GetDefaultBackgroundColor(&bgcolor);
bgSet = PR_TRUE;
}
}
}
mContentViewer->Destroy();
aNewViewer->SetPreviousViewer(mContentViewer);
mContentViewer = nsnull;
}
@ -3314,7 +3295,9 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer)
// XXX: It looks like the LayoutState gets restored again in Embed()
// right after the call to SetupNewViewer(...)
mContentViewer->Show();
// We don't show the mContentViewer yet, since we want to draw the old page
// until we have enough of the new page to show. Just return with the new
// viewer still set to hidden.
// Now that we have switched documents, forget all of our children
DestroyChildren();

View File

@ -33,10 +33,14 @@ 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();
void move(in long aX, in long aY);
void show();
void hide();
void validate();
attribute boolean enableRendering;
};

View File

@ -1568,7 +1568,7 @@ static void EnsureReflowFlushAndPaint(nsIDocShell* aDocShell)
presShell->FlushPendingNotifications();
// Unsuppress painting.
presShell->UnsuppressPainting(PR_TRUE);
presShell->UnsuppressPainting();
}
NS_IMETHODIMP GlobalWindowImpl::Alert(JSContext* cx, jsval* argv, PRUint32 argc)

View File

@ -513,7 +513,7 @@ public:
/**
* Unsuppress painting.
*/
NS_IMETHOD UnsuppressPainting(PRBool aCancelTimer) = 0;
NS_IMETHOD UnsuppressPainting() = 0;
enum InterruptType {Timeout};
/**

View File

@ -142,6 +142,10 @@
#include "nsILoadGroup.h"
#include "nsNetUtil.h"
// Content viewer interfaces
#include "nsIContentViewer.h"
#include "nsIDocumentViewer.h"
// SubShell map
#include "nsDST.h"
@ -919,8 +923,8 @@ public:
NS_IMETHOD ReleaseAnonymousContent();
NS_IMETHOD IsPaintingSuppressed(PRBool* aResult);
NS_IMETHOD UnsuppressPainting(PRBool aCancelTimer);
NS_IMETHOD UnsuppressPainting();
NS_IMETHOD HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent* aContent, PRUint32 aFlags, nsEventStatus* aStatus);
NS_IMETHOD GetEventTargetFrame(nsIFrame** aFrame);
@ -1053,7 +1057,7 @@ protected:
void HandlePostedReflowCallbacks();
void UnsuppressAndInvalidate();
/** notify all external reflow observers that reflow of type "aData" is about
* to begin.
*/
@ -1172,6 +1176,7 @@ protected:
nsCallbackEventRequest* mFirstCallbackEventRequest;
nsCallbackEventRequest* mLastCallbackEventRequest;
PRBool mIsDocumentGone; // We've been disconnected from the document.
PRBool mPaintingSuppressed; // For all documents we initially lock down painting.
// We will refuse to paint the document until either
// (a) our timer fires or (b) all frames are constructed.
@ -1180,7 +1185,7 @@ protected:
nsCOMPtr<nsITimer> mPaintSuppressionTimer; // This timer controls painting suppression. Until it fires
// or all frames are constructed, we won't paint anything but
// our <body> background and scrollbars.
#define PAINTLOCK_EVENT_DELAY 1200 // 1200 ms. This is actually pref-controlled, but we use this
#define PAINTLOCK_EVENT_DELAY 1000 // 1000 ms. This is actually pref-controlled, but we use this
// value if we fail to get the pref for any reason.
static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell); // A callback for the timer.
@ -1335,6 +1340,7 @@ PresShell::PresShell():mAnonymousContentTable(nsnull),
mShouldUnsuppressPainting(PR_FALSE)
{
NS_INIT_REFCNT();
mIsDocumentGone = PR_FALSE;
mIsDestroying = PR_FALSE;
mCaretEnabled = PR_FALSE;
mDisplayNonTextSelection = PR_FALSE;
@ -1426,6 +1432,18 @@ PresShell::~PresShell()
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();
@ -2333,6 +2351,7 @@ PresShell::BeginObservingDocument()
NS_IMETHODIMP
PresShell::EndObservingDocument()
{
mIsDocumentGone = PR_TRUE;
if (mDocument) {
mDocument->RemoveObserver(this);
}
@ -2634,7 +2653,7 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
if (prefs)
prefs->GetIntPref("nglayout.initialpaint.delay", &delay);
mPaintSuppressionTimer->Init(sPaintSuppressionCallback, this, delay, NS_PRIORITY_HIGH);
mPaintSuppressionTimer->Init(sPaintSuppressionCallback, this, delay, NS_PRIORITY_HIGHEST);
}
return NS_OK; //XXX this needs to be real. MMP
@ -2645,7 +2664,7 @@ PresShell::sPaintSuppressionCallback(nsITimer *aTimer, void* aPresShell)
{
PresShell* self = NS_STATIC_CAST(PresShell*, aPresShell);
if (self)
self->UnsuppressPainting(PR_TRUE);
self->UnsuppressPainting();
}
NS_IMETHODIMP
@ -2760,6 +2779,9 @@ PresShell::CreateResizeEventTimer ()
{
KillResizeEventTimer();
if (mIsDocumentGone)
return;
mResizeEventTimer = do_CreateInstance("@mozilla.org/timer;1");
if (mResizeEventTimer) {
mResizeEventTimer->Init(sResizeEventCallback, this, RESIZE_EVENT_DELAY, NS_PRIORITY_HIGH);
@ -2787,6 +2809,9 @@ PresShell::sResizeEventCallback(nsITimer *aTimer, void* aPresShell)
void
PresShell::FireResizeEvent()
{
if (mIsDocumentGone)
return;
//Send resize event from here.
nsEvent event;
nsEventStatus status = nsEventStatus_eIgnore;
@ -4466,6 +4491,24 @@ PresShell::IsPaintingSuppressed(PRBool* aResult)
void
PresShell::UnsuppressAndInvalidate()
{
nsCOMPtr<nsISupports> container;
nsCOMPtr<nsIContentViewer> cv;
nsCOMPtr<nsIDocumentViewer> dv;
mPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShell> cvc(do_QueryInterface(container));
if (cvc) {
cvc->GetContentViewer(getter_AddRefs(cv));
dv = do_QueryInterface(cv);
}
}
if (dv)
dv->Show();
if (cv)
cv->SetPreviousViewer(nsnull);
mPaintingSuppressed = PR_FALSE;
nsIFrame* rootFrame;
mFrameManager->GetRootFrame(&rootFrame);
@ -4477,14 +4520,14 @@ PresShell::UnsuppressAndInvalidate()
}
NS_IMETHODIMP
PresShell::UnsuppressPainting(PRBool aCancelTimer)
PresShell::UnsuppressPainting()
{
if (mPaintSuppressionTimer && aCancelTimer) {
if (mPaintSuppressionTimer) {
mPaintSuppressionTimer->Cancel();
mPaintSuppressionTimer = nsnull;
}
if (!mPaintingSuppressed || !aCancelTimer)
if (mIsDocumentGone || !mPaintingSuppressed)
return NS_OK;
// If we have reflows pending, just wait until we process
@ -4814,6 +4857,7 @@ PresShell::ContentAppended(nsIDocument *aDocument,
MOZ_TIMER_DEBUGLOG(("Start: Frame Creation: PresShell::ContentAppended(), this=%p\n", this));
MOZ_TIMER_START(mFrameCreationWatch);
CtlStyleWatch(kStyleWatchEnable,mStyleSet);
nsresult rv = mStyleSet->ContentAppended(mPresContext, aContainer, aNewIndexInContainer);
VERIFY_STYLE_TREE;

View File

@ -513,7 +513,7 @@ public:
/**
* Unsuppress painting.
*/
NS_IMETHOD UnsuppressPainting(PRBool aCancelTimer) = 0;
NS_IMETHOD UnsuppressPainting() = 0;
enum InterruptType {Timeout};
/**

View File

@ -142,6 +142,10 @@
#include "nsILoadGroup.h"
#include "nsNetUtil.h"
// Content viewer interfaces
#include "nsIContentViewer.h"
#include "nsIDocumentViewer.h"
// SubShell map
#include "nsDST.h"
@ -919,8 +923,8 @@ public:
NS_IMETHOD ReleaseAnonymousContent();
NS_IMETHOD IsPaintingSuppressed(PRBool* aResult);
NS_IMETHOD UnsuppressPainting(PRBool aCancelTimer);
NS_IMETHOD UnsuppressPainting();
NS_IMETHOD HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent* aContent, PRUint32 aFlags, nsEventStatus* aStatus);
NS_IMETHOD GetEventTargetFrame(nsIFrame** aFrame);
@ -1053,7 +1057,7 @@ protected:
void HandlePostedReflowCallbacks();
void UnsuppressAndInvalidate();
/** notify all external reflow observers that reflow of type "aData" is about
* to begin.
*/
@ -1172,6 +1176,7 @@ protected:
nsCallbackEventRequest* mFirstCallbackEventRequest;
nsCallbackEventRequest* mLastCallbackEventRequest;
PRBool mIsDocumentGone; // We've been disconnected from the document.
PRBool mPaintingSuppressed; // For all documents we initially lock down painting.
// We will refuse to paint the document until either
// (a) our timer fires or (b) all frames are constructed.
@ -1180,7 +1185,7 @@ protected:
nsCOMPtr<nsITimer> mPaintSuppressionTimer; // This timer controls painting suppression. Until it fires
// or all frames are constructed, we won't paint anything but
// our <body> background and scrollbars.
#define PAINTLOCK_EVENT_DELAY 1200 // 1200 ms. This is actually pref-controlled, but we use this
#define PAINTLOCK_EVENT_DELAY 1000 // 1000 ms. This is actually pref-controlled, but we use this
// value if we fail to get the pref for any reason.
static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell); // A callback for the timer.
@ -1335,6 +1340,7 @@ PresShell::PresShell():mAnonymousContentTable(nsnull),
mShouldUnsuppressPainting(PR_FALSE)
{
NS_INIT_REFCNT();
mIsDocumentGone = PR_FALSE;
mIsDestroying = PR_FALSE;
mCaretEnabled = PR_FALSE;
mDisplayNonTextSelection = PR_FALSE;
@ -1426,6 +1432,18 @@ PresShell::~PresShell()
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();
@ -2333,6 +2351,7 @@ PresShell::BeginObservingDocument()
NS_IMETHODIMP
PresShell::EndObservingDocument()
{
mIsDocumentGone = PR_TRUE;
if (mDocument) {
mDocument->RemoveObserver(this);
}
@ -2634,7 +2653,7 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
if (prefs)
prefs->GetIntPref("nglayout.initialpaint.delay", &delay);
mPaintSuppressionTimer->Init(sPaintSuppressionCallback, this, delay, NS_PRIORITY_HIGH);
mPaintSuppressionTimer->Init(sPaintSuppressionCallback, this, delay, NS_PRIORITY_HIGHEST);
}
return NS_OK; //XXX this needs to be real. MMP
@ -2645,7 +2664,7 @@ PresShell::sPaintSuppressionCallback(nsITimer *aTimer, void* aPresShell)
{
PresShell* self = NS_STATIC_CAST(PresShell*, aPresShell);
if (self)
self->UnsuppressPainting(PR_TRUE);
self->UnsuppressPainting();
}
NS_IMETHODIMP
@ -2760,6 +2779,9 @@ PresShell::CreateResizeEventTimer ()
{
KillResizeEventTimer();
if (mIsDocumentGone)
return;
mResizeEventTimer = do_CreateInstance("@mozilla.org/timer;1");
if (mResizeEventTimer) {
mResizeEventTimer->Init(sResizeEventCallback, this, RESIZE_EVENT_DELAY, NS_PRIORITY_HIGH);
@ -2787,6 +2809,9 @@ PresShell::sResizeEventCallback(nsITimer *aTimer, void* aPresShell)
void
PresShell::FireResizeEvent()
{
if (mIsDocumentGone)
return;
//Send resize event from here.
nsEvent event;
nsEventStatus status = nsEventStatus_eIgnore;
@ -4466,6 +4491,24 @@ PresShell::IsPaintingSuppressed(PRBool* aResult)
void
PresShell::UnsuppressAndInvalidate()
{
nsCOMPtr<nsISupports> container;
nsCOMPtr<nsIContentViewer> cv;
nsCOMPtr<nsIDocumentViewer> dv;
mPresContext->GetContainer(getter_AddRefs(container));
if (container) {
nsCOMPtr<nsIDocShell> cvc(do_QueryInterface(container));
if (cvc) {
cvc->GetContentViewer(getter_AddRefs(cv));
dv = do_QueryInterface(cv);
}
}
if (dv)
dv->Show();
if (cv)
cv->SetPreviousViewer(nsnull);
mPaintingSuppressed = PR_FALSE;
nsIFrame* rootFrame;
mFrameManager->GetRootFrame(&rootFrame);
@ -4477,14 +4520,14 @@ PresShell::UnsuppressAndInvalidate()
}
NS_IMETHODIMP
PresShell::UnsuppressPainting(PRBool aCancelTimer)
PresShell::UnsuppressPainting()
{
if (mPaintSuppressionTimer && aCancelTimer) {
if (mPaintSuppressionTimer) {
mPaintSuppressionTimer->Cancel();
mPaintSuppressionTimer = nsnull;
}
if (!mPaintingSuppressed || !aCancelTimer)
if (mIsDocumentGone || !mPaintingSuppressed)
return NS_OK;
// If we have reflows pending, just wait until we process
@ -4814,6 +4857,7 @@ PresShell::ContentAppended(nsIDocument *aDocument,
MOZ_TIMER_DEBUGLOG(("Start: Frame Creation: PresShell::ContentAppended(), this=%p\n", this));
MOZ_TIMER_START(mFrameCreationWatch);
CtlStyleWatch(kStyleWatchEnable,mStyleSet);
nsresult rv = mStyleSet->ContentAppended(mPresContext, aContainer, aNewIndexInContainer);
VERIFY_STYLE_TREE;

View File

@ -168,9 +168,12 @@ public:
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);
@ -530,6 +533,26 @@ PluginViewerImpl::GetBounds(nsRect& aResult)
return NS_OK;
}
NS_IMETHODIMP
PluginViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PluginViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PluginViewerImpl::Validate()
{
if (mWindow)
mWindow->Validate();
return NS_OK;
}
NS_IMETHODIMP
PluginViewerImpl::SetBounds(const nsRect& aBounds)
{

View File

@ -168,9 +168,12 @@ public:
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);
@ -530,6 +533,26 @@ PluginViewerImpl::GetBounds(nsRect& aResult)
return NS_OK;
}
NS_IMETHODIMP
PluginViewerImpl::GetPreviousViewer(nsIContentViewer** aViewer)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PluginViewerImpl::SetPreviousViewer(nsIContentViewer* aViewer)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PluginViewerImpl::Validate()
{
if (mWindow)
mWindow->Validate();
return NS_OK;
}
NS_IMETHODIMP
PluginViewerImpl::SetBounds(const nsRect& aBounds)
{