mirror of
https://github.com/servo/servo.git
synced 2025-06-22 16:18:59 +01:00
style: Undo the optimization for grabbing animation rules from the style data.
This is unfortunate, but for now it complicates things, I would like not needing a ElementData to get the style of an Element in order to fix all the getDefaultComputedStyle bugs. MozReview-Commit-ID: LZvsdFEqrDE
This commit is contained in:
parent
95a2ac51c4
commit
cc94a8b7cb
5 changed files with 51 additions and 86 deletions
|
@ -8,11 +8,11 @@ use arrayvec::ArrayVec;
|
||||||
use context::SharedStyleContext;
|
use context::SharedStyleContext;
|
||||||
use dom::TElement;
|
use dom::TElement;
|
||||||
use invalidation::element::restyle_hints::RestyleHint;
|
use invalidation::element::restyle_hints::RestyleHint;
|
||||||
use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock};
|
use properties::ComputedValues;
|
||||||
use properties::longhands::display::computed_value as display;
|
use properties::longhands::display::computed_value as display;
|
||||||
use rule_tree::StrongRuleNode;
|
use rule_tree::StrongRuleNode;
|
||||||
use selector_parser::{EAGER_PSEUDO_COUNT, PseudoElement, RestyleDamage};
|
use selector_parser::{EAGER_PSEUDO_COUNT, PseudoElement, RestyleDamage};
|
||||||
use shared_lock::{Locked, StylesheetGuards};
|
use shared_lock::StylesheetGuards;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use stylearc::Arc;
|
use stylearc::Arc;
|
||||||
|
|
||||||
|
@ -402,29 +402,4 @@ impl ElementData {
|
||||||
pub fn clear_restyle_state(&mut self) {
|
pub fn clear_restyle_state(&mut self) {
|
||||||
self.restyle.clear();
|
self.restyle.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns SMIL overriden value if exists.
|
|
||||||
pub fn get_smil_override(&self) -> Option<&Arc<Locked<PropertyDeclarationBlock>>> {
|
|
||||||
if cfg!(feature = "servo") {
|
|
||||||
// Servo has no knowledge of a SMIL rule, so just avoid looking for it.
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.styles.get_primary() {
|
|
||||||
Some(v) => v.rules().get_smil_animation_rule(),
|
|
||||||
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.styles.get_primary() {
|
|
||||||
Some(v) => v.rules().get_animation_rules(),
|
|
||||||
None => AnimationRules(None, None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use data::ElementData;
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
use media_queries::Device;
|
use media_queries::Device;
|
||||||
use properties::{ComputedValues, PropertyDeclarationBlock};
|
use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock};
|
||||||
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValue;
|
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValue;
|
||||||
#[cfg(feature = "gecko")] use properties::animated_properties::TransitionProperty;
|
#[cfg(feature = "gecko")] use properties::animated_properties::TransitionProperty;
|
||||||
use rule_tree::CascadeLevel;
|
use rule_tree::CascadeLevel;
|
||||||
|
@ -379,6 +379,18 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the combined animation and transition rules.
|
||||||
|
fn get_animation_rules(&self) -> AnimationRules {
|
||||||
|
if !self.may_have_animations() {
|
||||||
|
return AnimationRules(None, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationRules(
|
||||||
|
self.get_animation_rule(),
|
||||||
|
self.get_transition_rule(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get this element's animation rule.
|
/// Get this element's animation rule.
|
||||||
fn get_animation_rule(&self)
|
fn get_animation_rule(&self)
|
||||||
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
-> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
|
|
|
@ -237,7 +237,7 @@ impl CascadeVisitedMode {
|
||||||
|
|
||||||
/// Returns whether there might be visited values that should be inserted
|
/// Returns whether there might be visited values that should be inserted
|
||||||
/// within the regular computed values based on the cascade mode.
|
/// within the regular computed values based on the cascade mode.
|
||||||
fn visited_values_for_insertion(&self) -> bool {
|
pub fn visited_values_for_insertion(&self) -> bool {
|
||||||
*self == CascadeVisitedMode::Unvisited
|
*self == CascadeVisitedMode::Unvisited
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ impl CascadeVisitedMode {
|
||||||
|
|
||||||
/// Returns whether the cascade should filter to only visited dependent
|
/// Returns whether the cascade should filter to only visited dependent
|
||||||
/// properties based on the cascade mode.
|
/// properties based on the cascade mode.
|
||||||
fn visited_dependent_only(&self) -> bool {
|
pub fn visited_dependent_only(&self) -> bool {
|
||||||
*self == CascadeVisitedMode::Visited
|
*self == CascadeVisitedMode::Visited
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
debug_assert!(pseudo.is_before_or_after());
|
debug_assert!(pseudo.is_before_or_after());
|
||||||
let parent = self.parent_element().unwrap();
|
let parent = self.parent_element().unwrap();
|
||||||
if !parent.may_have_animations() ||
|
if !parent.may_have_animations() ||
|
||||||
primary_inputs.rules().get_animation_rules().is_empty() {
|
self.get_animation_rules().is_empty() {
|
||||||
let parent_data = parent.borrow_data().unwrap();
|
let parent_data = parent.borrow_data().unwrap();
|
||||||
let pseudo_style =
|
let pseudo_style =
|
||||||
parent_data.styles.pseudos.get(&pseudo).unwrap();
|
parent_data.styles.pseudos.get(&pseudo).unwrap();
|
||||||
|
@ -994,12 +994,12 @@ impl MatchingResults {
|
||||||
pub trait MatchMethods : TElement {
|
pub trait MatchMethods : TElement {
|
||||||
/// Performs selector matching and property cascading on an element and its
|
/// Performs selector matching and property cascading on an element and its
|
||||||
/// eager pseudos.
|
/// eager pseudos.
|
||||||
fn match_and_cascade(&self,
|
fn match_and_cascade(
|
||||||
context: &mut StyleContext<Self>,
|
&self,
|
||||||
data: &mut ElementData,
|
context: &mut StyleContext<Self>,
|
||||||
sharing: StyleSharingBehavior)
|
data: &mut ElementData,
|
||||||
-> ChildCascadeRequirement
|
sharing: StyleSharingBehavior
|
||||||
{
|
) -> ChildCascadeRequirement {
|
||||||
debug!("Match and cascade for {:?}", self);
|
debug!("Match and cascade for {:?}", self);
|
||||||
|
|
||||||
// Perform selector matching for the primary style.
|
// Perform selector matching for the primary style.
|
||||||
|
@ -1021,16 +1021,24 @@ pub trait MatchMethods : TElement {
|
||||||
// if our parent has visited styles.
|
// if our parent has visited styles.
|
||||||
let parent_and_styles = self.get_inherited_style_and_parent();
|
let parent_and_styles = self.get_inherited_style_and_parent();
|
||||||
if relevant_link_found || parent_and_styles.has_visited_style() {
|
if relevant_link_found || parent_and_styles.has_visited_style() {
|
||||||
self.cascade_primary(context, data, important_rules_changed,
|
self.cascade_primary(
|
||||||
&parent_and_styles,
|
context,
|
||||||
CascadeVisitedMode::Visited);
|
data,
|
||||||
|
important_rules_changed,
|
||||||
|
&parent_and_styles,
|
||||||
|
CascadeVisitedMode::Visited
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cascade properties and compute primary values.
|
// Cascade properties and compute primary values.
|
||||||
let child_cascade_requirement =
|
let child_cascade_requirement =
|
||||||
self.cascade_primary(context, data, important_rules_changed,
|
self.cascade_primary(
|
||||||
&parent_and_styles,
|
context,
|
||||||
CascadeVisitedMode::Unvisited);
|
data,
|
||||||
|
important_rules_changed,
|
||||||
|
&parent_and_styles,
|
||||||
|
CascadeVisitedMode::Unvisited
|
||||||
|
);
|
||||||
|
|
||||||
// Match and cascade eager pseudo-elements.
|
// Match and cascade eager pseudo-elements.
|
||||||
if !data.styles.is_display_none() {
|
if !data.styles.is_display_none() {
|
||||||
|
@ -1109,12 +1117,12 @@ pub trait MatchMethods : TElement {
|
||||||
///
|
///
|
||||||
/// Returns `MatchingResults` with the new rules and other associated data
|
/// Returns `MatchingResults` with the new rules and other associated data
|
||||||
/// from the matching process.
|
/// from the matching process.
|
||||||
fn match_primary(&self,
|
fn match_primary(
|
||||||
context: &mut StyleContext<Self>,
|
&self,
|
||||||
data: &mut ElementData,
|
context: &mut StyleContext<Self>,
|
||||||
visited_handling: VisitedHandlingMode)
|
data: &mut ElementData,
|
||||||
-> MatchingResults
|
visited_handling: VisitedHandlingMode
|
||||||
{
|
) -> MatchingResults {
|
||||||
debug!("Match primary for {:?}, visited: {:?}", self, visited_handling);
|
debug!("Match primary for {:?}, visited: {:?}", self, visited_handling);
|
||||||
|
|
||||||
let mut primary_inputs = context.thread_local.current_element_info
|
let mut primary_inputs = context.thread_local.current_element_info
|
||||||
|
@ -1145,7 +1153,7 @@ pub trait MatchMethods : TElement {
|
||||||
parent_data.styles.pseudos.get(&pseudo).unwrap();
|
parent_data.styles.pseudos.get(&pseudo).unwrap();
|
||||||
let mut rules = pseudo_style.rules().clone();
|
let mut rules = pseudo_style.rules().clone();
|
||||||
if parent.may_have_animations() {
|
if parent.may_have_animations() {
|
||||||
let animation_rules = data.get_animation_rules();
|
let animation_rules = self.get_animation_rules();
|
||||||
|
|
||||||
// Handle animations here.
|
// Handle animations here.
|
||||||
if let Some(animation_rule) = animation_rules.0 {
|
if let Some(animation_rule) = animation_rules.0 {
|
||||||
|
@ -1208,12 +1216,8 @@ pub trait MatchMethods : TElement {
|
||||||
context.shared.quirks_mode);
|
context.shared.quirks_mode);
|
||||||
|
|
||||||
{
|
{
|
||||||
let smil_override = data.get_smil_override();
|
let smil_override = self.get_smil_override();
|
||||||
let animation_rules = if self.may_have_animations() {
|
let animation_rules = self.get_animation_rules();
|
||||||
data.get_animation_rules()
|
|
||||||
} else {
|
|
||||||
AnimationRules(None, None)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute the primary rule node.
|
// Compute the primary rule node.
|
||||||
stylist.push_applicable_declarations(self,
|
stylist.push_applicable_declarations(self,
|
||||||
|
|
|
@ -28,10 +28,10 @@ use values::computed::Context;
|
||||||
///
|
///
|
||||||
/// The first one is for Animation cascade level, and the second one is for
|
/// The first one is for Animation cascade level, and the second one is for
|
||||||
/// Transition cascade level.
|
/// Transition cascade level.
|
||||||
pub struct AnimationRules<'a>(pub Option<&'a Arc<Locked<PropertyDeclarationBlock>>>,
|
pub struct AnimationRules(pub Option<Arc<Locked<PropertyDeclarationBlock>>>,
|
||||||
pub Option<&'a Arc<Locked<PropertyDeclarationBlock>>>);
|
pub Option<Arc<Locked<PropertyDeclarationBlock>>>);
|
||||||
|
|
||||||
impl<'a> AnimationRules<'a> {
|
impl AnimationRules {
|
||||||
/// Returns whether these animation rules represents an actual rule or not.
|
/// Returns whether these animation rules represents an actual rule or not.
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.0.is_none() && self.1.is_none()
|
self.0.is_none() && self.1.is_none()
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
use applicable_declarations::ApplicableDeclarationList;
|
use applicable_declarations::ApplicableDeclarationList;
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use heapsize::HeapSizeOf;
|
use heapsize::HeapSizeOf;
|
||||||
use properties::{AnimationRules, Importance, LonghandIdSet, PropertyDeclarationBlock};
|
use properties::{Importance, LonghandIdSet, PropertyDeclarationBlock};
|
||||||
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
|
use shared_lock::{Locked, StylesheetGuards, SharedRwLockReadGuard};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
@ -1321,32 +1321,6 @@ impl StrongRuleNode {
|
||||||
.find(|node| node.cascade_level() == CascadeLevel::SMILOverride)
|
.find(|node| node.cascade_level() == CascadeLevel::SMILOverride)
|
||||||
.map(|node| node.get_animation_style())
|
.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.
|
/// An iterator over a rule node and its ancestors.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue