From 73deb4e72792de32e956a2c2a73b5ded626301e2 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Mon, 1 Jun 2009 16:11:01 +0000 Subject: [PATCH] Bug 489050. Make sure to not notify on our content once we've disconnected from the document. r=bent, sr=sicking, a=dveditz git-svn-id: svn://10.0.0.236/trunk@257328 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsContentSink.h | 4 ++++ .../html/document/src/nsHTMLContentSink.cpp | 19 +++++++++++++------ .../xml/document/src/nsXMLContentSink.cpp | 19 ++++++++++++++----- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/mozilla/content/base/src/nsContentSink.h b/mozilla/content/base/src/nsContentSink.h index 0a772bab47b..fd646796f8f 100644 --- a/mozilla/content/base/src/nsContentSink.h +++ b/mozilla/content/base/src/nsContentSink.h @@ -277,6 +277,10 @@ protected: PRUint8 mDeferredLayoutStart : 1; // If true, we deferred notifications until sheets load PRUint8 mDeferredFlushTags : 1; + // If false, we're not ourselves a document observer; that means we + // shouldn't be performing any more content model notifications, + // since we're not longer updating our child counts. + PRUint8 mIsDocumentObserver : 1; // -- Can interrupt parsing members -- PRUint32 mDelayTimerStart; diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index 0ddf4eef354..ce53e5a883e 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -1661,6 +1661,7 @@ HTMLContentSink::Init(nsIDocument* aDoc, } aDoc->AddObserver(this); + mIsDocumentObserver = PR_TRUE; CallQueryInterface(aDoc, &mHTMLDocument); mObservers = nsnull; @@ -1838,8 +1839,10 @@ HTMLContentSink::DidBuildModel(void) // our notifications out, so there's no need to do anything else here. // XXXbz I wonder whether we could End() our contexts here too, or something, - // just to make sure we no longer notify... + // just to make sure we no longer notify... Or is the mIsDocumentObserver + // thing sufficient? mDocument->RemoveObserver(this); + mIsDocumentObserver = PR_FALSE; mDocument->EndLoad(); @@ -3203,11 +3206,15 @@ HTMLContentSink::FlushPendingNotifications(mozFlushType aType) // Only flush tags if we're not doing the notification ourselves // (since we aren't reentrant) if (!mInNotification) { - if (aType >= Flush_ContentAndNotify) { - FlushTags(); - } - else if (mCurrentContext) { - mCurrentContext->FlushText(); + // Only flush if we're still a document observer (so that our child counts + // should be correct). + if (mIsDocumentObserver) { + if (aType >= Flush_ContentAndNotify) { + FlushTags(); + } + else if (mCurrentContext) { + mCurrentContext->FlushText(); + } } if (aType >= Flush_Layout) { // Make sure that layout has started so that the reflow flush diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.cpp b/mozilla/content/xml/document/src/nsXMLContentSink.cpp index 4e9aaa47870..ff105ad50f2 100644 --- a/mozilla/content/xml/document/src/nsXMLContentSink.cpp +++ b/mozilla/content/xml/document/src/nsXMLContentSink.cpp @@ -168,6 +168,7 @@ nsXMLContentSink::Init(nsIDocument* aDoc, NS_ENSURE_SUCCESS(rv, rv); aDoc->AddObserver(this); + mIsDocumentObserver = PR_TRUE; if (!mDocShell) { mPrettyPrintXML = PR_FALSE; @@ -248,6 +249,7 @@ nsXMLContentSink::MaybePrettyPrint() // stop observing in order to avoid crashing when replacing content mDocument->RemoveObserver(this); + mIsDocumentObserver = PR_FALSE; // Reenable the CSSLoader so that the prettyprinting stylesheets can load if (mCSSLoader) { @@ -316,6 +318,7 @@ nsXMLContentSink::DidBuildModel() if (mXSLTProcessor) { // stop observing in order to avoid crashing when replacing content mDocument->RemoveObserver(this); + mIsDocumentObserver = PR_FALSE; // Check for xslt-param and xslt-param-namespace PIs PRUint32 i; @@ -374,6 +377,7 @@ nsXMLContentSink::DidBuildModel() } mDocument->RemoveObserver(this); + mIsDocumentObserver = PR_FALSE; mDocument->EndLoad(); } @@ -1455,6 +1459,7 @@ nsXMLContentSink::ReportError(const PRUnichar* aErrorText, // stop observing in order to avoid crashing when removing content mDocument->RemoveObserver(this); + mIsDocumentObserver = PR_FALSE; // Clear the current content and // prepare to set as the document root @@ -1618,11 +1623,15 @@ nsXMLContentSink::FlushPendingNotifications(mozFlushType aType) // Only flush tags if we're not doing the notification ourselves // (since we aren't reentrant) if (!mInNotification) { - if (aType >= Flush_ContentAndNotify) { - FlushTags(); - } - else { - FlushText(PR_FALSE); + if (mIsDocumentObserver) { + // Only flush if we're still a document observer (so that our child + // counts should be correct). + if (aType >= Flush_ContentAndNotify) { + FlushTags(); + } + else { + FlushText(PR_FALSE); + } } if (aType >= Flush_Layout) { // Make sure that layout has started so that the reflow flush