From 2cace767869b7574b13bbf560f7b5319359ff112 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Mon, 30 Apr 2007 03:09:55 +0000 Subject: [PATCH] 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 fully reflowed before onload fires. Bug 379093, r+sr=roc git-svn-id: svn://10.0.0.236/trunk@225241 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/nsDocumentViewer.cpp | 7 ++++ mozilla/layout/base/nsPresShell.cpp | 47 ++++-------------------- 2 files changed, 14 insertions(+), 40 deletions(-) diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index 03aa83a96b3..a1607c092a0 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -1030,6 +1030,13 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus) */ nsCOMPtr 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 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)) { diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index a8ce81631db..a8453941873 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -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 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