Bug 472212, r+sr=bz

This commit is contained in:
Olli Pettay 2009-01-06 21:37:28 +02:00
parent c878e5becb
commit 8ce81994af
3 changed files with 46 additions and 49 deletions

View File

@ -283,6 +283,9 @@ nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding)
nsXBLBinding::~nsXBLBinding(void) nsXBLBinding::~nsXBLBinding(void)
{ {
if (mContent) {
nsXBLBinding::UninstallAnonymousContent(mContent->GetOwnerDoc(), mContent);
}
delete mInsertionPointTable; delete mInsertionPointTable;
nsIXBLDocumentInfo* info = mPrototypeBinding->XBLDocumentInfo(); nsIXBLDocumentInfo* info = mPrototypeBinding->XBLDocumentInfo();
NS_RELEASE(info); NS_RELEASE(info);
@ -307,6 +310,10 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLBinding)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLBinding) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLBinding)
// XXX Probably can't unlink mPrototypeBinding->XBLDocumentInfo(), because // XXX Probably can't unlink mPrototypeBinding->XBLDocumentInfo(), because
// mPrototypeBinding is weak. // mPrototypeBinding is weak.
if (tmp->mContent) {
nsXBLBinding::UninstallAnonymousContent(tmp->mContent->GetOwnerDoc(),
tmp->mContent);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContent) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContent)
// XXX What about mNextBinding and mInsertionPointTable? // XXX What about mNextBinding and mInsertionPointTable?
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -372,6 +379,29 @@ nsXBLBinding::InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElem
} }
} }
void
nsXBLBinding::UninstallAnonymousContent(nsIDocument* aDocument,
nsIContent* aAnonParent)
{
nsAutoScriptBlocker scriptBlocker;
// Hold a strong ref while doing this, just in case.
nsCOMPtr<nsIContent> anonParent = aAnonParent;
#ifdef MOZ_XUL
nsCOMPtr<nsIXULDocument> xuldoc =
do_QueryInterface(aDocument);
#endif
PRUint32 childCount = aAnonParent->GetChildCount();
for (PRUint32 i = 0; i < childCount; ++i) {
nsIContent* child = aAnonParent->GetChildAt(i);
child->UnbindFromTree();
#ifdef MOZ_XUL
if (xuldoc) {
xuldoc->RemoveSubtreeFromDocument(child);
}
#endif
}
}
void void
nsXBLBinding::SetBoundElement(nsIContent* aElement) nsXBLBinding::SetBoundElement(nsIContent* aElement)
{ {
@ -726,19 +756,7 @@ nsXBLBinding::GenerateAnonymousContent()
(localName != nsGkAtoms::observes && (localName != nsGkAtoms::observes &&
localName != nsGkAtoms::_template)) { localName != nsGkAtoms::_template)) {
// Undo InstallAnonymousContent // Undo InstallAnonymousContent
PRUint32 childCount = mContent->GetChildCount(); UninstallAnonymousContent(doc, mContent);
#ifdef MOZ_XUL
nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(doc));
#endif
for (PRUint32 k = 0; k < childCount; ++k) {
nsIContent* child = mContent->GetChildAt(k);
child->UnbindFromTree();
#ifdef MOZ_XUL
if (xuldoc) {
xuldoc->RemoveSubtreeFromDocument(child);
}
#endif
}
// Kill all anonymous content. // Kill all anonymous content.
mContent = nsnull; mContent = nsnull;
@ -1153,28 +1171,7 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
mInsertionPointTable->Enumerate(ChangeDocumentForDefaultContent, mInsertionPointTable->Enumerate(ChangeDocumentForDefaultContent,
nsnull); nsnull);
#ifdef MOZ_XUL nsXBLBinding::UninstallAnonymousContent(aOldDocument, anonymous);
nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(aOldDocument));
#endif
nsAutoScriptBlocker scriptBlocker;
// Unbind the _kids_ of the anonymous content, not just the anonymous
// content itself, since they are bound to some other parent. Basically
// we want to undo the mess that InstallAnonymousContent created.
PRUint32 childCount = anonymous->GetChildCount();
for (PRUint32 i = 0; i < childCount; i++) {
anonymous->GetChildAt(i)->UnbindFromTree();
}
anonymous->UnbindFromTree(); // Kill it.
#ifdef MOZ_XUL
// To make XUL templates work (and other XUL-specific stuff),
// we'll need to notify it using its add & remove APIs. Grab the
// interface now...
if (xuldoc)
xuldoc->RemoveSubtreeFromDocument(anonymous);
#endif
} }
// Make sure that henceforth we don't claim that mBoundElement's children // Make sure that henceforth we don't claim that mBoundElement's children

View File

@ -120,6 +120,8 @@ public:
void GenerateAnonymousContent(); void GenerateAnonymousContent();
void InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement); void InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement);
static void UninstallAnonymousContent(nsIDocument* aDocument,
nsIContent* aAnonParent);
void InstallEventHandlers(); void InstallEventHandlers();
nsresult InstallImplementation(); nsresult InstallImplementation();

View File

@ -38,6 +38,7 @@
#include "nsXBLInsertionPoint.h" #include "nsXBLInsertionPoint.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsXBLBinding.h"
nsXBLInsertionPoint::nsXBLInsertionPoint(nsIContent* aParentElement, nsXBLInsertionPoint::nsXBLInsertionPoint(nsIContent* aParentElement,
PRUint32 aIndex, PRUint32 aIndex,
@ -50,6 +51,10 @@ nsXBLInsertionPoint::nsXBLInsertionPoint(nsIContent* aParentElement,
nsXBLInsertionPoint::~nsXBLInsertionPoint() nsXBLInsertionPoint::~nsXBLInsertionPoint()
{ {
if (mDefaultContent) {
nsXBLBinding::UninstallAnonymousContent(mDefaultContent->GetOwnerDoc(),
mDefaultContent);
}
} }
nsrefcnt nsrefcnt
@ -69,6 +74,10 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLInsertionPoint)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPoint) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPoint)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContentTemplate) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContentTemplate)
if (tmp->mDefaultContent) {
nsXBLBinding::UninstallAnonymousContent(tmp->mDefaultContent->GetOwnerDoc(),
tmp->mDefaultContent);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContent) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXBLInsertionPoint) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXBLInsertionPoint)
@ -116,18 +125,7 @@ nsXBLInsertionPoint::UnbindDefaultContent()
return; return;
} }
// Hold a strong ref while doing this, just in case // Undo InstallAnonymousContent.
nsCOMPtr<nsIContent> defContent = mDefaultContent; nsXBLBinding::UninstallAnonymousContent(mDefaultContent->GetOwnerDoc(),
mDefaultContent);
nsAutoScriptBlocker scriptBlocker;
// Unbind the _kids_ of the default content, not just the default content
// itself, since they are bound to some other parent. Basically we want to
// undo the mess that InstallAnonymousContent created.
PRUint32 childCount = mDefaultContent->GetChildCount();
for (PRUint32 i = 0; i < childCount; i++) {
defContent->GetChildAt(i)->UnbindFromTree();
}
defContent->UnbindFromTree();
} }