fixed bug 1504 (memory leak of select elements)

This commit is contained in:
karnaze%netscape.com 1998-11-24 18:54:26 +00:00
Родитель 498e51bba9
Коммит 73c8a02a2b
5 изменённых файлов: 86 добавлений и 30 удалений

Просмотреть файл

@ -161,7 +161,7 @@ nsHTMLFormElement::nsHTMLFormElement(nsIAtom* aTag)
mInner.Init(this, aTag);
mControls = new nsFormControlList();
NS_ADDREF(mControls);
//nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__);
nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__);
}
nsHTMLFormElement::~nsHTMLFormElement()
@ -180,7 +180,7 @@ nsHTMLFormElement::~nsHTMLFormElement()
NS_RELEASE(mControls);
//nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__);
nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__);
}
// nsISupports
@ -209,7 +209,7 @@ nsHTMLFormElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_IMETHODIMP
nsHTMLFormElement::AddRef(void)
{
//nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__);
nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__);
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
@ -217,7 +217,7 @@ nsHTMLFormElement::AddRef(void)
NS_IMETHODIMP_(nsrefcnt)
nsHTMLFormElement::Release()
{
//nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__);
nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__);
--mRefCnt;
PRUint32 numChildren;
GetElementCount(&numChildren);

Просмотреть файл

@ -161,7 +161,7 @@ nsHTMLFormElement::nsHTMLFormElement(nsIAtom* aTag)
mInner.Init(this, aTag);
mControls = new nsFormControlList();
NS_ADDREF(mControls);
//nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__);
nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__);
}
nsHTMLFormElement::~nsHTMLFormElement()
@ -180,7 +180,7 @@ nsHTMLFormElement::~nsHTMLFormElement()
NS_RELEASE(mControls);
//nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__);
nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__);
}
// nsISupports
@ -209,7 +209,7 @@ nsHTMLFormElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_IMETHODIMP
nsHTMLFormElement::AddRef(void)
{
//nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__);
nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__);
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
@ -217,7 +217,7 @@ nsHTMLFormElement::AddRef(void)
NS_IMETHODIMP_(nsrefcnt)
nsHTMLFormElement::Release()
{
//nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__);
nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__);
--mRefCnt;
PRUint32 numChildren;
GetElementCount(&numChildren);

Просмотреть файл

@ -79,6 +79,71 @@ static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
nsFormFrameTable* nsFormFrame::gFormFrameTable = new nsFormFrameTable();
nsFormFrameTableEntry::
nsFormFrameTableEntry(nsIPresContext& aPresContext,
nsIDOMHTMLFormElement& aFormElement,
nsFormFrame& aFormFrame) : mPresContext(&aPresContext),
mFormElement(&aFormElement),
mFormFrame(&aFormFrame)
{
}
nsFormFrameTableEntry::~nsFormFrameTableEntry()
{
}
nsFormFrameTable::~nsFormFrameTable()
{
PRInt32 count = mEntries.Count();
for (PRInt32 i = 0; i < count; i++) {
delete mEntries.ElementAt(i);
}
mEntries.Clear();
}
nsFormFrame*
nsFormFrameTable::Get(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem)
{
PRInt32 count = mEntries.Count();
for (PRInt32 i = 0; i < count; i++) {
nsFormFrameTableEntry* entry = (nsFormFrameTableEntry *)mEntries.ElementAt(i);
if ((entry->mPresContext == &aPresContext) && (entry->mFormElement == &aFormElem)) {
return entry->mFormFrame;
}
}
return nsnull;
}
void
nsFormFrameTable::Put(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem,
nsFormFrame& aFormFrame)
{
NS_ADDREF(&aFormElem);
mEntries.AppendElement(new nsFormFrameTableEntry(aPresContext, aFormElem, aFormFrame));
}
void
nsFormFrameTable::Remove(nsFormFrame& aFormFrame)
{
PRInt32 hits[10];
PRInt32 hitIndex = 0;
PRInt32 count = mEntries.Count();
PRInt32 i;
for (i = 0; i < count; i++) {
nsFormFrameTableEntry* entry = (nsFormFrameTableEntry *)mEntries.ElementAt(i);
if (entry->mFormFrame == &aFormFrame) {
hits[hitIndex] = i;
hitIndex++;
NS_IF_RELEASE(entry->mFormElement);
}
}
for (i = hitIndex-1; i >= 0; i--) {
delete mEntries.ElementAt(i);
mEntries.RemoveElementAt(i);
}
}
NS_IMETHODIMP
nsFormFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
@ -110,6 +175,7 @@ nsFormFrame::nsFormFrame(nsIContent* aContent, nsIFrame* aParentFrame)
nsFormFrame::~nsFormFrame()
{
mFormControls.Clear();
RemoveFormFrame(*this);
}
PRBool
@ -224,6 +290,7 @@ nsFormFrame::SetInitialChildList(nsIPresContext& aPresContext,
nsresult result = mContent->QueryInterface(kIDOMHTMLFormElementIID, (void**)&content);
if ((NS_OK == result) && (nsnull != content)) {
nsFormFrame::PutFormFrame(aPresContext, *content, *this);
NS_RELEASE(content);
}
}
return result;

Просмотреть файл

@ -44,33 +44,17 @@ struct nsFormFrameTableEntry
nsFormFrame* mFormFrame;
nsFormFrameTableEntry(nsIPresContext& aPresContext,
nsIDOMHTMLFormElement& aFormElement,
nsFormFrame& aFormFrame) : mPresContext(&aPresContext),
mFormElement(&aFormElement),
mFormFrame(&aFormFrame) {}
nsFormFrame& aFormFrame);
~nsFormFrameTableEntry();
};
struct nsFormFrameTable
{
nsVoidArray mEntries;
nsFormFrameTable() {}
nsFormFrame* Get(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem) {
PRInt32 count = mEntries.Count();
for (PRInt32 i = 0; i < count; i++) {
nsFormFrameTableEntry* entry = (nsFormFrameTableEntry *)mEntries.ElementAt(i);
if ((entry->mPresContext == &aPresContext) && (entry->mFormElement == &aFormElem)) {
return entry->mFormFrame;
}
}
return nsnull;
}
void Put(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem, nsFormFrame& aFormFrame) {
mEntries.AppendElement(new nsFormFrameTableEntry(aPresContext, aFormElem, aFormFrame));
}
~nsFormFrameTable() {
PRInt32 count = mEntries.Count();
for (PRInt32 i = 0; i < count; i++) {
delete mEntries.ElementAt(i);
}
}
~nsFormFrameTable();
void Put(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem, nsFormFrame& aFormFrame);
nsFormFrame* Get(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem);
void Remove(nsFormFrame& aFormFrame);
};
class nsFormFrame : public nsLeafFrame,
@ -120,6 +104,9 @@ public:
gFormFrameTable->Put(aPresContext, aFormElem, aFrame);
}
static void RemoveFormFrame(nsFormFrame& aFrame) {
gFormFrameTable->Remove(aFrame);
}
// static helper functions for nsIFormControls
static PRBool GetDisabled(nsIFrame* aChildFrame, nsIContent* aContent = 0);

Просмотреть файл

@ -212,6 +212,7 @@ nsSelectControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
}
nsIDOMHTMLCollection* options = GetOptions(select);
if (!options) {
NS_RELEASE(select);
return;
}
@ -289,6 +290,7 @@ nsSelectControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
}
NS_RELEASE(select);
NS_RELEASE(options);
}