Use animation values that have been processed during animation-only restyle for normal restyle.

This commit is contained in:
Hiroyuki Ikezoe 2017-05-24 11:11:56 +09:00
parent 35e0e3aa11
commit 4935d972e5
7 changed files with 76 additions and 47 deletions

View file

@ -6,7 +6,7 @@
use context::SharedStyleContext;
use dom::TElement;
use properties::{ComputedValues, PropertyDeclarationBlock};
use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock};
use properties::longhands::display::computed_value as display;
use restyle_hints::{HintComputationContext, RestyleReplacements, RestyleHint};
use rule_tree::StrongRuleNode;
@ -571,4 +571,16 @@ impl ElementData {
None => None,
}
}
/// Returns AnimationRules that has processed during animation-only restyles.
pub fn get_animation_rules(&self) -> AnimationRules {
if cfg!(feature = "servo") {
return AnimationRules(None, None)
}
match self.get_styles() {
Some(s) => s.primary.rules.get_animation_rules(),
None => AnimationRules(None, None),
}
}
}

View file

@ -13,7 +13,7 @@ use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use data::ElementData;
use element_state::ElementState;
use font_metrics::FontMetricsProvider;
use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock};
use properties::{ComputedValues, PropertyDeclarationBlock};
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValue;
#[cfg(feature = "gecko")] use properties::animated_properties::TransitionProperty;
use rule_tree::CascadeLevel;
@ -334,11 +334,6 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
None
}
/// Get this element's animation rules.
fn get_animation_rules(&self) -> AnimationRules {
AnimationRules(None, None)
}
/// Get this element's animation rule by the cascade level.
fn get_animation_rule_by_cascade(&self,
_cascade_level: CascadeLevel)

View file

