diff --git a/layout/base/nsCounterManager.cpp b/layout/base/nsCounterManager.cpp index 0a2424f3bd2b..ba2e19a3008e 100644 --- a/layout/base/nsCounterManager.cpp +++ b/layout/base/nsCounterManager.cpp @@ -1,5 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -// vim:cindent:ai:sw=4:ts=4:et: +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -226,40 +225,39 @@ nsCounterManager::AddCounterResetsAndIncrements(nsIFrame *aFrame) int32_t i, i_end; bool dirty = false; for (i = 0, i_end = styleContent->CounterResetCount(); i != i_end; ++i) - dirty |= AddResetOrIncrement(aFrame, i, - styleContent->GetCounterResetAt(i), - nsCounterChangeNode::RESET); + dirty |= AddResetOrIncrement(aFrame, i, styleContent->CounterResetAt(i), + nsCounterChangeNode::RESET); for (i = 0, i_end = styleContent->CounterIncrementCount(); i != i_end; ++i) - dirty |= AddResetOrIncrement(aFrame, i, - styleContent->GetCounterIncrementAt(i), - nsCounterChangeNode::INCREMENT); + dirty |= + AddResetOrIncrement(aFrame, i, styleContent->CounterIncrementAt(i), + nsCounterChangeNode::INCREMENT); return dirty; } bool -nsCounterManager::AddResetOrIncrement(nsIFrame *aFrame, int32_t aIndex, - const nsStyleCounterData *aCounterData, +nsCounterManager::AddResetOrIncrement(nsIFrame* aFrame, int32_t aIndex, + const nsStyleCounterData& aCounterData, nsCounterNode::Type aType) { - nsCounterChangeNode *node = - new nsCounterChangeNode(aFrame, aType, aCounterData->mValue, aIndex); + nsCounterChangeNode* node = + new nsCounterChangeNode(aFrame, aType, aCounterData.mValue, aIndex); - nsCounterList *counterList = CounterListFor(aCounterData->mCounter); + nsCounterList* counterList = CounterListFor(aCounterData.mCounter); - counterList->Insert(node); - if (!counterList->IsLast(node)) { - // Tell the caller it's responsible for recalculating the entire - // list. - counterList->SetDirty(); - return true; - } + counterList->Insert(node); + if (!counterList->IsLast(node)) { + // Tell the caller it's responsible for recalculating the entire + // list. + counterList->SetDirty(); + return true; + } - // Don't call Calc() if the list is already dirty -- it'll be recalculated - // anyway, and trying to calculate with a dirty list doesn't work. - if (MOZ_LIKELY(!counterList->IsDirty())) { - node->Calc(counterList); - } - return false; + // Don't call Calc() if the list is already dirty -- it'll be recalculated + // anyway, and trying to calculate with a dirty list doesn't work. + if (MOZ_LIKELY(!counterList->IsDirty())) { + node->Calc(counterList); + } + return false; } nsCounterList* @@ -289,70 +287,70 @@ nsCounterManager::RecalcAll() void nsCounterManager::SetAllCounterStylesDirty() { - for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) { - nsCounterList* list = iter.UserData(); - nsCounterNode* first = list->First(); - if (first) { - bool changed = false; - nsCounterNode* node = first; - do { - if (node->mType == nsCounterNode::USE) { - node->UseNode()->SetCounterStyleDirty(); - changed = true; - } - } while ((node = list->Next(node)) != first); - - if (changed) { - list->SetDirty(); - } + for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) { + nsCounterList* list = iter.UserData(); + nsCounterNode* first = list->First(); + if (first) { + bool changed = false; + nsCounterNode* node = first; + do { + if (node->mType == nsCounterNode::USE) { + node->UseNode()->SetCounterStyleDirty(); + changed = true; } + } while ((node = list->Next(node)) != first); + + if (changed) { + list->SetDirty(); + } } + } } bool nsCounterManager::DestroyNodesFor(nsIFrame *aFrame) { - bool destroyedAny = false; - for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) { - nsCounterList* list = iter.UserData(); - if (list->DestroyNodesFor(aFrame)) { - destroyedAny = true; - list->SetDirty(); - } + bool destroyedAny = false; + for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) { + nsCounterList* list = iter.UserData(); + if (list->DestroyNodesFor(aFrame)) { + destroyedAny = true; + list->SetDirty(); } - return destroyedAny; + } + return destroyedAny; } #ifdef DEBUG void nsCounterManager::Dump() { - printf("\n\nCounter Manager Lists:\n"); - for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) { - printf("Counter named \"%s\":\n", - NS_ConvertUTF16toUTF8(iter.Key()).get()); + printf("\n\nCounter Manager Lists:\n"); + for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) { + printf("Counter named \"%s\":\n", + NS_ConvertUTF16toUTF8(iter.Key()).get()); - nsCounterList* list = iter.UserData(); - nsCounterNode* node = list->First(); - if (node) { - int32_t i = 0; - do { - const char* types[] = { "RESET", "INCREMENT", "USE" }; - printf(" Node #%d @%p frame=%p index=%d type=%s valAfter=%d\n" - " scope-start=%p scope-prev=%p", - i++, (void*)node, (void*)node->mPseudoFrame, - node->mContentIndex, types[node->mType], - node->mValueAfter, (void*)node->mScopeStart, - (void*)node->mScopePrev); - if (node->mType == nsCounterNode::USE) { - nsAutoString text; - node->UseNode()->GetText(text); - printf(" text=%s", NS_ConvertUTF16toUTF8(text).get()); - } - printf("\n"); - } while ((node = list->Next(node)) != list->First()); + nsCounterList* list = iter.UserData(); + nsCounterNode* node = list->First(); + if (node) { + int32_t i = 0; + do { + const char* types[] = { "RESET", "INCREMENT", "USE" }; + printf(" Node #%d @%p frame=%p index=%d type=%s valAfter=%d\n" + " scope-start=%p scope-prev=%p", + i++, (void*)node, (void*)node->mPseudoFrame, + node->mContentIndex, types[node->mType], + node->mValueAfter, (void*)node->mScopeStart, + (void*)node->mScopePrev); + if (node->mType == nsCounterNode::USE) { + nsAutoString text; + node->UseNode()->GetText(text); + printf(" text=%s", NS_ConvertUTF16toUTF8(text).get()); } + printf("\n"); + } while ((node = list->Next(node)) != list->First()); } - printf("\n\n"); + } + printf("\n\n"); } #endif diff --git a/layout/base/nsCounterManager.h b/layout/base/nsCounterManager.h index d2a1d0e6e17a..e742239aae10 100644 --- a/layout/base/nsCounterManager.h +++ b/layout/base/nsCounterManager.h @@ -271,11 +271,11 @@ public: private: // for |AddCounterResetsAndIncrements| only - bool AddResetOrIncrement(nsIFrame *aFrame, int32_t aIndex, - const nsStyleCounterData *aCounterData, - nsCounterNode::Type aType); + bool AddResetOrIncrement(nsIFrame* aFrame, int32_t aIndex, + const nsStyleCounterData& aCounterData, + nsCounterNode::Type aType); - nsClassHashtable mNames; + nsClassHashtable mNames; }; #endif /* nsCounterManager_h_ */ diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 59328b1e150f..923da243f048 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1197,11 +1197,11 @@ nsComputedDOMStyle::DoGetCounterIncrement() RefPtr name = new nsROCSSPrimitiveValue; RefPtr value = new nsROCSSPrimitiveValue; - const nsStyleCounterData *data = content->GetCounterIncrementAt(i); + const nsStyleCounterData& data = content->CounterIncrementAt(i); nsAutoString escaped; - nsStyleUtil::AppendEscapedCSSIdent(data->mCounter, escaped); + nsStyleUtil::AppendEscapedCSSIdent(data.mCounter, escaped); name->SetString(escaped); - value->SetNumber(data->mValue); // XXX This should really be integer + value->SetNumber(data.mValue); // XXX This should really be integer valueList->AppendCSSValue(name.forget()); valueList->AppendCSSValue(value.forget()); @@ -1441,11 +1441,11 @@ nsComputedDOMStyle::DoGetCounterReset() RefPtr name = new nsROCSSPrimitiveValue; RefPtr value = new nsROCSSPrimitiveValue; - const nsStyleCounterData *data = content->GetCounterResetAt(i); + const nsStyleCounterData& data = content->CounterResetAt(i); nsAutoString escaped; - nsStyleUtil::AppendEscapedCSSIdent(data->mCounter, escaped); + nsStyleUtil::AppendEscapedCSSIdent(data.mCounter, escaped); name->SetString(escaped); - value->SetNumber(data->mValue); // XXX This should really be integer + value->SetNumber(data.mValue); // XXX This should really be integer valueList->AppendCSSValue(name.forget()); valueList->AppendCSSValue(value.forget()); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 5ae4f6b8fc6d..85aa81049f93 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -8882,10 +8882,9 @@ nsRuleNode::ComputeContentData(void* aStartStruct, case eCSSUnit_Inherit: conditions.SetUncacheable(); count = parentContent->ContentCount(); - if (NS_SUCCEEDED(content->AllocateContents(count))) { - while (0 < count--) { - content->ContentAt(count) = parentContent->ContentAt(count); - } + content->AllocateContents(count); + while (0 < count--) { + content->ContentAt(count) = parentContent->ContentAt(count); } break; @@ -8902,66 +8901,62 @@ nsRuleNode::ComputeContentData(void* aStartStruct, case eCSSUnit_List: case eCSSUnit_ListDep: { const nsCSSValueList* contentValueList = contentValue->GetListValue(); - count = 0; - while (contentValueList) { - count++; - contentValueList = contentValueList->mNext; - } - if (NS_SUCCEEDED(content->AllocateContents(count))) { - const nsAutoString nullStr; - count = 0; - contentValueList = contentValue->GetListValue(); - while (contentValueList) { - const nsCSSValue& value = contentValueList->mValue; - nsCSSUnit unit = value.GetUnit(); - nsStyleContentType type; - nsStyleContentData &data = content->ContentAt(count++); - switch (unit) { - case eCSSUnit_String: type = eStyleContentType_String; break; - case eCSSUnit_Image: type = eStyleContentType_Image; break; - case eCSSUnit_Attr: type = eStyleContentType_Attr; break; - case eCSSUnit_Counter: type = eStyleContentType_Counter; break; - case eCSSUnit_Counters: type = eStyleContentType_Counters; break; - case eCSSUnit_Enumerated: - switch (value.GetIntValue()) { - case NS_STYLE_CONTENT_OPEN_QUOTE: - type = eStyleContentType_OpenQuote; break; - case NS_STYLE_CONTENT_CLOSE_QUOTE: - type = eStyleContentType_CloseQuote; break; - case NS_STYLE_CONTENT_NO_OPEN_QUOTE: - type = eStyleContentType_NoOpenQuote; break; - case NS_STYLE_CONTENT_NO_CLOSE_QUOTE: - type = eStyleContentType_NoCloseQuote; break; - default: - NS_ERROR("bad content value"); - type = eStyleContentType_Uninitialized; - } - break; - default: - NS_ERROR("bad content type"); - type = eStyleContentType_Uninitialized; - } - data.mType = type; - if (type == eStyleContentType_Image) { - SetImageRequest([&](imgRequestProxy* req) { - data.SetImage(req); - }, mPresContext, value); - } - else if (type <= eStyleContentType_Attr) { - value.GetStringValue(buffer); - data.mContent.mString = NS_strdup(buffer.get()); - } - else if (type <= eStyleContentType_Counters) { - data.mContent.mCounters = value.GetArrayValue(); - data.mContent.mCounters->AddRef(); - } - else { - data.mContent.mString = nullptr; - } - contentValueList = contentValueList->mNext; + count = 0; + while (contentValueList) { + count++; + contentValueList = contentValueList->mNext; + } + content->AllocateContents(count); + const nsAutoString nullStr; + count = 0; + contentValueList = contentValue->GetListValue(); + while (contentValueList) { + const nsCSSValue& value = contentValueList->mValue; + nsCSSUnit unit = value.GetUnit(); + nsStyleContentType type; + nsStyleContentData &data = content->ContentAt(count++); + switch (unit) { + case eCSSUnit_String: type = eStyleContentType_String; break; + case eCSSUnit_Image: type = eStyleContentType_Image; break; + case eCSSUnit_Attr: type = eStyleContentType_Attr; break; + case eCSSUnit_Counter: type = eStyleContentType_Counter; break; + case eCSSUnit_Counters: type = eStyleContentType_Counters; break; + case eCSSUnit_Enumerated: + switch (value.GetIntValue()) { + case NS_STYLE_CONTENT_OPEN_QUOTE: + type = eStyleContentType_OpenQuote; break; + case NS_STYLE_CONTENT_CLOSE_QUOTE: + type = eStyleContentType_CloseQuote; break; + case NS_STYLE_CONTENT_NO_OPEN_QUOTE: + type = eStyleContentType_NoOpenQuote; break; + case NS_STYLE_CONTENT_NO_CLOSE_QUOTE: + type = eStyleContentType_NoCloseQuote; break; + default: + NS_ERROR("bad content value"); + type = eStyleContentType_Uninitialized; } + break; + default: + NS_ERROR("bad content type"); + type = eStyleContentType_Uninitialized; } - break; + data.mType = type; + if (type == eStyleContentType_Image) { + SetImageRequest([&](imgRequestProxy* req) { + data.SetImage(req); + }, mPresContext, value); + } else if (type <= eStyleContentType_Attr) { + value.GetStringValue(buffer); + data.mContent.mString = NS_strdup(buffer.get()); + } else if (type <= eStyleContentType_Counters) { + data.mContent.mCounters = value.GetArrayValue(); + data.mContent.mCounters->AddRef(); + } else { + data.mContent.mString = nullptr; + } + contentValueList = contentValueList->mNext; + } + break; } default: @@ -8984,12 +8979,10 @@ nsRuleNode::ComputeContentData(void* aStartStruct, case eCSSUnit_Inherit: conditions.SetUncacheable(); count = parentContent->CounterIncrementCount(); - if (NS_SUCCEEDED(content->AllocateCounterIncrements(count))) { - while (0 < count--) { - const nsStyleCounterData *data = - parentContent->GetCounterIncrementAt(count); - content->SetCounterIncrementAt(count, data->mCounter, data->mValue); - } + content->AllocateCounterIncrements(count); + while (count--) { + const nsStyleCounterData& data = parentContent->CounterIncrementAt(count); + content->SetCounterIncrementAt(count, data.mCounter, data.mValue); } break; @@ -9000,9 +8993,7 @@ nsRuleNode::ComputeContentData(void* aStartStruct, MOZ_ASSERT(ourIncrement->mXValue.GetUnit() == eCSSUnit_Ident, "unexpected value unit"); count = ListLength(ourIncrement); - if (NS_FAILED(content->AllocateCounterIncrements(count))) { - break; - } + content->AllocateCounterIncrements(count); count = 0; for (const nsCSSValuePairList* p = ourIncrement; p; p = p->mNext, count++) { @@ -9037,12 +9028,10 @@ nsRuleNode::ComputeContentData(void* aStartStruct, case eCSSUnit_Inherit: conditions.SetUncacheable(); count = parentContent->CounterResetCount(); - if (NS_SUCCEEDED(content->AllocateCounterResets(count))) { - while (0 < count--) { - const nsStyleCounterData *data = - parentContent->GetCounterResetAt(count); - content->SetCounterResetAt(count, data->mCounter, data->mValue); - } + content->AllocateCounterResets(count); + while (0 < count--) { + const nsStyleCounterData& data = parentContent->CounterResetAt(count); + content->SetCounterResetAt(count, data.mCounter, data.mValue); } break; @@ -9053,10 +9042,7 @@ nsRuleNode::ComputeContentData(void* aStartStruct, MOZ_ASSERT(ourReset->mXValue.GetUnit() == eCSSUnit_Ident, "unexpected value unit"); count = ListLength(ourReset); - if (NS_FAILED(content->AllocateCounterResets(count))) { - break; - } - + content->AllocateCounterResets(count); count = 0; for (const nsCSSValuePairList* p = ourReset; p; p = p->mNext, count++) { int32_t reset; diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 0d33c0d944e6..62496d53d276 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -3389,6 +3389,7 @@ nsStyleVisibility::CalcDifference(const nsStyleVisibility& aNewData) const nsStyleContentData::~nsStyleContentData() { + MOZ_COUNT_DTOR(nsStyleContentData); MOZ_ASSERT(!mImageTracked, "nsStyleContentData being destroyed while still tracking image!"); if (mType == eStyleContentType_Image) { @@ -3401,16 +3402,13 @@ nsStyleContentData::~nsStyleContentData() } } -nsStyleContentData& -nsStyleContentData::operator=(const nsStyleContentData& aOther) +nsStyleContentData::nsStyleContentData(const nsStyleContentData& aOther) + : mType(aOther.mType) +#ifdef DEBUG + , mImageTracked(false) +#endif { - if (this == &aOther) { - return *this; - } - this->~nsStyleContentData(); - new (this) nsStyleContentData(); - - mType = aOther.mType; + MOZ_COUNT_CTOR(nsStyleContentData); if (mType == eStyleContentType_Image) { mContent.mImage = aOther.mContent.mImage; NS_IF_ADDREF(mContent.mImage); @@ -3423,6 +3421,17 @@ nsStyleContentData::operator=(const nsStyleContentData& aOther) } else { mContent.mString = nullptr; } +} + +nsStyleContentData& +nsStyleContentData::operator=(const nsStyleContentData& aOther) +{ + if (this == &aOther) { + return *this; + } + this->~nsStyleContentData(); + new (this) nsStyleContentData(aOther); + return *this; } @@ -3503,12 +3512,6 @@ nsStyleContentData::UntrackImage(nsPresContext* aContext) nsStyleContent::nsStyleContent(StyleStructContext aContext) : mMarkerOffset(eStyleUnit_Auto) - , mContents(nullptr) - , mIncrements(nullptr) - , mResets(nullptr) - , mContentCount(0) - , mIncrementCount(0) - , mResetCount(0) { MOZ_COUNT_CTOR(nsStyleContent); } @@ -3516,61 +3519,29 @@ nsStyleContent::nsStyleContent(StyleStructContext aContext) nsStyleContent::~nsStyleContent() { MOZ_COUNT_DTOR(nsStyleContent); - DELETE_ARRAY_IF(mContents); - DELETE_ARRAY_IF(mIncrements); - DELETE_ARRAY_IF(mResets); } void nsStyleContent::Destroy(nsPresContext* aContext) { // Unregister any images we might have with the document. - for (uint32_t i = 0; i < mContentCount; ++i) { - if ((mContents[i].mType == eStyleContentType_Image) && - mContents[i].mContent.mImage) { - mContents[i].UntrackImage(aContext); + for (auto& content : mContents) { + if (content.mType == eStyleContentType_Image && content.mContent.mImage) { + content.UntrackImage(aContext); } } this->~nsStyleContent(); - aContext->PresShell()-> - FreeByObjectID(eArenaObjectID_nsStyleContent, this); + aContext->PresShell()->FreeByObjectID(eArenaObjectID_nsStyleContent, this); } nsStyleContent::nsStyleContent(const nsStyleContent& aSource) : mMarkerOffset(aSource.mMarkerOffset) - , mContents(nullptr) - , mIncrements(nullptr) - , mResets(nullptr) - , mContentCount(0) - , mIncrementCount(0) - , mResetCount(0) - + , mContents(aSource.mContents) + , mIncrements(aSource.mIncrements) + , mResets(aSource.mResets) { MOZ_COUNT_CTOR(nsStyleContent); - - uint32_t index; - if (NS_SUCCEEDED(AllocateContents(aSource.ContentCount()))) { - for (index = 0; index < mContentCount; index++) { - ContentAt(index) = aSource.ContentAt(index); - } - } - - if (NS_SUCCEEDED(AllocateCounterIncrements(aSource.CounterIncrementCount()))) { - for (index = 0; index < mIncrementCount; index++) { - const nsStyleCounterData *data = aSource.GetCounterIncrementAt(index); - mIncrements[index].mCounter = data->mCounter; - mIncrements[index].mValue = data->mValue; - } - } - - if (NS_SUCCEEDED(AllocateCounterResets(aSource.CounterResetCount()))) { - for (index = 0; index < mResetCount; index++) { - const nsStyleCounterData *data = aSource.GetCounterResetAt(index); - mResets[index].mCounter = data->mCounter; - mResets[index].mValue = data->mValue; - } - } } nsChangeHint @@ -3588,62 +3559,22 @@ nsStyleContent::CalcDifference(const nsStyleContent& aNewData) const // 'content' property, then we will need to revisit the optimization // in ReResolveStyleContext. - if (mContentCount != aNewData.mContentCount || - mIncrementCount != aNewData.mIncrementCount || - mResetCount != aNewData.mResetCount) { + // Unfortunately we need to reframe even if the content lengths are the same; + // a simple reflow will not pick up different text or different image URLs, + // since we set all that up in the CSSFrameConstructor + if (mContents != aNewData.mContents || + mIncrements != aNewData.mIncrements || + mResets != aNewData.mResets) { return nsChangeHint_ReconstructFrame; } - uint32_t ix = mContentCount; - while (0 < ix--) { - if (mContents[ix] != aNewData.mContents[ix]) { - // Unfortunately we need to reframe here; a simple reflow - // will not pick up different text or different image URLs, - // since we set all that up in the CSSFrameConstructor - return nsChangeHint_ReconstructFrame; - } - } - ix = mIncrementCount; - while (0 < ix--) { - if ((mIncrements[ix].mValue != aNewData.mIncrements[ix].mValue) || - (mIncrements[ix].mCounter != aNewData.mIncrements[ix].mCounter)) { - return nsChangeHint_ReconstructFrame; - } - } - ix = mResetCount; - while (0 < ix--) { - if ((mResets[ix].mValue != aNewData.mResets[ix].mValue) || - (mResets[ix].mCounter != aNewData.mResets[ix].mCounter)) { - return nsChangeHint_ReconstructFrame; - } - } if (mMarkerOffset != aNewData.mMarkerOffset) { return NS_STYLE_HINT_REFLOW; } + return nsChangeHint(0); } -nsresult -nsStyleContent::AllocateContents(uint32_t aCount) -{ - // We need to run the destructors of the elements of mContents, so we - // delete and reallocate even if aCount == mContentCount. (If - // nsStyleContentData had its members private and managed their - // ownership on setting, we wouldn't need this, but that seems - // unnecessary at this point.) - DELETE_ARRAY_IF(mContents); - if (aCount) { - mContents = new nsStyleContentData[aCount]; - if (! mContents) { - mContentCount = 0; - return NS_ERROR_OUT_OF_MEMORY; - } - } - mContentCount = aCount; - return NS_OK; -} - - // -------------------- // nsStyleTextReset // diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 1d78c6899648..a50ecadaea3d 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -3164,7 +3164,11 @@ struct nsStyleContentData #ifdef DEBUG , mImageTracked(false) #endif - { mContent.mString = nullptr; } + { + MOZ_COUNT_CTOR(nsStyleContentData); + mContent.mString = nullptr; + } + nsStyleContentData(const nsStyleContentData&); ~nsStyleContentData(); nsStyleContentData& operator=(const nsStyleContentData& aOther); @@ -3184,19 +3188,22 @@ struct nsStyleContentData MOZ_ASSERT(mType == eStyleContentType_Image, "Wrong type!"); NS_IF_ADDREF(mContent.mImage = aRequest); } -private: - nsStyleContentData(const nsStyleContentData&); // not to be implemented }; struct nsStyleCounterData { nsString mCounter; int32_t mValue; + + bool operator==(const nsStyleCounterData& aOther) const { + return mValue == aOther.mValue && mCounter == aOther.mCounter; + } + + bool operator!=(const nsStyleCounterData& aOther) const { + return !(*this == aOther); + } }; - -#define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nullptr; } - struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent { explicit nsStyleContent(StyleStructContext aContext); @@ -3223,90 +3230,60 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent nsChangeHint_ClearAncestorIntrinsics; } - uint32_t ContentCount() const { return mContentCount; } // [reset] + uint32_t ContentCount() const { return mContents.Length(); } // [reset] const nsStyleContentData& ContentAt(uint32_t aIndex) const { - NS_ASSERTION(aIndex < mContentCount, "out of range"); return mContents[aIndex]; } - nsStyleContentData& ContentAt(uint32_t aIndex) { - NS_ASSERTION(aIndex < mContentCount, "out of range"); - return mContents[aIndex]; + nsStyleContentData& ContentAt(uint32_t aIndex) { return mContents[aIndex]; } + + void AllocateContents(uint32_t aCount) { + // We need to run the destructors of the elements of mContents, so we + // delete and reallocate even if aCount == mContentCount. (If + // nsStyleContentData had its members private and managed their + // ownership on setting, we wouldn't need this, but that seems + // unnecessary at this point.) + mContents.Clear(); + mContents.SetLength(aCount); } - nsresult AllocateContents(uint32_t aCount); - - uint32_t CounterIncrementCount() const { return mIncrementCount; } // [reset] - const nsStyleCounterData* GetCounterIncrementAt(uint32_t aIndex) const { - NS_ASSERTION(aIndex < mIncrementCount, "out of range"); - return &mIncrements[aIndex]; + uint32_t CounterIncrementCount() const { return mIncrements.Length(); } // [reset] + const nsStyleCounterData& CounterIncrementAt(uint32_t aIndex) const { + return mIncrements[aIndex]; } - nsresult AllocateCounterIncrements(uint32_t aCount) { - if (aCount != mIncrementCount) { - DELETE_ARRAY_IF(mIncrements); - if (aCount) { - mIncrements = new nsStyleCounterData[aCount]; - if (! mIncrements) { - mIncrementCount = 0; - return NS_ERROR_OUT_OF_MEMORY; - } - } - mIncrementCount = aCount; - } - return NS_OK; + void AllocateCounterIncrements(uint32_t aCount) { + mIncrements.Clear(); + mIncrements.SetLength(aCount); } - nsresult SetCounterIncrementAt(uint32_t aIndex, const nsString& aCounter, int32_t aIncrement) { - if (aIndex < mIncrementCount) { - mIncrements[aIndex].mCounter = aCounter; - mIncrements[aIndex].mValue = aIncrement; - return NS_OK; - } - return NS_ERROR_ILLEGAL_VALUE; + void SetCounterIncrementAt(uint32_t aIndex, const nsString& aCounter, int32_t aIncrement) { + mIncrements[aIndex].mCounter = aCounter; + mIncrements[aIndex].mValue = aIncrement; } - uint32_t CounterResetCount() const { return mResetCount; } // [reset] - const nsStyleCounterData* GetCounterResetAt(uint32_t aIndex) const { - NS_ASSERTION(aIndex < mResetCount, "out of range"); - return &mResets[aIndex]; + uint32_t CounterResetCount() const { return mResets.Length(); } // [reset] + const nsStyleCounterData& CounterResetAt(uint32_t aIndex) const { + return mResets[aIndex]; } - nsresult AllocateCounterResets(uint32_t aCount) { - if (aCount != mResetCount) { - DELETE_ARRAY_IF(mResets); - if (aCount) { - mResets = new nsStyleCounterData[aCount]; - if (! mResets) { - mResetCount = 0; - return NS_ERROR_OUT_OF_MEMORY; - } - } - mResetCount = aCount; - } - return NS_OK; + void AllocateCounterResets(uint32_t aCount) { + mResets.Clear(); + mResets.SetLength(aCount); } - nsresult SetCounterResetAt(uint32_t aIndex, const nsString& aCounter, int32_t aValue) { - if (aIndex < mResetCount) { - mResets[aIndex].mCounter = aCounter; - mResets[aIndex].mValue = aValue; - return NS_OK; - } - return NS_ERROR_ILLEGAL_VALUE; + void SetCounterResetAt(uint32_t aIndex, const nsString& aCounter, int32_t aValue) { + mResets[aIndex].mCounter = aCounter; + mResets[aIndex].mValue = aValue; } nsStyleCoord mMarkerOffset; // [reset] coord, auto protected: - nsStyleContentData* mContents; - nsStyleCounterData* mIncrements; - nsStyleCounterData* mResets; - - uint32_t mContentCount; - uint32_t mIncrementCount; - uint32_t mResetCount; + nsTArray mContents; + nsTArray mIncrements; + nsTArray mResets; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset