Bug 1835062 - Make CSSStyleRule a GroupRule. r=smaug,dshin

Lazily create the rule list since most style rules won't have child
rules.

Remaining failures in the cssom tests are tracked in other bugs.

Differential Revision: https://phabricator.services.mozilla.com/D180649
This commit is contained in:
Emilio Cobos Álvarez
2023-06-14 09:36:22 +00:00
parent 0192a68a74
commit e11ddfc877
23 changed files with 131 additions and 120 deletions

View File

@@ -331,8 +331,7 @@ function processCSSRules(container) {
continue; continue;
} }
if (rule.cssRules) { if (rule.cssRules) {
processCSSRules(rule); // @supports, @media, @layer (block), @keyframes processCSSRules(rule); // @supports, @media, @layer (block), @keyframes, style rules with nested rules.
continue;
} }
if (!rule.style) { if (!rule.style) {
continue; // @layer (statement), @font-feature-values, @counter-style continue; // @layer (statement), @font-feature-values, @counter-style

View File

@@ -10,7 +10,7 @@
// https://drafts.csswg.org/cssom/#cssgroupingrule // https://drafts.csswg.org/cssom/#cssgroupingrule
[Exposed=Window] [Exposed=Window]
interface CSSGroupingRule : CSSRule { interface CSSGroupingRule : CSSRule {
[SameObject] readonly attribute CSSRuleList? cssRules; [SameObject] readonly attribute CSSRuleList cssRules;
[Throws] [Throws]
unsigned long insertRule(UTF8String rule, optional unsigned long index = 0); unsigned long insertRule(UTF8String rule, optional unsigned long index = 0);
[Throws] [Throws]

View File

@@ -12,4 +12,11 @@
interface CSSStyleRule : CSSRule { interface CSSStyleRule : CSSRule {
attribute UTF8String selectorText; attribute UTF8String selectorText;
[SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; [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);
}; };

View File

@@ -37,7 +37,7 @@ void ServoStyleRuleMap::EnsureTable(ShadowRoot& aShadowRoot) {
for (auto index : IntegerRange(aShadowRoot.SheetCount())) { for (auto index : IntegerRange(aShadowRoot.SheetCount())) {
FillTableFromStyleSheet(*aShadowRoot.SheetAt(index)); FillTableFromStyleSheet(*aShadowRoot.SheetAt(index));
} }
for (auto& sheet : aShadowRoot.AdoptedStyleSheets()) { for (const auto& sheet : aShadowRoot.AdoptedStyleSheets()) {
FillTableFromStyleSheet(*sheet); FillTableFromStyleSheet(*sheet);
} }
} }
@@ -80,18 +80,14 @@ void ServoStyleRuleMap::RuleRemoved(StyleSheet& aStyleSheet,
} }
switch (aStyleRule.Type()) { switch (aStyleRule.Type()) {
case StyleCssRuleType::Style: { case StyleCssRuleType::Style:
auto& rule = static_cast<CSSStyleRule&>(aStyleRule);
mTable.Remove(rule.Raw());
break;
}
case StyleCssRuleType::Import: case StyleCssRuleType::Import:
case StyleCssRuleType::Media: case StyleCssRuleType::Media:
case StyleCssRuleType::Supports: case StyleCssRuleType::Supports:
case StyleCssRuleType::LayerBlock: case StyleCssRuleType::LayerBlock:
case StyleCssRuleType::Container: case StyleCssRuleType::Container:
case StyleCssRuleType::Document: { case StyleCssRuleType::Document: {
// See the comment in StyleSheetRemoved. // See the comment in SheetRemoved.
mTable.Clear(); mTable.Clear();
break; break;
} }
@@ -121,7 +117,7 @@ void ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule) {
case StyleCssRuleType::Style: { case StyleCssRuleType::Style: {
auto& rule = static_cast<CSSStyleRule&>(aRule); auto& rule = static_cast<CSSStyleRule&>(aRule);
mTable.InsertOrUpdate(rule.Raw(), &rule); mTable.InsertOrUpdate(rule.Raw(), &rule);
break; [[fallthrough]];
} }
case StyleCssRuleType::LayerBlock: case StyleCssRuleType::LayerBlock:
case StyleCssRuleType::Media: case StyleCssRuleType::Media:
@@ -129,9 +125,7 @@ void ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule) {
case StyleCssRuleType::Container: case StyleCssRuleType::Container:
case StyleCssRuleType::Document: { case StyleCssRuleType::Document: {
auto& rule = static_cast<css::GroupRule&>(aRule); auto& rule = static_cast<css::GroupRule&>(aRule);
if (ServoCSSRuleList* ruleList = rule.GetCssRules()) { FillTableFromRuleList(*rule.CssRules());
FillTableFromRuleList(*ruleList);
}
break; break;
} }
case StyleCssRuleType::Import: { case StyleCssRuleType::Import: {

View File

@@ -55,9 +55,8 @@ class ServoStyleRuleMap {
void FillTableFromRuleList(ServoCSSRuleList&); void FillTableFromRuleList(ServoCSSRuleList&);
void FillTableFromStyleSheet(StyleSheet&); void FillTableFromStyleSheet(StyleSheet&);
typedef nsTHashMap<nsPtrHashKey<const StyleLockedStyleRule>, using Hashtable = nsTHashMap<nsPtrHashKey<const StyleLockedStyleRule>,
WeakPtr<dom::CSSStyleRule>> WeakPtr<dom::CSSStyleRule>>;
Hashtable;
Hashtable mTable; Hashtable mTable;
}; };

View File

@@ -17,8 +17,7 @@ namespace mozilla::dom {
CSSContainerRule::CSSContainerRule(RefPtr<StyleContainerRule> aRawRule, CSSContainerRule::CSSContainerRule(RefPtr<StyleContainerRule> aRawRule,
StyleSheet* aSheet, css::Rule* aParentRule, StyleSheet* aSheet, css::Rule* aParentRule,
uint32_t aLine, uint32_t aColumn) uint32_t aLine, uint32_t aColumn)
: css::ConditionRule(Servo_ContainerRule_GetRules(aRawRule).Consume(), : css::ConditionRule(aSheet, aParentRule, aLine, aColumn),
aSheet, aParentRule, aLine, aColumn),
mRawRule(std::move(aRawRule)) {} mRawRule(std::move(aRawRule)) {}
CSSContainerRule::~CSSContainerRule() = default; CSSContainerRule::~CSSContainerRule() = default;
@@ -42,6 +41,10 @@ void CSSContainerRule::List(FILE* out, int32_t aIndent) const {
} }
#endif #endif
already_AddRefed<StyleLockedCssRules> CSSContainerRule::GetOrCreateRawRules() {
return Servo_ContainerRule_GetRules(mRawRule).Consume();
}
StyleCssRuleType CSSContainerRule::Type() const { StyleCssRuleType CSSContainerRule::Type() const {
return StyleCssRuleType::Container; return StyleCssRuleType::Container;
} }
@@ -70,9 +73,7 @@ Element* CSSContainerRule::QueryContainerFor(const Element& aElement) const {
void CSSContainerRule::SetRawAfterClone(RefPtr<StyleContainerRule> aRaw) { void CSSContainerRule::SetRawAfterClone(RefPtr<StyleContainerRule> aRaw) {
mRawRule = std::move(aRaw); mRawRule = std::move(aRaw);
css::ConditionRule::DidSetRawAfterClone();
css::ConditionRule::SetRawAfterClone(
Servo_ContainerRule_GetRules(mRawRule).Consume());
} }
/* virtual */ /* virtual */

View File

@@ -26,6 +26,8 @@ class CSSContainerRule final : public css::ConditionRule {
StyleContainerRule* Raw() const { return mRawRule; } StyleContainerRule* Raw() const { return mRawRule; }
void SetRawAfterClone(RefPtr<StyleContainerRule>); void SetRawAfterClone(RefPtr<StyleContainerRule>);
already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final;
// WebIDL interface // WebIDL interface
StyleCssRuleType Type() const override; StyleCssRuleType Type() const override;
// WebIDL interface // WebIDL interface

View File

@@ -13,16 +13,13 @@ namespace mozilla::dom {
CSSLayerBlockRule::CSSLayerBlockRule(RefPtr<StyleLayerBlockRule> aRawRule, CSSLayerBlockRule::CSSLayerBlockRule(RefPtr<StyleLayerBlockRule> aRawRule,
StyleSheet* aSheet, css::Rule* aParentRule, StyleSheet* aSheet, css::Rule* aParentRule,
uint32_t aLine, uint32_t aColumn) uint32_t aLine, uint32_t aColumn)
: css::GroupRule(Servo_LayerBlockRule_GetRules(aRawRule).Consume(), aSheet, : css::GroupRule(aSheet, aParentRule, aLine, aColumn),
aParentRule, aLine, aColumn),
mRawRule(std::move(aRawRule)) {} mRawRule(std::move(aRawRule)) {}
NS_IMPL_ADDREF_INHERITED(CSSLayerBlockRule, GroupRule) NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSLayerBlockRule,
NS_IMPL_RELEASE_INHERITED(CSSLayerBlockRule, GroupRule) css::GroupRule)
// QueryInterface implementation for SupportsRule // QueryInterface implementation for SupportsRule
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSLayerBlockRule)
NS_INTERFACE_MAP_END_INHERITING(GroupRule)
#ifdef DEBUG #ifdef DEBUG
void CSSLayerBlockRule::List(FILE* out, int32_t aIndent) const { void CSSLayerBlockRule::List(FILE* out, int32_t aIndent) const {
@@ -39,10 +36,13 @@ StyleCssRuleType CSSLayerBlockRule::Type() const {
return StyleCssRuleType::LayerBlock; return StyleCssRuleType::LayerBlock;
} }
already_AddRefed<StyleLockedCssRules> CSSLayerBlockRule::GetOrCreateRawRules() {
return Servo_LayerBlockRule_GetRules(mRawRule).Consume();
}
void CSSLayerBlockRule::SetRawAfterClone(RefPtr<StyleLayerBlockRule> aRaw) { void CSSLayerBlockRule::SetRawAfterClone(RefPtr<StyleLayerBlockRule> aRaw) {
mRawRule = std::move(aRaw); mRawRule = std::move(aRaw);
css::GroupRule::SetRawAfterClone( css::GroupRule::DidSetRawAfterClone();
Servo_LayerBlockRule_GetRules(mRawRule).Consume());
} }
void CSSLayerBlockRule::GetCssText(nsACString& aCssText) const { void CSSLayerBlockRule::GetCssText(nsACString& aCssText) const {

View File

@@ -26,6 +26,8 @@ class CSSLayerBlockRule final : public css::GroupRule {
StyleLayerBlockRule* Raw() const { return mRawRule; } StyleLayerBlockRule* Raw() const { return mRawRule; }
void SetRawAfterClone(RefPtr<StyleLayerBlockRule>); void SetRawAfterClone(RefPtr<StyleLayerBlockRule>);
already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final;
// WebIDL interface // WebIDL interface
StyleCssRuleType Type() const final; StyleCssRuleType Type() const final;
void GetCssText(nsACString& aCssText) const final; void GetCssText(nsACString& aCssText) const final;

View File

@@ -15,8 +15,7 @@ namespace mozilla::dom {
CSSMediaRule::CSSMediaRule(RefPtr<StyleMediaRule> aRawRule, StyleSheet* aSheet, CSSMediaRule::CSSMediaRule(RefPtr<StyleMediaRule> aRawRule, StyleSheet* aSheet,
css::Rule* aParentRule, uint32_t aLine, css::Rule* aParentRule, uint32_t aLine,
uint32_t aColumn) uint32_t aColumn)
: ConditionRule(Servo_MediaRule_GetRules(aRawRule).Consume(), aSheet, : ConditionRule(aSheet, aParentRule, aLine, aColumn),
aParentRule, aLine, aColumn),
mRawRule(std::move(aRawRule)) {} mRawRule(std::move(aRawRule)) {}
CSSMediaRule::~CSSMediaRule() { CSSMediaRule::~CSSMediaRule() {
@@ -25,12 +24,7 @@ CSSMediaRule::~CSSMediaRule() {
} }
} }
NS_IMPL_ADDREF_INHERITED(CSSMediaRule, css::ConditionRule) NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(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_CYCLE_COLLECTION_CLASS(CSSMediaRule) 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(mMediaList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
bool CSSMediaRule::IsCCLeaf() const {
return ConditionRule::IsCCLeaf() && !mMediaList;
}
/* virtual */ /* virtual */
void CSSMediaRule::DropSheetReference() { void CSSMediaRule::DropSheetReference() {
if (mMediaList) { if (mMediaList) {
@@ -62,8 +60,11 @@ void CSSMediaRule::SetRawAfterClone(RefPtr<StyleMediaRule> aRaw) {
mMediaList->SetStyleSheet(nullptr); mMediaList->SetStyleSheet(nullptr);
mMediaList->SetStyleSheet(GetStyleSheet()); mMediaList->SetStyleSheet(GetStyleSheet());
} }
css::ConditionRule::SetRawAfterClone( css::ConditionRule::DidSetRawAfterClone();
Servo_MediaRule_GetRules(mRawRule).Consume()); }
already_AddRefed<StyleLockedCssRules> CSSMediaRule::GetOrCreateRawRules() {
return Servo_MediaRule_GetRules(mRawRule).Consume();
} }
StyleCssRuleType CSSMediaRule::Type() const { return StyleCssRuleType::Media; } StyleCssRuleType CSSMediaRule::Type() const { return StyleCssRuleType::Media; }

View File

@@ -28,6 +28,8 @@ class CSSMediaRule final : public css::ConditionRule {
StyleMediaRule* Raw() const { return mRawRule; } StyleMediaRule* Raw() const { return mRawRule; }
void SetRawAfterClone(RefPtr<StyleMediaRule>); void SetRawAfterClone(RefPtr<StyleMediaRule>);
already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final;
bool IsCCLeaf() const override;
// WebIDL interface // WebIDL interface
StyleCssRuleType Type() const override; StyleCssRuleType Type() const override;

View File

@@ -88,8 +88,7 @@ CSSMozDocumentRule::CSSMozDocumentRule(RefPtr<StyleDocumentRule> aRawRule,
StyleSheet* aSheet, StyleSheet* aSheet,
css::Rule* aParentRule, uint32_t aLine, css::Rule* aParentRule, uint32_t aLine,
uint32_t aColumn) uint32_t aColumn)
: css::ConditionRule(Servo_DocumentRule_GetRules(aRawRule).Consume(), : css::ConditionRule(aSheet, aParentRule, aLine, aColumn),
aSheet, aParentRule, aLine, aColumn),
mRawRule(std::move(aRawRule)) {} mRawRule(std::move(aRawRule)) {}
NS_IMPL_ADDREF_INHERITED(CSSMozDocumentRule, css::ConditionRule) NS_IMPL_ADDREF_INHERITED(CSSMozDocumentRule, css::ConditionRule)
@@ -113,8 +112,12 @@ void CSSMozDocumentRule::List(FILE* out, int32_t aIndent) const {
void CSSMozDocumentRule::SetRawAfterClone(RefPtr<StyleDocumentRule> aRaw) { void CSSMozDocumentRule::SetRawAfterClone(RefPtr<StyleDocumentRule> aRaw) {
mRawRule = std::move(aRaw); mRawRule = std::move(aRaw);
css::ConditionRule::SetRawAfterClone( css::ConditionRule::DidSetRawAfterClone();
Servo_DocumentRule_GetRules(mRawRule).Consume()); }
already_AddRefed<StyleLockedCssRules>
CSSMozDocumentRule::GetOrCreateRawRules() {
return Servo_DocumentRule_GetRules(mRawRule).Consume();
} }
StyleCssRuleType CSSMozDocumentRule::Type() const { StyleCssRuleType CSSMozDocumentRule::Type() const {

View File

@@ -11,8 +11,7 @@
#include "mozilla/css/DocumentMatchingFunction.h" #include "mozilla/css/DocumentMatchingFunction.h"
#include "mozilla/ServoBindingTypes.h" #include "mozilla/ServoBindingTypes.h"
namespace mozilla { namespace mozilla::dom {
namespace dom {
class CSSMozDocumentRule final : public css::ConditionRule { class CSSMozDocumentRule final : public css::ConditionRule {
public: public:
@@ -31,6 +30,7 @@ class CSSMozDocumentRule final : public css::ConditionRule {
StyleDocumentRule* Raw() const { return mRawRule; } StyleDocumentRule* Raw() const { return mRawRule; }
void SetRawAfterClone(RefPtr<StyleDocumentRule>); void SetRawAfterClone(RefPtr<StyleDocumentRule>);
already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final;
// WebIDL interface // WebIDL interface
StyleCssRuleType Type() const final; StyleCssRuleType Type() const final;
@@ -48,7 +48,6 @@ class CSSMozDocumentRule final : public css::ConditionRule {
RefPtr<StyleDocumentRule> mRawRule; RefPtr<StyleDocumentRule> mRawRule;
}; };
} // namespace dom } // namespace mozilla::dom
} // namespace mozilla
#endif // mozilla_dom_CSSMozDocumentRule_h #endif // mozilla_dom_CSSMozDocumentRule_h

View File

@@ -70,6 +70,11 @@ DeclarationBlock* CSSStyleRuleDeclaration::GetOrCreateCSSDeclaration(
void CSSStyleRule::SetRawAfterClone(RefPtr<StyleLockedStyleRule> aRaw) { void CSSStyleRule::SetRawAfterClone(RefPtr<StyleLockedStyleRule> aRaw) {
mRawRule = std::move(aRaw); mRawRule = std::move(aRaw);
mDecls.SetRawAfterClone(Servo_StyleRule_GetStyle(mRawRule).Consume()); mDecls.SetRawAfterClone(Servo_StyleRule_GetStyle(mRawRule).Consume());
GroupRule::DidSetRawAfterClone();
}
already_AddRefed<StyleLockedCssRules> CSSStyleRule::GetOrCreateRawRules() {
return Servo_StyleRule_EnsureRules(mRawRule, IsReadOnly()).Consume();
} }
void CSSStyleRuleDeclaration::SetRawAfterClone( void CSSStyleRuleDeclaration::SetRawAfterClone(
@@ -110,15 +115,15 @@ CSSStyleRuleDeclaration::GetParsingEnvironment(
CSSStyleRule::CSSStyleRule(already_AddRefed<StyleLockedStyleRule> aRawRule, CSSStyleRule::CSSStyleRule(already_AddRefed<StyleLockedStyleRule> aRawRule,
StyleSheet* aSheet, css::Rule* aParentRule, StyleSheet* aSheet, css::Rule* aParentRule,
uint32_t aLine, uint32_t aColumn) uint32_t aLine, uint32_t aColumn)
: css::Rule(aSheet, aParentRule, aLine, aColumn), : GroupRule(aSheet, aParentRule, aLine, aColumn),
mRawRule(aRawRule), mRawRule(aRawRule),
mDecls(Servo_StyleRule_GetStyle(mRawRule).Consume()) {} 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_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. // Keep this in sync with IsCCLeaf.
// Trace the wrapper for our declaration. This just expands out // 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. // Note that this has to happen before unlinking css::Rule.
tmp->UnlinkDeclarationWrapper(tmp->mDecls); tmp->UnlinkDeclarationWrapper(tmp->mDecls);
NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_PTR 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. // Keep this in sync with IsCCLeaf.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
bool CSSStyleRule::IsCCLeaf() const { bool CSSStyleRule::IsCCLeaf() const {
if (!Rule::IsCCLeaf()) { if (!GroupRule::IsCCLeaf()) {
return false; return false;
} }
return !mDecls.PreservingWrapper(); return !mDecls.PreservingWrapper();
} }

View File

@@ -7,7 +7,7 @@
#ifndef mozilla_CSSStyleRule_h #ifndef mozilla_CSSStyleRule_h
#define mozilla_CSSStyleRule_h #define mozilla_CSSStyleRule_h
#include "mozilla/css/Rule.h" #include "mozilla/css/GroupRule.h"
#include "mozilla/ServoBindingTypes.h" #include "mozilla/ServoBindingTypes.h"
#include "mozilla/NotNull.h" #include "mozilla/NotNull.h"
#include "mozilla/WeakPtr.h" #include "mozilla/WeakPtr.h"
@@ -55,7 +55,7 @@ class CSSStyleRuleDeclaration final : public nsDOMCSSDeclaration {
RefPtr<DeclarationBlock> mDecls; RefPtr<DeclarationBlock> mDecls;
}; };
class CSSStyleRule final : public css::Rule, public SupportsWeakPtr { class CSSStyleRule final : public css::GroupRule, public SupportsWeakPtr {
public: public:
CSSStyleRule(already_AddRefed<StyleLockedStyleRule> aRawRule, CSSStyleRule(already_AddRefed<StyleLockedStyleRule> aRawRule,
StyleSheet* aSheet, css::Rule* aParentRule, uint32_t aLine, 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_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CSSStyleRule, NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CSSStyleRule,
css::Rule) css::GroupRule)
bool IsCCLeaf() const final MOZ_MUST_OVERRIDE; bool IsCCLeaf() const final MOZ_MUST_OVERRIDE;
uint32_t GetSelectorCount() const; uint32_t GetSelectorCount() const;
@@ -84,6 +84,7 @@ class CSSStyleRule final : public css::Rule, public SupportsWeakPtr {
StyleLockedStyleRule* Raw() const { return mRawRule; } StyleLockedStyleRule* Raw() const { return mRawRule; }
void SetRawAfterClone(RefPtr<StyleLockedStyleRule>); void SetRawAfterClone(RefPtr<StyleLockedStyleRule>);
already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final;
// Methods of mozilla::css::Rule // Methods of mozilla::css::Rule
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final; size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;

View File

@@ -17,8 +17,7 @@ namespace mozilla::dom {
CSSSupportsRule::CSSSupportsRule(RefPtr<StyleSupportsRule> aRawRule, CSSSupportsRule::CSSSupportsRule(RefPtr<StyleSupportsRule> aRawRule,
StyleSheet* aSheet, css::Rule* aParentRule, StyleSheet* aSheet, css::Rule* aParentRule,
uint32_t aLine, uint32_t aColumn) uint32_t aLine, uint32_t aColumn)
: css::ConditionRule(Servo_SupportsRule_GetRules(aRawRule).Consume(), : css::ConditionRule(aSheet, aParentRule, aLine, aColumn),
aSheet, aParentRule, aLine, aColumn),
mRawRule(std::move(aRawRule)) {} mRawRule(std::move(aRawRule)) {}
NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, ConditionRule) NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, ConditionRule)
@@ -55,9 +54,11 @@ void CSSSupportsRule::GetCssText(nsACString& aCssText) const {
void CSSSupportsRule::SetRawAfterClone(RefPtr<StyleSupportsRule> aRaw) { void CSSSupportsRule::SetRawAfterClone(RefPtr<StyleSupportsRule> aRaw) {
mRawRule = std::move(aRaw); mRawRule = std::move(aRaw);
css::ConditionRule::DidSetRawAfterClone();
}
css::ConditionRule::SetRawAfterClone( already_AddRefed<StyleLockedCssRules> CSSSupportsRule::GetOrCreateRawRules() {
Servo_SupportsRule_GetRules(mRawRule).Consume()); return Servo_SupportsRule_GetRules(mRawRule).Consume();
} }
/* virtual */ /* virtual */

View File

@@ -10,10 +10,9 @@
#include "mozilla/css/GroupRule.h" #include "mozilla/css/GroupRule.h"
#include "mozilla/ServoBindingTypes.h" #include "mozilla/ServoBindingTypes.h"
namespace mozilla { namespace mozilla::dom {
namespace dom {
class CSSSupportsRule : public css::ConditionRule { class CSSSupportsRule final : public css::ConditionRule {
public: public:
CSSSupportsRule(RefPtr<StyleSupportsRule> aRawRule, StyleSheet* aSheet, CSSSupportsRule(RefPtr<StyleSupportsRule> aRawRule, StyleSheet* aSheet,
css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn); css::Rule* aParentRule, uint32_t aLine, uint32_t aColumn);
@@ -31,6 +30,7 @@ class CSSSupportsRule : public css::ConditionRule {
StyleCssRuleType Type() const final; StyleCssRuleType Type() const final;
void GetCssText(nsACString& aCssText) const final; void GetCssText(nsACString& aCssText) const final;
void GetConditionText(nsACString& aConditionText) final; void GetConditionText(nsACString& aConditionText) final;
already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() final;
size_t SizeOfIncludingThis(MallocSizeOf) const override; size_t SizeOfIncludingThis(MallocSizeOf) const override;
JSObject* WrapObject(JSContext* aCx, JSObject* WrapObject(JSContext* aCx,
@@ -42,7 +42,6 @@ class CSSSupportsRule : public css::ConditionRule {
RefPtr<StyleSupportsRule> mRawRule; RefPtr<StyleSupportsRule> mRawRule;
}; };
} // namespace dom } // namespace mozilla::dom
} // namespace mozilla
#endif // mozilla_dom_CSSSupportsRule_h #endif // mozilla_dom_CSSSupportsRule_h

View File

@@ -19,11 +19,9 @@ using namespace mozilla::dom;
namespace mozilla::css { namespace mozilla::css {
GroupRule::GroupRule(already_AddRefed<StyleLockedCssRules> aRules, GroupRule::GroupRule(StyleSheet* aSheet, Rule* aParentRule,
StyleSheet* aSheet, Rule* aParentRule,
uint32_t aLineNumber, uint32_t aColumnNumber) uint32_t aLineNumber, uint32_t aColumnNumber)
: Rule(aSheet, aParentRule, aLineNumber, aColumnNumber), : Rule(aSheet, aParentRule, aLineNumber, aColumnNumber) {}
mRuleList(new ServoCSSRuleList(std::move(aRules), aSheet, this)) {}
GroupRule::~GroupRule() { GroupRule::~GroupRule() {
MOZ_ASSERT(!mSheet, "SetStyleSheet should have been called"); 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) NS_INTERFACE_MAP_END_INHERITING(Rule)
bool GroupRule::IsCCLeaf() const { bool GroupRule::IsCCLeaf() const {
// Let's not worry for now about sorting out whether we're a leaf or not. if (!Rule::IsCCLeaf()) {
return false; 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) NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule)

View File

@@ -29,37 +29,31 @@ class CSSRuleList;
namespace css { namespace css {
// inherits from Rule so it can be shared between // Inherits from Rule so it can be shared between MediaRule and DocumentRule
// MediaRule and DocumentRule
class GroupRule : public Rule { class GroupRule : public Rule {
protected: protected:
GroupRule(already_AddRefed<StyleLockedCssRules> aRules, StyleSheet* aSheet, GroupRule(StyleSheet* aSheet, Rule* aParentRule, uint32_t aLineNumber,
Rule* aParentRule, uint32_t aLineNumber, uint32_t aColumnNumber); uint32_t aColumnNumber);
GroupRule(const GroupRule& aCopy) = delete;
virtual ~GroupRule(); virtual ~GroupRule();
virtual already_AddRefed<StyleLockedCssRules> GetOrCreateRawRules() = 0;
public: public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(GroupRule, Rule) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(GroupRule, Rule)
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
virtual bool IsCCLeaf() const override;
GroupRule(const GroupRule&) = delete;
bool IsCCLeaf() const override;
#ifdef DEBUG #ifdef DEBUG
void List(FILE* out = stdout, int32_t aIndent = 0) const override; void List(FILE* out = stdout, int32_t aIndent = 0) const override;
#endif #endif
void DropSheetReference() override; void DropSheetReference() override;
uint32_t StyleRuleCount() { return CssRules()->Length(); }
Rule* GetStyleRuleAt(int32_t aIndex) { return CssRules()->GetRule(aIndex); }
public: void DidSetRawAfterClone() {
int32_t StyleRuleCount() const { return mRuleList ? mRuleList->Length() : 0; }
Rule* GetStyleRuleAt(int32_t aIndex) const {
return mRuleList ? mRuleList->GetRule(aIndex) : nullptr;
}
void SetRawAfterClone(RefPtr<StyleLockedCssRules> aRules) {
if (mRuleList) { if (mRuleList) {
mRuleList->SetRawAfterClone(std::move(aRules)); mRuleList->SetRawAfterClone(GetOrCreateRawRules());
} else {
MOZ_ASSERT(!aRules, "Can't move from having no rules to having rules");
} }
} }
@@ -68,10 +62,7 @@ class GroupRule : public Rule {
* WillDirty() on the parent stylesheet. * WillDirty() on the parent stylesheet.
*/ */
nsresult DeleteStyleRuleAt(uint32_t aIndex) { nsresult DeleteStyleRuleAt(uint32_t aIndex) {
if (!mRuleList) { return CssRules()->DeleteRule(aIndex);
return NS_OK;
}
return mRuleList->DeleteRule(aIndex);
} }
// non-virtual -- it is only called by subclasses // non-virtual -- it is only called by subclasses
@@ -79,7 +70,7 @@ class GroupRule : public Rule {
size_t SizeOfIncludingThis(MallocSizeOf) const override = 0; size_t SizeOfIncludingThis(MallocSizeOf) const override = 0;
// WebIDL API // WebIDL API
ServoCSSRuleList* GetCssRules() { return mRuleList; } ServoCSSRuleList* CssRules();
uint32_t InsertRule(const nsACString& aRule, uint32_t aIndex, uint32_t InsertRule(const nsACString& aRule, uint32_t aIndex,
ErrorResult& aRv); ErrorResult& aRv);
void DeleteRule(uint32_t aIndex, ErrorResult& aRv); void DeleteRule(uint32_t aIndex, ErrorResult& aRv);

View File

@@ -101,6 +101,7 @@ void Rule::AssertParentRuleType() {
if (mParentRule) { if (mParentRule) {
auto type = mParentRule->Type(); auto type = mParentRule->Type();
MOZ_ASSERT(type == StyleCssRuleType::Media || MOZ_ASSERT(type == StyleCssRuleType::Media ||
type == StyleCssRuleType::Style ||
type == StyleCssRuleType::Document || type == StyleCssRuleType::Document ||
type == StyleCssRuleType::Supports || type == StyleCssRuleType::Supports ||
type == StyleCssRuleType::Keyframes || type == StyleCssRuleType::Keyframes ||

View File

@@ -1466,7 +1466,7 @@ nsresult StyleSheet::InsertRuleIntoGroupInternal(const nsACString& aRule,
uint32_t aIndex) { uint32_t aIndex) {
MOZ_ASSERT(!IsReadOnly()); MOZ_ASSERT(!IsReadOnly());
ServoCSSRuleList* rules = aGroup->GetCssRules(); ServoCSSRuleList* rules = aGroup->CssRules();
MOZ_ASSERT(rules && rules->GetParentRule() == aGroup); MOZ_ASSERT(rules && rules->GetParentRule() == aGroup);
return rules->InsertRule(aRule, aIndex); return rules->InsertRule(aRule, aIndex);
} }

View File

@@ -2270,6 +2270,25 @@ impl_basic_rule_funcs! { (Style, StyleRule, Locked<StyleRule>),
changed: Servo_StyleSet_StyleRuleChanged, changed: Servo_StyleSet_StyleRuleChanged,
} }
#[no_mangle]
pub extern "C" fn Servo_StyleRule_EnsureRules(rule: &LockedStyleRule, read_only: bool) -> Strong<LockedCssRules> {
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<ImportRule>), impl_basic_rule_funcs! { (Import, ImportRule, Locked<ImportRule>),
getter: Servo_CssRules_GetImportRuleAt, getter: Servo_CssRules_GetImportRuleAt,
debug: Servo_ImportRule_Debug, debug: Servo_ImportRule_Debug,

View File

@@ -1,28 +1,4 @@
[cssom.html] [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] [Simple CSSOM manipulation of subrules 9]
expected: FAIL expected: FAIL