Bug 489925 and bug 522030 branch-safe fix. Hold strong refs in the id table. r=jst
git-svn-id: svn://10.0.0.236/trunk@258670 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -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<nsIContent*>(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<nsIAtom> mKey;
|
||||
nsBaseContentList *mNameContentList;
|
||||
nsRefPtr<nsContentList> 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<nsCycleCollectionTraversalCallback*>(arg);
|
||||
IdAndNameMapEntry *entry = static_cast<IdAndNameMapEntry*>(hdr);
|
||||
|
||||
if (entry->mNameContentList != NAME_NOT_VALID)
|
||||
cb->NoteXPCOMChild(entry->mNameContentList);
|
||||
|
||||
cb->NoteXPCOMChild(static_cast<nsIDOMNodeList*>(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<nsIDOMNodeList*>(mDocAllList));
|
||||
|
||||
if (mIdContentList.Count() != 1 || mIdContentList[0] != ID_NOT_IN_DOCUMENT) {
|
||||
for (PRInt32 i = 0; i < mIdContentList.Count(); ++i) {
|
||||
cb->NoteXPCOMChild(static_cast<nsIContent*>(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();
|
||||
}
|
||||
|
||||
@@ -201,6 +201,8 @@ public:
|
||||
nsIContent** aResult);
|
||||
#endif
|
||||
|
||||
virtual NS_HIDDEN_(void) Destroy();
|
||||
|
||||
nsresult ChangeContentEditableCount(nsIContent *aElement, PRInt32 aChange);
|
||||
|
||||
virtual EditingState GetEditingState()
|
||||
|
||||
Reference in New Issue
Block a user