This commit is contained in:
Olli Pettay 2009-03-02 22:20:10 +02:00
Родитель d8257ed922
Коммит 7dc9c0ff12
4 изменённых файлов: 92 добавлений и 128 удалений

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

@ -6020,20 +6020,13 @@ nsDocShell::RestoreFromHistory()
}
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
PRUint32 parentSuspendCount = 0;
if (document) {
nsCOMPtr<nsIDocShellTreeItem> parent;
GetParent(getter_AddRefs(parent));
nsCOMPtr<nsIDOMDocument> parentDoc = do_GetInterface(parent);
nsCOMPtr<nsIDocument> d = do_QueryInterface(parentDoc);
if (d) {
if (d->EventHandlingSuppressed()) {
document->SuppressEventHandling(d->EventHandlingSuppressed());
}
nsCOMPtr<nsPIDOMWindow> parentWindow = d->GetWindow();
if (parentWindow) {
parentSuspendCount = parentWindow->TimeoutSuspendCount();
}
if (d && d->EventHandlingSuppressed()) {
document->SuppressEventHandling(d->EventHandlingSuppressed());
}
// Use the uri from the mLSHE we had when we entered this function
@ -6123,13 +6116,6 @@ nsDocShell::RestoreFromHistory()
}
}
// If parent is suspended, increase suspension count.
// This can't be done as early as event suppression since this
// depends on docshell tree.
if (parentSuspendCount) {
privWin->SuspendTimeouts(parentSuspendCount, PR_FALSE);
}
// Now that all of the child docshells have been put into place, we can
// restart the timers for the window and all of the child frames.
privWin->ResumeTimeouts();

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

@ -76,8 +76,8 @@ class nsScriptObjectHolder;
class nsXBLPrototypeHandler;
#define NS_PIDOMWINDOW_IID \
{ 0x80dd53b6, 0x8c61, 0x4dd6, \
{ 0xb4, 0x51, 0xf7, 0xd7, 0x5c, 0xfc, 0x51, 0x96 } }
{ 0x3d2b6b38, 0x810d, 0x4ac5, \
{ 0x81, 0x7c, 0xb9, 0x70, 0x81, 0x80, 0x4d, 0x9f } }
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@ -272,14 +272,11 @@ public:
virtual nsresult RestoreWindowState(nsISupports *aState) = 0;
// Suspend timeouts in this window and in child windows.
virtual void SuspendTimeouts(PRUint32 aIncrease = 1,
PRBool aFreezeChildren = PR_TRUE) = 0;
virtual void SuspendTimeouts() = 0;
// Resume suspended timeouts in this window and in child windows.
virtual nsresult ResumeTimeouts(PRBool aThawChildren = PR_TRUE) = 0;
virtual PRUint32 TimeoutSuspendCount() = 0;
virtual nsresult ResumeTimeouts() = 0;
// Fire any DOM notification events related to things that happened while
// the window was frozen.
virtual nsresult FireDelayedDOMEvents() = 0;

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

