diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp
index 17e072e93de..353318b1cf7 100644
--- a/mozilla/content/html/document/src/nsHTMLDocument.cpp
+++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp
@@ -242,6 +242,14 @@ public:
if (mNameContentList && mNameContentList != NAME_NOT_VALID) {
NS_RELEASE(mNameContentList);
}
+
+ if (mIdContentList.Count() != 1 ||
+ mIdContentList[0] != ID_NOT_IN_DOCUMENT) {
+ for (PRInt32 i = 0; i < mIdContentList.Count(); ++i) {
+ nsIContent* content = static_cast(mIdContentList[i]);
+ NS_RELEASE(content);
+ }
+ }
}
nsIContent* GetIdContent() {
@@ -253,8 +261,11 @@ public:
PRBool RemoveIdContent(nsIContent* aContent) {
// XXXbz should this ever Compact() I guess when all the content is gone
// we'll just get cleaned up in the natural order of things...
- return mIdContentList.RemoveElement(aContent) &&
- mIdContentList.Count() == 0;
+ if (!mIdContentList.RemoveElement(aContent)) {
+ return PR_FALSE;
+ }
+ NS_RELEASE(aContent);
+ return mIdContentList.Count() == 0;
}
void FlagIDNotInDocument() {
@@ -264,10 +275,13 @@ public:
mIdContentList.AppendElement(ID_NOT_IN_DOCUMENT);
}
+ void Traverse(nsCycleCollectionTraversalCallback* cb);
+
nsCOMPtr mKey;
nsBaseContentList *mNameContentList;
nsRefPtr mDocAllList;
private:
+ // The content nodes are stored addrefed.
nsSmallVoidArray mIdContentList;
};
@@ -282,12 +296,20 @@ IdAndNameMapEntry::AddIdContent(nsIContent* aContent)
if (GetIdContent() == ID_NOT_IN_DOCUMENT) {
NS_ASSERTION(mIdContentList.Count() == 1, "Bogus count");
- return mIdContentList.ReplaceElementAt(aContent, 0);
+ if (!mIdContentList.ReplaceElementAt(aContent, 0)) {
+ return PR_FALSE;
+ }
+ NS_ADDREF(aContent);
+ return PR_TRUE;
}
// Common case
if (mIdContentList.Count() == 0) {
- return mIdContentList.AppendElement(aContent);
+ if (!mIdContentList.AppendElement(aContent)) {
+ return PR_FALSE;
+ }
+ NS_ADDREF(aContent);
+ return PR_TRUE;
}
// We seem to have multiple content nodes for the same id, or we're doing our
@@ -314,7 +336,11 @@ IdAndNameMapEntry::AddIdContent(nsIContent* aContent)
}
} while (start != end);
- return mIdContentList.InsertElementAt(aContent, start);
+ if (!mIdContentList.InsertElementAt(aContent, start)) {
+ return PR_FALSE;
+ }
+ NS_ADDREF(aContent);
+ return PR_TRUE;
}
@@ -388,15 +414,26 @@ IdAndNameMapEntryTraverse(PLDHashTable *table, PLDHashEntryHdr *hdr,
nsCycleCollectionTraversalCallback *cb =
static_cast(arg);
IdAndNameMapEntry *entry = static_cast(hdr);
-
- if (entry->mNameContentList != NAME_NOT_VALID)
- cb->NoteXPCOMChild(entry->mNameContentList);
-
- cb->NoteXPCOMChild(static_cast(entry->mDocAllList));
+ entry->Traverse(cb);
return PL_DHASH_NEXT;
}
+void
+IdAndNameMapEntry::Traverse(nsCycleCollectionTraversalCallback* cb)
+{
+ if (mNameContentList != NAME_NOT_VALID)
+ cb->NoteXPCOMChild(mNameContentList);
+
+ cb->NoteXPCOMChild(static_cast(mDocAllList));
+
+ if (mIdContentList.Count() != 1 || mIdContentList[0] != ID_NOT_IN_DOCUMENT) {
+ for (PRInt32 i = 0; i < mIdContentList.Count(); ++i) {
+ cb->NoteXPCOMChild(static_cast(mIdContentList[i]));
+ }
+ }
+}
+
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
if (tmp->mIdAndNameHashTable.ops) {
PL_DHashTableEnumerate(&tmp->mIdAndNameHashTable,
@@ -4805,3 +4842,13 @@ nsHTMLDocument::CreateElem(nsIAtom *aName, nsIAtom *aPrefix,
aDocumentDefaultType, aResult);
}
#endif
+
+void
+nsHTMLDocument::Destroy()
+{
+ nsDocument::Destroy();
+
+ // Try really really hard to make sure we don't leak things through
+ // mIdAndNameHashTable
+ InvalidateHashTables();
+}
diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h
index 723d2996860..fe342295028 100644
--- a/mozilla/content/html/document/src/nsHTMLDocument.h
+++ b/mozilla/content/html/document/src/nsHTMLDocument.h
@@ -201,6 +201,8 @@ public:
nsIContent** aResult);
#endif
+ virtual NS_HIDDEN_(void) Destroy();
+
nsresult ChangeContentEditableCount(nsIContent *aElement, PRInt32 aChange);
virtual EditingState GetEditingState()