mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 04:03:47 +00:00
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:
parent
dc2e58efd7
commit
33d9c4b401
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user