LibWeb/CSS: Ensure properties can be computed from "basic" StyleValues

This commit modifies the `compute_foo()` code for `font-style` and
`math-depth`. They previously assumed that their StyleValue was always
a special kind: FontStyleStyleValue or MathDepthStyleValue. This was
always true, because that's how we parse them, but it stops being true
once StylePropertyMap is involved: An author can set font-style to a
CSSKeywordValue of "italic", and this should work.

There are multiple ways that we could solve this, but the simplest and
easiest to maintain seems to be to handle those more basic StyleValues
in this computation code. Going forward, we'll have to be aware that
similar properties could have a basic StyleValue from the typed-OM
instead of the property-specific one we'd expect.
This commit is contained in:
Sam Atkins 2025-10-02 16:58:18 +01:00 committed by Andreas Kling
commit b3ad4be90c
Notes: github-actions[bot] 2025-10-04 20:58:44 +00:00

View file

@ -3404,6 +3404,10 @@ NonnullRefPtr<StyleValue const> StyleComputer::compute_font_style(NonnullRefPtr<
// https://drafts.csswg.org/css-fonts-4/#font-style-prop
// the keyword specified, plus angle in degrees if specified
// NB: We always parse as a FontStyleStyleValue, but StylePropertyMap is able to set a KeywordStyleValue directly.
if (specified_value->is_keyword())
return FontStyleStyleValue::create(*keyword_to_font_style(specified_value->to_keyword()));
auto const& angle_value = specified_value->as_font_style().angle();
if (!angle_value)
@ -3714,7 +3718,26 @@ void StyleComputer::compute_math_depth(ComputedProperties& style, Optional<DOM::
return element_to_inherit_style_from->computed_properties()->math_depth();
};
auto const& math_depth = style.property(CSS::PropertyID::MathDepth).as_math_depth();
// NB: We always parse as a MathDepthStyleValue, but StylePropertyMap is able to set other StyleValues directly.
// So, extract the properties we care about from it or other StyleValue types we might have.
bool is_auto_add = false;
bool is_add = false;
bool is_integer = false;
RefPtr<StyleValue const> integer_value;
auto const& property_value = style.property(PropertyID::MathDepth);
if (property_value.to_keyword() == Keyword::AutoAdd) {
is_auto_add = true;
} else if (property_value.is_integer() || property_value.is_calculated()) {
integer_value = property_value;
} else {
auto const& math_depth = property_value.as_math_depth();
is_auto_add = math_depth.is_auto_add();
is_add = math_depth.is_add();
is_integer = math_depth.is_integer();
if (is_integer || is_add)
integer_value = math_depth.integer_value();
}
auto resolve_integer = [&](StyleValue const& integer_value) {
if (integer_value.is_integer())
@ -3736,20 +3759,20 @@ void StyleComputer::compute_math_depth(ComputedProperties& style, Optional<DOM::
// The computed value of the math-depth value is determined as follows:
// - If the specified value of math-depth is auto-add and the inherited value of math-style is compact
// then the computed value of math-depth of the element is its inherited value plus one.
if (math_depth.is_auto_add() && inherited_math_style()->to_keyword() == Keyword::Compact) {
if (is_auto_add && inherited_math_style()->to_keyword() == Keyword::Compact) {
style.set_math_depth(inherited_math_depth() + 1);
return;
}
// - If the specified value of math-depth is of the form add(<integer>) then the computed value of
// math-depth of the element is its inherited value plus the specified integer.
if (math_depth.is_add()) {
style.set_math_depth(inherited_math_depth() + resolve_integer(*math_depth.integer_value()));
if (is_add) {
style.set_math_depth(inherited_math_depth() + resolve_integer(*integer_value));
return;
}
// - If the specified value of math-depth is of the form <integer> then the computed value of math-depth
// of the element is the specified integer.
if (math_depth.is_integer()) {
style.set_math_depth(resolve_integer(*math_depth.integer_value()));
if (is_integer) {
style.set_math_depth(resolve_integer(*integer_value));
return;
}
// - Otherwise, the computed value of math-depth of the element is the inherited one.