From 19aea7ea78ca0cb26287812765febcee71a84175 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Tue, 24 Jan 2017 15:34:08 +0800 Subject: [PATCH] Bug 1317209 - Part 5: Support transition cascade level. r=emilio Support a new enum, EffectCompositor_CascadeLevel, which is an equivalent of EffectCompositor::CascadeLevel in Gecko. --- components/style/dom.rs | 12 ++++++---- components/style/gecko/wrapper.rs | 12 ++++++---- components/style/gecko_bindings/bindings.rs | 4 +++- .../style/gecko_bindings/structs_debug.rs | 6 +++++ .../style/gecko_bindings/structs_release.rs | 6 +++++ components/style/matching.rs | 8 +++---- components/style/stylist.rs | 22 ++++++++++++++----- 7 files changed, 52 insertions(+), 18 deletions(-) diff --git a/components/style/dom.rs b/components/style/dom.rs index 1019805cf2a9..8a023e764c3e 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -227,6 +227,11 @@ pub trait PresentationalHintsSynthetizer { where V: Push; } +/// The animation rules. The first one is for Animation cascade level, and the second one is for +/// Transition cascade level. +pub struct AnimationRules(pub Option>>, + pub Option>>); + /// The element trait, the main abstraction the style crate acts over. pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer { /// The concrete node type. @@ -248,10 +253,9 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre /// Get this element's style attribute. fn style_attribute(&self) -> Option<&Arc>>; - /// Get this element's animation rule. - fn get_animation_rule(&self, _pseudo: Option<&PseudoElement>) - -> Option>> { - None + /// Get this element's animation rules. + fn get_animation_rules(&self, _pseudo: Option<&PseudoElement>) -> AnimationRules { + AnimationRules(None, None) } /// Get this element's state, for non-tree-structural pseudos. diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 500dc92d7ccb..6456bfea90cb 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -16,7 +16,7 @@ use atomic_refcell::AtomicRefCell; use data::ElementData; -use dom::{LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode}; +use dom::{AnimationRules, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode}; use dom::{OpaqueNode, PresentationalHintsSynthetizer}; use element_state::ElementState; use error_reporting::StdoutErrorReporter; @@ -35,6 +35,7 @@ use gecko_bindings::bindings::Gecko_GetStyleContext; use gecko_bindings::structs; use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode}; use gecko_bindings::structs::{nsIAtom, nsIContent, nsStyleContext}; +use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; use gecko_bindings::structs::NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO; use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; use parking_lot::RwLock; @@ -336,10 +337,13 @@ impl<'le> TElement for GeckoElement<'le> { declarations.map(|s| s.as_arc_opt()).unwrap_or(None) } - fn get_animation_rule(&self, pseudo: Option<&PseudoElement>) - -> Option>> { + fn get_animation_rules(&self, pseudo: Option<&PseudoElement>) -> AnimationRules { let atom_ptr = pseudo.map(|p| p.as_atom().as_ptr()).unwrap_or(ptr::null_mut()); - unsafe { Gecko_GetAnimationRule(self.0, atom_ptr) }.into_arc_opt() + unsafe { + AnimationRules( + Gecko_GetAnimationRule(self.0, atom_ptr, CascadeLevel::Animations).into_arc_opt(), + Gecko_GetAnimationRule(self.0, atom_ptr, CascadeLevel::Transitions).into_arc_opt()) + } } fn get_state(&self) -> ElementState { diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index 37d4654a0495..2c13323bd831 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -3,6 +3,7 @@ pub use nsstring::{nsACString, nsAString}; type nsACString_internal = nsACString; type nsAString_internal = nsAString; +use gecko_bindings::structs::EffectCompositor_CascadeLevel; use gecko_bindings::structs::RawGeckoDocument; use gecko_bindings::structs::RawGeckoElement; use gecko_bindings::structs::RawGeckoNode; @@ -503,7 +504,8 @@ extern "C" { } extern "C" { pub fn Gecko_GetAnimationRule(element: RawGeckoElementBorrowed, - aAtom: *mut nsIAtom) + aAtom: *mut nsIAtom, + aCascadeLevel: EffectCompositor_CascadeLevel) -> RawServoDeclarationBlockStrong; } extern "C" { diff --git a/components/style/gecko_bindings/structs_debug.rs b/components/style/gecko_bindings/structs_debug.rs index 6204b548e339..51c53a59930b 100644 --- a/components/style/gecko_bindings/structs_debug.rs +++ b/components/style/gecko_bindings/structs_debug.rs @@ -3573,6 +3573,12 @@ pub mod root { impl Clone for StyleComplexColor { fn clone(&self) -> Self { *self } } + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum EffectCompositor_CascadeLevel { + Animations = 0, + Transitions = 1, + } #[repr(C)] #[derive(Debug)] pub struct PropertyStyleAnimationValuePair { diff --git a/components/style/gecko_bindings/structs_release.rs b/components/style/gecko_bindings/structs_release.rs index 34fa11b9a31a..64a5967f7a0f 100644 --- a/components/style/gecko_bindings/structs_release.rs +++ b/components/style/gecko_bindings/structs_release.rs @@ -3544,6 +3544,12 @@ pub mod root { impl Clone for StyleComplexColor { fn clone(&self) -> Self { *self } } + #[repr(u32)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum EffectCompositor_CascadeLevel { + Animations = 0, + Transitions = 1, + } #[repr(C)] #[derive(Debug)] pub struct PropertyStyleAnimationValuePair { diff --git a/components/style/matching.rs b/components/style/matching.rs index 939af246c3e8..11c1a85b382b 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -589,14 +589,14 @@ pub trait MatchMethods : TElement { let mut applicable_declarations: Vec = Vec::with_capacity(16); let stylist = &context.shared.stylist; let style_attribute = self.style_attribute(); - let animation_rule = self.get_animation_rule(None); + let animation_rules = self.get_animation_rules(None); // Compute the primary rule node. let mut primary_relations = stylist.push_applicable_declarations(self, parent_bf, style_attribute, - animation_rule, + animation_rules, None, &mut applicable_declarations, MatchingReason::ForStyling); @@ -606,9 +606,9 @@ pub trait MatchMethods : TElement { let mut per_pseudo: PseudoRuleNodes = HashMap::with_hasher(Default::default()); SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| { debug_assert!(applicable_declarations.is_empty()); - let pseudo_animation_rule = self.get_animation_rule(Some(&pseudo)); + let pseudo_animation_rules = self.get_animation_rules(Some(&pseudo)); stylist.push_applicable_declarations(self, parent_bf, None, - pseudo_animation_rule, + pseudo_animation_rules, Some(&pseudo.clone()), &mut applicable_declarations, MatchingReason::ForStyling); diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 3d1291788f09..4d8e3eb32f90 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -8,7 +8,7 @@ use {Atom, LocalName}; use data::ComputedStyle; -use dom::{PresentationalHintsSynthetizer, TElement}; +use dom::{AnimationRules, PresentationalHintsSynthetizer, TElement}; use error_reporting::StdoutErrorReporter; use keyframes::KeyframesAnimation; use media_queries::Device; @@ -21,7 +21,7 @@ use rule_tree::{RuleTree, StrongRuleNode, StyleSource}; use selector_parser::{ElementExt, SelectorImpl, PseudoElement, Snapshot}; use selectors::Element; use selectors::bloom::BloomFilter; -use selectors::matching::AFFECTED_BY_ANIMATIONS; +use selectors::matching::{AFFECTED_BY_ANIMATIONS, AFFECTED_BY_TRANSITIONS}; use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS}; use selectors::matching::{MatchingReason, StyleRelations, matches_complex_selector}; use selectors::parser::{Selector, SimpleSelector, LocalName as LocalNameSelector, ComplexSelector}; @@ -387,7 +387,7 @@ impl Stylist { self.push_applicable_declarations(element, None, None, - None, + AnimationRules(None, None), Some(pseudo), &mut declarations, MatchingReason::ForStyling); @@ -492,7 +492,7 @@ impl Stylist { element: &E, parent_bf: Option<&BloomFilter>, style_attribute: Option<&Arc>>, - animation_rule: Option>>, + animation_rules: AnimationRules, pseudo_element: Option<&PseudoElement>, applicable_declarations: &mut V, reason: MatchingReason) -> StyleRelations @@ -564,7 +564,9 @@ impl Stylist { debug!("style attr: {:?}", relations); // Step 5: Animations. - if let Some(anim) = animation_rule { + // 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 { relations |= AFFECTED_BY_ANIMATIONS; Push::push( applicable_declarations, @@ -617,6 +619,16 @@ impl Stylist { debug!("UA important: {:?}", relations); + // Step 10: Transitions. + // The transitions sheet (CSS transitions that are tied to CSS markup) + if let Some(anim) = animation_rules.1 { + relations |= AFFECTED_BY_TRANSITIONS; + Push::push( + applicable_declarations, + ApplicableDeclarationBlock::from_declarations(anim.clone(), Importance::Normal)); + } + debug!("transition: {:?}", relations); + debug!("push_applicable_declarations: shareable: {:?}", relations); relations