diff --git a/layout/base/nsStyleChangeList.cpp b/layout/base/nsStyleChangeList.cpp index d3d1b9c38cb..f588b3ad57a 100644 --- a/layout/base/nsStyleChangeList.cpp +++ b/layout/base/nsStyleChangeList.cpp @@ -48,7 +48,7 @@ static const PRUint32 kGrowArrayBy = 10; -nsStyleChangeList::nsStyleChangeList(void) +nsStyleChangeList::nsStyleChangeList() : mArray(mBuffer), mArraySize(kStyleChangeBufferSize), mCount(0) @@ -56,7 +56,7 @@ nsStyleChangeList::nsStyleChangeList(void) MOZ_COUNT_CTOR(nsStyleChangeList); } -nsStyleChangeList::~nsStyleChangeList(void) +nsStyleChangeList::~nsStyleChangeList() { MOZ_COUNT_DTOR(nsStyleChangeList); Clear(); @@ -97,9 +97,9 @@ nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChange if ((0 < mCount) && (aHint & nsChangeHint_ReconstructFrame)) { // filter out all other changes for same content if (aContent) { - PRInt32 index = mCount; - while (0 < index--) { + for (PRInt32 index = mCount - 1; index >= 0; --index) { if (aContent == mArray[index].mContent) { // remove this change + aContent->Release(); mCount--; if (index < mCount) { // move later changes down ::memmove(&mArray[index], &mArray[index + 1], @@ -132,6 +132,9 @@ nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChange } mArray[mCount].mFrame = aFrame; mArray[mCount].mContent = aContent; + if (aContent) { + aContent->AddRef(); + } mArray[mCount].mHint = aHint; mCount++; } @@ -141,6 +144,12 @@ nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChange void nsStyleChangeList::Clear() { + for (PRInt32 index = mCount - 1; index >= 0; --index) { + nsIContent* content = mArray[index].mContent; + if (content) { + content->Release(); + } + } if (mArray != mBuffer) { delete [] mArray; mArray = mBuffer; diff --git a/layout/base/nsStyleChangeList.h b/layout/base/nsStyleChangeList.h index b2a158ff958..41c1776d71a 100644 --- a/layout/base/nsStyleChangeList.h +++ b/layout/base/nsStyleChangeList.h @@ -58,18 +58,27 @@ struct nsStyleChangeData { static const PRUint32 kStyleChangeBufferSize = 10; +// Note: nsStyleChangeList owns a reference to +// nsIContent pointers in its list. class nsStyleChangeList { public: - nsStyleChangeList(void); - ~nsStyleChangeList(void); + nsStyleChangeList(); + ~nsStyleChangeList(); PRInt32 Count(void) const { return mCount; } + /** + * Fills in pointers without reference counting. + */ nsresult ChangeAt(PRInt32 aIndex, nsIFrame*& aFrame, nsIContent*& aContent, nsChangeHint& aHint) const; + /** + * Fills in a pointer to the list entry storage (no reference counting + * involved). + */ nsresult ChangeAt(PRInt32 aIndex, const nsStyleChangeData** aChangeData) const; nsresult AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChangeHint aHint); @@ -84,6 +93,9 @@ protected: PRInt32 mArraySize; PRInt32 mCount; nsStyleChangeData mBuffer[kStyleChangeBufferSize]; + +private: + nsStyleChangeList(const nsStyleChangeList&); // not implemented };