aboutsummaryrefslogtreecommitdiffstats
path: root/components/style/rule_tree/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/style/rule_tree/mod.rs')
-rw-r--r--components/style/rule_tree/mod.rs85
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,