Prechádzať zdrojové kódy

LibWeb: Implement animation class-specific composite order

This is a part of determining the composite order of two animations
Matthew Olsson 1 rok pred
rodič
commit
c3b689488e

+ 12 - 0
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<int> class_specific_composite_order(JS::NonnullGCPtr<Animation>) const { return {}; }
+
 protected:
     Animation(JS::Realm&);
 

+ 43 - 0
Userland/Libraries/LibWeb/CSS/CSSAnimation.cpp

@@ -16,6 +16,49 @@ JS::NonnullGCPtr<CSSAnimation> CSSAnimation::create(JS::Realm& realm)
     return realm.heap().allocate<CSSAnimation>(realm, realm);
 }
 
+// https://www.w3.org/TR/css-animations-2/#animation-composite-order
+Optional<int> CSSAnimation::class_specific_composite_order(JS::NonnullGCPtr<Animations::Animation> other_animation) const
+{
+    auto other = JS::NonnullGCPtr { verify_cast<CSSAnimation>(*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)
 {

+ 3 - 0
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<int> class_specific_composite_order(JS::NonnullGCPtr<Animations::Animation> other) const override;
+
 private:
     explicit CSSAnimation(JS::Realm&);