@ -57,7 +57,7 @@ use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS;
use gecko_bindings::sugar::ownership::HasArcFFI;
use logical_geometry::WritingMode;
use media_queries::Device;
use properties::{AnimationRules, ComputedValues, parse_style_attribute};
use properties::{ComputedValues, parse_style_attribute};
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
use properties::animated_properties::{AnimationValue, AnimationValueMap, TransitionProperty};
use properties::style_structs::Font;
@ -613,11 +613,6 @@ impl<'le> TElement for GeckoElement<'le> {
declarations.map(|s| s.as_arc_opt()).unwrap_or(None)
}
fn get_animation_rules(&self) -> AnimationRules {
AnimationRules(self.get_animation_rule(),
self.get_transition_rule())
}
fn get_animation_rule_by_cascade(&self, cascade_level: ServoCascadeLevel)
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
match cascade_level {

View file

@ -254,7 +254,7 @@ trait PrivateMatchMethods: TElement {
// We could make that a bit better if the complexity cost is not too
// big, but given further restyles are posted directly to
// pseudo-elements, it doesn't seem worth the effort at a glance.
if pseudo.is_eager() && self.get_animation_rules().is_empty() {
if pseudo.is_eager() && primary_style.rules.get_animation_rules().is_empty() {
let parent = self.parent_element().unwrap();
let parent_data = parent.borrow_data().unwrap();
let pseudo_style =
@ -692,38 +692,39 @@ pub trait MatchMethods : TElement {
let pseudo_style =
parent_data.styles().pseudos.get(&pseudo).unwrap();
let mut rules = pseudo_style.rules.clone();
let animation_rules = self.get_animation_rules();
{
let animation_rules = data.get_animation_rules();
// Handle animations here.
if let Some(animation_rule) = animation_rules.0 {
let animation_rule_node =
context.shared.stylist.rule_tree()
.update_rule_at_level(CascadeLevel::Animations,
Some(&animation_rule),
&mut rules,
&context.shared.guards);
if let Some(node) = animation_rule_node {
rules = node;
// Handle animations here.
if let Some(animation_rule) = animation_rules.0 {
let animation_rule_node =
context.shared.stylist.rule_tree()
.update_rule_at_level(CascadeLevel::Animations,
Some(&animation_rule),
&mut rules,
&context.shared.guards);
if let Some(node) = animation_rule_node {
rules = node;
}
}
if let Some(animation_rule) = animation_rules.1 {
let animation_rule_node =
context.shared.stylist.rule_tree()
.update_rule_at_level(CascadeLevel::Transitions,
Some(&animation_rule),
&mut rules,
&context.shared.guards);
if let Some(node) = animation_rule_node {
rules = node;
}
}
}
if let Some(animation_rule) = animation_rules.1 {
let animation_rule_node =
context.shared.stylist.rule_tree()
.update_rule_at_level(CascadeLevel::Transitions,
Some(&animation_rule),
&mut rules,
&context.shared.guards);
if let Some(node) = animation_rule_node {
rules = node;
}
}
let important_rules_changed =
self.has_animations() &&
data.has_styles() &&
data.important_rules_are_different(&rules,
&context.shared.guards);
&context.shared.guards);
return RulesMatchedResult {
rule_nodes_changed: data.set_primary_rules(rules),
@ -738,10 +739,9 @@ pub trait MatchMethods : TElement {
let style_attribute = self.style_attribute();
{
let smil_override = data.get_smil_override();
let animation_rules = self.get_animation_rules();
let animation_rules = data.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);

View file

@ -23,10 +23,10 @@ use super::*;
///
/// The first one is for Animation cascade level, and the second one is for
/// Transition cascade level.
pub struct AnimationRules(pub Option<Arc<Locked<PropertyDeclarationBlock>>>,
pub Option<Arc<Locked<PropertyDeclarationBlock>>>);
pub struct AnimationRules<'a>(pub Option<&'a Arc<Locked<PropertyDeclarationBlock>>>,
pub Option<&'a Arc<Locked<PropertyDeclarationBlock>>>);
impl AnimationRules {
impl<'a> AnimationRules<'a> {
/// Returns whether these animation rules represents an actual rule or not.
pub fn is_empty(&self) -> bool {
self.0.is_none() && self.1.is_none()

View file

@ -8,7 +8,7 @@
#[cfg(feature = "servo")]
use heapsize::HeapSizeOf;
use properties::{Importance, LonghandIdSet, PropertyDeclarationBlock};
use properties::{AnimationRules, Importance, LonghandIdSet, PropertyDeclarationBlock};
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
use smallvec::SmallVec;
use std::io::{self, Write};
@ -1152,6 +1152,32 @@ impl StrongRuleNode {
.find(|node| node.cascade_level() == CascadeLevel::SMILOverride)
.map(|node| node.get_animation_style())
}
/// Returns AnimationRules that has processed during animation-only restyles.
pub fn get_animation_rules(&self) -> AnimationRules {
if cfg!(feature = "servo") {
return AnimationRules(None, None);
}
let mut animation = None;
let mut transition = None;
for node in self.self_and_ancestors()
.take_while(|node| node.cascade_level() >= CascadeLevel::Animations) {
match node.cascade_level() {
CascadeLevel::Animations => {
debug_assert!(animation.is_none());
animation = Some(node.get_animation_style())
},
CascadeLevel::Transitions => {
debug_assert!(transition.is_none());
transition = Some(node.get_animation_style())
},
_ => {},
}
}
AnimationRules(animation, transition)
}
}
/// An iterator over a rule node and its ancestors.

View file

@ -943,7 +943,7 @@ impl Stylist {
if let Some(anim) = animation_rules.0 {
Push::push(
applicable_declarations,
ApplicableDeclarationBlock::from_declarations(anim,
ApplicableDeclarationBlock::from_declarations(anim.clone(),
CascadeLevel::Animations));
}
debug!("animation: {:?}", context.relations);
@ -961,7 +961,8 @@ impl Stylist {
if let Some(anim) = animation_rules.1 {
Push::push(
applicable_declarations,
ApplicableDeclarationBlock::from_declarations(anim, CascadeLevel::Transitions));
ApplicableDeclarationBlock::from_declarations(anim.clone(),
CascadeLevel::Transitions));
}
debug!("transition: {:?}", context.relations);
debug!("push_applicable_declarations: shareable: {:?}", context.relations);