Bug 1342303 part 4 - Remove nsCOMArray::EnumerateForwards uses in layout/style. r=heycam
MozReview-Commit-ID: UjIZgeWRwh
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -130,24 +130,16 @@ namespace mozilla {
CSSStyleSheetInner::CSSStyleSheetInner(CORSMode aCORSMode,
ReferrerPolicy aReferrerPolicy,
const SRIMetadata& aIntegrity)
: StyleSheetInfo(aCORSMode, aReferrerPolicy, aIntegrity)
{
MOZ_COUNT_CTOR(CSSStyleSheetInner);
}
-static bool SetStyleSheetReference(css::Rule* aRule, void* aSheet)
-{
- if (aRule) {
- aRule->SetStyleSheet(static_cast<CSSStyleSheet*>(aSheet));
- }
- return true;
-}
-
struct ChildSheetListBuilder {
RefPtr<StyleSheet>* sheetSlot;
StyleSheet* parent;
void SetParentLinks(StyleSheet* aSheet) {
aSheet->mParent = parent;
aSheet->SetAssociatedDocument(parent->mDocument,
parent->mDocumentAssociationMode);
@@ -160,51 +152,49 @@ struct ChildSheetListBuilder {
child->mParent = aPrimarySheet;
child->SetAssociatedDocument(aPrimarySheet->mDocument,
aPrimarySheet->mDocumentAssociationMode);
}
}
};
bool
-CSSStyleSheet::RebuildChildList(css::Rule* aRule, void* aBuilder)
+CSSStyleSheet::RebuildChildList(css::Rule* aRule,
+ ChildSheetListBuilder* aBuilder)
{
int32_t type = aRule->GetType();
if (type < css::Rule::IMPORT_RULE) {
// Keep going till we get to the import rules.
return true;
}
if (type != css::Rule::IMPORT_RULE) {
// We're past all the import rules; stop the enumeration.
return false;
}
- ChildSheetListBuilder* builder =
- static_cast<ChildSheetListBuilder*>(aBuilder);
-
// XXXbz We really need to decomtaminate all this stuff. Is there a reason
// that I can't just QI to ImportRule and get a CSSStyleSheet
// directly from it?
nsCOMPtr<nsIDOMCSSImportRule> importRule(do_QueryInterface(aRule));
NS_ASSERTION(importRule, "GetType lied");
nsCOMPtr<nsIDOMCSSStyleSheet> childSheet;
importRule->GetStyleSheet(getter_AddRefs(childSheet));
// Have to do this QI to be safe, since XPConnect can fake
// nsIDOMCSSStyleSheets
RefPtr<CSSStyleSheet> sheet = do_QueryObject(childSheet);
if (!sheet) {
return true;
}
- (*builder->sheetSlot) = sheet;
- builder->SetParentLinks(*builder->sheetSlot);
- builder->sheetSlot = &(*builder->sheetSlot)->mNext;
+ (*aBuilder->sheetSlot) = sheet;
+ aBuilder->SetParentLinks(*aBuilder->sheetSlot);
+ aBuilder->sheetSlot = &(*aBuilder->sheetSlot)->mNext;
return true;
}
size_t
CSSStyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = StyleSheet::SizeOfIncludingThis(aMallocSizeOf);
const CSSStyleSheet* s = this;
@@ -233,42 +223,54 @@ CSSStyleSheet::SizeOfIncludingThis(Mallo
return n;
}
CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
CSSStyleSheet* aPrimarySheet)
: StyleSheetInfo(aCopy, aPrimarySheet)
{
MOZ_COUNT_CTOR(CSSStyleSheetInner);
- aCopy.mOrderedRules.EnumerateForwards(css::GroupRule::CloneRuleInto, &mOrderedRules);
- mOrderedRules.EnumerateForwards(SetStyleSheetReference, aPrimarySheet);
+ for (css::Rule* rule : aCopy.mOrderedRules) {
+ RefPtr<css::Rule> clone = rule->Clone();
+ mOrderedRules.AppendObject(clone);
+ clone->SetStyleSheet(aPrimarySheet);
+ }
ChildSheetListBuilder builder = { &mFirstChild, aPrimarySheet };
- mOrderedRules.EnumerateForwards(CSSStyleSheet::RebuildChildList, &builder);
+ for (css::Rule* rule : mOrderedRules) {
+ if (!CSSStyleSheet::RebuildChildList(rule, &builder)) {
+ break;
+ }
+ }
RebuildNameSpaces();
}
CSSStyleSheetInner::~CSSStyleSheetInner()
{
MOZ_COUNT_DTOR(CSSStyleSheetInner);
- mOrderedRules.EnumerateForwards(SetStyleSheetReference, nullptr);
+ for (css::Rule* rule : mOrderedRules) {
+ rule->SetStyleSheet(nullptr);
+ }
}
CSSStyleSheetInner*
CSSStyleSheetInner::CloneFor(CSSStyleSheet* aPrimarySheet)
{
return new CSSStyleSheetInner(*this, aPrimarySheet);
}
void
CSSStyleSheetInner::RemoveSheet(StyleSheet* aSheet)
{
- if ((aSheet == mSheets.ElementAt(0)) && (mSheets.Length() > 1)) {
- mOrderedRules.EnumerateForwards(SetStyleSheetReference, mSheets[1]);
+ if (aSheet == mSheets.ElementAt(0) && mSheets.Length() > 1) {
+ StyleSheet* sheet = mSheets[1];
+ for (css::Rule* rule : mOrderedRules) {
+ rule->SetStyleSheet(sheet);
+ }
ChildSheetListBuilder::ReparentChildList(mSheets[1], mFirstChild);
}
// Don't do anything after this call, because superclass implementation
// may delete this.
StyleSheetInfo::RemoveSheet(aSheet);
}
@@ -281,36 +283,32 @@ AddNamespaceRuleToMap(css::Rule* aRule,
RefPtr<css::NameSpaceRule> nameSpaceRule = do_QueryObject(aRule);
nsAutoString urlSpec;
nameSpaceRule->GetURLSpec(urlSpec);
aMap->AddPrefix(nameSpaceRule->GetPrefix(), urlSpec);
}
-static bool
-CreateNameSpace(css::Rule* aRule, void* aNameSpacePtr)
-{
- int32_t type = aRule->GetType();
- if (css::Rule::NAMESPACE_RULE == type) {
- AddNamespaceRuleToMap(aRule,
- static_cast<nsXMLNameSpaceMap*>(aNameSpacePtr));
- return true;
- }
- // stop if not namespace, import or charset because namespace can't follow
- // anything else
- return (css::Rule::CHARSET_RULE == type || css::Rule::IMPORT_RULE == type);
-}
-
void
CSSStyleSheetInner::RebuildNameSpaces()
{
// Just nuke our existing namespace map, if any
if (NS_SUCCEEDED(CreateNamespaceMap())) {
- mOrderedRules.EnumerateForwards(CreateNameSpace, mNameSpaceMap);
+ for (css::Rule* rule : mOrderedRules) {
+ switch (rule->GetType()) {
+ case css::Rule::NAMESPACE_RULE:
+ AddNamespaceRuleToMap(rule, mNameSpaceMap);
+ continue;
+ case css::Rule::CHARSET_RULE:
+ case css::Rule::IMPORT_RULE:
+ continue;
+ }
+ break;
+ }
}
}
nsresult
CSSStyleSheetInner::CreateNamespaceMap()
{
mNameSpaceMap = nsXMLNameSpaceMap::Create(false);
NS_ENSURE_TRUE(mNameSpaceMap, NS_ERROR_OUT_OF_MEMORY);
@@ -432,17 +430,19 @@ void
CSSStyleSheet::UnlinkInner()
{
// We can only have a cycle through our inner if we have a unique inner,
// because otherwise there are no JS wrappers for anything in the inner.
if (mInner->mSheets.Length() != 1) {
return;
}
- Inner()->mOrderedRules.EnumerateForwards(SetStyleSheetReference, nullptr);
+ for (css::Rule* rule : Inner()->mOrderedRules) {
+ rule->SetStyleSheet(nullptr);
+ }
Inner()->mOrderedRules.Clear();
StyleSheet::UnlinkInner();
}
void
CSSStyleSheet::TraverseInner(nsCycleCollectionTraversalCallback &cb)
{
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -33,16 +33,17 @@ class nsCSSRuleProcessor;
class nsIURI;
class nsMediaQueryResultCacheKey;
class nsStyleSet;
class nsPresContext;
class nsXMLNameSpaceMap;
namespace mozilla {
class CSSStyleSheet;
+struct ChildSheetListBuilder;
namespace css {
class GroupRule;
} // namespace css
namespace dom {
class CSSRuleList;
} // namespace dom
@@ -159,17 +160,18 @@ public:
nsMediaQueryResultCacheKey& aKey) const;
nsresult ReparseSheet(const nsAString& aInput);
void SetInRuleProcessorCache() { mInRuleProcessorCache = true; }
// Function used as a callback to rebuild our inner's child sheet
// list after we clone a unique inner for ourselves.
- static bool RebuildChildList(css::Rule* aRule, void* aBuilder);
+ static bool RebuildChildList(css::Rule* aRule,
+ ChildSheetListBuilder* aBuilder);
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
dom::Element* GetScopeElement() const { return mScopeElement; }
void SetScopeElement(dom::Element* aScopeElement)
{
mScopeElement = aScopeElement;
}
--- a/layout/style/GroupRule.h
+++ b/layout/style/GroupRule.h
@@ -71,24 +71,16 @@ public:
virtual bool UseForPresentation(nsPresContext* aPresContext,
nsMediaQueryResultCacheKey& aKey) = 0;
// non-virtual -- it is only called by subclasses
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override = 0;
- static bool
- CloneRuleInto(Rule* aRule, void* aArray)
- {
- RefPtr<Rule> clone = aRule->Clone();
- static_cast<IncrementalClearCOMRuleArray*>(aArray)->AppendObject(clone);
- return true;
- }
-
// WebIDL API
dom::CSSRuleList* CssRules();
uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
ErrorResult& aRv);
void DeleteRule(uint32_t aIndex, ErrorResult& aRv);
protected:
// to help implement nsIDOMCSSRule
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -3668,19 +3668,21 @@ nsCSSRuleProcessor::CascadeSheet(CSSStyl
StyleSheet* child = aSheet->GetFirstChild();
while (child) {
CascadeSheet(child->AsGecko(), aData);
child = child->mNext;
}
- if (!aSheet->Inner()->mOrderedRules.EnumerateForwards(CascadeRuleEnumFunc,
- aData))
- return false;
+ for (css::Rule* rule : aSheet->Inner()->mOrderedRules) {
+ if (!CascadeRuleEnumFunc(rule, aData)) {
+ return false;
+ }
+ }
}
return true;
}
static int CompareWeightData(const void* aArg1, const void* aArg2,
void* closure)
{
const PerWeightData* arg1 = static_cast<const PerWeightData*>(aArg1);
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -426,35 +426,32 @@ ImportRule::WrapObject(JSContext* aCx,
return CSSImportRuleBinding::Wrap(aCx, this, aGivenProto);
}
GroupRule::GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber)
: Rule(aLineNumber, aColumnNumber)
{
}
-static bool
-SetParentRuleReference(Rule* aRule, void* aParentRule)
-{
- GroupRule* parentRule = static_cast<GroupRule*>(aParentRule);
- aRule->SetParentRule(parentRule);
- return true;
-}
-
GroupRule::GroupRule(const GroupRule& aCopy)
: Rule(aCopy)
{
- const_cast<GroupRule&>(aCopy).mRules.EnumerateForwards(GroupRule::CloneRuleInto, &mRules);
- mRules.EnumerateForwards(SetParentRuleReference, this);
+ for (const Rule* rule : aCopy.mRules) {
+ RefPtr<Rule> clone = rule->Clone();
+ mRules.AppendObject(clone);
+ clone->SetParentRule(this);
+ }
}
GroupRule::~GroupRule()
{
MOZ_ASSERT(!mSheet, "SetStyleSheet should have been called");
- mRules.EnumerateForwards(SetParentRuleReference, nullptr);
+ for (Rule* rule : mRules) {
+ rule->SetParentRule(nullptr);
+ }
if (mRuleCollection) {
mRuleCollection->DropReference();
}
}
NS_IMPL_ADDREF_INHERITED(GroupRule, Rule)
NS_IMPL_RELEASE_INHERITED(GroupRule, Rule)
@@ -463,35 +460,32 @@ NS_INTERFACE_MAP_END_INHERITING(Rule)
bool
GroupRule::IsCCLeaf() const
{
// Let's not worry for now about sorting out whether we're a leaf or not.
return false;
}
-static bool
-SetStyleSheetReference(Rule* aRule, void* aSheet)
-{
- aRule->SetStyleSheet(reinterpret_cast<StyleSheet*>(aSheet));
- return true;
-}
-
NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GroupRule, Rule)
- tmp->mRules.EnumerateForwards(SetParentRuleReference, nullptr);
+ for (Rule* rule : tmp->mRules) {
+ rule->SetParentRule(nullptr);
+ }
// If tmp does not have a stylesheet, neither do its descendants. In that
// case, don't try to null out their stylesheet, to avoid O(N^2) behavior in
// depth of group rule nesting. But if tmp _does_ have a stylesheet (which
// can happen if it gets unlinked earlier than its owning stylesheet), then we
// need to null out the stylesheet pointer on descendants now, before we clear
// tmp->mRules.
if (tmp->GetStyleSheet()) {
- tmp->mRules.EnumerateForwards(SetStyleSheetReference, nullptr);
+ for (Rule* rule : tmp->mRules) {
+ rule->SetStyleSheet(nullptr);
+ }
}
tmp->mRules.Clear();
if (tmp->mRuleCollection) {
tmp->mRuleCollection->DropReference();
tmp->mRuleCollection = nullptr;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@@ -509,17 +503,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
/* virtual */ void
GroupRule::SetStyleSheet(StyleSheet* aSheet)
{
// Don't set the sheet on the kids if it's already the same as the sheet we
// already have. This is needed to avoid O(N^2) behavior in group nesting
// depth when seting the sheet to null during unlink, if we happen to unlin in
// order from most nested rule up to least nested rule.
if (aSheet != GetStyleSheet()) {
- mRules.EnumerateForwards(SetStyleSheetReference, aSheet);
+ for (Rule* rule : mRules) {
+ rule->SetStyleSheet(aSheet);
+ }
Rule::SetStyleSheet(aSheet);
}
}
#ifdef DEBUG
/* virtual */ void
GroupRule::List(FILE* out, int32_t aIndent) const
{
@@ -545,18 +541,22 @@ Rule*
GroupRule::GetStyleRuleAt(int32_t aIndex) const
{
return mRules.SafeObjectAt(aIndex);
}
bool
GroupRule::EnumerateRulesForwards(RuleEnumFunc aFunc, void * aData) const
{
- return
- const_cast<GroupRule*>(this)->mRules.EnumerateForwards(aFunc, aData);
+ for (const Rule* rule : mRules) {
+ if (!aFunc(const_cast<Rule*>(rule), aData)) {
+ return false;
+ }
+ }
+ return true;
}
/*
* The next two methods (DeleteStyleRuleAt and InsertStyleRuleAt)
* should never be called unless you have first called WillDirty() on
* the parents stylesheet. After they are called, DidDirty() needs to
* be called on the sheet
*/