瀏覽代碼

LibWeb: Be more strict about invoking .play() on element animations

We don't want to always invoke the .play() method if an animation is
relevant and had a play state of running, as the play state is
essentially just "paused" or "not paused". We replace that relevancy
check with the inverse of the pause check so we don't constantly call
.play() on animations that are finished.

Also duplicates and moves the temporary context into both blocks, since
most of the time neither condition will be true.
Matthew Olsson 1 年之前
父節點
當前提交
cf54ba01ac
共有 1 個文件被更改,包括 11 次插入5 次删除
  1. 11 5
      Userland/Libraries/LibWeb/CSS/StyleComputer.cpp

+ 11 - 5
Userland/Libraries/LibWeb/CSS/StyleComputer.cpp

@@ -1410,7 +1410,11 @@ void StyleComputer::collect_animation_into(DOM::Element& element, Optional<CSS::
     }
 }
 
-static void apply_animation_properties(DOM::Document& document, StyleProperties& style, Animations::Animation& animation)
+enum class AnimationIsNew {
+    Yes,
+    No,
+};
+static void apply_animation_properties(DOM::Document& document, StyleProperties& style, Animations::Animation& animation, AnimationIsNew animation_is_new)
 {
     auto& effect = verify_cast<Animations::KeyframeEffect>(*animation.effect());
 
@@ -1468,10 +1472,12 @@ static void apply_animation_properties(DOM::Document& document, StyleProperties&
     effect.set_fill_mode(Animations::css_fill_mode_to_bindings_fill_mode(fill_mode));
     effect.set_playback_direction(Animations::css_animation_direction_to_bindings_playback_direction(direction));
 
-    HTML::TemporaryExecutionContext context(document.relevant_settings_object());
-    if (play_state == CSS::AnimationPlayState::Running && !animation.is_relevant()) {
+    // If this is a new animation, we always want to play it
+    if (play_state == CSS::AnimationPlayState::Running && (animation_is_new == AnimationIsNew::Yes || animation.play_state() == Bindings::AnimationPlayState::Paused)) {
+        HTML::TemporaryExecutionContext context(document.relevant_settings_object());
         animation.play().release_value_but_fixme_should_propagate_errors();
     } else if (play_state == CSS::AnimationPlayState::Paused && animation.play_state() != Bindings::AnimationPlayState::Paused) {
+        HTML::TemporaryExecutionContext context(document.relevant_settings_object());
         animation.pause().release_value_but_fixme_should_propagate_errors();
     }
 }
@@ -1553,7 +1559,7 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element
                 animation->set_timeline(m_document->timeline());
                 animation->set_owning_element(element);
                 animation->set_effect(effect);
-                apply_animation_properties(m_document, style, animation);
+                apply_animation_properties(m_document, style, animation, AnimationIsNew::Yes);
                 if (pseudo_element.has_value())
                     effect->set_pseudo_element(Selector::PseudoElement { pseudo_element.value() });
 
@@ -1565,7 +1571,7 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element
                 element.set_cached_animation_name_animation(animation);
             } else {
                 // The animation hasn't changed, but some properties of the animation may have
-                apply_animation_properties(m_document, style, *element.cached_animation_name_animation());
+                apply_animation_properties(m_document, style, *element.cached_animation_name_animation(), AnimationIsNew::No);
             }
         }
     } else {