Make sure to flush out reflows before firing onload instead of (imperfectly)blocking onload on reflow events. This makes sure that we are in fact fullyreflowed before onload fires. Bug 379093, r+sr=roc

This commit is contained in:
bzbarsky@mit.edu 2007-04-29 20:09:55 -07:00
Родитель dc2e58efd7
Коммит 33d9c4b401
2 изменённых файлов: 14 добавлений и 40 удалений

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

@ -1030,6 +1030,13 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus)
*/
nsCOMPtr<nsIDocumentViewer> kungFuDeathGrip(this);
// Flush out layout so it's up-to-date by the time onload is called
if (mPresShell && !mStopped) {
// Hold strong ref because this could conceivably run script
nsCOMPtr<nsIPresShell> shell = mPresShell;
shell->FlushPendingNotifications(Flush_Layout);
}
// Now, fire either an OnLoad or OnError event to the document...
PRBool restoring = PR_FALSE;
if(NS_SUCCEEDED(aStatus)) {

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

@ -1055,13 +1055,6 @@ protected:
void UnsuppressAndInvalidate();
// This method should be called after mDirtyRoots has been emptied,
// but after the state in the presshell is such that it's safe to
// flush (i.e. mIsReflowing == PR_FALSE) If there are no load-created
// reflow commands and we blocked onload on the document, we'll
// unblock it.
void DoneRemovingDirtyRoots();
void WillCauseReflow() { ++mChangeNestCount; }
nsresult DidCauseReflow();
void WillDoReflow();
@ -1169,7 +1162,6 @@ protected:
nsVoidArray mDirtyRoots;
PRPackedBool mDocumentLoading;
PRPackedBool mDocumentOnloadBlocked;
PRPackedBool mIsReflowing;
PRPackedBool mIgnoreFrameDestruction;
@ -1737,9 +1729,6 @@ PresShell::Destroy()
NS_RELEASE(mViewEventListener);
}
NS_ASSERTION(!mDocumentOnloadBlocked,
"CancelAllPendingReflows() didn't unblock onload?");
KillResizeEventTimer();
mHaveShutDown = PR_TRUE;
@ -3378,8 +3367,6 @@ PresShell::CancelAllPendingReflows()
{
mDirtyRoots.Clear();
DoneRemovingDirtyRoots();
return NS_OK;
}
@ -6036,12 +6023,6 @@ PresShell::PostReflowEvent()
mDirtyRoots.Count() == 0)
return;
// Block onload if needed until the event fires
if (mDocumentLoading && !mDocumentOnloadBlocked) {
mDocument->BlockOnload();
mDocumentOnloadBlocked = PR_TRUE;
}
nsRefPtr<ReflowEvent> ev = new ReflowEvent(this);
if (NS_FAILED(NS_DispatchToCurrentThread(ev))) {
NS_WARNING("failed to dispatch reflow event");
@ -6264,11 +6245,6 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible)
mIsReflowing = PR_FALSE;
}
// If any new reflow commands were enqueued during the reflow,
// schedule another reflow event to process them.
if (mDirtyRoots.Count())
PostReflowEvent();
DidDoReflow();
#ifdef DEBUG
@ -6279,9 +6255,13 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible)
DoVerifyReflow();
#endif
// If there are no more reflow commands in the queue, we'll want
// to unblock onload.
DoneRemovingDirtyRoots();
// If any new reflow commands were enqueued during the reflow, schedule
// another reflow event to process them. Note that we want to do this
// after DidDoReflow(), since that method can change whether there are
// dirty roots around by flushing, and there's no point in posting a reflow
// event just to have the flush revoke it.
if (mDirtyRoots.Count())
PostReflowEvent();
}
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::ProcessReflowCommands(), this=%p\n", this));
@ -6305,19 +6285,6 @@ PresShell::ClearReflowEventStatus()
mReflowEvent.Forget();
}
void
PresShell::DoneRemovingDirtyRoots()
{
// We want to unblock here even if we're destroying, since onload
// can well fire with no presentation in sight. So just check
// whether we actually blocked onload.
// XXXldb Do we want to readd the mIsReflowing check?
if (mDocumentOnloadBlocked && mDirtyRoots.Count() == 0 && !mIsReflowing) {
mDocument->UnblockOnload(PR_FALSE);
mDocumentOnloadBlocked = PR_FALSE;
}
}
#ifdef MOZ_XUL
/*
* It's better to add stuff to the |DidSetStyleContext| method of the