mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
animations: Don't always re-resolve the node style
When animations and transitions change don't always re-resolve node style, just replace the animation and transition rules and re-cascade.
This commit is contained in:
parent
364235ac0c
commit
af0bb1f728
4 changed files with 108 additions and 108 deletions
|
@ -882,10 +882,9 @@ impl ElementAnimationSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cancel_active_transitions(&mut self) {
|
fn cancel_active_transitions(&mut self) {
|
||||||
self.dirty = !self.transitions.is_empty();
|
|
||||||
|
|
||||||
for transition in self.transitions.iter_mut() {
|
for transition in self.transitions.iter_mut() {
|
||||||
if transition.state != AnimationState::Finished {
|
if transition.state != AnimationState::Finished {
|
||||||
|
self.dirty = true;
|
||||||
transition.state = AnimationState::Canceled;
|
transition.state = AnimationState::Canceled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,10 @@ use crate::dom::TNode;
|
||||||
use crate::invalidation::element::restyle_hints::RestyleHint;
|
use crate::invalidation::element::restyle_hints::RestyleHint;
|
||||||
use crate::properties::longhands::display::computed_value::T as Display;
|
use crate::properties::longhands::display::computed_value::T as Display;
|
||||||
use crate::properties::ComputedValues;
|
use crate::properties::ComputedValues;
|
||||||
|
use crate::properties::PropertyDeclarationBlock;
|
||||||
use crate::rule_tree::{CascadeLevel, StrongRuleNode};
|
use crate::rule_tree::{CascadeLevel, StrongRuleNode};
|
||||||
use crate::selector_parser::{PseudoElement, RestyleDamage};
|
use crate::selector_parser::{PseudoElement, RestyleDamage};
|
||||||
|
use crate::shared_lock::Locked;
|
||||||
use crate::style_resolver::ResolvedElementStyles;
|
use crate::style_resolver::ResolvedElementStyles;
|
||||||
use crate::style_resolver::{PseudoElementResolution, StyleResolverForElement};
|
use crate::style_resolver::{PseudoElementResolution, StyleResolverForElement};
|
||||||
use crate::stylist::RuleInclusion;
|
use crate::stylist::RuleInclusion;
|
||||||
|
@ -87,6 +89,29 @@ enum CascadeVisitedMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PrivateMatchMethods: TElement {
|
trait PrivateMatchMethods: TElement {
|
||||||
|
fn replace_single_rule_node(
|
||||||
|
context: &mut StyleContext<Self>,
|
||||||
|
level: CascadeLevel,
|
||||||
|
pdb: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
|
||||||
|
path: &mut StrongRuleNode,
|
||||||
|
) -> bool {
|
||||||
|
let stylist = &context.shared.stylist;
|
||||||
|
let guards = &context.shared.guards;
|
||||||
|
|
||||||
|
let mut important_rules_changed = false;
|
||||||
|
let new_node = stylist.rule_tree().update_rule_at_level(
|
||||||
|
level,
|
||||||
|
pdb,
|
||||||
|
path,
|
||||||
|
guards,
|
||||||
|
&mut important_rules_changed,
|
||||||
|
);
|
||||||
|
if let Some(n) = new_node {
|
||||||
|
*path = n;
|
||||||
|
}
|
||||||
|
important_rules_changed
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates the rule nodes without re-running selector matching, using just
|
/// Updates the rule nodes without re-running selector matching, using just
|
||||||
/// the rule tree, for a specific visited mode.
|
/// the rule tree, for a specific visited mode.
|
||||||
///
|
///
|
||||||
|
@ -98,17 +123,11 @@ trait PrivateMatchMethods: TElement {
|
||||||
cascade_visited: CascadeVisitedMode,
|
cascade_visited: CascadeVisitedMode,
|
||||||
cascade_inputs: &mut ElementCascadeInputs,
|
cascade_inputs: &mut ElementCascadeInputs,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
use crate::properties::PropertyDeclarationBlock;
|
|
||||||
use crate::shared_lock::Locked;
|
|
||||||
|
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
replacements.intersects(RestyleHint::replacements()) &&
|
replacements.intersects(RestyleHint::replacements()) &&
|
||||||
(replacements & !RestyleHint::replacements()).is_empty()
|
(replacements & !RestyleHint::replacements()).is_empty()
|
||||||
);
|
);
|
||||||
|
|
||||||
let stylist = &context.shared.stylist;
|
|
||||||
let guards = &context.shared.guards;
|
|
||||||
|
|
||||||
let primary_rules = match cascade_visited {
|
let primary_rules = match cascade_visited {
|
||||||
CascadeVisitedMode::Unvisited => cascade_inputs.primary.rules.as_mut(),
|
CascadeVisitedMode::Unvisited => cascade_inputs.primary.rules.as_mut(),
|
||||||
CascadeVisitedMode::Visited => cascade_inputs.primary.visited_rules.as_mut(),
|
CascadeVisitedMode::Visited => cascade_inputs.primary.visited_rules.as_mut(),
|
||||||
|
@ -119,34 +138,18 @@ trait PrivateMatchMethods: TElement {
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let replace_rule_node = |level: CascadeLevel,
|
|
||||||
pdb: Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>,
|
|
||||||
path: &mut StrongRuleNode|
|
|
||||||
-> bool {
|
|
||||||
let mut important_rules_changed = false;
|
|
||||||
let new_node = stylist.rule_tree().update_rule_at_level(
|
|
||||||
level,
|
|
||||||
pdb,
|
|
||||||
path,
|
|
||||||
guards,
|
|
||||||
&mut important_rules_changed,
|
|
||||||
);
|
|
||||||
if let Some(n) = new_node {
|
|
||||||
*path = n;
|
|
||||||
}
|
|
||||||
important_rules_changed
|
|
||||||
};
|
|
||||||
|
|
||||||
if !context.shared.traversal_flags.for_animation_only() {
|
if !context.shared.traversal_flags.for_animation_only() {
|
||||||
let mut result = false;
|
let mut result = false;
|
||||||
if replacements.contains(RestyleHint::RESTYLE_STYLE_ATTRIBUTE) {
|
if replacements.contains(RestyleHint::RESTYLE_STYLE_ATTRIBUTE) {
|
||||||
let style_attribute = self.style_attribute();
|
let style_attribute = self.style_attribute();
|
||||||
result |= replace_rule_node(
|
result |= Self::replace_single_rule_node(
|
||||||
|
context,
|
||||||
CascadeLevel::same_tree_author_normal(),
|
CascadeLevel::same_tree_author_normal(),
|
||||||
style_attribute,
|
style_attribute,
|
||||||
primary_rules,
|
primary_rules,
|
||||||
);
|
);
|
||||||
result |= replace_rule_node(
|
result |= Self::replace_single_rule_node(
|
||||||
|
context,
|
||||||
CascadeLevel::same_tree_author_important(),
|
CascadeLevel::same_tree_author_important(),
|
||||||
style_attribute,
|
style_attribute,
|
||||||
primary_rules,
|
primary_rules,
|
||||||
|
@ -166,7 +169,8 @@ trait PrivateMatchMethods: TElement {
|
||||||
debug_assert!(context.shared.traversal_flags.for_animation_only());
|
debug_assert!(context.shared.traversal_flags.for_animation_only());
|
||||||
|
|
||||||
if replacements.contains(RestyleHint::RESTYLE_SMIL) {
|
if replacements.contains(RestyleHint::RESTYLE_SMIL) {
|
||||||
replace_rule_node(
|
Self::replace_single_rule_node(
|
||||||
|
context,
|
||||||
CascadeLevel::SMILOverride,
|
CascadeLevel::SMILOverride,
|
||||||
self.smil_override(),
|
self.smil_override(),
|
||||||
primary_rules,
|
primary_rules,
|
||||||
|
@ -174,7 +178,8 @@ trait PrivateMatchMethods: TElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
if replacements.contains(RestyleHint::RESTYLE_CSS_TRANSITIONS) {
|
if replacements.contains(RestyleHint::RESTYLE_CSS_TRANSITIONS) {
|
||||||
replace_rule_node(
|
Self::replace_single_rule_node(
|
||||||
|
context,
|
||||||
CascadeLevel::Transitions,
|
CascadeLevel::Transitions,
|
||||||
self.transition_rule(&context.shared)
|
self.transition_rule(&context.shared)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -184,7 +189,8 @@ trait PrivateMatchMethods: TElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
if replacements.contains(RestyleHint::RESTYLE_CSS_ANIMATIONS) {
|
if replacements.contains(RestyleHint::RESTYLE_CSS_ANIMATIONS) {
|
||||||
replace_rule_node(
|
Self::replace_single_rule_node(
|
||||||
|
context,
|
||||||
CascadeLevel::Animations,
|
CascadeLevel::Animations,
|
||||||
self.animation_rule(&context.shared)
|
self.animation_rule(&context.shared)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -374,12 +380,13 @@ trait PrivateMatchMethods: TElement {
|
||||||
&self,
|
&self,
|
||||||
context: &mut StyleContext<Self>,
|
context: &mut StyleContext<Self>,
|
||||||
old_values: &mut Option<Arc<ComputedValues>>,
|
old_values: &mut Option<Arc<ComputedValues>>,
|
||||||
new_values: &mut Arc<ComputedValues>,
|
new_styles: &mut ResolvedElementStyles,
|
||||||
restyle_hint: RestyleHint,
|
restyle_hint: RestyleHint,
|
||||||
important_rules_changed: bool,
|
important_rules_changed: bool,
|
||||||
) {
|
) {
|
||||||
use crate::context::UpdateAnimationsTasks;
|
use crate::context::UpdateAnimationsTasks;
|
||||||
|
|
||||||
|
let new_values = new_styles.primary_style_mut();
|
||||||
if context.shared.traversal_flags.for_animation_only() {
|
if context.shared.traversal_flags.for_animation_only() {
|
||||||
self.handle_display_change_for_smil_if_needed(
|
self.handle_display_change_for_smil_if_needed(
|
||||||
context,
|
context,
|
||||||
|
@ -458,10 +465,65 @@ trait PrivateMatchMethods: TElement {
|
||||||
&self,
|
&self,
|
||||||
context: &mut StyleContext<Self>,
|
context: &mut StyleContext<Self>,
|
||||||
old_values: &mut Option<Arc<ComputedValues>>,
|
old_values: &mut Option<Arc<ComputedValues>>,
|
||||||
new_values: &mut Arc<ComputedValues>,
|
new_resolved_styles: &mut ResolvedElementStyles,
|
||||||
_restyle_hint: RestyleHint,
|
_restyle_hint: RestyleHint,
|
||||||
_important_rules_changed: bool,
|
_important_rules_changed: bool,
|
||||||
) {
|
) {
|
||||||
|
if !self.process_animations_for_style(
|
||||||
|
context,
|
||||||
|
old_values,
|
||||||
|
new_resolved_styles.primary_style_mut(),
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have modified animation or transitions, we recascade style for this node.
|
||||||
|
let mut rule_node = new_resolved_styles.primary_style().rules().clone();
|
||||||
|
Self::replace_single_rule_node(
|
||||||
|
context,
|
||||||
|
CascadeLevel::Transitions,
|
||||||
|
self.transition_rule(&context.shared)
|
||||||
|
.as_ref()
|
||||||
|
.map(|a| a.borrow_arc()),
|
||||||
|
&mut rule_node,
|
||||||
|
);
|
||||||
|
Self::replace_single_rule_node(
|
||||||
|
context,
|
||||||
|
CascadeLevel::Animations,
|
||||||
|
self.animation_rule(&context.shared)
|
||||||
|
.as_ref()
|
||||||
|
.map(|a| a.borrow_arc()),
|
||||||
|
&mut rule_node,
|
||||||
|
);
|
||||||
|
|
||||||
|
// If these animations haven't modified the rule now, we can just exit early.
|
||||||
|
if rule_node == *new_resolved_styles.primary_style().rules() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let inputs = CascadeInputs {
|
||||||
|
rules: Some(rule_node),
|
||||||
|
visited_rules: new_resolved_styles.primary_style().visited_rules().cloned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let style = StyleResolverForElement::new(
|
||||||
|
*self,
|
||||||
|
context,
|
||||||
|
RuleInclusion::All,
|
||||||
|
PseudoElementResolution::IfApplicable,
|
||||||
|
)
|
||||||
|
.cascade_style_and_visited_with_default_parents(inputs);
|
||||||
|
|
||||||
|
new_resolved_styles.primary.style = style;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
fn process_animations_for_style(
|
||||||
|
&self,
|
||||||
|
context: &mut StyleContext<Self>,
|
||||||
|
old_values: &mut Option<Arc<ComputedValues>>,
|
||||||
|
new_values: &mut Arc<ComputedValues>,
|
||||||
|
) -> bool {
|
||||||
use crate::animation::AnimationState;
|
use crate::animation::AnimationState;
|
||||||
|
|
||||||
// We need to call this before accessing the `ElementAnimationSet` from the
|
// We need to call this before accessing the `ElementAnimationSet` from the
|
||||||
|
@ -533,17 +595,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
.insert(this_opaque, animation_set);
|
.insert(this_opaque, animation_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have modified animation or transitions, we recascade style for this node.
|
changed_animations
|
||||||
if changed_animations {
|
|
||||||
let mut resolver = StyleResolverForElement::new(
|
|
||||||
*self,
|
|
||||||
context,
|
|
||||||
RuleInclusion::All,
|
|
||||||
PseudoElementResolution::IfApplicable,
|
|
||||||
);
|
|
||||||
let new_primary = resolver.resolve_style_with_default_parents();
|
|
||||||
*new_values = new_primary.primary.style.0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes and applies non-redundant damage.
|
/// Computes and applies non-redundant damage.
|
||||||
|
@ -709,7 +761,7 @@ pub trait MatchMethods: TElement {
|
||||||
self.process_animations(
|
self.process_animations(
|
||||||
context,
|
context,
|
||||||
&mut data.styles.primary,
|
&mut data.styles.primary,
|
||||||
&mut new_styles.primary.style.0,
|
&mut new_styles,
|
||||||
data.hint,
|
data.hint,
|
||||||
important_rules_changed,
|
important_rules_changed,
|
||||||
);
|
);
|
||||||
|
|
|
@ -66,6 +66,18 @@ pub struct ResolvedElementStyles {
|
||||||
pub pseudos: EagerPseudoStyles,
|
pub pseudos: EagerPseudoStyles,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ResolvedElementStyles {
|
||||||
|
/// Convenience accessor for the primary style.
|
||||||
|
pub fn primary_style(&self) -> &Arc<ComputedValues> {
|
||||||
|
&self.primary.style.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience mutable accessor for the style.
|
||||||
|
pub fn primary_style_mut(&mut self) -> &mut Arc<ComputedValues> {
|
||||||
|
&mut self.primary.style.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PrimaryStyle {
|
impl PrimaryStyle {
|
||||||
/// Convenience accessor for the style.
|
/// Convenience accessor for the style.
|
||||||
pub fn style(&self) -> &ComputedValues {
|
pub fn style(&self) -> &ComputedValues {
|
||||||
|
|
|
@ -5,24 +5,9 @@
|
||||||
[Web Animations: property <opacity> from [0\] to [1\] at (0) should be [0\]]
|
[Web Animations: property <opacity> from [0\] to [1\] at (0) should be [0\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CSS Transitions with transition: all: property <opacity> from [inherit\] to [0.2\] at (1.5) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions with transition: all: property <opacity> from [initial\] to [0.2\] at (1.5) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions: property <opacity> from [inherit\] to [0.2\] at (1.5) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Web Animations: property <opacity> from [inherit\] to [0.2\] at (0.3) should be [0.62\]]
|
[Web Animations: property <opacity> from [inherit\] to [0.2\] at (0.3) should be [0.62\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CSS Transitions: property <opacity> from [0\] to [1\] at (1.5) should be [1\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions with transition: all: property <opacity> from [unset\] to [0.2\] at (1.5) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Web Animations: property <opacity> from [initial\] to [0.2\] at (0.6) should be [0.52\]]
|
[Web Animations: property <opacity> from [initial\] to [0.2\] at (0.6) should be [0.52\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -44,9 +29,6 @@
|
||||||
[Web Animations: property <opacity> from [inherit\] to [0.2\] at (-0.3) should be [0.98\]]
|
[Web Animations: property <opacity> from [inherit\] to [0.2\] at (-0.3) should be [0.98\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CSS Animations: property <opacity> from [inherit\] to [0.2\] at (1.5) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Web Animations: property <opacity> from [initial\] to [0.2\] at (-0.3) should be [1\]]
|
[Web Animations: property <opacity> from [initial\] to [0.2\] at (-0.3) should be [1\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -56,15 +38,6 @@
|
||||||
[Web Animations: property <opacity> from [initial\] to [0.2\] at (0) should be [1\]]
|
[Web Animations: property <opacity> from [initial\] to [0.2\] at (0) should be [1\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CSS Transitions: property <opacity> from [initial\] to [0.2\] at (1.5) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Animations: property <opacity> from [unset\] to [0.2\] at (-0.3) should be [1\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions: property <opacity> from [unset\] to [0.2\] at (1.5) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Web Animations: property <opacity> from [0\] to [1\] at (0.3) should be [0.3\]]
|
[Web Animations: property <opacity> from [0\] to [1\] at (0.3) should be [0.3\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -74,9 +47,6 @@
|
||||||
[Web Animations: property <opacity> from [inherit\] to [0.2\] at (1.5) should be [0\]]
|
[Web Animations: property <opacity> from [inherit\] to [0.2\] at (1.5) should be [0\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CSS Animations: property <opacity> from [0\] to [1\] at (1.5) should be [1\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Web Animations: property <opacity> from [unset\] to [0.2\] at (1) should be [0.2\]]
|
[Web Animations: property <opacity> from [unset\] to [0.2\] at (1) should be [0.2\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -86,12 +56,6 @@
|
||||||
[Web Animations: property <opacity> from [inherit\] to [0.2\] at (0.6) should be [0.44\]]
|
[Web Animations: property <opacity> from [inherit\] to [0.2\] at (0.6) should be [0.44\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CSS Animations: property <opacity> from [initial\] to [0.2\] at (1.5) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Animations: property <opacity> from [0\] to [1\] at (-0.3) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Web Animations: property <opacity> from [unset\] to [0.2\] at (-0.3) should be [1\]]
|
[Web Animations: property <opacity> from [unset\] to [0.2\] at (-0.3) should be [1\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -101,12 +65,6 @@
|
||||||
[Web Animations: property <opacity> from [unset\] to [0.2\] at (1.5) should be [0\]]
|
[Web Animations: property <opacity> from [unset\] to [0.2\] at (1.5) should be [0\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CSS Animations: property <opacity> from [unset\] to [0.2\] at (1.5) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions with transition: all: property <opacity> from [0\] to [1\] at (1.5) should be [1\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Web Animations: property <opacity> from [0\] to [1\] at (-0.3) should be [0\]]
|
[Web Animations: property <opacity> from [0\] to [1\] at (-0.3) should be [0\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -131,27 +89,6 @@
|
||||||
[Web Animations: property <opacity> from neutral to [0.2\] at (-0.3) should be [0.07\]]
|
[Web Animations: property <opacity> from neutral to [0.2\] at (-0.3) should be [0.07\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CSS Animations: property <opacity> from [initial\] to [0.2\] at (-0.3) should be [1\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Web Animations: property <opacity> from [initial\] to [0.2\] at (0.3) should be [0.76\]]
|
[Web Animations: property <opacity> from [initial\] to [0.2\] at (0.3) should be [0.76\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CSS Transitions with transition: all: property <opacity> from [0\] to [1\] at (-0.3) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions: property <opacity> from [initial\] to [0.2\] at (-0.3) should be [1\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions with transition: all: property <opacity> from [initial\] to [0.2\] at (-0.3) should be [1\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions: property <opacity> from [0\] to [1\] at (-0.3) should be [0\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions: property <opacity> from [unset\] to [0.2\] at (-0.3) should be [1\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CSS Transitions with transition: all: property <opacity> from [unset\] to [0.2\] at (-0.3) should be [1\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue