From 432c756b59701cec15913fdcbdaeeaed6d2a9486 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Tue, 22 Dec 2009 18:09:10 -0600 Subject: [PATCH] Bug 396367. Make sure that we have flushed content notifications anytime we process restyles that might cause frame construction. r=bzbarsky --HG-- extra : rebase_source : 67d99a197a4974684f57f23873033b85c276ef86 --- layout/base/nsCSSFrameConstructor.cpp | 8 ++- layout/base/nsPresShell.cpp | 46 +++++++++++------ layout/base/tests/chrome/Makefile.in | 2 + .../base/tests/chrome/test_bug396367-1.html | 44 ++++++++++++++++ .../base/tests/chrome/test_bug396367-2.html | 51 +++++++++++++++++++ 5 files changed, 134 insertions(+), 17 deletions(-) create mode 100644 layout/base/tests/chrome/test_bug396367-1.html create mode 100644 layout/base/tests/chrome/test_bug396367-2.html diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 7f6a4ca8ce86..409bd0bb03fe 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -11057,8 +11057,6 @@ nsCSSFrameConstructor::RebuildAllStyleData(nsChangeHint aExtraHint) if (!mPresShell || !mPresShell->GetRootFrame()) return; - nsAutoScriptBlocker scriptBlocker; - // Make sure that the viewmanager will outlive the presshell nsIViewManager::UpdateViewBatch batch(mPresShell->GetViewManager()); @@ -11066,6 +11064,12 @@ nsCSSFrameConstructor::RebuildAllStyleData(nsChangeHint aExtraHint) // the parent frame and thus destroys the pres shell. nsCOMPtr kungFuDeathGrip(mPresShell); + // We may reconstruct frames below and hence process anything that is in the + // tree. We don't want to get notified to process those items again after. + mPresShell->GetDocument()->FlushPendingNotifications(Flush_ContentAndNotify); + + nsAutoScriptBlocker scriptBlocker; + // Tell the style set to get the old rule tree out of the way // so we can recalculate while maintaining rule tree immutability nsresult rv = mPresShell->StyleSet()->BeginReconstruct(); diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 8a91a4f01356..7dca144919f0 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -2650,6 +2650,10 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight) { nsIViewManager::UpdateViewBatch batch(mViewManager); + // Have to make sure that the content notifications are flushed before we + // start messing with the frame model; otherwise we can get content doubling. + mDocument->FlushPendingNotifications(Flush_ContentAndNotify); + // Make sure style is up to date { nsAutoScriptBlocker scriptBlocker; @@ -5019,6 +5023,12 @@ PresShell::ContentRemoved(nsIDocument *aDocument, nsresult PresShell::ReconstructFrames(void) { + nsCOMPtr kungFuDeathGrip(this); + + // Have to make sure that the content notifications are flushed before we + // start messing with the frame model; otherwise we can get content doubling. + mDocument->FlushPendingNotifications(Flush_ContentAndNotify); + nsAutoCauseReflowNotifier crNotifier(this); mFrameConstructor->BeginUpdate(); nsresult rv = mFrameConstructor->ReconstructDocElementHierarchy(); @@ -7544,23 +7554,29 @@ PresShell::Observe(nsISupports* aSubject, NS_ASSERTION(mViewManager, "View manager must exist"); nsIViewManager::UpdateViewBatch batch(mViewManager); - WalkFramesThroughPlaceholders(mPresContext, rootFrame, - &ReResolveMenusAndTrees, nsnull); + nsWeakFrame weakRoot(rootFrame); + // Have to make sure that the content notifications are flushed before we + // start messing with the frame model; otherwise we can get content doubling. + mDocument->FlushPendingNotifications(Flush_ContentAndNotify); - // Because "chrome:" URL equality is messy, reframe image box - // frames (hack!). - nsStyleChangeList changeList; - WalkFramesThroughPlaceholders(mPresContext, rootFrame, - ReframeImageBoxes, &changeList); - // Mark ourselves as not safe to flush while we're doing frame - // construction. - { - nsAutoScriptBlocker scriptBlocker; - ++mChangeNestCount; - mFrameConstructor->ProcessRestyledFrames(changeList); - --mChangeNestCount; + if (weakRoot.IsAlive()) { + WalkFramesThroughPlaceholders(mPresContext, rootFrame, + &ReResolveMenusAndTrees, nsnull); + + // Because "chrome:" URL equality is messy, reframe image box + // frames (hack!). + nsStyleChangeList changeList; + WalkFramesThroughPlaceholders(mPresContext, rootFrame, + ReframeImageBoxes, &changeList); + // Mark ourselves as not safe to flush while we're doing frame + // construction. + { + nsAutoScriptBlocker scriptBlocker; + ++mChangeNestCount; + mFrameConstructor->ProcessRestyledFrames(changeList); + --mChangeNestCount; + } } - batch.EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC); #ifdef ACCESSIBILITY InvalidateAccessibleSubtree(nsnull); diff --git a/layout/base/tests/chrome/Makefile.in b/layout/base/tests/chrome/Makefile.in index 35ee57db7466..7c0fd7e88797 100644 --- a/layout/base/tests/chrome/Makefile.in +++ b/layout/base/tests/chrome/Makefile.in @@ -46,6 +46,8 @@ include $(topsrcdir)/config/rules.mk _CHROME_FILES = \ test_bug396024.xul \ bug396024_helper.xul \ + test_bug396367-1.html \ + test_bug396367-2.html \ test_bug482976.xul \ bug482976_helper.xul \ test_bug504311.xul \ diff --git a/layout/base/tests/chrome/test_bug396367-1.html b/layout/base/tests/chrome/test_bug396367-1.html new file mode 100644 index 000000000000..12ace642020c --- /dev/null +++ b/layout/base/tests/chrome/test_bug396367-1.html @@ -0,0 +1,44 @@ + + + + + Test for Bug 396367 + + + + + + + +Mozilla Bug 396367 +

+ +
+
+
+
+
+
+
+
+ + diff --git a/layout/base/tests/chrome/test_bug396367-2.html b/layout/base/tests/chrome/test_bug396367-2.html new file mode 100644 index 000000000000..ee1ddc230c94 --- /dev/null +++ b/layout/base/tests/chrome/test_bug396367-2.html @@ -0,0 +1,51 @@ + + + + + Test for Bug 396367 + + + + + + + + +Mozilla Bug 396367 +

+ +
+
+
+ + + +
  • + + +
  • +
    + + +
    + +