LibWeb: Make transition order consider property name

class_specific_composite_order() also has no reason to return an
Optional<int>, since it can just return 0.
This commit is contained in:
Psychpsyo 2025-11-11 11:45:36 +01:00 committed by Jelle Raaijmakers
parent 1df94c4513
commit 2c4f2a3cb6
Notes: github-actions[bot] 2025-11-11 12:48:13 +00:00
8 changed files with 36 additions and 12 deletions

View file

@ -108,7 +108,7 @@ public:
void set_owning_element(GC::Ptr<DOM::Element> value) { m_owning_element = value; } void set_owning_element(GC::Ptr<DOM::Element> value) { m_owning_element = value; }
virtual AnimationClass animation_class() const { return AnimationClass::None; } virtual AnimationClass animation_class() const { return AnimationClass::None; }
virtual Optional<int> class_specific_composite_order(GC::Ref<Animation>) const { return {}; } virtual int class_specific_composite_order(GC::Ref<Animation>) const { return 0; }
unsigned int global_animation_list_order() const { return m_global_animation_list_order; } unsigned int global_animation_list_order() const { return m_global_animation_list_order; }

View file

@ -647,8 +647,8 @@ int KeyframeEffect::composite_order(GC::Ref<KeyframeEffect> a, GC::Ref<KeyframeE
// 2. If A and B are still not sorted, sort by any class-specific composite order defined by the common class of // 2. If A and B are still not sorted, sort by any class-specific composite order defined by the common class of
// A and Bs associated animations. // A and Bs associated animations.
if (auto order = a_animation->class_specific_composite_order(*b_animation); order.has_value()) if (auto order = a_animation->class_specific_composite_order(*b_animation); order != 0)
return order.value(); return order;
// 3. If A and B are still not sorted, sort by the position of their associated animations in the global // 3. If A and B are still not sorted, sort by the position of their associated animations in the global
// animation list. // animation list.

View file

@ -20,7 +20,7 @@ GC::Ref<CSSAnimation> CSSAnimation::create(JS::Realm& realm)
} }
// https://www.w3.org/TR/css-animations-2/#animation-composite-order // https://www.w3.org/TR/css-animations-2/#animation-composite-order
Optional<int> CSSAnimation::class_specific_composite_order(GC::Ref<Animations::Animation> other_animation) const int CSSAnimation::class_specific_composite_order(GC::Ref<Animations::Animation> other_animation) const
{ {
auto other = GC::Ref { as<CSSAnimation>(*other_animation) }; auto other = GC::Ref { as<CSSAnimation>(*other_animation) };
@ -42,13 +42,13 @@ Optional<int> CSSAnimation::class_specific_composite_order(GC::Ref<Animations::A
// - element children // - element children
if (owning_element().ptr() != other->owning_element().ptr()) { if (owning_element().ptr() != other->owning_element().ptr()) {
// FIXME: Sort by tree order // FIXME: Sort by tree order
return {}; return 0;
} }
// 2. Otherwise, sort A and B based on their position in the computed value of the animation-name property of the // 2. Otherwise, sort A and B based on their position in the computed value of the animation-name property of the
// (common) owning element. // (common) owning element.
// FIXME: Do this when animation-name supports multiple values // FIXME: Do this when animation-name supports multiple values
return {}; return 0;
} }
// The composite order of CSS Animations without an owning element is based on their position in the global animation list. // The composite order of CSS Animations without an owning element is based on their position in the global animation list.

View file

@ -23,7 +23,7 @@ public:
void set_animation_name(FlyString const& animation_name) { m_animation_name = animation_name; } void set_animation_name(FlyString const& animation_name) { m_animation_name = animation_name; }
virtual Animations::AnimationClass animation_class() const override; virtual Animations::AnimationClass animation_class() const override;
virtual Optional<int> class_specific_composite_order(GC::Ref<Animations::Animation> other) const override; virtual int class_specific_composite_order(GC::Ref<Animations::Animation> other) const override;
private: private:
explicit CSSAnimation(JS::Realm&); explicit CSSAnimation(JS::Realm&);

View file

@ -38,7 +38,7 @@ Animations::AnimationClass CSSTransition::animation_class() const
return Animations::AnimationClass::CSSTransition; return Animations::AnimationClass::CSSTransition;
} }
Optional<int> CSSTransition::class_specific_composite_order(GC::Ref<Animations::Animation> other_animation) const int CSSTransition::class_specific_composite_order(GC::Ref<Animations::Animation> other_animation) const
{ {
auto other = GC::Ref { as<CSSTransition>(*other_animation) }; auto other = GC::Ref { as<CSSTransition>(*other_animation) };
@ -66,7 +66,7 @@ Optional<int> CSSTransition::class_specific_composite_order(GC::Ref<Animations::
// - element children // - element children
if (owning_element().ptr() != other->owning_element().ptr()) { if (owning_element().ptr() != other->owning_element().ptr()) {
// FIXME: Actually sort by tree order // FIXME: Actually sort by tree order
return {}; return 0;
} }
// 4. Otherwise, if A and B have different transition generation values, sort by their corresponding transition // 4. Otherwise, if A and B have different transition generation values, sort by their corresponding transition
@ -74,11 +74,11 @@ Optional<int> CSSTransition::class_specific_composite_order(GC::Ref<Animations::
if (m_transition_generation != other->m_transition_generation) if (m_transition_generation != other->m_transition_generation)
return m_transition_generation - other->m_transition_generation; return m_transition_generation - other->m_transition_generation;
// FIXME:
// 5. Otherwise, sort A and B in ascending order by the Unicode codepoints that make up the expanded transition // 5. Otherwise, sort A and B in ascending order by the Unicode codepoints that make up the expanded transition
// property name of each transition (i.e. without attempting case conversion and such that -moz-column-width // property name of each transition (i.e. without attempting case conversion and such that -moz-column-width
// sorts before column-width). // sorts before column-width).
return {}; // FIXME: This should operate on Unicode strings, not StringViews.
return transition_property() > other->transition_property();
} }
CSSTransition::CSSTransition(JS::Realm& realm, DOM::AbstractElement abstract_element, PropertyID property_id, size_t transition_generation, CSSTransition::CSSTransition(JS::Realm& realm, DOM::AbstractElement abstract_element, PropertyID property_id, size_t transition_generation,

View file

@ -27,7 +27,7 @@ public:
StringView transition_property() const; StringView transition_property() const;
virtual Animations::AnimationClass animation_class() const override; virtual Animations::AnimationClass animation_class() const override;
virtual Optional<int> class_specific_composite_order(GC::Ref<Animations::Animation> other) const override; virtual int class_specific_composite_order(GC::Ref<Animations::Animation> other) const override;
double transition_start_time() const { return m_start_time; } double transition_start_time() const { return m_start_time; }
double transition_end_time() const { return m_end_time; } double transition_end_time() const { return m_end_time; }

View file

@ -0,0 +1 @@
Order: left, right, top

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<style>
#foo {
transition-property: top, left, right;
transition-duration: 1s;
}
</style>
<div id="foo" style="top: 0; left: 0; right: 0"></div>
<script src="../include.js"></script>
<script>
promiseTest(async () => {
await animationFrame();
await animationFrame();
foo.style.left = "10px";
foo.style.top = "10px";
foo.style.right = "10px";
println("Order: " + document.getAnimations().map(animation => animation.transitionProperty).join(", "));
});
</script>
</html>