Bug 1436059: Fix inspector. r=xidorn
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 16 Feb 2018 11:34:12 +0100
changeset 404242 99d75ed01742cd938c61ab5da22ea52369917419
parent 404241 aeca8702a854546d527205281948fb739e5f0cf6
child 404243 9f1b9c33846a2a7260878d840504ed776c1d34cf
push id99968
push userrgurzau@mozilla.com
push dateFri, 16 Feb 2018 22:14:56 +0000
treeherdermozilla-inbound@2e16779c96cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersxidorn
bugs1436059
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1436059: Fix inspector. r=xidorn This removes a hack, but adds slightly more complex code in inspector-only code. I'm not excited about this code, but this fixes ServoStyleRuleMap for XBL. MozReview-Commit-ID: 6h0dCsiIWKU
layout/style/ServoBindingList.h
layout/style/ServoStyleSet.cpp
layout/style/StyleSheet.cpp
layout/style/StyleSheet.h
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -178,16 +178,18 @@ SERVO_BINDING_FUNC(Servo_UACache_AddSize
 
 // AuthorStyles
 SERVO_BINDING_FUNC(Servo_AuthorStyles_Create, RawServoAuthorStyles*)
 // TODO(emilio): This will need to take an optional master style set to
 // implement invalidation for Shadow DOM.
 SERVO_BINDING_FUNC(Servo_AuthorStyles_AppendStyleSheet, void,
                    RawServoAuthorStylesBorrowedMut self,
                    const mozilla::ServoStyleSheet* gecko_sheet)
+SERVO_BINDING_FUNC(Servo_AuthorStyles_ForceDirty, void,
+                   RawServoAuthorStylesBorrowedMut self)
 // TODO(emilio): This will need to take an element to implement invalidation for
 // Shadow DOM.
 SERVO_BINDING_FUNC(Servo_AuthorStyles_Flush, void,
                    RawServoAuthorStylesBorrowedMut self,
                    RawServoStyleSetBorrowed document_styles)
 
 SERVO_BINDING_FUNC(Servo_StyleContext_AddRef, void, ServoStyleContextBorrowed ctx);
 SERVO_BINDING_FUNC(Servo_StyleContext_Release, void, ServoStyleContextBorrowed ctx);
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -1265,45 +1265,71 @@ ServoStyleSet::ComputeAnimationValue(
                                       aDeclarations,
                                       aContext,
                                       mRawSet.get()).Consume();
 }
 
 bool
 ServoStyleSet::EnsureUniqueInnerOnCSSSheets()
 {
-  AutoTArray<StyleSheet*, 32> queue;
+  using SheetOwner = Variant<ServoStyleSet*, nsXBLPrototypeBinding*>;
+
+  AutoTArray<Pair<StyleSheet*, SheetOwner>, 32> queue;
   for (auto& entryArray : mSheets) {
     for (auto& sheet : entryArray) {
-      queue.AppendElement(sheet);
+      StyleSheet* downcasted = sheet;
+      queue.AppendElement(MakePair(downcasted, SheetOwner { this }));
     }
   }
-  // This is a stub until more of the functionality of nsStyleSet is
-  // replicated for Servo here.
 
-  // Bug 1290276 will replicate the nsStyleSet work of checking
-  // a nsBindingManager
+  mDocument->BindingManager()->EnumerateBoundContentBindings(
+      [&](nsXBLBinding* aBinding) {
+        AutoTArray<StyleSheet*, 3> sheets;
+        aBinding->PrototypeBinding()->AppendStyleSheetsTo(sheets);
+        for (auto* sheet : sheets) {
+          queue.AppendElement(MakePair(sheet, SheetOwner { aBinding->PrototypeBinding() }));
+        }
+        return true;
+      });
 
+  bool anyXBLSheetChanged = false;
   while (!queue.IsEmpty()) {
     uint32_t idx = queue.Length() - 1;
-    StyleSheet* sheet = queue[idx];
+    auto* sheet = queue[idx].first();
+    SheetOwner owner = queue[idx].second();
     queue.RemoveElementAt(idx);
 
+    if (!sheet->HasUniqueInner() && owner.is<nsXBLPrototypeBinding*>()) {
+      if (auto* styles = owner.as<nsXBLPrototypeBinding*>()->GetServoStyles()) {
+        Servo_AuthorStyles_ForceDirty(styles);
+        mNeedsRestyleAfterEnsureUniqueInner = true;
+        anyXBLSheetChanged = true;
+      }
+    }
+
     // Only call EnsureUniqueInner for complete sheets. If we do call it on
     // incomplete sheets, we'll cause problems when the sheet is actually
     // loaded. We don't care about incomplete sheets here anyway, because this
     // method is only invoked by nsPresContext::EnsureSafeToHandOutCSSRules.
     // The CSSRule objects we are handing out won't contain any rules derived
     // from incomplete sheets (because they aren't yet applied in styling).
     if (sheet->IsComplete()) {
       sheet->EnsureUniqueInner();
     }
 
     // Enqueue all the sheet's children.
-    sheet->AppendAllChildSheets(queue);
+    AutoTArray<StyleSheet*, 3> children;
+    sheet->AppendAllChildSheets(children);
+    for (auto* sheet : children) {
+      queue.AppendElement(MakePair(sheet, owner));
+    }
+  }
+
+  if (anyXBLSheetChanged) {
+    SetStylistXBLStyleSheetsDirty();
   }
 
   if (mNeedsRestyleAfterEnsureUniqueInner) {
     // TODO(emilio): We could make this faster if needed tracking the specific
     // origins and all that, but the only caller of this doesn't seem to really
     // care about perf.
     MarkOriginsDirty(OriginFlags::All);
   }
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -396,33 +396,16 @@ StyleSheet::EnsureUniqueInner()
              "unexpected number of outers");
   mDirtyFlags |= FORCED_UNIQUE_INNER;
 
   if (HasUniqueInner()) {
     // already unique
     return;
   }
 
