LibWeb: Skip unstyled descendants in animation updates
Animation updates propagate inherited animated values by walking the animated target's subtree and calling `recompute_inherited_style()` on each element. Elements inserted during the same rendering update may not have computed properties yet, which violates an existing assertion, causing a crash. Fix this by skipping unstyled descendants during this walk. The subsequent recursive style update computes their style from scratch.
This commit is contained in:
parent
f426f021ef
commit
06ee7bc532
2 changed files with 27 additions and 0 deletions
|
|
@ -822,6 +822,8 @@ AnimationUpdateContext::~AnimationUpdateContext()
|
|||
|
||||
// Traversal of the subtree is necessary to update the animated properties inherited from the target element.
|
||||
target->for_each_in_subtree_of_type<DOM::Element>([&](auto& element) {
|
||||
if (!element.cascaded_properties({}))
|
||||
return TraversalDecision::SkipChildrenAndContinue;
|
||||
auto element_invalidation = element.recompute_inherited_style();
|
||||
if (element_invalidation.is_none())
|
||||
return TraversalDecision::SkipChildrenAndContinue;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="test-wait">
|
||||
<style>
|
||||
@keyframes anim { from { opacity: 1 } to { opacity: 0.5 } }
|
||||
#target { animation: anim 10s infinite; }
|
||||
</style>
|
||||
<div id="target"></div>
|
||||
<script>
|
||||
const animation = target.getAnimations()[0];
|
||||
|
||||
function waitForAnimationTick() {
|
||||
if (animation.currentTime === null || animation.currentTime === 0) {
|
||||
requestAnimationFrame(waitForAnimationTick);
|
||||
return;
|
||||
}
|
||||
|
||||
target.appendChild(document.createElement("div"));
|
||||
requestAnimationFrame(() => {
|
||||
document.documentElement.classList.remove("test-wait");
|
||||
});
|
||||
}
|
||||
|
||||
requestAnimationFrame(waitForAnimationTick);
|
||||
</script>
|
||||
</html>
|
||||
Loading…
Reference in a new issue