From c3b689488eaf3ead74c5cd6bbd5ff5d50e1ac757 Mon Sep 17 00:00:00 2001 From: Matthew Olsson Date: Fri, 2 Feb 2024 16:38:09 -0700 Subject: [PATCH] LibWeb: Implement animation class-specific composite order This is a part of determining the composite order of two animations --- .../Libraries/LibWeb/Animations/Animation.h | 12 ++++++ .../Libraries/LibWeb/CSS/CSSAnimation.cpp | 43 +++++++++++++++++++ Userland/Libraries/LibWeb/CSS/CSSAnimation.h | 3 ++ 3 files changed, 58 insertions(+) diff --git a/Userland/Libraries/LibWeb/Animations/Animation.h b/Userland/Libraries/LibWeb/Animations/Animation.h index 212d87fe16..429a7e8a22 100644 --- a/Userland/Libraries/LibWeb/Animations/Animation.h +++ b/Userland/Libraries/LibWeb/Animations/Animation.h @@ -12,6 +12,15 @@ namespace Web::Animations { +// Sorted by composite order: +// https://www.w3.org/TR/css-animations-2/#animation-composite-order +enum class AnimationClass { + CSSAnimationWithOwningElement, + CSSTransition, + CSSAnimationWithoutOwningElement, + None, +}; + // https://www.w3.org/TR/web-animations-1/#the-animation-interface class Animation : public DOM::EventTarget { WEB_PLATFORM_OBJECT(Animation, DOM::EventTarget); @@ -69,6 +78,9 @@ public: virtual bool is_css_animation() const { return false; } + virtual AnimationClass animation_class() const { return AnimationClass::None; } + virtual Optional class_specific_composite_order(JS::NonnullGCPtr) const { return {}; } + protected: Animation(JS::Realm&); diff --git a/Userland/Libraries/LibWeb/CSS/CSSAnimation.cpp b/Userland/Libraries/LibWeb/CSS/CSSAnimation.cpp index cf8edeba96..b4db3c3cc3 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSAnimation.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSAnimation.cpp @@ -16,6 +16,49 @@ JS::NonnullGCPtr CSSAnimation::create(JS::Realm& realm) return realm.heap().allocate(realm, realm); } +// https://www.w3.org/TR/css-animations-2/#animation-composite-order +Optional CSSAnimation::class_specific_composite_order(JS::NonnullGCPtr other_animation) const +{ + auto other = JS::NonnullGCPtr { verify_cast(*other_animation) }; + + // The existance of an owning element determines the animation class, so both animations should have their owning + // element in the same state + VERIFY(!m_owning_element == !other->m_owning_element); + + // Within the set of CSS Animations with an owning element, two animations A and B are sorted in composite order + // (first to last) as follows: + if (m_owning_element) { + // 1. If the owning element of A and B differs, sort A and B by tree order of their corresponding owning elements. + // With regard to pseudo-elements, the sort order is as follows: + // - element + // - ::marker + // - ::before + // - any other pseudo-elements not mentioned specifically in this list, sorted in ascending order by the Unicode + // codepoints that make up each selector + // - ::after + // - element children + if (m_owning_element.ptr() != other->m_owning_element.ptr()) { + // FIXME: Sort by tree order + return {}; + } + + // 2. Otherwise, sort A and B based on their position in the computed value of the animation-name property of the + // (common) owning element. + // FIXME: Do this when animation-name supports multiple values + return {}; + } + + // The composite order of CSS Animations without an owning element is based on their position in the global animation list. + return global_animation_list_order() - other->global_animation_list_order(); +} + +Animations::AnimationClass CSSAnimation::animation_class() const +{ + if (m_owning_element) + return Animations::AnimationClass::CSSAnimationWithOwningElement; + return Animations::AnimationClass::CSSAnimationWithoutOwningElement; +} + CSSAnimation::CSSAnimation(JS::Realm& realm) : Animations::Animation(realm) { diff --git a/Userland/Libraries/LibWeb/CSS/CSSAnimation.h b/Userland/Libraries/LibWeb/CSS/CSSAnimation.h index d6cab51dc3..5313ca9bab 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSAnimation.h +++ b/Userland/Libraries/LibWeb/CSS/CSSAnimation.h @@ -24,6 +24,9 @@ public: FlyString const& animation_name() const { return id(); } + virtual Animations::AnimationClass animation_class() const override; + virtual Optional class_specific_composite_order(JS::NonnullGCPtr other) const override; + private: explicit CSSAnimation(JS::Realm&);