diff options
Diffstat (limited to 'components/style/rule_tree/mod.rs')
-rw-r--r-- | components/style/rule_tree/mod.rs | 85 |
1 files changed, 42 insertions, 43 deletions
diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index e50382255ca..c8705165776 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -6,9 +6,10 @@ //! The rule tree. -use crate::applicable_declarations::ApplicableDeclarationList; +use crate::applicable_declarations::{ApplicableDeclarationList, CascadePriority}; use crate::properties::{LonghandIdSet, PropertyDeclarationBlock}; use crate::shared_lock::{Locked, StylesheetGuards}; +use crate::stylesheets::layer_rule::LayerOrder; use servo_arc::{Arc, ArcBorrow}; use smallvec::SmallVec; use std::io::{self, Write}; @@ -47,21 +48,22 @@ impl RuleTree { guards: &StylesheetGuards, ) -> StrongRuleNode where - I: Iterator<Item = (StyleSource, CascadeLevel)>, + I: Iterator<Item = (StyleSource, CascadePriority)>, { use self::CascadeLevel::*; let mut current = self.root().clone(); let mut found_important = false; - let mut important_author = SmallVec::<[(StyleSource, ShadowCascadeOrder); 4]>::new(); - - let mut important_user = SmallVec::<[StyleSource; 4]>::new(); - let mut important_ua = SmallVec::<[StyleSource; 4]>::new(); + let mut important_author = SmallVec::<[(StyleSource, CascadePriority); 4]>::new(); + let mut important_user = SmallVec::<[(StyleSource, CascadePriority); 4]>::new(); + let mut important_ua = SmallVec::<[(StyleSource, CascadePriority); 4]>::new(); let mut transition = None; - for (source, level) in iter { + for (source, priority) in iter { + let level = priority.cascade_level(); debug_assert!(!level.is_important(), "Important levels handled internally"); + let any_important = { let pdb = source.read(level.guard(guards)); pdb.any_important() @@ -70,13 +72,9 @@ impl RuleTree { if any_important { found_important = true; match level { - AuthorNormal { - shadow_cascade_order, - } => { - important_author.push((source.clone(), shadow_cascade_order)); - }, - UANormal => important_ua.push(source.clone()), - UserNormal => important_user.push(source.clone()), + AuthorNormal { .. } => important_author.push((source.clone(), priority.important())), + UANormal => important_ua.push((source.clone(), priority.important())), + UserNormal => important_user.push((source.clone(), priority.important())), _ => {}, }; } @@ -98,7 +96,7 @@ impl RuleTree { debug_assert!(transition.is_none()); transition = Some(source); } else { - current = current.ensure_child(self.root(), source, level); + current = current.ensure_child(self.root(), source, priority); } } @@ -110,10 +108,8 @@ impl RuleTree { // Insert important declarations, in order of increasing importance, // followed by any transition rule. // - // Inner shadow wins over same-tree, which wins over outer-shadow. - // - // We negate the shadow cascade order to preserve the right PartialOrd - // behavior. + // Important rules are sorted differently from unimportant ones by + // shadow order and cascade order. if !important_author.is_empty() && important_author.first().unwrap().1 != important_author.last().unwrap().1 { @@ -129,29 +125,27 @@ impl RuleTree { // inside the same chunk already sorted. Seems like we could try to // keep a SmallVec-of-SmallVecs with the chunks and just iterate the // outer in reverse. - important_author.sort_by_key(|&(_, order)| -order); + important_author.sort_by_key(|&(_, priority)| priority); } - for (source, shadow_cascade_order) in important_author.drain(..) { - current = current.ensure_child( - self.root(), - source, - AuthorImportant { - shadow_cascade_order: -shadow_cascade_order, - }, - ); + for (source, priority) in important_author.drain(..) { + current = current.ensure_child(self.root(), source, priority); } - for source in important_user.drain(..) { - current = current.ensure_child(self.root(), source, UserImportant); + for (source, priority) in important_user.drain(..) { + current = current.ensure_child(self.root(), source, priority); } - for source in important_ua.drain(..) { - current = current.ensure_child(self.root(), source, UAImportant); + for (source, priority) in important_ua.drain(..) { + current = current.ensure_child(self.root(), source, priority); } if let Some(source) = transition { - current = current.ensure_child(self.root(), source, Transitions); + current = current.ensure_child( + self.root(), + source, + CascadePriority::new(Transitions, LayerOrder::root()), + ); } current @@ -174,18 +168,18 @@ impl RuleTree { /// return the corresponding rule node representing the last inserted one. pub fn insert_ordered_rules<'a, I>(&self, iter: I) -> StrongRuleNode where - I: Iterator<Item = (StyleSource, CascadeLevel)>, + I: Iterator<Item = (StyleSource, CascadePriority)>, { self.insert_ordered_rules_from(self.root().clone(), iter) } fn insert_ordered_rules_from<'a, I>(&self, from: StrongRuleNode, iter: I) -> StrongRuleNode where - I: Iterator<Item = (StyleSource, CascadeLevel)>, + I: Iterator<Item = (StyleSource, CascadePriority)>, { let mut current = from; - for (source, level) in iter { - current = current.ensure_child(self.root(), source, level); + for (source, priority) in iter { + current = current.ensure_child(self.root(), source, priority); } current } @@ -197,6 +191,7 @@ impl RuleTree { pub fn update_rule_at_level( &self, level: CascadeLevel, + layer_order: LayerOrder, pdb: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>, path: &StrongRuleNode, guards: &StylesheetGuards, @@ -209,10 +204,10 @@ impl RuleTree { // First walk up until the first less-or-equally specific rule. let mut children = SmallVec::<[_; 10]>::new(); - while current.cascade_level() > level { + while current.cascade_priority().cascade_level() > level { children.push(( current.style_source().unwrap().clone(), - current.cascade_level(), + current.cascade_priority(), )); current = current.parent().unwrap().clone(); } @@ -227,7 +222,7 @@ impl RuleTree { // to special-case (isn't hard, it's just about removing the `if` and // special cases, and replacing them for a `while` loop, avoiding the // optimizations). - if current.cascade_level() == level { + if current.cascade_priority().cascade_level() == level { *important_rules_changed |= level.is_important(); let current_decls = current.style_source().unwrap().as_declarations(); @@ -267,7 +262,7 @@ impl RuleTree { current = current.ensure_child( self.root(), StyleSource::from_declarations(pdb.clone_arc()), - level, + CascadePriority::new(level, layer_order), ); *important_rules_changed = true; } @@ -276,7 +271,7 @@ impl RuleTree { current = current.ensure_child( self.root(), StyleSource::from_declarations(pdb.clone_arc()), - level, + CascadePriority::new(level, layer_order), ); } } @@ -312,7 +307,10 @@ impl RuleTree { let mut children = SmallVec::<[_; 10]>::new(); for node in iter { if !node.cascade_level().is_animation() { - children.push((node.style_source().unwrap().clone(), node.cascade_level())); + children.push(( + node.style_source().unwrap().clone(), + node.cascade_priority(), + )); } last = node; } @@ -336,6 +334,7 @@ impl RuleTree { let mut dummy = false; self.update_rule_at_level( CascadeLevel::Transitions, + LayerOrder::root(), Some(pdb.borrow_arc()), path, guards, |