diff --git a/content/base/src/nsGenericDOMDataNode.cpp b/content/base/src/nsGenericDOMDataNode.cpp index 322b80105f8..43df0c8c23f 100644 --- a/content/base/src/nsGenericDOMDataNode.cpp +++ b/content/base/src/nsGenericDOMDataNode.cpp @@ -565,7 +565,7 @@ nsGenericDOMDataNode::UnbindFromTree(PRBool aDeep, PRBool aNullParent) // Notify XBL- & nsIAnonymousContentCreator-generated // anonymous content that the document is changing. // This is needed to update the insertion point. - document->BindingManager()->RemovedFromDocument(this, document); + document->BindingManager()->ChangeDocumentFor(this, document, nsnull); } mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT; diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 652a64c6401..c8872746278 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -2969,7 +2969,7 @@ nsGenericElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) if (document) { // Notify XBL- & nsIAnonymousContentCreator-generated // anonymous content that the document is changing. - document->BindingManager()->RemovedFromDocument(this, document); + document->BindingManager()->ChangeDocumentFor(this, document, nsnull); document->ClearBoxObjectFor(this); } @@ -3766,7 +3766,7 @@ nsGenericElement::DestroyContent() { nsIDocument *document = GetOwnerDoc(); if (document) { - document->BindingManager()->RemovedFromDocument(this, document); + document->BindingManager()->ChangeDocumentFor(this, document, nsnull); document->ClearBoxObjectFor(this); } @@ -4327,8 +4327,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericElement) { nsIDocument *doc; - if (!tmp->GetNodeParent() && (doc = tmp->GetOwnerDoc())) { - doc->BindingManager()->RemovedFromDocument(tmp, doc); + if (!tmp->GetNodeParent() && (doc = tmp->GetOwnerDoc()) && + tmp->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) { + doc->BindingManager()->ChangeDocumentFor(tmp, doc, nsnull); } } NS_IMPL_CYCLE_COLLECTION_UNLINK_END diff --git a/content/xbl/src/nsBindingManager.cpp b/content/xbl/src/nsBindingManager.cpp index 5a06be1ecf6..c8ae5bc500f 100644 --- a/content/xbl/src/nsBindingManager.cpp +++ b/content/xbl/src/nsBindingManager.cpp @@ -621,11 +621,17 @@ nsBindingManager::SetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS* aWra return SetOrRemoveObject(mWrapperTable, aContent, aWrappedJS); } -void -nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent, - nsIDocument* aOldDocument) +nsresult +nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument, + nsIDocument* aNewDocument) { + // XXXbz this code is pretty broken, since moving from one document + // to another always passes through a null document! NS_PRECONDITION(aOldDocument != nsnull, "no old document"); + NS_PRECONDITION(!aNewDocument, + "Changing to a non-null new document not supported yet"); + if (! aOldDocument) + return NS_ERROR_NULL_POINTER; // Hold a ref to the binding so it won't die when we remove it from our // table. @@ -644,14 +650,18 @@ nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent, } if (binding) { - binding->ChangeDocument(aOldDocument, nsnull); + binding->ChangeDocument(aOldDocument, aNewDocument); SetBinding(aContent, nsnull); + if (aNewDocument) + aNewDocument->BindingManager()->SetBinding(aContent, binding); } // Clear out insertion parents and content lists. SetInsertionParent(aContent, nsnull); SetContentListFor(aContent, nsnull); SetAnonymousNodesFor(aContent, nsnull); + + return NS_OK; } nsIAtom* diff --git a/content/xbl/src/nsBindingManager.h b/content/xbl/src/nsBindingManager.h index c71ba37cde4..31bb3bfb831 100644 --- a/content/xbl/src/nsBindingManager.h +++ b/content/xbl/src/nsBindingManager.h @@ -84,22 +84,21 @@ public: /** * Notify the binding manager that an element - * has been removed from its document, + * has been moved from one document to another, * so that it can update any bindings or * nsIAnonymousContentCreator-created anonymous * content that may depend on the document. * @param aContent the element that's being moved * @param aOldDocument the old document in which the - * content resided. + * content resided. May be null if the the content + * was not in any document. + * @param aNewDocument the document in which the + * content will reside. May be null if the content + * will not reside in any document, or if the + * content is being destroyed. */ - void RemovedFromDocument(nsIContent* aContent, nsIDocument* aOldDocument) - { - if (aContent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) { - RemovedFromDocumentInternal(aContent, aOldDocument); - } - } - void RemovedFromDocumentInternal(nsIContent* aContent, - nsIDocument* aOldDocument); + nsresult ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument, + nsIDocument* aNewDocument); nsIAtom* ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID);