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
--- 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);