Bug 1396700 - Add a method to ServoStyleSet for creating XBL style set. draft
authorTing-Yu Lin <tlin@mozilla.com>
Fri, 01 Sep 2017 16:45:39 +0800
changeset 658891 539454bc519a6b7166affa0388181501ed270bdc
parent 658878 e04bee92f6b35913206dfc5938cb206afd753396
child 729792 bfb1c5336b73c092c9f967a1cf09dddbdffd605f
push id77919
push userbmo:tlin@mozilla.com
push dateTue, 05 Sep 2017 04:13:26 +0000
bugs1396700
milestone57.0a1
Bug 1396700 - Add a method to ServoStyleSet for creating XBL style set. The motivation of this patch is that clearing mPresContext should be an implementation detail of XBL style set, so I create a method for that, and remove ClearPresContext(). MozReview-Commit-ID: Ftta0rcAqu6
dom/xbl/nsXBLPrototypeResources.cpp
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
--- a/dom/xbl/nsXBLPrototypeResources.cpp
+++ b/dom/xbl/nsXBLPrototypeResources.cpp
@@ -162,33 +162,24 @@ nsXBLPrototypeResources::GatherRuleProce
                                           SheetType::Doc,
                                           nullptr,
                                           mRuleProcessor);
 }
 
 void
 nsXBLPrototypeResources::ComputeServoStyleSet(nsPresContext* aPresContext)
 {
-  mServoStyleSet.reset(new ServoStyleSet(ServoStyleSet::Kind::ForXBL));
-  mServoStyleSet->Init(aPresContext, nullptr);
+  nsTArray<RefPtr<ServoStyleSheet>> sheets(mStyleSheetList.Length());
   for (StyleSheet* sheet : mStyleSheetList) {
     MOZ_ASSERT(sheet->IsServo(),
                "This should only be called with Servo-flavored style backend!");
-    // The XBL style sheets aren't document level sheets, but we need to
-    // decide a particular SheetType to add them to style set. This type
-    // doesn't affect the place where we pull those rules from
-    // stylist::push_applicable_declarations_as_xbl_only_stylist().
-    mServoStyleSet->AppendStyleSheet(SheetType::Doc, sheet->AsServo());
+    sheets.AppendElement(sheet->AsServo());
   }
-  mServoStyleSet->UpdateStylistIfNeeded();
 
-  // The PresContext of the bound document could be destroyed anytime later,
-  // which shouldn't be used for XBL styleset, so we clear it here to avoid
-  // dangling pointer.
-  mServoStyleSet->ClearPresContext();
+  mServoStyleSet = ServoStyleSet::CreateXBLServoStyleSet(aPresContext, sheets);
 }
 
 void
 nsXBLPrototypeResources::AppendStyleSheet(StyleSheet* aSheet)
 {
   mStyleSheetList.AppendElement(aSheet);
 }
 
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -100,16 +100,41 @@ ServoStyleSet::~ServoStyleSet()
 {
   for (auto& sheetArray : mSheets) {
     for (auto& sheet : sheetArray) {
       sheet->DropStyleSet(this);
     }
   }
 }
 
+UniquePtr<ServoStyleSet>
+ServoStyleSet::CreateXBLServoStyleSet(
+  nsPresContext* aPresContext,
+  const nsTArray<RefPtr<ServoStyleSheet>>& aNewSheets)
+{
+  auto set = MakeUnique<ServoStyleSet>(Kind::ForXBL);
+  set->Init(aPresContext, nullptr);
+
+  // The XBL style sheets aren't document level sheets, but we need to
+  // decide a particular SheetType to add them to style set. This type
+  // doesn't affect the place where we pull those rules from
+  // stylist::push_applicable_declarations_as_xbl_only_stylist().
+  set->ReplaceSheets(SheetType::Doc, aNewSheets);
+
+  // Update stylist immediately.
+  set->UpdateStylist();
+
+  // The PresContext of the bound document could be destroyed anytime later,
+  // which shouldn't be used for XBL styleset, so we clear it here to avoid
+  // dangling pointer.
+  set->mPresContext = nullptr;
+
+  return set;
+}
+
 void
 ServoStyleSet::Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager)
 {
   mPresContext = aPresContext;
   mLastPresContextUsesXBLStyleSet = aPresContext;
 
   mRawSet.reset(Servo_StyleSet_Init(aPresContext));
   mBindingManager = aBindingManager;
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -113,16 +113,20 @@ public:
 
     // A StyleSet for XBL, which is owned by a given XBL binding.
     ForXBL,
   };
 
   explicit ServoStyleSet(Kind aKind);
   ~ServoStyleSet();
 
+  static UniquePtr<ServoStyleSet>
+  CreateXBLServoStyleSet(nsPresContext* aPresContext,
+                         const nsTArray<RefPtr<ServoStyleSheet>>& aNewSheets);
+
   void Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager);
   void BeginShutdown();
   void Shutdown();
 
   void RecordStyleSheetChange(mozilla::ServoStyleSheet*, StyleSheet::ChangeType);
 
   void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot) {
     // FIXME(emilio): When we properly support shadow dom we'll need to do
@@ -425,21 +429,16 @@ public:
   // its inner.
   void SetNeedsRestyleAfterEnsureUniqueInner() {
     mNeedsRestyleAfterEnsureUniqueInner = true;
   }
 
   // Returns the style rule map.
   ServoStyleRuleMap* StyleRuleMap();
 
-  // Clear mPresContext. This is needed after XBL ServoStyleSet is created.
-  void ClearPresContext() {
-    mPresContext = nullptr;
-  }
-
   // Return whether this is the last PresContext which uses this XBL styleset.
   bool IsPresContextChanged(nsPresContext* aPresContext) const {
     return aPresContext != mLastPresContextUsesXBLStyleSet;
   }
 
   // Set PresContext (i.e. Device) for mRawSet. This should be called only
   // by XBL stylesets. Returns true if there is any rule changing.
   bool SetPresContext(nsPresContext* aPresContext);