diff --git a/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp b/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp index 6da75f69707..459f0a72a60 100644 --- a/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -343,6 +344,40 @@ Optional CSSStyleDeclaration::get_property_internal(PropertyID pr auto left = get_property_internal(PropertyID::BorderLeftWidth); return style_property_for_sided_shorthand(property_id, top, right, bottom, left); } + case PropertyID::FontVariant: { + auto ligatures = get_property_internal(PropertyID::FontVariantLigatures); + auto caps = get_property_internal(PropertyID::FontVariantCaps); + auto alternates = get_property_internal(PropertyID::FontVariantAlternates); + auto numeric = get_property_internal(PropertyID::FontVariantNumeric); + auto east_asian = get_property_internal(PropertyID::FontVariantEastAsian); + auto position = get_property_internal(PropertyID::FontVariantPosition); + auto emoji = get_property_internal(PropertyID::FontVariantEmoji); + + if (!ligatures.has_value() || !caps.has_value() || !alternates.has_value() || !numeric.has_value() || !east_asian.has_value() || !position.has_value() || !emoji.has_value()) + return {}; + + if (ligatures->important != caps->important || ligatures->important != alternates->important || ligatures->important != numeric->important || ligatures->important != east_asian->important || ligatures->important != position->important || ligatures->important != emoji->important) + return {}; + + // If ligatures is `none` and any other value isn't `normal`, that's invalid. + if (ligatures->value->to_keyword() == Keyword::None + && (caps->value->to_keyword() != Keyword::Normal + || alternates->value->to_keyword() != Keyword::Normal + || numeric->value->to_keyword() != Keyword::Normal + || east_asian->value->to_keyword() != Keyword::Normal + || position->value->to_keyword() != Keyword::Normal + || emoji->value->to_keyword() != Keyword::Normal)) { + return {}; + } + + return StyleProperty { + .important = ligatures->important, + .property_id = property_id, + .value = ShorthandStyleValue::create(property_id, + { PropertyID::FontVariantLigatures, PropertyID::FontVariantCaps, PropertyID::FontVariantAlternates, PropertyID::FontVariantNumeric, PropertyID::FontVariantEastAsian, PropertyID::FontVariantPosition, PropertyID::FontVariantEmoji }, + { ligatures->value, caps->value, alternates->value, numeric->value, east_asian->value, position->value, emoji->value }) + }; + } case PropertyID::Margin: { auto top = get_property_internal(PropertyID::MarginTop); auto right = get_property_internal(PropertyID::MarginRight); diff --git a/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp index c6614bce7fd..ca33d81182a 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp @@ -197,100 +197,33 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const return builder.to_string_without_validation(); } case PropertyID::FontVariant: { - Vector values; - auto ligatures_or_null = longhand(PropertyID::FontVariantLigatures)->to_font_variant_ligatures(); - if (ligatures_or_null.has_value()) { - auto ligatures = ligatures_or_null.release_value(); - if (ligatures.none) { - return MUST(String::formatted(""sv)); - } else { - if (ligatures.common == Gfx::FontVariantLigatures::Common::Common) - values.append("common-ligatures"sv); - else if (ligatures.common == Gfx::FontVariantLigatures::Common::NoCommon) - values.append("no-common-ligatures"sv); - if (ligatures.discretionary == Gfx::FontVariantLigatures::Discretionary::Discretionary) - values.append("discretionary-ligatures"sv); - else if (ligatures.discretionary == Gfx::FontVariantLigatures::Discretionary::NoDiscretionary) - values.append("no-discretionary-ligatures"sv); - if (ligatures.historical == Gfx::FontVariantLigatures::Historical::Historical) - values.append("historical-ligatures"sv); - else if (ligatures.historical == Gfx::FontVariantLigatures::Historical::NoHistorical) - values.append("no-historical-ligatures"sv); - if (ligatures.contextual == Gfx::FontVariantLigatures::Contextual::Contextual) - values.append("contextual"sv); - else if (ligatures.contextual == Gfx::FontVariantLigatures::Contextual::NoContextual) - values.append("no-contextual"sv); - } - } + auto ligatures = longhand(PropertyID::FontVariantLigatures); + auto caps = longhand(PropertyID::FontVariantCaps); + auto alternates = longhand(PropertyID::FontVariantAlternates); + auto numeric = longhand(PropertyID::FontVariantNumeric); + auto east_asian = longhand(PropertyID::FontVariantEastAsian); + auto position = longhand(PropertyID::FontVariantPosition); + auto emoji = longhand(PropertyID::FontVariantEmoji); - auto caps_or_null = longhand(PropertyID::FontVariantCaps)->to_font_variant_caps(); - if (caps_or_null.has_value() && caps_or_null.value() != CSS::FontVariantCaps::Normal) { - values.append(CSS::to_string(caps_or_null.release_value())); - } + Vector values; + if (ligatures->to_keyword() != Keyword::Normal) + values.append(ligatures->to_string(mode)); + if (caps->to_keyword() != Keyword::Normal) + values.append(caps->to_string(mode)); + if (alternates->to_keyword() != Keyword::Normal) + values.append(alternates->to_string(mode)); + if (numeric->to_keyword() != Keyword::Normal) + values.append(numeric->to_string(mode)); + if (east_asian->to_keyword() != Keyword::Normal) + values.append(east_asian->to_string(mode)); + if (position->to_keyword() != Keyword::Normal) + values.append(position->to_string(mode)); + if (emoji->to_keyword() != Keyword::Normal) + values.append(emoji->to_string(mode)); - auto emoji_or_null = longhand(PropertyID::FontVariantEmoji)->to_font_variant_emoji(); - if (emoji_or_null.has_value() && emoji_or_null.value() != CSS::FontVariantEmoji::Normal) { - values.append(CSS::to_string(emoji_or_null.release_value())); - } - - auto alternates_or_null = longhand(PropertyID::FontVariantAlternates)->to_font_variant_alternates(); - if (alternates_or_null.has_value()) - values.append("historical-forms"sv); - - auto numeric_or_null = longhand(PropertyID::FontVariantNumeric)->to_font_variant_numeric(); - if (numeric_or_null.has_value()) { - auto numeric = numeric_or_null.release_value(); - if (numeric.ordinal) - values.append("ordinal"sv); - if (numeric.slashed_zero) - values.append("slashed-zero"sv); - if (numeric.figure == Gfx::FontVariantNumeric::Figure::Oldstyle) - values.append("oldstyle-nums"sv); - else if (numeric.figure == Gfx::FontVariantNumeric::Figure::Lining) - values.append("lining-nums"sv); - if (numeric.spacing == Gfx::FontVariantNumeric::Spacing::Proportional) - values.append("proportional-nums"sv); - else if (numeric.spacing == Gfx::FontVariantNumeric::Spacing::Tabular) - values.append("tabular-nums"sv); - if (numeric.fraction == Gfx::FontVariantNumeric::Fraction::Diagonal) - values.append("diagonal-fractions"sv); - else if (numeric.fraction == Gfx::FontVariantNumeric::Fraction::Stacked) - values.append("stacked-fractions"sv); - } - auto east_asian_or_null = longhand(PropertyID::FontVariantEastAsian)->to_font_variant_east_asian(); - if (east_asian_or_null.has_value()) { - auto east_asian = east_asian_or_null.release_value(); - if (east_asian.ruby) - values.append("ruby"sv); - else { - if (east_asian.variant == Gfx::FontVariantEastAsian::Variant::Jis78) - values.append("jis78"sv); - else if (east_asian.variant == Gfx::FontVariantEastAsian::Variant::Jis83) - values.append("jis83"sv); - else if (east_asian.variant == Gfx::FontVariantEastAsian::Variant::Jis90) - values.append("jis90"sv); - else if (east_asian.variant == Gfx::FontVariantEastAsian::Variant::Jis04) - values.append("jis04"sv); - else if (east_asian.variant == Gfx::FontVariantEastAsian::Variant::Simplified) - values.append("simplified"sv); - else if (east_asian.variant == Gfx::FontVariantEastAsian::Variant::Traditional) - values.append("traditional"sv); - if (east_asian.width == Gfx::FontVariantEastAsian::Width::Proportional) - values.append("proportional-width"sv); - else if (east_asian.width == Gfx::FontVariantEastAsian::Width::FullWidth) - values.append("full-width"sv); - } - } - auto position_or_null = longhand(PropertyID::FontVariantPosition)->to_font_variant_position(); - if (position_or_null.has_value() && position_or_null.value() != CSS::FontVariantPosition::Normal) { - values.append(CSS::to_string(position_or_null.release_value())); - } - StringBuilder builder; if (values.is_empty()) - builder.append("normal"sv); - else - builder.join(' ', values); - return MUST(builder.to_string()); + return "normal"_string; + return MUST(String::join(' ', values)); } case PropertyID::GridArea: { auto& row_start = longhand(PropertyID::GridRowStart)->as_grid_track_placement(); diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-fonts/parsing/font-variant-valid.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-fonts/parsing/font-variant-valid.txt index 8406d2ee966..d3e995dd63d 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-fonts/parsing/font-variant-valid.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-fonts/parsing/font-variant-valid.txt @@ -2,8 +2,8 @@ Harness status: OK Found 46 tests -36 Pass -10 Fail +37 Pass +9 Fail Pass e.style['font-variant'] = "normal" should set the property value Pass e.style['font-variant'] = "none" should set the property value Pass e.style['font-variant'] = "common-ligatures" should set the property value @@ -49,4 +49,4 @@ Pass e.style['font-variant'] = "ruby" should set the property value Pass e.style['font-variant'] = "sub" should set the property value Pass e.style['font-variant'] = "super" should set the property value Fail e.style['font-variant'] = "common-ligatures discretionary-ligatures historical-ligatures contextual small-caps stylistic(flowing) lining-nums proportional-nums diagonal-fractions ordinal slashed-zero jis78 full-width ruby sub" should set the property value -Fail e.style['font-variant'] = "super proportional-width jis83 stacked-fractions tabular-nums oldstyle-nums historical-forms all-small-caps no-contextual no-historical-ligatures no-discretionary-ligatures no-common-ligatures" should set the property value \ No newline at end of file +Pass e.style['font-variant'] = "super proportional-width jis83 stacked-fractions tabular-nums oldstyle-nums historical-forms all-small-caps no-contextual no-historical-ligatures no-discretionary-ligatures no-common-ligatures" should set the property value \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/cssom/font-variant-shorthand-serialization.txt b/Tests/LibWeb/Text/expected/wpt-import/css/cssom/font-variant-shorthand-serialization.txt index 08f7267ed32..23ad6e3ade7 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/cssom/font-variant-shorthand-serialization.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/cssom/font-variant-shorthand-serialization.txt @@ -2,10 +2,10 @@ Harness status: OK Found 7 tests -4 Pass -3 Fail +5 Pass +2 Fail Pass font-variant: normal serialization -Fail font-variant: none serialization +Pass font-variant: none serialization Pass font-variant-ligatures: none serialization with non-default value for another longhand Pass font-variant: normal with non-default longhands Fail CSS-wide keyword in one longhand