diff --git a/components/style/data.rs b/components/style/data.rs index 6e0feb35b68..41a618dd32e 100644 --- a/components/style/data.rs +++ b/components/style/data.rs @@ -6,12 +6,12 @@ use context::SharedStyleContext; use dom::TElement; -use properties::ComputedValues; +use properties::{ComputedValues, PropertyDeclarationBlock}; use properties::longhands::display::computed_value as display; use restyle_hints::{HintComputationContext, RestyleReplacements, RestyleHint}; use rule_tree::StrongRuleNode; use selector_parser::{EAGER_PSEUDO_COUNT, PseudoElement, RestyleDamage}; -use shared_lock::StylesheetGuards; +use shared_lock::{Locked, StylesheetGuards}; use std::fmt; use stylearc::Arc; use traversal::TraversalFlags; @@ -558,4 +558,17 @@ impl ElementData { pub fn restyle_mut(&mut self) -> &mut RestyleData { self.get_restyle_mut().expect("Calling restyle_mut without RestyleData") } + + /// Returns SMIL overriden value if exists. + pub fn get_smil_override(&self) -> Option<&Arc>> { + if cfg!(feature = "servo") { + // Servo has no knowledge of a SMIL rule, so just avoid looking for it. + return None; + } + + match self.get_styles() { + Some(s) => s.primary.rules.get_smil_animation_rule(), + None => None, + } + } } diff --git a/components/style/matching.rs b/components/style/matching.rs index e0a8e4ec755..f0e23baecff 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -736,30 +736,32 @@ 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(); - let bloom = context.thread_local.bloom_filter.filter(); + { + let smil_override = data.get_smil_override(); + let animation_rules = self.get_animation_rules(); + let bloom = context.thread_local.bloom_filter.filter(); - let map = &mut context.thread_local.selector_flags; - let mut set_selector_flags = |element: &Self, flags: ElementSelectorFlags| { - self.apply_selector_flags(map, element, flags); - }; + let map = &mut context.thread_local.selector_flags; + let mut set_selector_flags = |element: &Self, flags: ElementSelectorFlags| { + self.apply_selector_flags(map, element, flags); + }; - let mut matching_context = - MatchingContext::new(MatchingMode::Normal, Some(bloom)); + let mut matching_context = + MatchingContext::new(MatchingMode::Normal, Some(bloom)); - // Compute the primary rule node. - stylist.push_applicable_declarations(self, - implemented_pseudo.as_ref(), - style_attribute, - smil_override, - animation_rules, - &mut applicable_declarations, - &mut matching_context, - &mut set_selector_flags); + // Compute the primary rule node. + stylist.push_applicable_declarations(self, + implemented_pseudo.as_ref(), + style_attribute, + smil_override, + animation_rules, + &mut applicable_declarations, + &mut matching_context, + &mut set_selector_flags); - *relations = matching_context.relations; + *relations = matching_context.relations; + } let primary_rule_node = compute_rule_node::(stylist.rule_tree(), diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index bfc6c19bf96..d5c44329b72 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -1128,6 +1128,30 @@ impl StrongRuleNode { } result } + + /// Returns PropertyDeclarationBlock for this node. + /// This function must be called only for animation level node. + fn get_animation_style(&self) -> &Arc> { + debug_assert!(self.cascade_level().is_animation(), + "The cascade level should be an animation level"); + match *self.style_source().unwrap() { + StyleSource::Declarations(ref block) => block, + StyleSource::Style(_) => unreachable!("animating style should not be a style rule"), + } + } + + /// Returns SMIL override declaration block if exists. + pub fn get_smil_animation_rule(&self) -> Option<&Arc>> { + if cfg!(feature = "servo") { + // Servo has no knowledge of a SMIL rule, so just avoid looking for it. + return None; + } + + self.self_and_ancestors() + .take_while(|node| node.cascade_level() >= CascadeLevel::SMILOverride) + .find(|node| node.cascade_level() == CascadeLevel::SMILOverride) + .map(|node| node.get_animation_style()) + } } /// An iterator over a rule node and its ancestors.