3737#include < LibWeb/CSS/StyleValues/StringStyleValue.h>
3838#include < LibWeb/CSS/StyleValues/StyleValueList.h>
3939#include < LibWeb/CSS/StyleValues/TextUnderlinePositionStyleValue.h>
40+ #include < LibWeb/CSS/StyleValues/TimeStyleValue.h>
4041#include < LibWeb/CSS/StyleValues/TransformationStyleValue.h>
4142#include < LibWeb/Layout/BlockContainer.h>
4243#include < LibWeb/Layout/Node.h>
@@ -53,7 +54,6 @@ ComputedProperties::~ComputedProperties() = default;
5354void ComputedProperties::visit_edges (Visitor& visitor)
5455{
5556 Base::visit_edges (visitor);
56- visitor.visit (m_animation_name_source);
5757 visitor.visit (m_transition_property_source);
5858}
5959
@@ -1934,6 +1934,108 @@ Optional<FlyString> ComputedProperties::view_transition_name() const
19341934 return {};
19351935}
19361936
1937+ Vector<ComputedProperties::AnimationProperties> ComputedProperties::animations () const
1938+ {
1939+ // CSS Animations are defined by binding keyframes to an element using the animation-* properties. These list-valued
1940+ // properties, which are all longhands of the animation shorthand, form a coordinating list property group with
1941+ // animation-name as the coordinating list base property and each item in the coordinated value list defining the
1942+ // properties of a single animation effect.
1943+ auto const & coordinated_properties = assemble_coordinated_value_list (
1944+ PropertyID::AnimationName,
1945+ { PropertyID::AnimationDuration,
1946+ PropertyID::AnimationTimingFunction,
1947+ PropertyID::AnimationIterationCount,
1948+ PropertyID::AnimationDirection,
1949+ PropertyID::AnimationPlayState,
1950+ PropertyID::AnimationDelay,
1951+ PropertyID::AnimationFillMode,
1952+ PropertyID::AnimationComposition,
1953+ PropertyID::AnimationName });
1954+
1955+ Vector<AnimationProperties> animations;
1956+
1957+ for (size_t i = 0 ; i < coordinated_properties.get (PropertyID::AnimationName)->size (); i++) {
1958+ // https://drafts.csswg.org/css-animations-1/#propdef-animation-name
1959+ // none: No keyframes are specified at all, so there will be no animation. Any other animations properties
1960+ // specified for this animation have no effect.
1961+ if (coordinated_properties.get (PropertyID::AnimationName).value ()[i]->to_keyword () == Keyword::None)
1962+ continue ;
1963+
1964+ auto animation_name_style_value = coordinated_properties.get (PropertyID::AnimationName).value ()[i];
1965+ auto animation_duration_style_value = coordinated_properties.get (PropertyID::AnimationDuration).value ()[i];
1966+ auto animation_timing_function_style_value = coordinated_properties.get (PropertyID::AnimationTimingFunction).value ()[i];
1967+ auto animation_iteration_count_style_value = coordinated_properties.get (PropertyID::AnimationIterationCount).value ()[i];
1968+ auto animation_direction_style_value = coordinated_properties.get (PropertyID::AnimationDirection).value ()[i];
1969+ auto animation_play_state_style_value = coordinated_properties.get (PropertyID::AnimationPlayState).value ()[i];
1970+ auto animation_delay_style_value = coordinated_properties.get (PropertyID::AnimationDelay).value ()[i];
1971+ auto animation_fill_mode_style_value = coordinated_properties.get (PropertyID::AnimationFillMode).value ()[i];
1972+ auto animation_composition_style_value = coordinated_properties.get (PropertyID::AnimationComposition).value ()[i];
1973+
1974+ auto duration = [&] {
1975+ if (animation_duration_style_value->is_time ())
1976+ return animation_duration_style_value->as_time ().time ().to_milliseconds ();
1977+
1978+ if (animation_duration_style_value->is_calculated ())
1979+ return animation_duration_style_value->as_calculated ().resolve_time ({}).value ().to_milliseconds ();
1980+
1981+ VERIFY_NOT_REACHED ();
1982+ }();
1983+
1984+ auto timing_function = EasingFunction::from_style_value (animation_timing_function_style_value);
1985+
1986+ auto iteration_count = [&] {
1987+ if (animation_iteration_count_style_value->to_keyword () == Keyword::Infinite)
1988+ return AK::Infinity<double >;
1989+
1990+ if (animation_iteration_count_style_value->is_number ())
1991+ return animation_iteration_count_style_value->as_number ().number ();
1992+
1993+ if (animation_iteration_count_style_value->is_calculated ())
1994+ return animation_iteration_count_style_value->as_calculated ().resolve_number ({}).value ();
1995+
1996+ VERIFY_NOT_REACHED ();
1997+ }();
1998+
1999+ auto direction = keyword_to_animation_direction (animation_direction_style_value->to_keyword ()).value ();
2000+ auto play_state = keyword_to_animation_play_state (animation_play_state_style_value->to_keyword ()).value ();
2001+ auto delay = [&] {
2002+ if (animation_delay_style_value->is_time ())
2003+ return animation_delay_style_value->as_time ().time ().to_milliseconds ();
2004+
2005+ if (animation_delay_style_value->is_calculated ())
2006+ return animation_delay_style_value->as_calculated ().resolve_time ({}).value ().to_milliseconds ();
2007+
2008+ VERIFY_NOT_REACHED ();
2009+ }();
2010+ auto fill_mode = keyword_to_animation_fill_mode (animation_fill_mode_style_value->to_keyword ()).value ();
2011+ auto composition = keyword_to_animation_composition (animation_composition_style_value->to_keyword ()).value ();
2012+
2013+ auto name = [&] {
2014+ if (animation_name_style_value->is_custom_ident ())
2015+ return animation_name_style_value->as_custom_ident ().custom_ident ();
2016+
2017+ if (animation_name_style_value->is_string ())
2018+ return animation_name_style_value->as_string ().string_value ();
2019+
2020+ VERIFY_NOT_REACHED ();
2021+ }();
2022+
2023+ animations.append (AnimationProperties {
2024+ .duration = duration,
2025+ .timing_function = timing_function,
2026+ .iteration_count = iteration_count,
2027+ .direction = direction,
2028+ .play_state = play_state,
2029+ .delay = delay,
2030+ .fill_mode = fill_mode,
2031+ .composition = composition,
2032+ .name = name,
2033+ });
2034+ }
2035+
2036+ return animations;
2037+ }
2038+
19372039MaskType ComputedProperties::mask_type () const
19382040{
19392041 auto const & value = property (PropertyID::MaskType);
0 commit comments