diff --git a/browser/base/content/test/static/browser_parsable_css.js b/browser/base/content/test/static/browser_parsable_css.js index 6ff480fddc13..0cfd066cdc82 100644 --- a/browser/base/content/test/static/browser_parsable_css.js +++ b/browser/base/content/test/static/browser_parsable_css.js @@ -331,8 +331,7 @@ function processCSSRules(container) { continue; } if (rule.cssRules) { - processCSSRules(rule); // @supports, @media, @layer (block), @keyframes - continue; + processCSSRules(rule); // @supports, @media, @layer (block), @keyframes, style rules with nested rules. } if (!rule.style) { continue; // @layer (statement), @font-feature-values, @counter-style diff --git a/dom/webidl/CSSGroupingRule.webidl b/dom/webidl/CSSGroupingRule.webidl index 32c33814e06a..1cb6d49cb989 100644 --- a/dom/webidl/CSSGroupingRule.webidl +++ b/dom/webidl/CSSGroupingRule.webidl @@ -10,7 +10,7 @@ // https://drafts.csswg.org/cssom/#cssgroupingrule [Exposed=Window] interface CSSGroupingRule : CSSRule { - [SameObject] readonly attribute CSSRuleList? cssRules; + [SameObject] readonly attribute CSSRuleList cssRules; [Throws] unsigned long insertRule(UTF8String rule, optional unsigned long index = 0); [Throws] diff --git a/dom/webidl/CSSStyleRule.webidl b/dom/webidl/CSSStyleRule.webidl index 739bd958bb20..1e65d1a2233a 100644 --- a/dom/webidl/CSSStyleRule.webidl +++ b/dom/webidl/CSSStyleRule.webidl @@ -12,4 +12,11 @@ interface CSSStyleRule : CSSRule { attribute UTF8String selectorText; [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; + + // https://drafts.csswg.org/css-nesting/#cssom-style + // FIXME: Ideally CSSStyleRule should inherit from CSSGroupingRule instead, + // see https://github.com/w3c/csswg-drafts/issues/8940 + [Pref="layout.css.nesting.enabled", SameObject] readonly attribute CSSRuleList cssRules; + [Pref="layout.css.nesting.enabled", Throws] unsigned long insertRule(UTF8String rule, optional unsigned long index = 0); + [Pref="layout.css.nesting.enabled", Throws] undefined deleteRule(unsigned long index); }; diff --git a/layout/inspector/ServoStyleRuleMap.cpp b/layout/inspector/ServoStyleRuleMap.cpp index c7daae234d7a..2285ec8298b6 100644 --- a/layout/inspector/ServoStyleRuleMap.cpp +++ b/layout/inspector/ServoStyleRuleMap.cpp @@ -37,7 +37,7 @@ void ServoStyleRuleMap::EnsureTable(ShadowRoot& aShadowRoot) { for (auto index : IntegerRange(aShadowRoot.SheetCount())) { FillTableFromStyleSheet(*aShadowRoot.SheetAt(index)); } - for (auto& sheet : aShadowRoot.AdoptedStyleSheets()) { + for (const auto& sheet : aShadowRoot.AdoptedStyleSheets()) { FillTableFromStyleSheet(*sheet); } } @@ -80,18 +80,14 @@ void ServoStyleRuleMap::RuleRemoved(StyleSheet& aStyleSheet, } switch (aStyleRule.Type()) { - case StyleCssRuleType::Style: { - auto& rule = static_cast(aStyleRule); - mTable.Remove(rule.Raw()); - break; - } + case StyleCssRuleType::Style: case StyleCssRuleType::Import: case StyleCssRuleType::Media: case StyleCssRuleType::Supports: case StyleCssRuleType::LayerBlock: case StyleCssRuleType::Container: case StyleCssRuleType::Document: { - // See the comment in StyleSheetRemoved. + // See the comment in SheetRemoved. mTable.Clear(); break; } @@ -121,7 +117,7 @@ void ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule) { case StyleCssRuleType::Style: { auto& rule = static_cast(aRule); mTable.InsertOrUpdate(rule.Raw(), &rule); - break; + [[fallthrough]]; } case StyleCssRuleType::LayerBlock: case StyleCssRuleType::Media: @@ -129,9 +125,7 @@ void ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule) { case StyleCssRuleType::Container: case StyleCssRuleType::Document: { auto& rule = static_cast(aRule); - if (ServoCSSRuleList* ruleList = rule.GetCssRules()) { - FillTableFromRuleList(*ruleList); - } + FillTableFromRuleList(*rule.CssRules()); break; } case StyleCssRuleType::Import: { diff --git a/layout/inspector/ServoStyleRuleMap.h b/layout/inspector/ServoStyleRuleMap.h index 65399c043243..09d5dae260af 100644 --- a/layout/inspector/ServoStyleRuleMap.h +++ b/layout/inspector/ServoStyleRuleMap.h @@ -55,9 +55,8 @@ class ServoStyleRuleMap { void FillTableFromRuleList(ServoCSSRuleList&); void FillTableFromStyleSheet(StyleSheet&); - typedef nsTHashMap, - WeakPtr> - Hashtable; + using Hashtable = nsTHashMap, + WeakPtr>; Hashtable mTable; }; diff --git a/layout/style/CSSContainerRule.cpp b/layout/style/CSSContainerRule.cpp index a92874f45419..4d798c0dda13 100644 --- a/layout/style/CSSContainerRule.cpp +++ b/layout/style/CSSContainerRule.cpp @@ -17,8 +17,7 @@ namespace mozilla::dom { CSSContainerRule::CSSContainerRule(RefPtr aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn) - : css::ConditionRule(Servo_ContainerRule_GetRules(aRawRule).Consume(), - aSheet, aParentRule, aLine, aColumn), + : css::ConditionRule(aSheet, aParentRule, aLine, aColumn), mRawRule(std::move(aRawRule)) {} CSSContainerRule::~CSSContainerRule() = default; @@ -42,6 +41,10 @@ void CSSContainerRule::List(FILE* out, int32_t aIndent) const { } #endif +already_AddRefed CSSContainerRule::GetOrCreateRawRules() { + return Servo_ContainerRule_GetRules(mRawRule).Consume(); +} + StyleCssRuleType CSSContainerRule::Type() const { return StyleCssRuleType::Container; } @@ -70,9 +73,7 @@ Element* CSSContainerRule::QueryContainerFor(const Element& aElement) const { void CSSContainerRule::SetRawAfterClone(RefPtr aRaw) { mRawRule = std::move(aRaw); - - css::ConditionRule::SetRawAfterClone( - Servo_ContainerRule_GetRules(mRawRule).Consume()); + css::ConditionRule::DidSetRawAfterClone(); } /* virtual */ diff --git a/layout/style/CSSContainerRule.h b/layout/style/CSSContainerRule.h index abe00e12d365..683a17604ec1 100644 --- a/layout/style/CSSContainerRule.h +++ b/layout/style/CSSContainerRule.h @@ -26,6 +26,8 @@ class CSSContainerRule final : public css::ConditionRule { StyleContainerRule* Raw() const { return mRawRule; } void SetRawAfterClone(RefPtr); + already_AddRefed GetOrCreateRawRules() final; + // WebIDL interface StyleCssRuleType Type() const override; // WebIDL interface diff --git a/layout/style/CSSLayerBlockRule.cpp b/layout/style/CSSLayerBlockRule.cpp index acc57949e3c2..23453fb3af41 100644 --- a/layout/style/CSSLayerBlockRule.cpp +++ b/layout/style/CSSLayerBlockRule.cpp @@ -13,16 +13,13 @@ namespace mozilla::dom { CSSLayerBlockRule::CSSLayerBlockRule(RefPtr aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn) - : css::GroupRule(Servo_LayerBlockRule_GetRules(aRawRule).Consume(), aSheet, - aParentRule, aLine, aColumn), + : css::GroupRule(aSheet, aParentRule, aLine, aColumn), mRawRule(std::move(aRawRule)) {} -NS_IMPL_ADDREF_INHERITED(CSSLayerBlockRule, GroupRule) -NS_IMPL_RELEASE_INHERITED(CSSLayerBlockRule, GroupRule) +NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSLayerBlockRule, + css::GroupRule) // QueryInterface implementation for SupportsRule -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSLayerBlockRule) -NS_INTERFACE_MAP_END_INHERITING(GroupRule) #ifdef DEBUG void CSSLayerBlockRule::List(FILE* out, int32_t aIndent) const { @@ -39,10 +36,13 @@ StyleCssRuleType CSSLayerBlockRule::Type() const { return StyleCssRuleType::LayerBlock; } +already_AddRefed CSSLayerBlockRule::GetOrCreateRawRules() { + return Servo_LayerBlockRule_GetRules(mRawRule).Consume(); +} + void CSSLayerBlockRule::SetRawAfterClone(RefPtr aRaw) { mRawRule = std::move(aRaw); - css::GroupRule::SetRawAfterClone( - Servo_LayerBlockRule_GetRules(mRawRule).Consume()); + css::GroupRule::DidSetRawAfterClone(); } void CSSLayerBlockRule::GetCssText(nsACString& aCssText) const { diff --git a/layout/style/CSSLayerBlockRule.h b/layout/style/CSSLayerBlockRule.h index 7679468c15d7..fbba832eef1f 100644 --- a/layout/style/CSSLayerBlockRule.h +++ b/layout/style/CSSLayerBlockRule.h @@ -26,6 +26,8 @@ class CSSLayerBlockRule final : public css::GroupRule { StyleLayerBlockRule* Raw() const { return mRawRule; } void SetRawAfterClone(RefPtr); + already_AddRefed GetOrCreateRawRules() final; + // WebIDL interface StyleCssRuleType Type() const final; void GetCssText(nsACString& aCssText) const final; diff --git a/layout/style/CSSMediaRule.cpp b/layout/style/CSSMediaRule.cpp index f41d5ddbf5b0..75b4ce4571be 100644 --- a/layout/style/CSSMediaRule.cpp +++ b/layout/style/CSSMediaRule.cpp @@ -15,8 +15,7 @@ namespace mozilla::dom { CSSMediaRule::CSSMediaRule(RefPtr aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn) - : ConditionRule(Servo_MediaRule_GetRules(aRawRule).Consume(), aSheet, - aParentRule, aLine, aColumn), + : ConditionRule(aSheet, aParentRule, aLine, aColumn), mRawRule(std::move(aRawRule)) {} CSSMediaRule::~CSSMediaRule() { @@ -25,12 +24,7 @@ CSSMediaRule::~CSSMediaRule() { } } -NS_IMPL_ADDREF_INHERITED(CSSMediaRule, css::ConditionRule) -NS_IMPL_RELEASE_INHERITED(CSSMediaRule, css::ConditionRule) - -// QueryInterface implementation for MediaRule -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSMediaRule) -NS_INTERFACE_MAP_END_INHERITING(css::ConditionRule) +NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSMediaRule, css::ConditionRule) NS_IMPL_CYCLE_COLLECTION_CLASS(CSSMediaRule) @@ -47,6 +41,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSMediaRule, NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +bool CSSMediaRule::IsCCLeaf() const { + return ConditionRule::IsCCLeaf() && !mMediaList; +} + /* virtual */ void CSSMediaRule::DropSheetReference() { if (mMediaList) { @@ -62,8 +60,11 @@ void CSSMediaRule::SetRawAfterClone(RefPtr aRaw) { mMediaList->SetStyleSheet(nullptr); mMediaList->SetStyleSheet(GetStyleSheet()); } - css::ConditionRule::SetRawAfterClone( - Servo_MediaRule_GetRules(mRawRule).Consume()); + css::ConditionRule::DidSetRawAfterClone(); +} + +already_AddRefed CSSMediaRule::GetOrCreateRawRules() { + return Servo_MediaRule_GetRules(mRawRule).Consume(); } StyleCssRuleType CSSMediaRule::Type() const { return StyleCssRuleType::Media; } diff --git a/layout/style/CSSMediaRule.h b/layout/style/CSSMediaRule.h index a1c430212795..d5904ca5cb7c 100644 --- a/layout/style/CSSMediaRule.h +++ b/layout/style/CSSMediaRule.h @@ -28,6 +28,8 @@ class CSSMediaRule final : public css::ConditionRule { StyleMediaRule* Raw() const { return mRawRule; } void SetRawAfterClone(RefPtr); + already_AddRefed GetOrCreateRawRules() final; + bool IsCCLeaf() const override; // WebIDL interface StyleCssRuleType Type() const override; diff --git a/layout/style/CSSMozDocumentRule.cpp b/layout/style/CSSMozDocumentRule.cpp index f06fe38207e7..b59a66d85640 100644 --- a/layout/style/CSSMozDocumentRule.cpp +++ b/layout/style/CSSMozDocumentRule.cpp @@ -88,8 +88,7 @@ CSSMozDocumentRule::CSSMozDocumentRule(RefPtr aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn) - : css::ConditionRule(Servo_DocumentRule_GetRules(aRawRule).Consume(), - aSheet, aParentRule, aLine, aColumn), + : css::ConditionRule(aSheet, aParentRule, aLine, aColumn), mRawRule(std::move(aRawRule)) {} NS_IMPL_ADDREF_INHERITED(CSSMozDocumentRule, css::ConditionRule) @@ -113,8 +112,12 @@ void CSSMozDocumentRule::List(FILE* out, int32_t aIndent) const { void CSSMozDocumentRule::SetRawAfterClone(RefPtr aRaw) { mRawRule = std::move(aRaw); - css::ConditionRule::SetRawAfterClone( - Servo_DocumentRule_GetRules(mRawRule).Consume()); + css::ConditionRule::DidSetRawAfterClone(); +} + +already_AddRefed +CSSMozDocumentRule::GetOrCreateRawRules() { + return Servo_DocumentRule_GetRules(mRawRule).Consume(); } StyleCssRuleType CSSMozDocumentRule::Type() const { diff --git a/layout/style/CSSMozDocumentRule.h b/layout/style/CSSMozDocumentRule.h index b75da3f7b820..0c1b0ab0227c 100644 --- a/layout/style/CSSMozDocumentRule.h +++ b/layout/style/CSSMozDocumentRule.h @@ -11,8 +11,7 @@ #include "mozilla/css/DocumentMatchingFunction.h" #include "mozilla/ServoBindingTypes.h" -namespace mozilla { -namespace dom { +namespace mozilla::dom { class CSSMozDocumentRule final : public css::ConditionRule { public: @@ -31,6 +30,7 @@ class CSSMozDocumentRule final : public css::ConditionRule { StyleDocumentRule* Raw() const { return mRawRule; } void SetRawAfterClone(RefPtr); + already_AddRefed GetOrCreateRawRules() final; // WebIDL interface StyleCssRuleType Type() const final; @@ -48,7 +48,6 @@ class CSSMozDocumentRule final : public css::ConditionRule { RefPtr mRawRule; }; -} // namespace dom -} // namespace mozilla +} // namespace mozilla::dom #endif // mozilla_dom_CSSMozDocumentRule_h diff --git a/layout/style/CSSStyleRule.cpp b/layout/style/CSSStyleRule.cpp index 966725371f5a..fd57d09162bc 100644 --- a/layout/style/CSSStyleRule.cpp +++ b/layout/style/CSSStyleRule.cpp @@ -70,6 +70,11 @@ DeclarationBlock* CSSStyleRuleDeclaration::GetOrCreateCSSDeclaration( void CSSStyleRule::SetRawAfterClone(RefPtr aRaw) { mRawRule = std::move(aRaw); mDecls.SetRawAfterClone(Servo_StyleRule_GetStyle(mRawRule).Consume()); + GroupRule::DidSetRawAfterClone(); +} + +already_AddRefed CSSStyleRule::GetOrCreateRawRules() { + return Servo_StyleRule_EnsureRules(mRawRule, IsReadOnly()).Consume(); } void CSSStyleRuleDeclaration::SetRawAfterClone( @@ -110,15 +115,15 @@ CSSStyleRuleDeclaration::GetParsingEnvironment( CSSStyleRule::CSSStyleRule(already_AddRefed aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn) - : css::Rule(aSheet, aParentRule, aLine, aColumn), + : GroupRule(aSheet, aParentRule, aLine, aColumn), mRawRule(aRawRule), mDecls(Servo_StyleRule_GetStyle(mRawRule).Consume()) {} -NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSStyleRule, css::Rule) +NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSStyleRule, GroupRule) NS_IMPL_CYCLE_COLLECTION_CLASS(CSSStyleRule) -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSStyleRule, css::Rule) +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSStyleRule, GroupRule) // Keep this in sync with IsCCLeaf. // Trace the wrapper for our declaration. This just expands out @@ -135,17 +140,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSStyleRule) // Note that this has to happen before unlinking css::Rule. tmp->UnlinkDeclarationWrapper(tmp->mDecls); NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_PTR -NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::Rule) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(GroupRule) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSStyleRule, css::Rule) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSStyleRule, GroupRule) // Keep this in sync with IsCCLeaf. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END bool CSSStyleRule::IsCCLeaf() const { - if (!Rule::IsCCLeaf()) { + if (!GroupRule::IsCCLeaf()) { return false; } - return !mDecls.PreservingWrapper(); } diff --git a/layout/style/CSSStyleRule.h b/layout/style/CSSStyleRule.h index 70f20a69ebf4..16157a2c2e21 100644 --- a/layout/style/CSSStyleRule.h +++ b/layout/style/CSSStyleRule.h @@ -7,7 +7,7 @@ #ifndef mozilla_CSSStyleRule_h #define mozilla_CSSStyleRule_h -#include "mozilla/css/Rule.h" +#include "mozilla/css/GroupRule.h" #include "mozilla/ServoBindingTypes.h" #include "mozilla/NotNull.h" #include "mozilla/WeakPtr.h" @@ -55,7 +55,7 @@ class CSSStyleRuleDeclaration final : public nsDOMCSSDeclaration { RefPtr mDecls; }; -class CSSStyleRule final : public css::Rule, public SupportsWeakPtr { +class CSSStyleRule final : public css::GroupRule, public SupportsWeakPtr { public: CSSStyleRule(already_AddRefed aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, @@ -63,7 +63,7 @@ class CSSStyleRule final : public css::Rule, public SupportsWeakPtr { NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CSSStyleRule, - css::Rule) + css::GroupRule) bool IsCCLeaf() const final MOZ_MUST_OVERRIDE; uint32_t GetSelectorCount() const; @@ -84,6 +84,7 @@ class CSSStyleRule final : public css::Rule, public SupportsWeakPtr { StyleLockedStyleRule* Raw() const { return mRawRule; } void SetRawAfterClone(RefPtr); + already_AddRefed GetOrCreateRawRules() final; // Methods of mozilla::css::Rule size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final; diff --git a/layout/style/CSSSupportsRule.cpp b/layout/style/CSSSupportsRule.cpp index 1f1bbae3799c..e848258ed886 100644 --- a/layout/style/CSSSupportsRule.cpp +++ b/layout/style/CSSSupportsRule.cpp @@ -17,8 +17,7 @@ namespace mozilla::dom { CSSSupportsRule::CSSSupportsRule(RefPtr aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn) - : css::ConditionRule(Servo_SupportsRule_GetRules(aRawRule).Consume(), - aSheet, aParentRule, aLine, aColumn), + : css::ConditionRule(aSheet, aParentRule, aLine, aColumn), mRawRule(std::move(aRawRule)) {} NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, ConditionRule) @@ -55,9 +54,11 @@ void CSSSupportsRule::GetCssText(nsACString& aCssText) const { void CSSSupportsRule::SetRawAfterClone(RefPtr aRaw) { mRawRule = std::move(aRaw); + css::ConditionRule::DidSetRawAfterClone(); +} - css::ConditionRule::SetRawAfterClone( - Servo_SupportsRule_GetRules(mRawRule).Consume()); +already_AddRefed CSSSupportsRule::GetOrCreateRawRules() { + return Servo_SupportsRule_GetRules(mRawRule).Consume(); } /* virtual */ diff --git a/layout/style/CSSSupportsRule.h b/layout/style/CSSSupportsRule.h index b6c40c6b3eac..58b622c96fdd 100644 --- a/layout/style/CSSSupportsRule.h +++ b/layout/style/CSSSupportsRule.h @@ -10,10 +10,9 @@ #include "mozilla/css/GroupRule.h" #include "mozilla/ServoBindingTypes.h" -namespace mozilla { -namespace dom { +namespace mozilla::dom { -class CSSSupportsRule : public css::ConditionRule { +class CSSSupportsRule final : public css::ConditionRule { public: CSSSupportsRule(RefPtr aRawRule, StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn); @@ -31,6 +30,7 @@ class CSSSupportsRule : public css::ConditionRule { StyleCssRuleType Type() const final; void GetCssText(nsACString& aCssText) const final; void GetConditionText(nsACString& aConditionText) final; + already_AddRefed GetOrCreateRawRules() final; size_t SizeOfIncludingThis(MallocSizeOf) const override; JSObject* WrapObject(JSContext* aCx, @@ -42,7 +42,6 @@ class CSSSupportsRule : public css::ConditionRule { RefPtr mRawRule; }; -} // namespace dom -} // namespace mozilla +} // namespace mozilla::dom #endif // mozilla_dom_CSSSupportsRule_h diff --git a/layout/style/GroupRule.cpp b/layout/style/GroupRule.cpp index 018be3109efc..ff3cd11f8c3c 100644 --- a/layout/style/GroupRule.cpp +++ b/layout/style/GroupRule.cpp @@ -19,11 +19,9 @@ using namespace mozilla::dom; namespace mozilla::css { -GroupRule::GroupRule(already_AddRefed aRules, - StyleSheet* aSheet, Rule* aParentRule, +GroupRule::GroupRule(StyleSheet* aSheet, Rule* aParentRule, uint32_t aLineNumber, uint32_t aColumnNumber) - : Rule(aSheet, aParentRule, aLineNumber, aColumnNumber), - mRuleList(new ServoCSSRuleList(std::move(aRules), aSheet, this)) {} + : Rule(aSheet, aParentRule, aLineNumber, aColumnNumber) {} GroupRule::~GroupRule() { MOZ_ASSERT(!mSheet, "SetStyleSheet should have been called"); @@ -39,8 +37,20 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GroupRule) 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; + if (!Rule::IsCCLeaf()) { + return false; + } + return !mRuleList; +} + +ServoCSSRuleList* GroupRule::CssRules() { + if (!mRuleList) { + // Lazily create the rule list since most style rules won't have child + // rules. + mRuleList = + new ServoCSSRuleList(GetOrCreateRawRules(), GetStyleSheet(), this); + } + return mRuleList; } NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule) diff --git a/layout/style/GroupRule.h b/layout/style/GroupRule.h index 5994436a7b06..ca3bd58e083f 100644 --- a/layout/style/GroupRule.h +++ b/layout/style/GroupRule.h @@ -29,37 +29,31 @@ class CSSRuleList; namespace css { -// inherits from Rule so it can be shared between -// MediaRule and DocumentRule +// Inherits from Rule so it can be shared between MediaRule and DocumentRule class GroupRule : public Rule { protected: - GroupRule(already_AddRefed aRules, StyleSheet* aSheet, - Rule* aParentRule, uint32_t aLineNumber, uint32_t aColumnNumber); - GroupRule(const GroupRule& aCopy) = delete; + GroupRule(StyleSheet* aSheet, Rule* aParentRule, uint32_t aLineNumber, + uint32_t aColumnNumber); virtual ~GroupRule(); + virtual already_AddRefed GetOrCreateRawRules() = 0; public: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(GroupRule, Rule) NS_DECL_ISUPPORTS_INHERITED - virtual bool IsCCLeaf() const override; + + GroupRule(const GroupRule&) = delete; + bool IsCCLeaf() const override; #ifdef DEBUG void List(FILE* out = stdout, int32_t aIndent = 0) const override; #endif void DropSheetReference() override; + uint32_t StyleRuleCount() { return CssRules()->Length(); } + Rule* GetStyleRuleAt(int32_t aIndex) { return CssRules()->GetRule(aIndex); } - public: - int32_t StyleRuleCount() const { return mRuleList ? mRuleList->Length() : 0; } - - Rule* GetStyleRuleAt(int32_t aIndex) const { - return mRuleList ? mRuleList->GetRule(aIndex) : nullptr; - } - - void SetRawAfterClone(RefPtr aRules) { + void DidSetRawAfterClone() { if (mRuleList) { - mRuleList->SetRawAfterClone(std::move(aRules)); - } else { - MOZ_ASSERT(!aRules, "Can't move from having no rules to having rules"); + mRuleList->SetRawAfterClone(GetOrCreateRawRules()); } } @@ -68,10 +62,7 @@ class GroupRule : public Rule { * WillDirty() on the parent stylesheet. */ nsresult DeleteStyleRuleAt(uint32_t aIndex) { - if (!mRuleList) { - return NS_OK; - } - return mRuleList->DeleteRule(aIndex); + return CssRules()->DeleteRule(aIndex); } // non-virtual -- it is only called by subclasses @@ -79,7 +70,7 @@ class GroupRule : public Rule { size_t SizeOfIncludingThis(MallocSizeOf) const override = 0; // WebIDL API - ServoCSSRuleList* GetCssRules() { return mRuleList; } + ServoCSSRuleList* CssRules(); uint32_t InsertRule(const nsACString& aRule, uint32_t aIndex, ErrorResult& aRv); void DeleteRule(uint32_t aIndex, ErrorResult& aRv); diff --git a/layout/style/Rule.cpp b/layout/style/Rule.cpp index a107dc3f01b4..0a7de4278905 100644 --- a/layout/style/Rule.cpp +++ b/layout/style/Rule.cpp @@ -101,6 +101,7 @@ void Rule::AssertParentRuleType() { if (mParentRule) { auto type = mParentRule->Type(); MOZ_ASSERT(type == StyleCssRuleType::Media || + type == StyleCssRuleType::Style || type == StyleCssRuleType::Document || type == StyleCssRuleType::Supports || type == StyleCssRuleType::Keyframes || diff --git a/layout/style/StyleSheet.cpp b/layout/style/StyleSheet.cpp index 5f639cada72d..53cefeb5a01c 100644 --- a/layout/style/StyleSheet.cpp +++ b/layout/style/StyleSheet.cpp @@ -1466,7 +1466,7 @@ nsresult StyleSheet::InsertRuleIntoGroupInternal(const nsACString& aRule, uint32_t aIndex) { MOZ_ASSERT(!IsReadOnly()); - ServoCSSRuleList* rules = aGroup->GetCssRules(); + ServoCSSRuleList* rules = aGroup->CssRules(); MOZ_ASSERT(rules && rules->GetParentRule() == aGroup); return rules->InsertRule(aRule, aIndex); } diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 0238c632a023..d5eb7cf50ea6 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -2270,6 +2270,25 @@ impl_basic_rule_funcs! { (Style, StyleRule, Locked), changed: Servo_StyleSet_StyleRuleChanged, } +#[no_mangle] +pub extern "C" fn Servo_StyleRule_EnsureRules(rule: &LockedStyleRule, read_only: bool) -> Strong { + let global_style_data = &*GLOBAL_STYLE_DATA; + let lock = &global_style_data.shared_lock; + if read_only { + let guard = lock.read(); + if let Some(ref rules) = rule.read_with(&guard).rules { + return rules.clone().into(); + } + return CssRules::new(vec![], lock).into(); + } + let mut guard = lock.write(); + rule.write_with(&mut guard) + .rules + .get_or_insert_with(|| CssRules::new(vec![], lock)) + .clone() + .into() +} + impl_basic_rule_funcs! { (Import, ImportRule, Locked), getter: Servo_CssRules_GetImportRuleAt, debug: Servo_ImportRule_Debug, diff --git a/testing/web-platform/meta/css/css-nesting/cssom.html.ini b/testing/web-platform/meta/css/css-nesting/cssom.html.ini index cf18f78006c5..0833d8ad04d7 100644 --- a/testing/web-platform/meta/css/css-nesting/cssom.html.ini +++ b/testing/web-platform/meta/css/css-nesting/cssom.html.ini @@ -1,28 +1,4 @@ [cssom.html] - [Simple CSSOM manipulation of subrules] - expected: FAIL - - [Simple CSSOM manipulation of subrules 1] - expected: FAIL - - [Simple CSSOM manipulation of subrules 2] - expected: FAIL - - [Simple CSSOM manipulation of subrules 3] - expected: FAIL - - [Simple CSSOM manipulation of subrules 4] - expected: FAIL - - [Simple CSSOM manipulation of subrules 5] - expected: FAIL - - [Simple CSSOM manipulation of subrules 6] - expected: FAIL - - [Simple CSSOM manipulation of subrules 7] - expected: FAIL - [Simple CSSOM manipulation of subrules 9] expected: FAIL