Bug 1339629 Part 8: Uplift ClearRuleCascades into StyleSheet.
MozReview-Commit-ID: CCYIYjWrw86
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -568,19 +568,16 @@ CSSStyleSheet::GetStyleRuleAt(int32_t aI
return Inner()->mOrderedRules.SafeObjectAt(aIndex);
}
void
CSSStyleSheet::EnsureUniqueInner()
{
StyleSheet::EnsureUniqueInner();
- // otherwise the rule processor has pointers to the old rules
- ClearRuleCascades();
-
// let our containing style sets know that if we call
// nsPresContext::EnsureSafeToHandOutCSSRules we will need to restyle the
// document
for (StyleSetHandle setHandle : mStyleSets) {
setHandle->AsGecko()->SetNeedsRestyleAfterEnsureUniqueInner();
}
}
@@ -623,19 +620,19 @@ CSSStyleSheet::List(FILE* out, int32_t a
StyleSheet::List(out, aIndent);
fprintf_stderr(out, "%s", "Rules in source order:\n");
ListRules(Inner()->mOrderedRules, out, aIndent);
}
#endif
void
-CSSStyleSheet::ClearRuleCascades()
+CSSStyleSheet::ClearRuleCascadesInternal()
{
- // We might be in ClearRuleCascades because we had a modification
+ // We might be in ClearRuleCascadesInternal because we had a modification
// to the sheet that resulted in an nsCSSSelector being destroyed.
// Tell the RestyleManager for each document we're used in
// so that they can drop any nsCSSSelector pointers (used for
// eRestyle_SomeDescendants) in their mPendingRestyles.
for (StyleSetHandle setHandle : mStyleSets) {
setHandle->AsGecko()->ClearSelectors();
}
@@ -649,20 +646,16 @@ CSSStyleSheet::ClearRuleCascades()
// RuleProcessorCache entries that contain this sheet, as the
// list of @-moz-document rules might have changed.
RuleProcessorCache::RemoveSheet(this);
removedSheetFromRuleProcessorCache = true;
}
(*iter)->ClearRuleCascades();
}
}
- if (mParent) {
- CSSStyleSheet* parent = (CSSStyleSheet*)mParent;
- parent->ClearRuleCascades();
- }
}
void
CSSStyleSheet::DidDirty()
{
MOZ_ASSERT(!mInner->mComplete || mDirty,
"caller must have called WillDirty()");
ClearRuleCascades();
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -178,17 +178,17 @@ private:
nsINode* aOwningNodeToUse);
CSSStyleSheet(const CSSStyleSheet& aCopy) = delete;
CSSStyleSheet& operator=(const CSSStyleSheet& aCopy) = delete;
protected:
virtual ~CSSStyleSheet();
- void ClearRuleCascades();
+ void ClearRuleCascadesInternal() override;
// Add the namespace mapping from this @namespace rule to our namespace map
nsresult RegisterNamespaceRule(css::Rule* aRule);
// Drop our reference to mRuleCollection
void DropRuleCollection();
CSSStyleSheetInner* Inner() const
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -275,16 +275,27 @@ public:
/**
* Records that the contents of style sheets have changed since the last
* restyle. Calling this will ensure that the Stylist rebuilds its
* selector maps.
*/
void NoteStyleSheetsChanged();
+ /**
+ * Helper for correctly calling RebuildStylist without paying the cost of an
+ * extra function call in the common no-rebuild-needed case.
+ */
+ void UpdateStylistIfNeeded()
+ {
+ if (StylistNeedsUpdate()) {
+ UpdateStylist();
+ }
+ }
+
#ifdef DEBUG
void AssertTreeIsClean();
#else
void AssertTreeIsClean() {}
#endif
/**
* Clears the style data, both style sheet data and cached non-inheriting
@@ -464,27 +475,16 @@ private:
/**
* Update the stylist as needed to ensure style data is up-to-date.
*
* This should only be called if StylistNeedsUpdate returns true.
*/
void UpdateStylist();
- /**
- * Helper for correctly calling RebuildStylist without paying the cost of an
- * extra function call in the common no-rebuild-needed case.
- */
- void UpdateStylistIfNeeded()
- {
- if (StylistNeedsUpdate()) {
- UpdateStylist();
- }
- }
-
already_AddRefed<ServoComputedValues>
ResolveStyleLazily(dom::Element* aElement, CSSPseudoElementType aPseudoType);
void RunPostTraversalTasks();
void PrependSheetOfType(SheetType aType,
ServoStyleSheet* aSheet);
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -208,16 +208,25 @@ ServoStyleSheet::Clone(StyleSheet* aClon
RefPtr<StyleSheet> clone = new ServoStyleSheet(*this,
static_cast<ServoStyleSheet*>(aCloneParent),
aCloneOwnerRule,
aCloneDocument,
aCloneOwningNode);
return clone.forget();
}
+void
+ServoStyleSheet::ClearRuleCascadesInternal()
+{
+ for (StyleSetHandle& setHandle : mStyleSets) {
+ setHandle->AsServo()->NoteStyleSheetsChanged();
+ setHandle->AsServo()->UpdateStylistIfNeeded();
+ }
+}
+
CSSRuleList*
ServoStyleSheet::GetCssRulesInternal(ErrorResult& aRv)
{
if (!mRuleList) {
RefPtr<ServoCssRules> rawRules =
Servo_StyleSheet_GetRules(Inner()->mSheet).Consume();
mRuleList = new ServoCSSRuleList(rawRules.forget());
mRuleList->SetStyleSheet(this);
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -108,16 +108,18 @@ public:
// nsICSSLoaderObserver interface
NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasAlternate,
nsresult aStatus) final;
protected:
virtual ~ServoStyleSheet();
+ void ClearRuleCascadesInternal() override;
+
ServoStyleSheetInner* Inner() const
{
return static_cast<ServoStyleSheetInner*>(mInner);
}
// Internal methods which do not have security check and completeness check.
dom::CSSRuleList* GetCssRulesInternal(ErrorResult& aRv);
uint32_t InsertRuleInternal(const nsAString& aRule,
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -122,16 +122,25 @@ StyleSheet::TraverseInner(nsCycleCollect
StyleSheet* childSheet = GetFirstChild();
while (childSheet) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "child sheet");
cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, childSheet));
childSheet = childSheet->mNext;
}
}
+void
+StyleSheet::ClearRuleCascades()
+{
+ ClearRuleCascadesInternal();
+ if (mParent) {
+ mParent->ClearRuleCascades();
+ }
+}
+
// QueryInterface implementation for StyleSheet
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StyleSheet)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
NS_INTERFACE_MAP_ENTRY(nsIDOMStyleSheet)
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleSheet)
NS_INTERFACE_MAP_END
@@ -432,16 +441,19 @@ StyleSheet::EnsureUniqueInner()
// already unique
return;
}
StyleSheetInfo* clone = mInner->CloneFor(this);
MOZ_ASSERT(clone);
mInner->RemoveSheet(this);
mInner = clone;
+
+ // Ensure we're using the new rules.
+ ClearRuleCascades();
}
// WebIDL CSSStyleSheet API
#define FORWARD_INTERNAL(method_, args_) \
if (IsServo()) { \
return AsServo()->method_ args_; \
} \
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -266,16 +266,19 @@ protected:
// Called from SetEnabled when the enabled state changed.
void EnabledStateChanged();
// Unlink our inner, if needed, for cycle collection
virtual void UnlinkInner();
// Traverse our inner, if needed, for cycle collection
virtual void TraverseInner(nsCycleCollectionTraversalCallback &);
+ void ClearRuleCascades();
+ virtual void ClearRuleCascadesInternal() {}
+
StyleSheet* mParent; // weak ref
nsString mTitle;
nsIDocument* mDocument; // weak ref; parents maintain this for their children
nsINode* mOwningNode; // weak ref
RefPtr<dom::MediaList> mMedia;