Bug 1339629 Part 8: Uplift ClearRuleCascades into StyleSheet. draft
authorBrad Werth <bwerth@mozilla.com>
Thu, 18 May 2017 14:21:11 -0700
changeset 584202 ee30e8bde771c866569858bda0b729aab57fae2e
parent 584201 c5d413ace25161ef455f3e9eb8d7c81e3391316e
child 584203 c7bd633953f04477d7ea7505c5130874258f5af9
push id60647
push userbwerth@mozilla.com
push dateThu, 25 May 2017 00:33:14 +0000
bugs1339629
milestone55.0a1
Bug 1339629 Part 8: Uplift ClearRuleCascades into StyleSheet. MozReview-Commit-ID: CCYIYjWrw86
layout/style/CSSStyleSheet.cpp
layout/style/CSSStyleSheet.h
layout/style/ServoStyleSet.h
layout/style/ServoStyleSheet.cpp
layout/style/ServoStyleSheet.h
layout/style/StyleSheet.cpp
layout/style/StyleSheet.h
--- 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;