@ -1885,14 +1885,6 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if (st_id == nsIProgrammingLanguage::JAVASCRIPT)
JS_EndRequest((JSContext *)this_ctx->GetNativeContext());
}
nsCOMPtr<nsIContent> frame = do_QueryInterface(GetFrameElementInternal());
if (frame && frame->GetOwnerDoc()) {
nsPIDOMWindow* parentWindow = frame->GetOwnerDoc()->GetWindow();
if (parentWindow && parentWindow->TimeoutSuspendCount()) {
SuspendTimeouts(parentWindow->TimeoutSuspendCount());
}
}
}
// Tell the contexts we have completed setting up the doc.
NS_STID_FOR_ID(st_id) {
@ -2062,7 +2054,7 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
// Call FreeInnerObjects on all inner windows, not just the current
// one, since some could be held by WindowStateHolder objects that
// are GC-owned.
for (nsRefPtr<nsGlobalWindow> inner = (nsGlobalWindow *)PR_LIST_HEAD(this);
for (nsGlobalWindow *inner = (nsGlobalWindow *)PR_LIST_HEAD(this);
inner != this;
inner = (nsGlobalWindow*)PR_NEXT_LINK(inner)) {
NS_ASSERTION(inner->mOuterWindow == this, "bad outer window pointer");
@ -8397,39 +8389,37 @@ nsGlobalWindow::RestoreWindowState(nsISupports *aState)
}
void
nsGlobalWindow::SuspendTimeouts(PRUint32 aIncrease,
PRBool aFreezeChildren)
nsGlobalWindow::SuspendTimeouts()
{
FORWARD_TO_INNER_VOID(SuspendTimeouts, (aIncrease, aFreezeChildren));
FORWARD_TO_INNER_VOID(SuspendTimeouts, ());
PRBool suspended = (mTimeoutsSuspendDepth != 0);
mTimeoutsSuspendDepth += aIncrease;
if (++mTimeoutsSuspendDepth != 1) {
return;
}
if (!suspended) {
nsDOMThreadService* dts = nsDOMThreadService::get();
if (dts) {
dts->SuspendWorkersForGlobal(static_cast<nsIScriptGlobalObject*>(this));
}
PRTime now = PR_Now();
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
// Change mWhen to be the time remaining for this timer.
if (t->mWhen > now)
t->mWhen -= now;
else
t->mWhen = 0;
// Drop the XPCOM timer; we'll reschedule when restoring the state.
if (t->mTimer) {
t->mTimer->Cancel();
t->mTimer = nsnull;
// Drop the reference that the timer's closure had on this timeout, we'll
// add it back in ResumeTimeouts. Note that it shouldn't matter that we're
// passing null for the context, since this shouldn't actually release this
// timeout.
t->Release();
}
nsDOMThreadService* dts = nsDOMThreadService::get();
if (dts) {
dts->SuspendWorkersForGlobal(static_cast<nsIScriptGlobalObject*>(this));
}
PRTime now = PR_Now();
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
// Change mWhen to be the time remaining for this timer.
if (t->mWhen > now)
t->mWhen -= now;
else
t->mWhen = 0;
// Drop the XPCOM timer; we'll reschedule when restoring the state.
if (t->mTimer) {
t->mTimer->Cancel();
t->mTimer = nsnull;
// Drop the reference that the timer's closure had on this timeout, we'll
// add it back in ResumeTimeouts. Note that it shouldn't matter that we're
// passing null for the context, since this shouldn't actually release this
// timeout.
t->Release();
}
}
@ -8449,11 +8439,12 @@ nsGlobalWindow::SuspendTimeouts(PRUint32 aIncrease,
nsGlobalWindow *win =
static_cast<nsGlobalWindow*>
(static_cast<nsPIDOMWindow*>(pWin));
win->SuspendTimeouts(aIncrease, aFreezeChildren);
win->SuspendTimeouts();
NS_ASSERTION(win->IsOuterWindow(), "Expected outer window");
nsGlobalWindow* inner = win->GetCurrentInnerWindowInternal();
if (inner && aFreezeChildren) {
if (inner) {
inner->Freeze();
}
}
@ -8462,68 +8453,67 @@ nsGlobalWindow::SuspendTimeouts(PRUint32 aIncrease,
}
nsresult
nsGlobalWindow::ResumeTimeouts(PRBool aThawChildren)
nsGlobalWindow::ResumeTimeouts()
{
FORWARD_TO_INNER(ResumeTimeouts, (), NS_ERROR_NOT_INITIALIZED);
NS_ASSERTION(mTimeoutsSuspendDepth, "Mismatched calls to ResumeTimeouts!");
--mTimeoutsSuspendDepth;
PRBool shouldResume = (mTimeoutsSuspendDepth == 0);
if (--mTimeoutsSuspendDepth != 0) {
return NS_OK;
}
nsDOMThreadService* dts = nsDOMThreadService::get();
if (dts) {
dts->ResumeWorkersForGlobal(static_cast<nsIScriptGlobalObject*>(this));
}
// Restore all of the timeouts, using the stored time remaining
// (stored in timeout->mWhen).
PRTime now = PR_Now();
nsresult rv;
if (shouldResume) {
nsDOMThreadService* dts = nsDOMThreadService::get();
if (dts) {
dts->ResumeWorkersForGlobal(static_cast<nsIScriptGlobalObject*>(this));
}
// Restore all of the timeouts, using the stored time remaining
// (stored in timeout->mWhen).
PRTime now = PR_Now();
#ifdef DEBUG
PRBool _seenDummyTimeout = PR_FALSE;
PRBool _seenDummyTimeout = PR_FALSE;
#endif
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
// There's a chance we're being called with RunTimeout on the stack in which
// case we have a dummy timeout in the list that *must not* be resumed. It
// can be identified by a null mWindow.
if (!t->mWindow) {
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
// There's a chance we're being called with RunTimeout on the stack in which
// case we have a dummy timeout in the list that *must not* be resumed. It
// can be identified by a null mWindow.
if (!t->mWindow) {
#ifdef DEBUG
NS_ASSERTION(!_seenDummyTimeout, "More than one dummy timeout?!");
_seenDummyTimeout = PR_TRUE;
NS_ASSERTION(!_seenDummyTimeout, "More than one dummy timeout?!");
_seenDummyTimeout = PR_TRUE;
#endif
continue;
}
// Make sure to cast the unsigned PR_USEC_PER_MSEC to signed
// PRTime to make the division do the right thing on 64-bit
// platforms whether t->mWhen is positive or negative (which is
// likely to always be positive here, but cast anyways for
// consistency).
PRUint32 delay =
PR_MAX(((PRUint32)(t->mWhen / (PRTime)PR_USEC_PER_MSEC)),
DOM_MIN_TIMEOUT_VALUE);
// Set mWhen back to the time when the timer is supposed to
// fire.
t->mWhen += now;
t->mTimer = do_CreateInstance("@mozilla.org/timer;1");
NS_ENSURE_TRUE(t->mTimer, NS_ERROR_OUT_OF_MEMORY);
rv = t->mTimer->InitWithFuncCallback(TimerCallback, t, delay,
nsITimer::TYPE_ONE_SHOT);
if (NS_FAILED(rv)) {
t->mTimer = nsnull;
return rv;
}
// Add a reference for the new timer's closure.
t->AddRef();
continue;
}
// Make sure to cast the unsigned PR_USEC_PER_MSEC to signed
// PRTime to make the division do the right thing on 64-bit
// platforms whether t->mWhen is positive or negative (which is
// likely to always be positive here, but cast anyways for
// consistency).
PRUint32 delay =
PR_MAX(((PRUint32)(t->mWhen / (PRTime)PR_USEC_PER_MSEC)),
DOM_MIN_TIMEOUT_VALUE);
// Set mWhen back to the time when the timer is supposed to
// fire.
t->mWhen += now;
t->mTimer = do_CreateInstance("@mozilla.org/timer;1");
NS_ENSURE_TRUE(t->mTimer, NS_ERROR_OUT_OF_MEMORY);
rv = t->mTimer->InitWithFuncCallback(TimerCallback, t, delay,
nsITimer::TYPE_ONE_SHOT);
if (NS_FAILED(rv)) {
t->mTimer = nsnull;
return rv;
}
// Add a reference for the new timer's closure.
t->AddRef();
}
// Resume our children as well.
@ -8546,11 +8536,11 @@ nsGlobalWindow::ResumeTimeouts(PRBool aThawChildren)
NS_ASSERTION(win->IsOuterWindow(), "Expected outer window");
nsGlobalWindow* inner = win->GetCurrentInnerWindowInternal();
if (inner && aThawChildren) {
if (inner) {
inner->Thaw();
}
rv = win->ResumeTimeouts(aThawChildren);
rv = win->ResumeTimeouts();
NS_ENSURE_SUCCESS(rv, rv);
}
}
@ -8559,13 +8549,6 @@ nsGlobalWindow::ResumeTimeouts(PRBool aThawChildren)
return NS_OK;
}
PRUint32
nsGlobalWindow::TimeoutSuspendCount()
{
FORWARD_TO_INNER(TimeoutSuspendCount, (), 0);
return mTimeoutsSuspendDepth;
}
NS_IMETHODIMP
nsGlobalWindow::GetScriptTypeID(PRUint32 *aScriptType)
{

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

@ -303,10 +303,8 @@ public:
virtual NS_HIDDEN_(nsresult) SaveWindowState(nsISupports **aState);
virtual NS_HIDDEN_(nsresult) RestoreWindowState(nsISupports *aState);
virtual NS_HIDDEN_(void) SuspendTimeouts(PRUint32 aIncrease = 1,
PRBool aFreezeChildren = PR_TRUE);
virtual NS_HIDDEN_(nsresult) ResumeTimeouts(PRBool aThawChildren = PR_TRUE);
virtual NS_HIDDEN_(PRUint32) TimeoutSuspendCount();
virtual NS_HIDDEN_(void) SuspendTimeouts();
virtual NS_HIDDEN_(nsresult) ResumeTimeouts();
virtual NS_HIDDEN_(nsresult) FireDelayedDOMEvents();
virtual NS_HIDDEN_(PRBool) IsFrozen() const
{