Bug 1436798: style: Move author-style-disabled handling to push_applicable_declarations. draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 08 Feb 2018 13:05:28 +0100
changeset 752877 c2f415c31e2c0eb352d467daa7f50fb8f6ede329
parent 752876 8af6199f59c786eacfe9a4231637ed3ecba2033e
child 752878 c3267da3c9f40c103db799c4108eeed6f58bad4d
push id98405
push userbmo:emilio@crisal.io
push dateFri, 09 Feb 2018 01:50:06 +0000
bugs1436798
milestone60.0a1
Bug 1436798: style: Move author-style-disabled handling to push_applicable_declarations. This will make it easier to handle it properly for Shadow DOM, though this patch doesn't do that. This also makes some method inline and infallible for convenience, since nobody checks the errors anyway. MozReview-Commit-ID: Hq3erAUs5tf
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
layout/style/StyleSetHandle.h
layout/style/StyleSetHandleInlines.h
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
servo/components/style/stylesheet_set.rs
servo/components/style/stylist.rs
servo/ports/geckolib/glue.rs
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -350,33 +350,29 @@ ServoStyleSet::AddSizeOfIncludingThis(ns
   // worthwhile:
   // - mSheets
   // - mNonInheritingStyleContexts
   //
   // The following members are not measured:
   // - mDocument, because it a non-owning pointer
 }
 
-bool
-ServoStyleSet::GetAuthorStyleDisabled() const
-{
-  return mAuthorStyleDisabled;
-}
-
-nsresult
+void
 ServoStyleSet::SetAuthorStyleDisabled(bool aStyleDisabled)
 {
   if (mAuthorStyleDisabled == aStyleDisabled) {
-    return NS_OK;
+    return;
   }
 
   mAuthorStyleDisabled = aStyleDisabled;
-  MarkOriginsDirty(OriginFlags::Author);
-
-  return NS_OK;
+  if (Element* root = mDocument->GetRootElement()) {
+    if (nsPresContext* pc = GetPresContext()) {
+      pc->RestyleManager()->PostRestyleEvent(root, eRestyle_Subtree, nsChangeHint(0));
+    }
+  }
 }
 
 void
 ServoStyleSet::BeginUpdate()
 {
 }
 
 nsresult
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -162,18 +162,22 @@ public:
 
   void InvalidateStyleForCSSRuleChanges();
 
   void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const;
   const RawServoStyleSet* RawSet() const {
     return mRawSet.get();
   }
 
-  bool GetAuthorStyleDisabled() const;
-  nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
+  bool GetAuthorStyleDisabled() const
+  {
+    return mAuthorStyleDisabled;
+  }
+
+  void SetAuthorStyleDisabled(bool aStyleDisabled);
 
   void BeginUpdate();
   nsresult EndUpdate();
 
   already_AddRefed<ServoStyleContext>
   ResolveStyleFor(dom::Element* aElement,
                   ServoStyleContext* aParentContext,
                   LazyComputeBehavior aMayCompute);
--- a/layout/style/StyleSetHandle.h
+++ b/layout/style/StyleSetHandle.h
@@ -131,17 +131,17 @@ public:
     // StyleSetHandleInlines.h and just forward to the underlying
     // nsStyleSet or ServoStyleSet.  See corresponding comments in
     // nsStyleSet.h for descriptions of these methods.
 
     inline void Init(nsPresContext* aPresContext);
     inline void BeginShutdown();
     inline void Shutdown();
     inline bool GetAuthorStyleDisabled() const;
-    inline nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
+    inline void SetAuthorStyleDisabled(bool aStyleDisabled);
     inline void BeginUpdate();
     inline nsresult EndUpdate();
     inline already_AddRefed<nsStyleContext>
     ResolveStyleFor(dom::Element* aElement,
                     nsStyleContext* aParentContext,
                     LazyComputeBehavior aMayCompute);
     inline already_AddRefed<nsStyleContext>
     ResolveStyleFor(dom::Element* aElement,
--- a/layout/style/StyleSetHandleInlines.h
+++ b/layout/style/StyleSetHandleInlines.h
@@ -82,17 +82,17 @@ StyleSetHandle::Ptr::Shutdown()
 }
 
 bool
 StyleSetHandle::Ptr::GetAuthorStyleDisabled() const
 {
   FORWARD(GetAuthorStyleDisabled, ());
 }
 
