LibWeb: Make sure style is up-to-date in getAnimations()

StyleComputer is responsible for assigning animation targets, so we
have to make sure there are no pending style updates before querying
animations of an element.

This change also introduces a version of getAnimations() that does not
check style updates and used by StyleComputer to avoid mutual recursion.
This commit is contained in:
Aliaksandr Kalenik 2024-10-02 05:53:03 +02:00 committed by Sam Atkins
parent c412181683
commit 94b3b84dd8
Notes: github-actions[bot] 2024-10-02 15:29:35 +00:00
5 changed files with 35 additions and 1 deletions

View file

@ -0,0 +1 @@
This is a animated div animation count: 1

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<script src="../../include.js"></script>
<style>
@keyframes test {
from {
background-color: green;
}
to {
background-color: yellow;
}
}
#animated {
width: 100px;
height: 100px;
background-color: green;
animation: test 2s infinite;
}
</style>
<div id="animated">This is a animated div</div>
<script>
const animationCount = document.getElementById("animated").getAnimations().length;
test(() => {
println(`animation count: ${animationCount}`);
});
</script>

View file

@ -60,6 +60,12 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Animation>> Animatable::animate(Optional<JS
// https://www.w3.org/TR/web-animations-1/#dom-animatable-getanimations
Vector<JS::NonnullGCPtr<Animation>> Animatable::get_animations(GetAnimationsOptions options)
{
verify_cast<DOM::Element>(*this).document().update_style();
return get_animations_internal(options);
}
Vector<JS::NonnullGCPtr<Animation>> Animatable::get_animations_internal(GetAnimationsOptions options)
{
// Returns the set of relevant animations for this object, or, if an options parameter is passed with subtree set to
// true, returns the set of relevant animations for a subtree for this object.

View file

@ -41,6 +41,7 @@ public:
WebIDL::ExceptionOr<JS::NonnullGCPtr<Animation>> animate(Optional<JS::Handle<JS::Object>> keyframes, Variant<Empty, double, KeyframeAnimationOptions> options = {});
Vector<JS::NonnullGCPtr<Animation>> get_animations(GetAnimationsOptions options = {});
Vector<JS::NonnullGCPtr<Animation>> get_animations_internal(GetAnimationsOptions options = {});
void associate_with_animation(JS::NonnullGCPtr<Animation>);
void disassociate_with_animation(JS::NonnullGCPtr<Animation>);

View file

@ -1563,7 +1563,7 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element
}
}
auto animations = element.get_animations({ .subtree = false });
auto animations = element.get_animations_internal({ .subtree = false });
for (auto& animation : animations) {
if (auto effect = animation->effect(); effect && effect->is_keyframe_effect()) {
auto& keyframe_effect = *static_cast<Animations::KeyframeEffect*>(effect.ptr());