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