-nsresult
+void
 StyleSetHandle::Ptr::SetAuthorStyleDisabled(bool aStyleDisabled)
 {
   FORWARD(SetAuthorStyleDisabled, (aStyleDisabled));
 }
 
 void
 StyleSetHandle::Ptr::BeginUpdate()
 {
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -402,20 +402,22 @@ SortStyleSheetsByScope(nsTArray<CSSStyle
   // Sort by depth first, then document order.
   sheets.Sort();
 
   for (uint32_t i = 0; i < n; i++) {
     aSheets[i] = sheets[i].mSheet;
   }
 }
 
-nsresult
+void
 nsStyleSet::GatherRuleProcessors(SheetType aType)
 {
-  NS_ENSURE_FALSE(mInShutdown, NS_ERROR_FAILURE);
+  if (mInShutdown) {
+    return;
+  }
 
   // We might be in GatherRuleProcessors because we are dropping a sheet,
   // resulting 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.
   if (IsCSSSheetType(aType)) {
     ClearSelectors();
@@ -444,39 +446,39 @@ nsStyleSet::GatherRuleProcessors(SheetTy
     oldScopedDocRuleProcessors.SwapElements(mScopedDocSheetRuleProcessors);
   }
   if (mAuthorStyleDisabled && (aType == SheetType::Doc ||
                                aType == SheetType::ScopedDoc ||
                                aType == SheetType::StyleAttr)) {
     // Don't regather if this level is disabled.  Note that we gather
     // preshint sheets no matter what, but then skip them for some
     // elements later if mAuthorStyleDisabled.
-    return NS_OK;
+    return;
   }
   switch (aType) {
     // levels that do not contain CSS style sheets
     case SheetType::Animation:
       MOZ_ASSERT(mSheets[aType].IsEmpty());
       mRuleProcessors[aType] = PresContext()->EffectCompositor()->
         RuleProcessor(EffectCompositor::CascadeLevel::Animations);
-      return NS_OK;
+      return;
     case SheetType::Transition:
       MOZ_ASSERT(mSheets[aType].IsEmpty());
       mRuleProcessors[aType] = PresContext()->EffectCompositor()->
         RuleProcessor(EffectCompositor::CascadeLevel::Transitions);
-      return NS_OK;
+      return;
     case SheetType::StyleAttr:
       MOZ_ASSERT(mSheets[aType].IsEmpty());
       mRuleProcessors[aType] = PresContext()->Document()->GetInlineStyleSheet();
-      return NS_OK;
+      return;
     case SheetType::PresHint:
       MOZ_ASSERT(mSheets[aType].IsEmpty());
       mRuleProcessors[aType] =
         PresContext()->Document()->GetAttributeStyleSheet();
-      return NS_OK;
+      return;
     default:
       // keep going
       break;
   }
   MOZ_ASSERT(IsCSSSheetType(aType));
   if (aType == SheetType::ScopedDoc) {
     // Create a rule processor for each scope.
     uint32_t count = mSheets[SheetType::ScopedDoc].Length();
@@ -527,17 +529,17 @@ nsStyleSet::GatherRuleProcessors(SheetTy
         sheetsForScope.AppendElements(sheets.Elements() + start, end - start);
         nsCSSRuleProcessor* oldRP = oldScopedRuleProcessorHash.Get(scope);
         mScopedDocSheetRuleProcessors.AppendElement
           (new nsCSSRuleProcessor(Move(sheetsForScope), aType, scope, oldRP));
 
         start = end;
       } while (start < count);
     }
-    return NS_OK;
+    return;
   }
   if (!mSheets[aType].IsEmpty()) {
     switch (aType) {
       case SheetType::Agent:
       case SheetType::User: {
         // levels containing non-scoped CSS style sheets whose rule processors
         // we want to re-use
         nsTArray<CSSStyleSheet*> sheets(mSheets[aType].Length());
@@ -573,18 +575,16 @@ nsStyleSet::GatherRuleProcessors(SheetTy
                                    oldRuleProcessor.get()));
       } break;
 
       default:
         MOZ_ASSERT_UNREACHABLE("non-CSS sheet types should be handled above");
         break;
     }
   }
-
-  return NS_OK;
 }
 
 nsresult
 nsStyleSet::AppendStyleSheet(SheetType aType, CSSStyleSheet* aSheet)
 {
   NS_PRECONDITION(aSheet, "null arg");
   NS_ASSERTION(aSheet->IsApplicable(),
                "Inapplicable sheet being placed in style set");
@@ -678,41 +678,36 @@ static inline uint32_t
 DirtyBit(SheetType aType)
 {
   return 1 << uint32_t(aType);
 }
 
 nsresult
 nsStyleSet::DirtyRuleProcessors(SheetType aType)
 {
-  if (!mBatching)
-    return GatherRuleProcessors(aType);
+  if (!mBatching) {
+    GatherRuleProcessors(aType);
+    return NS_OK;
+  }
 
   mDirty |= DirtyBit(aType);
   return NS_OK;
 }
 
-bool
-nsStyleSet::GetAuthorStyleDisabled() const
-{
-  return mAuthorStyleDisabled;
-}
-
-nsresult
+void
 nsStyleSet::SetAuthorStyleDisabled(bool aStyleDisabled)
 {
   if (aStyleDisabled == !mAuthorStyleDisabled) {
     mAuthorStyleDisabled = aStyleDisabled;
     BeginUpdate();
     mDirty |= DirtyBit(SheetType::Doc) |
               DirtyBit(SheetType::ScopedDoc) |
               DirtyBit(SheetType::StyleAttr);
-    return EndUpdate();
+    EndUpdate();
   }
-  return NS_OK;
 }
 
 // -------- Doc Sheets
 
 nsresult
 nsStyleSet::AddDocStyleSheet(CSSStyleSheet* aSheet, nsIDocument* aDocument)
 {
   NS_PRECONDITION(aSheet && aDocument, "null arg");
@@ -765,18 +760,17 @@ nsStyleSet::EndUpdate()
   NS_ASSERTION(mBatching > 0, "Unbalanced EndUpdate");
   if (--mBatching) {
     // We're not completely done yet.
     return NS_OK;
   }
 
   for (SheetType type : MakeEnumeratedRange(SheetType::Count)) {
     if (mDirty & DirtyBit(type)) {
-      nsresult rv = GatherRuleProcessors(type);
-      NS_ENSURE_SUCCESS(rv, rv);
+      GatherRuleProcessors(type);
     }
   }
 
   mDirty = 0;
   return NS_OK;
 }
 
 template<class T>
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -426,18 +426,22 @@ class nsStyleSet final
                             mozilla::CSSStyleSheet* aSheet);
   nsresult ReplaceSheets(mozilla::SheetType aType,
                          const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets);
   nsresult InsertStyleSheetBefore(mozilla::SheetType aType,
                                   mozilla::CSSStyleSheet* aNewSheet,
                                   mozilla::CSSStyleSheet* aReferenceSheet);
 
   // Enable/Disable entire author style level (Doc, ScopedDoc & PresHint levels)
