mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-06 08:10:02 +00:00
LibWeb: Add slots for pseudo-elements animation cache in Animatable
Fixes the bug when animation does not run at all if an element has a pseudo-element, because both of them use the same cache.
This commit is contained in:
parent
6a19cffdde
commit
4049cce40c
Notes:
github-actions[bot]
2024-08-02 06:06:26 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 4049cce40c
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/921
3 changed files with 51 additions and 16 deletions
|
@ -102,8 +102,42 @@ void Animatable::disassociate_with_animation(JS::NonnullGCPtr<Animation> animati
|
||||||
void Animatable::visit_edges(JS::Cell::Visitor& visitor)
|
void Animatable::visit_edges(JS::Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
visitor.visit(m_associated_animations);
|
visitor.visit(m_associated_animations);
|
||||||
visitor.visit(m_cached_animation_name_source);
|
for (auto const& cached_animation_source : m_cached_animation_name_source)
|
||||||
visitor.visit(m_cached_animation_name_animation);
|
visitor.visit(cached_animation_source);
|
||||||
|
for (auto const& cached_animation_name : m_cached_animation_name_animation)
|
||||||
|
visitor.visit(cached_animation_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::GCPtr<CSS::CSSStyleDeclaration const> Animatable::cached_animation_name_source(Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
|
||||||
|
{
|
||||||
|
if (pseudo_element.has_value())
|
||||||
|
return m_cached_animation_name_source[to_underlying(pseudo_element.value()) + 1];
|
||||||
|
return m_cached_animation_name_source[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animatable::set_cached_animation_name_source(JS::GCPtr<CSS::CSSStyleDeclaration const> value, Optional<CSS::Selector::PseudoElement::Type> pseudo_element)
|
||||||
|
{
|
||||||
|
if (pseudo_element.has_value()) {
|
||||||
|
m_cached_animation_name_source[to_underlying(pseudo_element.value()) + 1] = value;
|
||||||
|
} else {
|
||||||
|
m_cached_animation_name_source[0] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::GCPtr<Animations::Animation> Animatable::cached_animation_name_animation(Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
|
||||||
|
{
|
||||||
|
if (pseudo_element.has_value())
|
||||||
|
return m_cached_animation_name_animation[to_underlying(pseudo_element.value()) + 1];
|
||||||
|
return m_cached_animation_name_animation[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Animatable::set_cached_animation_name_animation(JS::GCPtr<Animations::Animation> value, Optional<CSS::Selector::PseudoElement::Type> pseudo_element)
|
||||||
|
{
|
||||||
|
if (pseudo_element.has_value()) {
|
||||||
|
m_cached_animation_name_animation[to_underlying(pseudo_element.value()) + 1] = value;
|
||||||
|
} else {
|
||||||
|
m_cached_animation_name_animation[0] = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,11 @@ public:
|
||||||
void associate_with_animation(JS::NonnullGCPtr<Animation>);
|
void associate_with_animation(JS::NonnullGCPtr<Animation>);
|
||||||
void disassociate_with_animation(JS::NonnullGCPtr<Animation>);
|
void disassociate_with_animation(JS::NonnullGCPtr<Animation>);
|
||||||
|
|
||||||
JS::GCPtr<CSS::CSSStyleDeclaration const> cached_animation_name_source() const { return m_cached_animation_name_source; }
|
JS::GCPtr<CSS::CSSStyleDeclaration const> cached_animation_name_source(Optional<CSS::Selector::PseudoElement::Type>) const;
|
||||||
void set_cached_animation_name_source(JS::GCPtr<CSS::CSSStyleDeclaration const> value) { m_cached_animation_name_source = value; }
|
void set_cached_animation_name_source(JS::GCPtr<CSS::CSSStyleDeclaration const> value, Optional<CSS::Selector::PseudoElement::Type>);
|
||||||
|
|
||||||
JS::GCPtr<Animations::Animation> cached_animation_name_animation() const { return m_cached_animation_name_animation; }
|
JS::GCPtr<Animations::Animation> cached_animation_name_animation(Optional<CSS::Selector::PseudoElement::Type>) const;
|
||||||
void set_cached_animation_name_animation(JS::GCPtr<Animations::Animation> value) { m_cached_animation_name_animation = value; }
|
void set_cached_animation_name_animation(JS::GCPtr<Animations::Animation> value, Optional<CSS::Selector::PseudoElement::Type>);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void visit_edges(JS::Cell::Visitor&);
|
void visit_edges(JS::Cell::Visitor&);
|
||||||
|
@ -45,8 +45,9 @@ protected:
|
||||||
private:
|
private:
|
||||||
Vector<JS::NonnullGCPtr<Animation>> m_associated_animations;
|
Vector<JS::NonnullGCPtr<Animation>> m_associated_animations;
|
||||||
bool m_is_sorted_by_composite_order { true };
|
bool m_is_sorted_by_composite_order { true };
|
||||||
JS::GCPtr<CSS::CSSStyleDeclaration const> m_cached_animation_name_source;
|
|
||||||
JS::GCPtr<Animations::Animation> m_cached_animation_name_animation;
|
Array<JS::GCPtr<CSS::CSSStyleDeclaration const>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount) + 1> m_cached_animation_name_source;
|
||||||
|
Array<JS::GCPtr<Animations::Animation>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount) + 1> m_cached_animation_name_animation;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1774,11 +1774,11 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element
|
||||||
if (auto source_declaration = style.property_source_declaration(PropertyID::AnimationName); source_declaration) {
|
if (auto source_declaration = style.property_source_declaration(PropertyID::AnimationName); source_declaration) {
|
||||||
auto& realm = element.realm();
|
auto& realm = element.realm();
|
||||||
|
|
||||||
if (source_declaration != element.cached_animation_name_source()) {
|
if (source_declaration != element.cached_animation_name_source(pseudo_element)) {
|
||||||
// This animation name is new, so we need to create a new animation for it.
|
// This animation name is new, so we need to create a new animation for it.
|
||||||
if (auto existing_animation = element.cached_animation_name_animation())
|
if (auto existing_animation = element.cached_animation_name_animation(pseudo_element))
|
||||||
existing_animation->cancel(Animations::Animation::ShouldInvalidate::No);
|
existing_animation->cancel(Animations::Animation::ShouldInvalidate::No);
|
||||||
element.set_cached_animation_name_source(source_declaration);
|
element.set_cached_animation_name_source(source_declaration, pseudo_element);
|
||||||
|
|
||||||
auto effect = Animations::KeyframeEffect::create(realm);
|
auto effect = Animations::KeyframeEffect::create(realm);
|
||||||
auto animation = CSSAnimation::create(realm);
|
auto animation = CSSAnimation::create(realm);
|
||||||
|
@ -1795,21 +1795,21 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element
|
||||||
effect->set_key_frame_set(keyframe_set.value());
|
effect->set_key_frame_set(keyframe_set.value());
|
||||||
|
|
||||||
effect->set_target(&element);
|
effect->set_target(&element);
|
||||||
element.set_cached_animation_name_animation(animation);
|
element.set_cached_animation_name_animation(animation, pseudo_element);
|
||||||
|
|
||||||
HTML::TemporaryExecutionContext context(m_document->relevant_settings_object());
|
HTML::TemporaryExecutionContext context(m_document->relevant_settings_object());
|
||||||
animation->play().release_value_but_fixme_should_propagate_errors();
|
animation->play().release_value_but_fixme_should_propagate_errors();
|
||||||
} else {
|
} else {
|
||||||
// The animation hasn't changed, but some properties of the animation may have
|
// 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(pseudo_element));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If the element had an existing animation, cancel it
|
// If the element had an existing animation, cancel it
|
||||||
if (auto existing_animation = element.cached_animation_name_animation()) {
|
if (auto existing_animation = element.cached_animation_name_animation(pseudo_element)) {
|
||||||
existing_animation->cancel(Animations::Animation::ShouldInvalidate::No);
|
existing_animation->cancel(Animations::Animation::ShouldInvalidate::No);
|
||||||
element.set_cached_animation_name_animation({});
|
element.set_cached_animation_name_animation({}, pseudo_element);
|
||||||
element.set_cached_animation_name_source({});
|
element.set_cached_animation_name_source({}, pseudo_element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue