diff --git a/Tests/LibWeb/Text/expected/WebAnimations/transition-unknown-property.txt b/Tests/LibWeb/Text/expected/WebAnimations/transition-unknown-property.txt new file mode 100644 index 00000000000..39701378c55 --- /dev/null +++ b/Tests/LibWeb/Text/expected/WebAnimations/transition-unknown-property.txt @@ -0,0 +1 @@ + PASS (didn't crash) diff --git a/Tests/LibWeb/Text/input/WebAnimations/transition-unknown-property.html b/Tests/LibWeb/Text/input/WebAnimations/transition-unknown-property.html new file mode 100644 index 00000000000..189029b9751 --- /dev/null +++ b/Tests/LibWeb/Text/input/WebAnimations/transition-unknown-property.html @@ -0,0 +1,15 @@ + +
+ + diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index fa9322f2cb0..d359e3f268f 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -1220,79 +1220,82 @@ static void compute_transitioned_properties(StyleProperties const& style, DOM::E // FIXME: Implement transitioning for pseudo-elements (void)pseudo_element; - if (auto const source_declaration = style.transition_property_source(); source_declaration && element.computed_css_values()) { - if (source_declaration != element.cached_transition_property_source()) { - // Reparse this transition property - element.clear_transitions(); - element.set_cached_transition_property_source(*source_declaration); + auto const source_declaration = style.transition_property_source(); + if (!source_declaration) + return; + if (!element.computed_css_values()) + return; + if (source_declaration == element.cached_transition_property_source()) + return; + // Reparse this transition property + element.clear_transitions(); + element.set_cached_transition_property_source(*source_declaration); - auto transition_properties_value = style.property(PropertyID::TransitionProperty); - auto transition_properties = transition_properties_value->is_value_list() - ? transition_properties_value->as_value_list().values() - : StyleValueVector { transition_properties_value }; + auto transition_properties_value = style.property(PropertyID::TransitionProperty); + auto transition_properties = transition_properties_value->is_value_list() + ? transition_properties_value->as_value_list().values() + : StyleValueVector { transition_properties_value }; - auto normalize_transition_length_list = [&](PropertyID property, auto make_default_value) { - auto style_value = style.maybe_null_property(property); - StyleValueVector list; + Vector> properties; - if (!style_value || !style_value->is_value_list() || style_value->as_value_list().size() == 0) { - auto default_value = make_default_value(); - for (size_t i = 0; i < transition_properties.size(); i++) - list.append(default_value); - return list; - } + for (size_t i = 0; i < transition_properties.size(); i++) { + auto property_value = transition_properties[i]; + Vector properties_for_this_transition; - auto const& value_list = style_value->as_value_list(); - for (size_t i = 0; i < transition_properties.size(); i++) - list.append(value_list.value_at(i, true)); - - return list; - }; - - auto delays = normalize_transition_length_list( - PropertyID::TransitionDelay, - [] { return TimeStyleValue::create(Time::make_seconds(0.0)); }); - auto durations = normalize_transition_length_list( - PropertyID::TransitionDuration, - [] { return TimeStyleValue::create(Time::make_seconds(0.0)); }); - auto timing_functions = normalize_transition_length_list( - PropertyID::TransitionTimingFunction, - [] { return EasingStyleValue::create(EasingStyleValue::CubicBezier::ease()); }); - - Vector> properties; - - for (size_t i = 0; i < transition_properties.size(); i++) { - auto property_value = transition_properties[i]; - Vector properties_for_this_transition; - - if (property_value->is_keyword()) { - auto keyword = property_value->as_keyword().keyword(); - if (keyword == Keyword::None) - continue; - if (keyword == Keyword::All) { - for (auto prop = first_property_id; prop != last_property_id; prop = static_cast(to_underlying(prop) + 1)) - properties_for_this_transition.append(prop); - } - } else { - auto maybe_property = property_id_from_string(property_value->as_custom_ident().custom_ident()); - if (!maybe_property.has_value()) - continue; - - auto transition_property = maybe_property.release_value(); - if (property_is_shorthand(transition_property)) { - for (auto const& prop : longhands_for_shorthand(transition_property)) - properties_for_this_transition.append(prop); - } else { - properties_for_this_transition.append(transition_property); - } - } - - properties.append(move(properties_for_this_transition)); + if (property_value->is_keyword()) { + auto keyword = property_value->as_keyword().keyword(); + if (keyword == Keyword::None) + continue; + if (keyword == Keyword::All) { + for (auto prop = first_property_id; prop != last_property_id; prop = static_cast(to_underlying(prop) + 1)) + properties_for_this_transition.append(prop); } + } else { + auto maybe_property = property_id_from_string(property_value->as_custom_ident().custom_ident()); + if (!maybe_property.has_value()) + continue; - element.add_transitioned_properties(move(properties), move(delays), move(durations), move(timing_functions)); + auto transition_property = maybe_property.release_value(); + if (property_is_shorthand(transition_property)) { + for (auto const& prop : longhands_for_shorthand(transition_property)) + properties_for_this_transition.append(prop); + } else { + properties_for_this_transition.append(transition_property); + } } + + properties.append(move(properties_for_this_transition)); } + + auto normalize_transition_length_list = [&properties, &style](PropertyID property, auto make_default_value) { + auto style_value = style.maybe_null_property(property); + StyleValueVector list; + + if (!style_value || !style_value->is_value_list() || style_value->as_value_list().size() == 0) { + auto default_value = make_default_value(); + for (size_t i = 0; i < properties.size(); i++) + list.append(default_value); + return list; + } + + auto const& value_list = style_value->as_value_list(); + for (size_t i = 0; i < properties.size(); i++) + list.append(value_list.value_at(i, true)); + + return list; + }; + + auto delays = normalize_transition_length_list( + PropertyID::TransitionDelay, + [] { return TimeStyleValue::create(Time::make_seconds(0.0)); }); + auto durations = normalize_transition_length_list( + PropertyID::TransitionDuration, + [] { return TimeStyleValue::create(Time::make_seconds(0.0)); }); + auto timing_functions = normalize_transition_length_list( + PropertyID::TransitionTimingFunction, + [] { return EasingStyleValue::create(EasingStyleValue::CubicBezier::ease()); }); + + element.add_transitioned_properties(move(properties), move(delays), move(durations), move(timing_functions)); } // https://drafts.csswg.org/css-transitions/#starting