Browse Source

LibWeb: Allow `auto` as `animation-duration` and make that the default

This is a spec change: https://github.com/w3c/csswg-drafts/commit/2a7cc4b58f903389926cb429af2f42307dced186
Sam Atkins 2 years ago
parent
commit
7a2c8d30b9

+ 4 - 1
Userland/Libraries/LibWeb/CSS/Properties.json

@@ -67,9 +67,12 @@
   "animation-duration": {
   "animation-duration": {
     "affects-layout": true,
     "affects-layout": true,
     "inherited": false,
     "inherited": false,
-    "initial": "0s",
+    "initial": "auto",
     "valid-types": [
     "valid-types": [
       "time [0,∞]"
       "time [0,∞]"
+    ],
+    "valid-identifiers": [
+      "auto"
     ]
     ]
   },
   },
   "animation-fill-mode": {
   "animation-fill-mode": {

+ 14 - 4
Userland/Libraries/LibWeb/CSS/StyleComputer.cpp

@@ -1090,7 +1090,11 @@ StyleComputer::AnimationStepTransition StyleComputer::Animation::step(CSS::Time
     remaining_delay = CSS::Time { 0, CSS::Time::Type::Ms };
     remaining_delay = CSS::Time { 0, CSS::Time::Type::Ms };
     time_step_ms -= delay_ms;
     time_step_ms -= delay_ms;
 
 
-    auto added_progress = time_step_ms / duration.to_milliseconds();
+    // "auto": For time-driven animations, equivalent to 0s.
+    // https://www.w3.org/TR/2023/WD-css-animations-2-20230602/#valdef-animation-duration-auto
+    auto used_duration = duration.value_or(CSS::Time { 0, CSS::Time::Type::S });
+
+    auto added_progress = time_step_ms / used_duration.to_milliseconds();
     auto new_progress = progress.as_fraction() + added_progress;
     auto new_progress = progress.as_fraction() + added_progress;
     auto changed_iteration = false;
     auto changed_iteration = false;
     if (new_progress >= 1) {
     if (new_progress >= 1) {
@@ -1498,9 +1502,15 @@ ErrorOr<void> StyleComputer::compute_cascaded_values(StyleProperties& style, DOM
                 auto active_animation = m_active_animations.get(animation_key);
                 auto active_animation = m_active_animations.get(animation_key);
                 if (!active_animation.has_value()) {
                 if (!active_animation.has_value()) {
                     // New animation!
                     // New animation!
-                    CSS::Time duration { 0, CSS::Time::Type::S };
-                    if (auto duration_value = style.maybe_null_property(PropertyID::AnimationDuration); duration_value && duration_value->is_time())
-                        duration = duration_value->as_time().time();
+                    Optional<CSS::Time> duration;
+                    if (auto duration_value = style.maybe_null_property(PropertyID::AnimationDuration); duration_value) {
+                        if (duration_value->is_time()) {
+                            duration = duration_value->as_time().time();
+                        } else if (duration_value->is_identifier() && duration_value->as_identifier().id() == ValueID::Auto) {
+                            // We use empty optional to represent "auto".
+                            duration = {};
+                        }
+                    }
 
 
                     CSS::Time delay { 0, CSS::Time::Type::S };
                     CSS::Time delay { 0, CSS::Time::Type::S };
                     if (auto delay_value = style.maybe_null_property(PropertyID::AnimationDelay); delay_value && delay_value->is_time())
                     if (auto delay_value = style.maybe_null_property(PropertyID::AnimationDelay); delay_value && delay_value->is_time())

+ 1 - 1
Userland/Libraries/LibWeb/CSS/StyleComputer.h

@@ -199,7 +199,7 @@ private:
 
 
     struct Animation {
     struct Animation {
         String name;
         String name;
-        CSS::Time duration;
+        Optional<CSS::Time> duration; // "auto" if not set.
         CSS::Time delay;
         CSS::Time delay;
         Optional<size_t> iteration_count; // Infinite if not set.
         Optional<size_t> iteration_count; // Infinite if not set.
         CSS::AnimationDirection direction;
         CSS::AnimationDirection direction;