зеркало из https://github.com/mozilla/pjs.git
fixed bug 1504 (memory leak of select elements)
This commit is contained in:
Родитель
498e51bba9
Коммит
73c8a02a2b
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче