Fix for 108389. r=jkeiser, sr=jst

This commit is contained in:
hyatt%netscape.com 2001-11-05 06:45:04 +00:00
parent 76a930d89c
commit 34f94450e0
5 changed files with 41 additions and 30 deletions

View File

@ -355,12 +355,19 @@ nsXBLContentSink::CreateElement(const nsIParserNode& aNode, PRInt32 aNameSpaceID
if (!prototype) if (!prototype)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
prototype->mType = nsXULPrototypeNode::eType_RefCounted_Element;
prototype->mNodeInfo = aNodeInfo; prototype->mNodeInfo = aNodeInfo;
// Reset the refcnt to 0. Normally XUL prototype elements get a refcnt of 1
// to represent ownership by the XUL prototype document. In our case we have
// no prototype document, and our initial ref count of 1 will come from being
// wrapped by a real XUL element in the Create call below.
prototype->mRefCnt = 0;
AddAttributesToXULPrototype(aNode, prototype); AddAttributesToXULPrototype(aNode, prototype);
// Following this function call, the prototype's ref count will be 1.
nsresult rv = nsXULElement::Create(prototype, mDocument, PR_FALSE, aResult); nsresult rv = nsXULElement::Create(prototype, mDocument, PR_FALSE, aResult);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
return NS_OK; return NS_OK;
} }

View File

@ -515,11 +515,8 @@ nsXULElement::Init()
nsXULElement::~nsXULElement() nsXULElement::~nsXULElement()
{ {
if (mPrototype && mPrototype->mType == nsXULPrototypeNode::eType_RefCounted_Element) { if (mPrototype)
mPrototype->mRefCnt--; mPrototype->Release();
if (mPrototype->mRefCnt == 0)
delete mPrototype;
}
delete mSlots; delete mSlots;
@ -578,8 +575,7 @@ nsXULElement::Create(nsXULPrototypeElement* aPrototype,
element->mPrototype = aPrototype; element->mPrototype = aPrototype;
element->mDocument = aDocument; element->mDocument = aDocument;
if (aPrototype->mType == nsXULPrototypeNode::eType_RefCounted_Element) aPrototype->AddRef();
aPrototype->mRefCnt++;
if (aIsScriptable) { if (aIsScriptable) {
// Check each attribute on the prototype to see if we need to do // Check each attribute on the prototype to see if we need to do
@ -4760,13 +4756,7 @@ nsresult nsXULElement::MakeHeavyweight()
} }
} }
if (proto->mType == nsXULPrototypeNode::eType_RefCounted_Element) { proto->Release();
proto->mRefCnt--;
if (proto->mRefCnt == 0)
delete proto;
}
return NS_OK; return NS_OK;
} }

View File

@ -186,24 +186,31 @@ public:
class nsXULPrototypeNode class nsXULPrototypeNode
{ {
public: public:
enum Type { eType_Element, eType_RefCounted_Element, eType_Script, eType_Text }; enum Type { eType_Element, eType_Script, eType_Text };
Type mType; Type mType;
union { PRInt32 mLineNo;
PRInt32 mLineNo; PRInt32 mRefCnt;
PRInt32 mRefCnt;
};
virtual ~nsXULPrototypeNode() {} virtual ~nsXULPrototypeNode() {}
virtual nsresult Serialize(nsIObjectOutputStream* aStream, virtual nsresult Serialize(nsIObjectOutputStream* aStream,
nsIScriptContext* aContext); nsIScriptContext* aContext);
virtual nsresult Deserialize(nsIObjectInputStream* aStream, virtual nsresult Deserialize(nsIObjectInputStream* aStream,
nsIScriptContext* aContext); nsIScriptContext* aContext);
void AddRef() { mRefCnt++; };
void Release()
{
mRefCnt--;
if (mRefCnt == 0)
delete this;
};
virtual void ReleaseSubtree() { Release(); };
protected: protected:
nsXULPrototypeNode(Type aType, PRInt32 aLineNo) nsXULPrototypeNode(Type aType, PRInt32 aLineNo)
: mType(aType), mLineNo(aLineNo) {} : mType(aType), mLineNo(aLineNo), mRefCnt(1) {}
}; };
class nsXULPrototypeElement : public nsXULPrototypeNode class nsXULPrototypeElement : public nsXULPrototypeNode
@ -226,13 +233,19 @@ public:
delete[] mAttributes; delete[] mAttributes;
delete mClassList; delete mClassList;
for (PRInt32 i = mNumChildren - 1; i >= 0; --i)
delete mChildren[i];
delete[] mChildren; delete[] mChildren;
} }
virtual void ReleaseSubtree()
{
if (mChildren) {
for (PRInt32 i = mNumChildren-1; i >= 0; i--)
mChildren[i]->ReleaseSubtree();
}
nsXULPrototypeNode::ReleaseSubtree();
}
virtual nsresult Serialize(nsIObjectOutputStream* aStream, virtual nsresult Serialize(nsIObjectOutputStream* aStream,
nsIScriptContext* aContext); nsIScriptContext* aContext);
virtual nsresult Deserialize(nsIObjectInputStream* aStream, virtual nsresult Deserialize(nsIObjectInputStream* aStream,

View File

@ -1399,7 +1399,7 @@ XULContentSinkImpl::CreateElement(nsINodeInfo *aNodeInfo,
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
element->mNodeInfo = aNodeInfo; element->mNodeInfo = aNodeInfo;
*aResult = element; *aResult = element;
return NS_OK; return NS_OK;
} }

View File

@ -238,14 +238,15 @@ nsXULPrototypeDocument::Init()
return NS_OK; return NS_OK;
} }
nsXULPrototypeDocument::~nsXULPrototypeDocument() nsXULPrototypeDocument::~nsXULPrototypeDocument()
{ {
if (mGlobalObject) { if (mGlobalObject) {
mGlobalObject->SetContext(nsnull); // remove circular reference mGlobalObject->SetContext(nsnull); // remove circular reference
mGlobalObject->SetGlobalObjectOwner(nsnull); // just in case mGlobalObject->SetGlobalObjectOwner(nsnull); // just in case
} }
delete mRoot;
if (mRoot)
mRoot->ReleaseSubtree();
} }
NS_IMPL_ISUPPORTS3(nsXULPrototypeDocument, NS_IMPL_ISUPPORTS3(nsXULPrototypeDocument,