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()