From 97ce9ed5b08f7b1c7c6cd71a9499068b8bd2ae4e Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Thu, 27 Apr 2017 12:35:12 +0900 Subject: [PATCH] Add SMIL override cascade level --- components/style/dom.rs | 5 +++++ components/style/matching.rs | 6 +++++- components/style/rule_tree/mod.rs | 28 +++++++++++++++++++++------- components/style/stylist.rs | 24 ++++++++++++++++++------ 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/components/style/dom.rs b/components/style/dom.rs index 645db055be7..c937dba8bb3 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -319,6 +319,11 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + /// Get this element's style attribute. fn style_attribute(&self) -> Option<&Arc>>; + /// Get this element's SMIL override declarations. + fn get_smil_override(&self) -> Option<&Arc>> { + None + } + /// Get this element's animation rules. fn get_animation_rules(&self, _pseudo: Option<&PseudoElement>) -> AnimationRules { AnimationRules(None, None) diff --git a/components/style/matching.rs b/components/style/matching.rs index 201f6c50878..e1e64906f1c 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -882,6 +882,7 @@ pub trait MatchMethods : TElement { let stylist = &context.shared.stylist; let style_attribute = self.style_attribute(); + let smil_override = self.get_smil_override(); let animation_rules = self.get_animation_rules(None); let mut rule_nodes_changed = false; let bloom = context.thread_local.bloom_filter.filter(); @@ -895,6 +896,7 @@ pub trait MatchMethods : TElement { *relations = stylist.push_applicable_declarations(self, Some(bloom), style_attribute, + smil_override, animation_rules, None, &context.shared.guards, @@ -952,7 +954,9 @@ pub trait MatchMethods : TElement { }; stylist.push_applicable_declarations(self, Some(bloom_filter), - None, pseudo_animation_rules, + None, + None, + pseudo_animation_rules, Some(&pseudo), &guards, &mut applicable_declarations, diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index 128de7a67e2..1ec22e8b277 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -254,19 +254,19 @@ impl RuleTree { path.parent().unwrap().clone() } - /// Returns new rule node without Animations and Transitions level rules. + /// Returns new rule node without rules from declarative animations. pub fn remove_animation_and_transition_rules(&self, path: &StrongRuleNode) -> StrongRuleNode { - // Return a clone if there is neither animation nor transition level. + // Return a clone if there are no animation rules. if !path.has_animation_or_transition_rules() { return path.clone(); } - let iter = path.self_and_ancestors().take_while(|node| node.cascade_level() >= CascadeLevel::Animations); + let iter = path.self_and_ancestors().take_while( + |node| node.cascade_level() >= CascadeLevel::SMILOverride); let mut last = path; let mut children = vec![]; for node in iter { - if node.cascade_level() != CascadeLevel::Animations && - node.cascade_level() != CascadeLevel::Transitions { + if node.cascade_level().is_animation() { children.push((node.get().source.clone().unwrap(), node.cascade_level())); } last = node; @@ -301,6 +301,8 @@ pub enum CascadeLevel { AuthorNormal, /// Style attribute normal rules. StyleAttributeNormal, + /// SVG SMIL animations. + SMILOverride, /// CSS animations and script-generated animations. Animations, /// Author-supplied important rules. @@ -333,6 +335,7 @@ impl CascadeLevel { match *self { CascadeLevel::Transitions | CascadeLevel::Animations | + CascadeLevel::SMILOverride | CascadeLevel::StyleAttributeNormal | CascadeLevel::StyleAttributeImportant => true, _ => false, @@ -362,6 +365,17 @@ impl CascadeLevel { Importance::Normal } } + + /// Returns whether this cascade level represents an animation rules. + #[inline] + pub fn is_animation(&self) -> bool { + match *self { + CascadeLevel::SMILOverride | + CascadeLevel::Animations | + CascadeLevel::Transitions => true, + _ => false, + } + } } struct RuleNode { @@ -780,8 +794,8 @@ impl StrongRuleNode { /// Returns true if there is either animation or transition level rule. pub fn has_animation_or_transition_rules(&self) -> bool { self.self_and_ancestors() - .take_while(|node| node.cascade_level() >= CascadeLevel::Animations) - .any(|node| matches!(node.cascade_level(), CascadeLevel::Animations | CascadeLevel::Transitions)) + .take_while(|node| node.cascade_level() >= CascadeLevel::SMILOverride) + .any(|node| node.cascade_level().is_animation()) } } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 8ae9998c4cb..af0a4eb0e8a 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -510,6 +510,7 @@ impl Stylist { self.push_applicable_declarations(element, + None, None, None, AnimationRules(None, None), @@ -631,6 +632,7 @@ impl Stylist { element: &E, parent_bf: Option<&BloomFilter>, style_attribute: Option<&Arc>>, + smil_override: Option<&Arc>>, animation_rules: AnimationRules, pseudo_element: Option<&PseudoElement>, guards: &StylesheetGuards, @@ -711,7 +713,17 @@ impl Stylist { debug!("style attr: {:?}", relations); - // Step 5: Animations. + // Step 5: SMIL override. + // Declarations from SVG SMIL animation elements. + if let Some(so) = smil_override { + Push::push( + applicable_declarations, + ApplicableDeclarationBlock::from_declarations(so.clone(), + CascadeLevel::SMILOverride)); + } + debug!("SMIL: {:?}", relations); + + // Step 6: Animations. // The animations sheet (CSS animations, script-generated animations, // and CSS transitions that are no longer tied to CSS markup) if let Some(anim) = animation_rules.0 { @@ -722,7 +734,7 @@ impl Stylist { } debug!("animation: {:?}", relations); - // Step 6: Author-supplied `!important` rules. + // Step 7: Author-supplied `!important` rules. map.author.get_all_matching_rules(element, parent_bf, applicable_declarations, @@ -732,7 +744,7 @@ impl Stylist { debug!("author important: {:?}", relations); - // Step 7: `!important` style attributes. + // Step 8: `!important` style attributes. if let Some(sa) = style_attribute { if sa.read_with(guards.author).any_important() { relations |= AFFECTED_BY_STYLE_ATTRIBUTE; @@ -745,7 +757,7 @@ impl Stylist { debug!("style attr important: {:?}", relations); - // Step 8: User `!important` rules. + // Step 9: User `!important` rules. map.user.get_all_matching_rules(element, parent_bf, applicable_declarations, @@ -758,7 +770,7 @@ impl Stylist { debug!("skipping non-agent rules"); } - // Step 9: UA `!important` rules. + // Step 10: UA `!important` rules. map.user_agent.get_all_matching_rules(element, parent_bf, applicable_declarations, @@ -768,7 +780,7 @@ impl Stylist { debug!("UA important: {:?}", relations); - // Step 10: Transitions. + // Step 11: Transitions. // The transitions sheet (CSS transitions that are tied to CSS markup) if let Some(anim) = animation_rules.1 { Push::push(