LibWeb: Don't extrapolate transition properties for unknown properties
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-22.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-14, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-22.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-22.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-22.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run

If we don't recognize a given transition-property value as a known CSS
property (one that we know about, not necessarily an invalid one),
we should not extrapolate the other transition-foo values for it.

Fixes #1480
This commit is contained in:
Andreas Kling 2024-09-24 20:19:54 +02:00 committed by Andreas Kling
parent de31ea5852
commit 9765a733d0
Notes: github-actions[bot] 2024-09-24 19:54:35 +00:00
3 changed files with 84 additions and 65 deletions

View file

@ -0,0 +1 @@
PASS (didn't crash)

View file

@ -0,0 +1,15 @@
<style>
#foo {
transition-property: filter;
transition-timing-function: linear;
transition-duration:.3s;
}
</style>
<div id="foo"></div>
<script src="../include.js"></script>
<script>
test(() => {
foo.offsetWidth;
println("PASS (didn't crash)");
});
</script>

View file

@ -1220,8 +1220,13 @@ static void compute_transitioned_properties(StyleProperties const& style, DOM::E
// FIXME: Implement transitioning for pseudo-elements // FIXME: Implement transitioning for pseudo-elements
(void)pseudo_element; (void)pseudo_element;
if (auto const source_declaration = style.transition_property_source(); source_declaration && element.computed_css_values()) { auto const source_declaration = style.transition_property_source();
if (source_declaration != element.cached_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 // Reparse this transition property
element.clear_transitions(); element.clear_transitions();
element.set_cached_transition_property_source(*source_declaration); element.set_cached_transition_property_source(*source_declaration);
@ -1231,34 +1236,6 @@ static void compute_transitioned_properties(StyleProperties const& style, DOM::E
? transition_properties_value->as_value_list().values() ? transition_properties_value->as_value_list().values()
: StyleValueVector { transition_properties_value }; : 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;
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;
}
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<Vector<PropertyID>> properties; Vector<Vector<PropertyID>> properties;
for (size_t i = 0; i < transition_properties.size(); i++) { for (size_t i = 0; i < transition_properties.size(); i++) {
@ -1290,10 +1267,36 @@ static void compute_transitioned_properties(StyleProperties const& style, DOM::E
properties.append(move(properties_for_this_transition)); 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)); element.add_transitioned_properties(move(properties), move(delays), move(durations), move(timing_functions));
} }
}
}
// https://drafts.csswg.org/css-transitions/#starting // https://drafts.csswg.org/css-transitions/#starting
void StyleComputer::start_needed_transitions(StyleProperties const& previous_style, StyleProperties& new_style, DOM::Element& element, Optional<Selector::PseudoElement::Type> pseudo_element) const void StyleComputer::start_needed_transitions(StyleProperties const& previous_style, StyleProperties& new_style, DOM::Element& element, Optional<Selector::PseudoElement::Type> pseudo_element) const