-  // If this stylesheet is for XBL with Servo, don't bother cloning
-  // it, as it may break ServoStyleRuleMap. XBL stylesheets are not
-  // supposed to change anyway.
-  //
-  // The mDocument check is used as a fast reject path because no
-  // XBL stylesheets would have associated document, but in normal
-  // cases, content stylesheets should usually have one.
-  //
-  // FIXME(emilio): Shadow DOM definitely modifies stylesheets! Right now all of
-  // them are unique anyway because we don't support <link>, but that needs to
-  // change.
-  if (!mDocument && IsServo() &&
-      mStyleSets.Length() == 1 &&
-      mStyleSets[0]->AsServo()->IsForXBL()) {
-    return;
-  }
-
   StyleSheetInfo* clone = mInner->CloneFor(this);
   MOZ_ASSERT(clone);
   mInner->RemoveSheet(this);
   mInner = clone;
 
   if (IsGecko()) {
 #ifdef MOZ_OLD_STYLE
     // Ensure we're using the new rules.
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -127,21 +127,30 @@ public:
   inline bool IsApplicable() const;
   inline bool HasRules() const;
 
   virtual already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
                                              dom::CSSImportRule* aCloneOwnerRule,
                                              nsIDocument* aCloneDocument,
                                              nsINode* aCloneOwningNode) const = 0;
 
-  bool HasForcedUniqueInner() const { return mDirtyFlags &
-                                             FORCED_UNIQUE_INNER; }
-  bool HasModifiedRules() const { return mDirtyFlags &
-                                         MODIFIED_RULES; }
-  void ClearModifiedRules() { mDirtyFlags &= ~MODIFIED_RULES; }
+  bool HasForcedUniqueInner() const
+  {
+    return mDirtyFlags & FORCED_UNIQUE_INNER;
+  }
+
+  bool HasModifiedRules() const
+  {
+    return mDirtyFlags & MODIFIED_RULES;
+  }
+
+  void ClearModifiedRules()
+  {
+    mDirtyFlags &= ~MODIFIED_RULES;
+  }
 
   inline bool HasUniqueInner() const;
   void EnsureUniqueInner();
 
   // Append all of this sheet's child sheets to aArray.
   void AppendAllChildSheets(nsTArray<StyleSheet*>& aArray);
 
   // style sheet owner info