Bug 1436782: Cascade pres hints after normal user rules. r?bholley draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 09 Feb 2018 20:18:23 +0100
changeset 753255 23c8b93228783491710110cf1622bb8e2394b549
parent 753254 803c061bd33fa418c1995cfd3cd05b62a8edf5fa
child 753256 80fab259e94d17ff9045b028c9b154614149c90e
push id98536
push userbmo:emilio@crisal.io
push dateFri, 09 Feb 2018 21:48:04 +0000
reviewersbholley
bugs1436782
milestone60.0a1
Bug 1436782: Cascade pres hints after normal user rules. r?bholley Per https://drafts.csswg.org/css-cascade/#preshint. This was causing failures in the link color reftests. MozReview-Commit-ID: 9iwEqPBw4CF
servo/components/style/rule_tree/mod.rs
servo/components/style/stylist.rs
--- a/servo/components/style/rule_tree/mod.rs
+++ b/servo/components/style/rule_tree/mod.rs
@@ -467,32 +467,33 @@ impl RuleTree {
     }
 }
 
 /// The number of RuleNodes added to the free list before we will consider
 /// doing a GC when calling maybe_gc().  (The value is copied from Gecko,
 /// where it likely did not result from a rigorous performance analysis.)
 const RULE_TREE_GC_INTERVAL: usize = 300;
 
-/// The cascade level these rules are relevant at, as per[1].
+/// The cascade level these rules are relevant at, as per[1] and [2].
 ///
 /// The order of variants declared here is significant, and must be in
 /// _ascending_ order of precedence.
 ///
 /// [1]: https://drafts.csswg.org/css-cascade/#cascade-origin
+/// [2]: https://drafts.csswg.org/css-cascade/#preshint
 #[repr(u8)]
 #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)]
 #[cfg_attr(feature = "servo", derive(MallocSizeOf))]
 pub enum CascadeLevel {
     /// Normal User-Agent rules.
     UANormal = 0,
+    /// User normal rules.
+    UserNormal,
     /// Presentational hints.
     PresHints,
-    /// User normal rules.
-    UserNormal,
     /// Author normal rules.
     AuthorNormal,
     /// Style attribute normal rules.
     StyleAttributeNormal,
     /// SVG SMIL animations.
     SMILOverride,
     /// CSS animations and script-generated animations.
     Animations,
--- a/servo/components/style/stylist.rs
+++ b/servo/components/style/stylist.rs
@@ -1199,32 +1199,16 @@ impl Stylist {
                 rule_hash_target,
                 applicable_declarations,
                 context,
                 flags_setter,
                 CascadeLevel::UANormal
             );
         }
 
-        if pseudo_element.is_none() && !only_default_rules {
-            // Step 2: Presentational hints.
-            let length_before_preshints = applicable_declarations.len();
-            element.synthesize_presentational_hints_for_legacy_attributes(
-                context.visited_handling(),
-                applicable_declarations
-            );
-            if applicable_declarations.len() != length_before_preshints {
-                if cfg!(debug_assertions) {
-                    for declaration in &applicable_declarations[length_before_preshints..] {
-                        assert_eq!(declaration.level(), CascadeLevel::PresHints);
-                    }
-                }
-            }
-        }
-
         // 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.
@@ -1237,16 +1221,35 @@ impl Stylist {
                     applicable_declarations,
                     context,
                     flags_setter,
                     CascadeLevel::UserNormal,
                 );
             }
         }
 
+        if pseudo_element.is_none() && !only_default_rules {
+            // Step 3: Presentational hints.
+            //
+            // These go before author rules, but after user rules, see:
+            // https://drafts.csswg.org/css-cascade/#preshint
+            let length_before_preshints = applicable_declarations.len();
+            element.synthesize_presentational_hints_for_legacy_attributes(
+                context.visited_handling(),
+                applicable_declarations
+            );
+            if applicable_declarations.len() != length_before_preshints {
+                if cfg!(debug_assertions) {
+                    for declaration in &applicable_declarations[length_before_preshints..] {
+                        assert_eq!(declaration.level(), CascadeLevel::PresHints);
+                    }
+                }
+            }
+        }
+
         // 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 matches_author_rules && !only_default_rules {
             // Match slotted rules in reverse order, so that the outer slotted