From a07cb5caa8afa2f38845614fa487d3f69dbcb7b0 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Thu, 31 Aug 2006 03:17:45 +0000 Subject: [PATCH] Just make all document mutation observers get notified through the binding manager, to resolve issues with them depending on insertion points. Bug 348573 follow, r+sr=sicking git-svn-id: svn://10.0.0.236/trunk@208874 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsDocument.cpp | 18 +++- mozilla/content/base/src/nsDocument.h | 3 + .../content/xbl/public/nsIBindingManager.h | 10 +- mozilla/content/xbl/src/nsBindingManager.cpp | 100 +----------------- mozilla/content/xbl/src/nsBindingManager.h | 16 +-- mozilla/layout/base/nsPresShell.cpp | 4 +- 6 files changed, 36 insertions(+), 115 deletions(-) diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index e49ef153162..75ef7805e40 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -830,10 +830,8 @@ nsDocument::Init() NS_ENSURE_TRUE(bindingManager, NS_ERROR_OUT_OF_MEMORY); mBindingManager = bindingManager; - if (!mObservers.PrependObserver(bindingManager)) { - return NS_ERROR_OUT_OF_MEMORY; - } - + // The binding manager needs to come before everything but us in our + // mutation observer list. nsINode::nsSlots* slots = GetSlots(); NS_ENSURE_TRUE(slots && slots->mMutationObservers.PrependObserver(bindingManager), @@ -2247,6 +2245,18 @@ nsDocument::GetScriptLoader() return mScriptLoader; } +void +nsDocument::AddMutationObserver(nsIMutationObserver* aMutationObserver) +{ + mBindingManager->AddObserver(aMutationObserver); +} + +void +nsDocument::RemoveMutationObserver(nsIMutationObserver* aMutationObserver) +{ + mBindingManager->RemoveObserver(aMutationObserver); +} + // Note: We don't hold a reference to the document observer; we assume // that it has a live reference to the document. void diff --git a/mozilla/content/base/src/nsDocument.h b/mozilla/content/base/src/nsDocument.h index d341d7594d0..95caa5d6c70 100644 --- a/mozilla/content/base/src/nsDocument.h +++ b/mozilla/content/base/src/nsDocument.h @@ -452,6 +452,9 @@ public: */ virtual nsIScriptLoader* GetScriptLoader(); + virtual void AddMutationObserver(nsIMutationObserver* aObserver); + virtual void RemoveMutationObserver(nsIMutationObserver* aMutationObserver); + /** * Add a new observer of document change notifications. Whenever * content is changed, appended, inserted or removed the observers are diff --git a/mozilla/content/xbl/public/nsIBindingManager.h b/mozilla/content/xbl/public/nsIBindingManager.h index 1fdc3b6b1a9..7d6bc823d5b 100644 --- a/mozilla/content/xbl/public/nsIBindingManager.h +++ b/mozilla/content/xbl/public/nsIBindingManager.h @@ -57,11 +57,11 @@ class nsIURI; class nsIXPConnectWrappedJS; class nsIDOMNodeList; class nsVoidArray; -class nsIDocumentObserver; +class nsIMutationObserver; #define NS_IBINDING_MANAGER_IID \ -{ 0x8186980b, 0x35b8, 0x469f, \ - { 0x8b, 0xc5, 0x33, 0xad, 0x3c, 0x35, 0x90, 0x98 } } +{ 0x6abe92b0, 0x4553, 0x4301, \ + { 0xa1, 0xcb, 0x3e, 0x2d, 0x85, 0xd0, 0xec, 0x8c } } class nsIBindingManager : public nsISupports { @@ -187,13 +187,13 @@ public: * ContentInserted/ContentAppended and before they're updated for * ContentRemoved. */ - virtual void AddObserver(nsIDocumentObserver* aObserver) = 0; + virtual void AddObserver(nsIMutationObserver* aObserver) = 0; /** * Remove an observer of document change notifications. This will * return false if the observer cannot be found. */ - virtual PRBool RemoveObserver(nsIDocumentObserver* aObserver) = 0; + virtual PRBool RemoveObserver(nsIMutationObserver* aObserver) = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIBindingManager, NS_IBINDING_MANAGER_IID) diff --git a/mozilla/content/xbl/src/nsBindingManager.cpp b/mozilla/content/xbl/src/nsBindingManager.cpp index 284715633fd..26c48b9d1f2 100644 --- a/mozilla/content/xbl/src/nsBindingManager.cpp +++ b/mozilla/content/xbl/src/nsBindingManager.cpp @@ -295,8 +295,8 @@ SetOrRemoveObject(PLDHashTable& table, nsISupports* aKey, nsISupports* aValue) // Static member variable initialization // Implement our nsISupports methods -NS_IMPL_ISUPPORTS4(nsBindingManager, nsIBindingManager, nsIStyleRuleSupplier, - nsIDocumentObserver, nsIMutationObserver) +NS_IMPL_ISUPPORTS3(nsBindingManager, nsIBindingManager, nsIStyleRuleSupplier, + nsIMutationObserver) // Constructors/Destructors nsBindingManager::nsBindingManager(void) @@ -1156,42 +1156,18 @@ nsBindingManager::GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChil // Note: We don't hold a reference to the document observer; we assume // that it has a live reference to the document. void -nsBindingManager::AddObserver(nsIDocumentObserver* aObserver) +nsBindingManager::AddObserver(nsIMutationObserver* aObserver) { // The array makes sure the observer isn't already in the list mObservers.AppendObserver(aObserver); } PRBool -nsBindingManager::RemoveObserver(nsIDocumentObserver* aObserver) +nsBindingManager::RemoveObserver(nsIMutationObserver* aObserver) { return mObservers.RemoveObserver(aObserver); } -void -nsBindingManager::BeginUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(BeginUpdate, (aDocument, aUpdateType)); -} - -void -nsBindingManager::EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(EndUpdate, (aDocument, aUpdateType)); -} - -void -nsBindingManager::BeginLoad(nsIDocument* aDocument) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(BeginLoad, (aDocument)); -} - -void -nsBindingManager::EndLoad(nsIDocument* aDocument) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(EndLoad, (aDocument)); -} - void nsBindingManager::CharacterDataChanged(nsIDocument* aDocument, nsIContent* aContent, @@ -1201,17 +1177,6 @@ nsBindingManager::CharacterDataChanged(nsIDocument* aDocument, (aDocument, aContent, aAppend)); } -void -nsBindingManager::ContentStatesChanged(nsIDocument* aDocument, - nsIContent* aContent1, - nsIContent* aContent2, - PRInt32 aStateMask) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(ContentStatesChanged, - (aDocument, aContent1, aContent2, - aStateMask)); -} - void nsBindingManager::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, @@ -1391,60 +1356,3 @@ nsBindingManager::NodeWillBeDestroyed(const nsINode *aNode) { NS_BINDINGMANAGER_NOTIFY_OBSERVERS(NodeWillBeDestroyed, (aNode)); } - -void -nsBindingManager::StyleSheetAdded(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet, - PRBool aDocumentSheet) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(StyleSheetAdded, - (aDocument, aStyleSheet, aDocumentSheet)); -} - -void -nsBindingManager::StyleSheetRemoved(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet, - PRBool aDocumentSheet) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(StyleSheetRemoved, - (aDocument, aStyleSheet, aDocumentSheet)); -} - -void -nsBindingManager::StyleSheetApplicableStateChanged(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet, - PRBool aApplicable) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(StyleSheetApplicableStateChanged, - (aDocument, aStyleSheet, aApplicable)); -} - -void -nsBindingManager::StyleRuleChanged(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet, - nsIStyleRule* aOldStyleRule, - nsIStyleRule* aNewStyleRule) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(StyleRuleChanged, - (aDocument, aStyleSheet, aOldStyleRule, - aNewStyleRule)); -} - -void -nsBindingManager::StyleRuleAdded(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet, - nsIStyleRule* aStyleRule) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(StyleRuleAdded, - (aDocument, aStyleSheet, aStyleRule)); -} - -void -nsBindingManager::StyleRuleRemoved(nsIDocument* aDocument, - nsIStyleSheet* aStyleSheet, - nsIStyleRule* aStyleRule) -{ - NS_BINDINGMANAGER_NOTIFY_OBSERVERS(StyleRuleRemoved, - (aDocument, aStyleSheet, aStyleRule)); -} - diff --git a/mozilla/content/xbl/src/nsBindingManager.h b/mozilla/content/xbl/src/nsBindingManager.h index bd3254ec8d2..4a165371098 100755 --- a/mozilla/content/xbl/src/nsBindingManager.h +++ b/mozilla/content/xbl/src/nsBindingManager.h @@ -42,7 +42,7 @@ #include "nsIBindingManager.h" #include "nsIStyleRuleSupplier.h" -#include "nsStubDocumentObserver.h" +#include "nsIMutationObserver.h" #include "pldhash.h" #include "nsInterfaceHashtable.h" #include "nsRefPtrHashtable.h" @@ -61,11 +61,11 @@ class nsStyleSet; class nsBindingManager : public nsIBindingManager, public nsIStyleRuleSupplier, - public nsIDocumentObserver + public nsIMutationObserver { public: NS_DECL_ISUPPORTS - NS_DECL_NSIDOCUMENTOBSERVER + NS_DECL_NSIMUTATIONOBSERVER nsBindingManager(); ~nsBindingManager(); @@ -124,9 +124,9 @@ public: NS_IMETHOD ShouldBuildChildFrames(nsIContent* aContent, PRBool* aResult); - virtual NS_HIDDEN_(void) AddObserver(nsIDocumentObserver* aObserver); + virtual NS_HIDDEN_(void) AddObserver(nsIMutationObserver* aObserver); - virtual NS_HIDDEN_(PRBool) RemoveObserver(nsIDocumentObserver* aObserver); + virtual NS_HIDDEN_(PRBool) RemoveObserver(nsIMutationObserver* aObserver); // nsIStyleRuleSupplier NS_IMETHOD WalkRules(nsStyleSet* aStyleSet, @@ -149,7 +149,7 @@ protected: nsresult GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult); #define NS_BINDINGMANAGER_NOTIFY_OBSERVERS(func_, params_) \ - NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mObservers, nsIDocumentObserver, \ + NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mObservers, nsIMutationObserver, \ func_, params_); // MEMBER VARIABLES @@ -197,10 +197,10 @@ protected: // table, they have not yet finished loading. nsInterfaceHashtable mLoadingDocTable; - // Array of document observers who would like to be notified of content + // Array of mutation observers who would like to be notified of content // appends/inserts after we update our data structures and of content removes // before we do so. - nsTObserverArray mObservers; + nsTObserverArray mObservers; // A queue of binding attached event handlers that are awaiting execution. nsVoidArray mAttachedStack; diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 5a88b5099d6..62d4cd914c4 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -2721,7 +2721,7 @@ NS_IMETHODIMP PresShell::BeginObservingDocument() { if (mDocument) { - mDocument->BindingManager()->AddObserver(this); + mDocument->AddObserver(this); if (mIsDocumentGone) { NS_WARNING("Adding a presshell that was disconnected from the document " "as a document observer? Sounds wrong..."); @@ -2739,7 +2739,7 @@ PresShell::EndObservingDocument() // is gone, perhaps? Except for printing it's NOT gone, sometimes. mIsDocumentGone = PR_TRUE; if (mDocument) { - mDocument->BindingManager()->RemoveObserver(this); + mDocument->RemoveObserver(this); } return NS_OK; }