-  bool GetAuthorStyleDisabled() const;
-  nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
+  bool GetAuthorStyleDisabled() const
+  {
+    return mAuthorStyleDisabled;
+  }
+
+  void SetAuthorStyleDisabled(bool aStyleDisabled);
 
   int32_t SheetCount(mozilla::SheetType aType) const {
     return mSheets[aType].Length();
   }
 
   mozilla::CSSStyleSheet* StyleSheetAt(mozilla::SheetType aType,
                                        int32_t aIndex) const {
     return mSheets[aType][aIndex];
@@ -530,17 +534,17 @@ private:
   // of nodes whose reference-count drops to zero during the destruction of
   // a child node. This allows the collection of entire trees at once, since
   // children hold their parents alive.
   void GCRuleTrees();
 
   nsresult DirtyRuleProcessors(mozilla::SheetType aType);
 
   // Update the rule processor list after a change to the style sheet list.
-  nsresult GatherRuleProcessors(mozilla::SheetType aType);
+  void GatherRuleProcessors(mozilla::SheetType aType);
 
   void AddImportantRules(nsRuleNode* aCurrLevelNode,
                          nsRuleNode* aLastPrevLevelNode,
                          nsRuleWalker* aRuleWalker);
 
   // Move aRuleWalker forward by the appropriate rule if we need to add
   // a rule due to property restrictions on pseudo-elements.
   void WalkRestrictionRule(mozilla::CSSPseudoElementType aPseudoType,
--- a/servo/components/style/stylesheet_set.rs
+++ b/servo/components/style/stylesheet_set.rs
@@ -119,35 +119,24 @@ pub enum DataValidity {
 }
 
 impl Default for DataValidity {
     fn default() -> Self {
         DataValidity::Valid
     }
 }
 
-/// Whether author styles are enabled.
-///
-/// This is used to support Gecko.
-#[allow(missing_docs)]
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum AuthorStylesEnabled {
-    Yes,
-    No,
-}
-
 /// A struct to iterate over the different stylesheets to be flushed.
 pub struct StylesheetFlusher<'a, S>
 where
     S: StylesheetInDocument + PartialEq + 'static,
 {
     origins_dirty: OriginSet,
     collections: &'a mut PerOrigin<SheetCollection<S>>,
     origin_data_validity: PerOrigin<DataValidity>,
-    author_styles_enabled: AuthorStylesEnabled,
     had_invalidations: bool,
 }
 
 /// The type of rebuild that we need to do for a given stylesheet.
 #[derive(Clone, Copy, Debug)]
 pub enum SheetRebuildKind {
     /// A full rebuild, of both cascade data and invalidation data.
     Full,
@@ -204,24 +193,16 @@ where
         let validity = self.data_validity(origin);
         let origin_dirty = self.origins_dirty.contains(origin.into());
 
         debug_assert!(
             origin_dirty || validity == DataValidity::Valid,
             "origin_data_validity should be a subset of origins_dirty!"
         );
 
-        if self.author_styles_enabled == AuthorStylesEnabled::No &&
-            origin == Origin::Author
-        {
-            return PerOriginFlusher {
-                iter: [].iter_mut(),
-                validity,
-            }
-        }
         PerOriginFlusher {
             iter: self.collections.borrow_mut_for_origin(&origin).entries.iter_mut(),
             validity,
         }
     }
 
     /// Returns whether running the whole flushing process would be a no-op.
     pub fn nothing_to_do(&self) -> bool {
@@ -406,31 +387,27 @@ pub struct DocumentStylesheetSet<S>
 where
     S: StylesheetInDocument + PartialEq + 'static,
 {
     /// The collections of sheets per each origin.
     collections: PerOrigin<SheetCollection<S>>,
 
     /// The invalidations for stylesheets added or removed from this document.
     invalidations: StylesheetInvalidationSet,
-
-    /// Whether author styles are enabled.
-    author_styles_enabled: AuthorStylesEnabled,
 }
 
 impl<S> DocumentStylesheetSet<S>
 where
     S: StylesheetInDocument + PartialEq + 'static,
 {
     /// Create a new empty StylesheetSet.
     pub fn new() -> Self {
         Self {
             collections: Default::default(),
             invalidations: StylesheetInvalidationSet::new(),
-            author_styles_enabled: AuthorStylesEnabled::Yes,
         }
     }
 
     /// Returns the number of stylesheets in the set.
     pub fn len(&self) -> usize {
         self.collections.iter_origins().fold(0, |s, (item, _)| s + item.len())
     }
 
@@ -505,28 +482,16 @@ where
     ) {
         debug!("StylesheetSet::remove_stylesheet");
         self.collect_invalidations_for(device, &sheet, guard);
 
         let origin = sheet.contents(guard).origin;
         self.collections.borrow_mut_for_origin(&origin).remove(&sheet)
     }
 
-    /// Notes that the author style has been disabled for this document.
-    pub fn set_author_styles_enabled(&mut self, enabled: AuthorStylesEnabled) {
-        debug!("DocumentStylesheetSet::set_author_styles_enabled");
-        if self.author_styles_enabled == enabled {
-            return;
-        }
-        self.author_styles_enabled = enabled;
-        self.invalidations.invalidate_fully();
-        self.collections.borrow_mut_for_origin(&Origin::Author)
-            .set_data_validity_at_least(DataValidity::FullyInvalid)
-    }
-
     /// Returns whether the given set has changed from the last flush.
     pub fn has_changed(&self) -> bool {
         self.collections.iter_origins().any(|(collection, _)| collection.dirty)
     }
 
     /// Flush the current set, unmarking it as dirty, and returns a
     /// `StylesheetFlusher` in order to rebuild the stylist.
     pub fn flush<'a, E>(
@@ -555,17 +520,16 @@ where
 
             origins_dirty |= origin;
             *origin_data_validity.borrow_mut_for_origin(&origin) =
                 mem::replace(&mut collection.data_validity, DataValidity::Valid);
         }
 
         StylesheetFlusher {
             collections: &mut self.collections,
-            author_styles_enabled: self.author_styles_enabled,
             had_invalidations,
             origins_dirty,
             origin_data_validity,
         }
     }
 
     /// Flush stylesheets, but without running any of the invalidation passes.
     #[cfg(feature = "servo")]
--- a/servo/components/style/stylist.rs
+++ b/servo/components/style/stylist.rs
@@ -36,17 +36,17 @@ use selectors::parser::{SelectorIter, Vi
 use selectors::visitor::SelectorVisitor;
 use servo_arc::{Arc, ArcBorrow};
 use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
 use smallbitvec::SmallBitVec;
 use smallvec::SmallVec;
 use std::ops;
 use std::sync::Mutex;
 use style_traits::viewport::ViewportConstraints;
-use stylesheet_set::{AuthorStylesEnabled, DataValidity, SheetRebuildKind, DocumentStylesheetSet, StylesheetFlusher};
+use stylesheet_set::{DataValidity, SheetRebuildKind, DocumentStylesheetSet, StylesheetFlusher};
 #[cfg(feature = "gecko")]
 use stylesheets::{CounterStyleRule, FontFaceRule, FontFeatureValuesRule, PageRule};
 use stylesheets::{CssRule, Origin, OriginSet, PerOrigin, PerOriginIter};
 use stylesheets::StyleRule;
 use stylesheets::StylesheetInDocument;
 use stylesheets::keyframes_rule::KeyframesAnimation;
 use stylesheets::viewport_rule::{self, MaybeNew, ViewportRule};
 use thread_state::{self, ThreadState};
@@ -327,16 +327,26 @@ impl DocumentCascadeData {
     /// Measures heap usage.
     #[cfg(feature = "gecko")]
     pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) {
         self.user.add_size_of(ops, sizes);
         self.author.add_size_of(ops, sizes);
     }
 }
 
+/// Whether author styles are enabled.
+///
+/// This is used to support Gecko.
+#[allow(missing_docs)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum AuthorStylesEnabled {
+    Yes,
+    No,
+}
+
 /// A wrapper over a DocumentStylesheetSet that can be `Sync`, since it's only
 /// used and exposed via mutable methods in the `Stylist`.
 #[cfg_attr(feature = "servo", derive(MallocSizeOf))]
 struct StylistStylesheetSet(DocumentStylesheetSet<StylistSheet>);
 // Read above to see why this is fine.
 unsafe impl Sync for StylistStylesheetSet {}
 
 impl StylistStylesheetSet {
@@ -392,16 +402,19 @@ pub struct Stylist {
     #[cfg_attr(feature = "servo", ignore_malloc_size_of = "defined in selectors")]
     quirks_mode: QuirksMode,
 
     /// Selector maps for all of the style sheets in the stylist, after
     /// evalutaing media rules against the current device, split out per
     /// cascade level.
     cascade_data: DocumentCascadeData,
 
+    /// Whether author styles are enabled.
+    author_styles_enabled: AuthorStylesEnabled,
+
     /// The rule tree, that stores the results of selector matching.
     rule_tree: RuleTree,
 
     /// The total number of times the stylist has been rebuilt.
     num_rebuilds: usize,
 }
 
 /// What cascade levels to include when styling elements.
@@ -432,16 +445,17 @@ impl Stylist {
     #[inline]
     pub fn new(device: Device, quirks_mode: QuirksMode) -> Self {
         Self {
             viewport_constraints: None,
             device,
             quirks_mode,
             stylesheets: StylistStylesheetSet::new(),
             cascade_data: Default::default(),
+            author_styles_enabled: AuthorStylesEnabled::Yes,
             rule_tree: RuleTree::new(),
             num_rebuilds: 0,
         }
     }
 
     /// Returns the cascade data for the author level.
     #[inline]
     pub fn author_cascade_data(&self) -> &CascadeData {
@@ -588,17 +602,17 @@ impl Stylist {
     /// FIXME(emilio): Eventually it'd be nice for this to become more
     /// fine-grained.
     pub fn force_stylesheet_origins_dirty(&mut self, origins: OriginSet) {
         self.stylesheets.force_dirty(origins)
     }
 
     /// Sets whether author style is enabled or not.
     pub fn set_author_styles_enabled(&mut self, enabled: AuthorStylesEnabled) {
-        self.stylesheets.set_author_styles_enabled(enabled);
+        self.author_styles_enabled = enabled;
     }
 
     /// Returns whether we've recorded any stylesheet change so far.
     pub fn stylesheets_have_changed(&self) -> bool {
         self.stylesheets.has_changed()
     }
 
     /// Appends a new stylesheet to the current set.
@@ -1216,18 +1230,21 @@ impl Stylist {
 
         let rule_hash_target = element.rule_hash_target();
 
         debug!("Determining if style is shareable: pseudo: {}",
                pseudo_element.is_some());
 
         let only_default_rules =
             rule_inclusion == RuleInclusion::DefaultOnly;
-        let matches_user_and_author_rules =
+        let matches_user_rules =
             rule_hash_target.matches_user_and_author_rules();
+        let matches_author_rules =
+            matches_user_rules &&
+            self.author_styles_enabled == AuthorStylesEnabled::Yes;
 
         // Step 1: Normal user-agent rules.
         if let Some(map) = self.cascade_data.user_agent.cascade_data.normal_rules(pseudo_element) {
             map.get_all_matching_rules(
                 element,
                 rule_hash_target,
                 applicable_declarations,
                 context,
@@ -1255,17 +1272,17 @@ impl Stylist {
         // NB: the following condition, although it may look somewhat
         // inaccurate, would be equivalent to something like:
         //
         //     element.matches_user_and_author_rules() ||
         //     (is_implemented_pseudo &&
         //      rule_hash_target.matches_user_and_author_rules())
         //
         // Which may be more what you would probably expect.
-        if matches_user_and_author_rules {
+        if matches_user_rules {
             // Step 3a: User normal rules.
             if let Some(map) = self.cascade_data.user.normal_rules(pseudo_element) {
                 map.get_all_matching_rules(
                     element,
                     rule_hash_target,
                     applicable_declarations,
                     context,
                     flags_setter,
@@ -1275,17 +1292,17 @@ impl Stylist {
         }
 
         // Step 3b: XBL / Shadow DOM rules.
         //
         // TODO(emilio): Cascade order here is wrong for Shadow DOM. In
         // particular, normally document rules override ::slotted() rules, but
         // for !important it should be the other way around. So probably we need
         // to add some sort of AuthorScoped cascade level or something.
-        if !only_default_rules {
+        if matches_author_rules && !only_default_rules {
             // Match slotted rules in reverse order, so that the outer slotted
             // rules come before the inner rules (and thus have less priority).
             let mut slots = SmallVec::<[_; 3]>::new();
             let mut current = rule_hash_target.assigned_slot();
             while let Some(slot) = current {
                 slots.push(slot);
                 current = slot.assigned_slot();
             }
@@ -1303,19 +1320,19 @@ impl Stylist {
                         );
                     }
                 });
             }
         }
 
         // FIXME(emilio): It looks very wrong to match XBL / Shadow DOM rules
         // even for getDefaultComputedStyle!
+        //
+        // Also, this doesn't account for the author_styles_enabled stuff.
         let cut_off_inheritance = element.each_xbl_stylist(|stylist| {
-            // ServoStyleSet::CreateXBLServoStyleSet() loads XBL style sheets
-            // under eAuthorSheetFeatures level.
             if let Some(map) = stylist.cascade_data.author.normal_rules(pseudo_element) {
                 // NOTE(emilio): This is needed because the XBL stylist may
                 // think it has a different quirks mode than the document.
                 //
                 // FIXME(emilio): this should use the same VisitedMatchingMode
                 // as `context`, write a test-case of :visited not working on
                 // Shadow DOM and fix it!
                 let mut matching_context = MatchingContext::new(
@@ -1332,19 +1349,17 @@ impl Stylist {
                     applicable_declarations,
                     &mut matching_context,
                     flags_setter,
                     CascadeLevel::AuthorNormal,
                 );
             }
         });
 
-        if matches_user_and_author_rules && !only_default_rules &&
-            !cut_off_inheritance
-        {
+        if matches_author_rules && !only_default_rules && !cut_off_inheritance {
             // Step 3c: Author normal rules.
             if let Some(map) = self.cascade_data.author.normal_rules(pseudo_element) {
                 map.get_all_matching_rules(
                     element,
                     rule_hash_target,
                     applicable_declarations,
                     context,
                     flags_setter,
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -130,25 +130,24 @@ use style::properties::{parse_one_declar
 use style::properties::animated_properties::AnimationValue;
 use style::properties::animated_properties::compare_property_priority;
 use style::rule_cache::RuleCacheConditions;
 use style::rule_tree::{CascadeLevel, StrongRuleNode, StyleSource};
 use style::selector_parser::{PseudoElementCascadeType, SelectorImpl};
 use style::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard, Locked};
 use style::string_cache::{Atom, WeakAtom};
 use style::style_adjuster::StyleAdjuster;
-use style::stylesheet_set::AuthorStylesEnabled;
 use style::stylesheets::{CssRule, CssRules, CssRuleType, CssRulesHelpers, DocumentRule};
 use style::stylesheets::{FontFeatureValuesRule, ImportRule, KeyframesRule, MediaRule};
 use style::stylesheets::{NamespaceRule, Origin, OriginSet, PageRule, StyleRule};
 use style::stylesheets::{StylesheetContents, SupportsRule};
 use style::stylesheets::StylesheetLoader as StyleStylesheetLoader;
 use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue};
 use style::stylesheets::supports_rule::parse_condition_or_declaration;
-use style::stylist::{add_size_of_ua_cache, RuleInclusion, Stylist};
+use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist};
 use style::thread_state;
 use style::timer::Timer;
 use style::traversal::DomTraversal;
 use style::traversal::resolve_style;
 use style::traversal_flags::{self, TraversalFlags};
 use style::values::{CustomIdent, KeyframesName};
 use style::values::animated::{Animate, Procedure, ToAnimatedZero};
 use style::values::computed::{Context, ToComputedValue};