Resize the subdocument off a post-reflow callback so that we don't run script

during reflow, and a few related checks to make sure we can deal with script in
reflow callbacks better.  Bug 396587, r+sr+a=roc.


git-svn-id: svn://10.0.0.236/trunk@236344 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzbarsky%mit.edu
2007-09-20 02:46:28 +00:00
parent 581d7f7752
commit f0794c0305
3 changed files with 101 additions and 49 deletions

View File

@@ -2480,29 +2480,40 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
return NS_OK;
NS_ASSERTION(mViewManager, "Must have view manager");
mViewManager->BeginUpdateViewBatch();
nsCOMPtr<nsIViewManager> viewManager = mViewManager;
viewManager->BeginUpdateViewBatch();
// XXX Do a full invalidate at the beginning so that invalidates along
// the way don't have region accumulation issues?
// Take this ref after viewManager so it'll make sure to go away first
nsCOMPtr<nsIPresShell> kungFuDeathGrip(this);
WillCauseReflow();
WillDoReflow();
// Make sure style is up to date
mFrameConstructor->ProcessPendingRestyles();
if (!mIsDestroying) {
// XXX Do a full invalidate at the beginning so that invalidates along
// the way don't have region accumulation issues?
{
// Kick off a top-down reflow
AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow);
mIsReflowing = PR_TRUE;
WillCauseReflow();
WillDoReflow();
mDirtyRoots.RemoveElement(rootFrame);
DoReflow(rootFrame);
mIsReflowing = PR_FALSE;
{
// Kick off a top-down reflow
AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow);
mIsReflowing = PR_TRUE;
mDirtyRoots.RemoveElement(rootFrame);
DoReflow(rootFrame);
mIsReflowing = PR_FALSE;
}
DidCauseReflow();
DidDoReflow();
}
DidCauseReflow();
DidDoReflow();
mViewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
viewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
CreateResizeEventTimer();
if (!mIsDestroying) {
CreateResizeEventTimer();
}
return NS_OK; //XXX this needs to be real. MMP
}
@@ -6223,26 +6234,31 @@ PresShell::ProcessReflowCommands(PRBool aInterruptible)
DidDoReflow();
// DidDoReflow might have killed us
if (!mIsDestroying) {
#ifdef DEBUG
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n", (void*)this);
}
DoVerifyReflow();
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n",
(void*)this);
}
DoVerifyReflow();
#endif
// 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();
// 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));
MOZ_TIMER_STOP(mReflowWatch);
if (mShouldUnsuppressPainting && mDirtyRoots.Count() == 0) {
if (!mIsDestroying && mShouldUnsuppressPainting &&
mDirtyRoots.Count() == 0) {
// We only unlock if we're out of reflows. It's pointless
// to unlock if reflows are still pending, since reflows
// are just going to thrash the frames around some more. By