mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-01 05:39:11 +00:00
LibWeb: Parse font-variant-* css properties
This commit is contained in:
parent
8bd94e2593
commit
aabbe87628
Notes:
github-actions[bot]
2024-12-17 18:08:36 +00:00
Author: https://github.com/jdahlin
Commit: aabbe87628
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2197
Reviewed-by: https://github.com/AtkinsSJ
Reviewed-by: https://github.com/gmta ✅
Reviewed-by: https://github.com/kalenikaliaksandr
Reviewed-by: https://github.com/tcl3
2 changed files with 484 additions and 0 deletions
|
@ -6056,6 +6056,459 @@ RefPtr<CSSStyleValue> Parser::parse_font_variation_settings_value(TokenStream<Co
|
||||||
return StyleValueList::create(move(axis_tags), StyleValueList::Separator::Comma);
|
return StyleValueList::create(move(axis_tags), StyleValueList::Separator::Comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefPtr<CSSStyleValue> Parser::parse_font_variant(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// 6.11 https://drafts.csswg.org/css-fonts/#propdef-font-variant
|
||||||
|
// normal | none |
|
||||||
|
// [ [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]
|
||||||
|
// || [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ] ||
|
||||||
|
// [ FIXME: stylistic(<feature-value-name>) ||
|
||||||
|
// historical-forms ||
|
||||||
|
// FIXME: styleset(<feature-value-name>#) ||
|
||||||
|
// FIXME: character-variant(<feature-value-name>#) ||
|
||||||
|
// FIXME: swash(<feature-value-name>) ||
|
||||||
|
// FIXME: ornaments(<feature-value-name>) ||
|
||||||
|
// FIXME: annotation(<feature-value-name>) ] ||
|
||||||
|
// [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> ||
|
||||||
|
// ordinal || slashed-zero ] || [ <east-asian-variant-values> || <east-asian-width-values> || ruby ] ||
|
||||||
|
// [ sub | super ] || [ text | emoji | unicode ] ]
|
||||||
|
|
||||||
|
bool has_common_ligatures = false;
|
||||||
|
bool has_discretionary_ligatures = false;
|
||||||
|
bool has_historical_ligatures = false;
|
||||||
|
bool has_contextual = false;
|
||||||
|
bool has_numeric_figures = false;
|
||||||
|
bool has_numeric_spacing = false;
|
||||||
|
bool has_numeric_fractions = false;
|
||||||
|
bool has_numeric_ordinals = false;
|
||||||
|
bool has_numeric_slashed_zero = false;
|
||||||
|
bool has_east_asian_variant = false;
|
||||||
|
bool has_east_asian_width = false;
|
||||||
|
bool has_east_asian_ruby = false;
|
||||||
|
RefPtr<CSSStyleValue> alternates_value {};
|
||||||
|
RefPtr<CSSStyleValue> caps_value {};
|
||||||
|
RefPtr<CSSStyleValue> emoji_value {};
|
||||||
|
RefPtr<CSSStyleValue> position_value {};
|
||||||
|
StyleValueVector east_asian_values;
|
||||||
|
StyleValueVector ligatures_values;
|
||||||
|
StyleValueVector numeric_values;
|
||||||
|
|
||||||
|
if (auto parsed_value = parse_all_as_single_keyword_value(tokens, Keyword::Normal)) {
|
||||||
|
// normal, do nothing
|
||||||
|
} else if (auto parsed_value = parse_all_as_single_keyword_value(tokens, Keyword::None)) {
|
||||||
|
// none
|
||||||
|
ligatures_values.append(parsed_value.release_nonnull());
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while (tokens.has_next_token()) {
|
||||||
|
auto maybe_value = parse_keyword_value(tokens);
|
||||||
|
if (!maybe_value)
|
||||||
|
break;
|
||||||
|
auto value = maybe_value.release_nonnull();
|
||||||
|
if (!value->is_keyword()) {
|
||||||
|
// FIXME: alternate functions such as stylistic()
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto keyword = value->to_keyword();
|
||||||
|
|
||||||
|
switch (keyword) {
|
||||||
|
// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
|
||||||
|
case Keyword::CommonLigatures:
|
||||||
|
case Keyword::NoCommonLigatures:
|
||||||
|
if (has_common_ligatures)
|
||||||
|
return nullptr;
|
||||||
|
ligatures_values.append(move(value));
|
||||||
|
has_common_ligatures = true;
|
||||||
|
break;
|
||||||
|
// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
|
||||||
|
case Keyword::DiscretionaryLigatures:
|
||||||
|
case Keyword::NoDiscretionaryLigatures:
|
||||||
|
if (has_discretionary_ligatures)
|
||||||
|
return nullptr;
|
||||||
|
ligatures_values.append(move(value));
|
||||||
|
has_discretionary_ligatures = true;
|
||||||
|
break;
|
||||||
|
// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
|
||||||
|
case Keyword::HistoricalLigatures:
|
||||||
|
case Keyword::NoHistoricalLigatures:
|
||||||
|
if (has_historical_ligatures)
|
||||||
|
return nullptr;
|
||||||
|
ligatures_values.append(move(value));
|
||||||
|
has_historical_ligatures = true;
|
||||||
|
break;
|
||||||
|
// <contextual-alt-values> = [ contextual | no-contextual ]
|
||||||
|
case Keyword::Contextual:
|
||||||
|
case Keyword::NoContextual:
|
||||||
|
if (has_contextual)
|
||||||
|
return nullptr;
|
||||||
|
ligatures_values.append(move(value));
|
||||||
|
has_contextual = true;
|
||||||
|
break;
|
||||||
|
// historical-forms
|
||||||
|
case Keyword::HistoricalForms:
|
||||||
|
if (alternates_value != nullptr)
|
||||||
|
return nullptr;
|
||||||
|
alternates_value = value.ptr();
|
||||||
|
break;
|
||||||
|
// [ small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps ]
|
||||||
|
case Keyword::SmallCaps:
|
||||||
|
case Keyword::AllSmallCaps:
|
||||||
|
case Keyword::PetiteCaps:
|
||||||
|
case Keyword::AllPetiteCaps:
|
||||||
|
case Keyword::Unicase:
|
||||||
|
case Keyword::TitlingCaps:
|
||||||
|
if (caps_value != nullptr)
|
||||||
|
return nullptr;
|
||||||
|
caps_value = value.ptr();
|
||||||
|
break;
|
||||||
|
// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
|
||||||
|
case Keyword::LiningNums:
|
||||||
|
case Keyword::OldstyleNums:
|
||||||
|
if (has_numeric_figures)
|
||||||
|
return nullptr;
|
||||||
|
numeric_values.append(move(value));
|
||||||
|
has_numeric_figures = true;
|
||||||
|
break;
|
||||||
|
// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
|
||||||
|
case Keyword::ProportionalNums:
|
||||||
|
case Keyword::TabularNums:
|
||||||
|
if (has_numeric_spacing)
|
||||||
|
return nullptr;
|
||||||
|
numeric_values.append(move(value));
|
||||||
|
has_numeric_spacing = true;
|
||||||
|
break;
|
||||||
|
// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions]
|
||||||
|
case Keyword::DiagonalFractions:
|
||||||
|
case Keyword::StackedFractions:
|
||||||
|
if (has_numeric_fractions)
|
||||||
|
return nullptr;
|
||||||
|
numeric_values.append(move(value));
|
||||||
|
has_numeric_fractions = true;
|
||||||
|
break;
|
||||||
|
// ordinal
|
||||||
|
case Keyword::Ordinal:
|
||||||
|
if (has_numeric_ordinals)
|
||||||
|
return nullptr;
|
||||||
|
numeric_values.append(move(value));
|
||||||
|
has_numeric_ordinals = true;
|
||||||
|
break;
|
||||||
|
case Keyword::SlashedZero:
|
||||||
|
if (has_numeric_slashed_zero)
|
||||||
|
return nullptr;
|
||||||
|
numeric_values.append(move(value));
|
||||||
|
has_numeric_slashed_zero = true;
|
||||||
|
break;
|
||||||
|
// <east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
|
||||||
|
case Keyword::Jis78:
|
||||||
|
case Keyword::Jis83:
|
||||||
|
case Keyword::Jis90:
|
||||||
|
case Keyword::Jis04:
|
||||||
|
case Keyword::Simplified:
|
||||||
|
case Keyword::Traditional:
|
||||||
|
if (has_east_asian_variant)
|
||||||
|
return nullptr;
|
||||||
|
east_asian_values.append(move(value));
|
||||||
|
has_east_asian_variant = true;
|
||||||
|
break;
|
||||||
|
// <east-asian-width-values> = [ full-width | proportional-width ]
|
||||||
|
case Keyword::FullWidth:
|
||||||
|
case Keyword::ProportionalWidth:
|
||||||
|
if (has_east_asian_width)
|
||||||
|
return nullptr;
|
||||||
|
east_asian_values.append(move(value));
|
||||||
|
has_east_asian_width = true;
|
||||||
|
break;
|
||||||
|
// ruby
|
||||||
|
case Keyword::Ruby:
|
||||||
|
if (has_east_asian_ruby)
|
||||||
|
return nullptr;
|
||||||
|
east_asian_values.append(move(value));
|
||||||
|
has_east_asian_ruby = true;
|
||||||
|
break;
|
||||||
|
// text | emoji | unicode
|
||||||
|
case Keyword::Text:
|
||||||
|
case Keyword::Emoji:
|
||||||
|
case Keyword::Unicode:
|
||||||
|
if (emoji_value != nullptr)
|
||||||
|
return nullptr;
|
||||||
|
emoji_value = value.ptr();
|
||||||
|
break;
|
||||||
|
// sub | super
|
||||||
|
case Keyword::Sub:
|
||||||
|
case Keyword::Super:
|
||||||
|
if (position_value != nullptr)
|
||||||
|
return nullptr;
|
||||||
|
position_value = value.ptr();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ligatures_values.is_empty())
|
||||||
|
ligatures_values.append(CSSKeywordValue::create(Keyword::Normal));
|
||||||
|
if (numeric_values.is_empty())
|
||||||
|
numeric_values.append(CSSKeywordValue::create(Keyword::Normal));
|
||||||
|
if (east_asian_values.is_empty())
|
||||||
|
east_asian_values.append(CSSKeywordValue::create(Keyword::Normal));
|
||||||
|
|
||||||
|
return ShorthandStyleValue::create(PropertyID::FontVariant,
|
||||||
|
{ PropertyID::FontVariantAlternates,
|
||||||
|
PropertyID::FontVariantCaps,
|
||||||
|
PropertyID::FontVariantEastAsian,
|
||||||
|
PropertyID::FontVariantEmoji,
|
||||||
|
PropertyID::FontVariantLigatures,
|
||||||
|
PropertyID::FontVariantNumeric,
|
||||||
|
PropertyID::FontVariantPosition },
|
||||||
|
{
|
||||||
|
alternates_value == nullptr ? CSSKeywordValue::create(Keyword::Normal) : alternates_value.release_nonnull(),
|
||||||
|
caps_value == nullptr ? CSSKeywordValue::create(Keyword::Normal) : caps_value.release_nonnull(),
|
||||||
|
StyleValueList::create(move(east_asian_values), StyleValueList::Separator::Space),
|
||||||
|
emoji_value == nullptr ? CSSKeywordValue::create(Keyword::Normal) : emoji_value.release_nonnull(),
|
||||||
|
StyleValueList::create(move(ligatures_values), StyleValueList::Separator::Space),
|
||||||
|
StyleValueList::create(move(numeric_values), StyleValueList::Separator::Space),
|
||||||
|
position_value == nullptr ? CSSKeywordValue::create(Keyword::Normal) : position_value.release_nonnull(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<CSSStyleValue> Parser::parse_font_variant_alternates_value(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// 6.8 https://drafts.csswg.org/css-fonts/#font-variant-alternates-prop
|
||||||
|
// normal |
|
||||||
|
// [ FIXME: stylistic(<feature-value-name>) ||
|
||||||
|
// historical-forms ||
|
||||||
|
// FIXME: styleset(<feature-value-name>#) ||
|
||||||
|
// FIXME: character-variant(<feature-value-name>#) ||
|
||||||
|
// FIXME: swash(<feature-value-name>) ||
|
||||||
|
// FIXME: ornaments(<feature-value-name>) ||
|
||||||
|
// FIXME: annotation(<feature-value-name>) ]
|
||||||
|
|
||||||
|
// normal
|
||||||
|
if (auto normal = parse_all_as_single_keyword_value(tokens, Keyword::Normal))
|
||||||
|
return normal;
|
||||||
|
|
||||||
|
// historical-forms
|
||||||
|
// FIXME: Support this together with other values when we parse them.
|
||||||
|
if (auto historical_forms = parse_all_as_single_keyword_value(tokens, Keyword::HistoricalForms))
|
||||||
|
return historical_forms;
|
||||||
|
|
||||||
|
dbgln_if(CSS_PARSER_DEBUG, "CSSParser: @font-variant-alternate: parsing {} not implemented.", tokens.next_token().to_debug_string());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: This should not be needed, however http://wpt.live/css/css-fonts/font-variant-caps.html fails without it
|
||||||
|
RefPtr<CSSStyleValue> Parser::parse_font_variant_caps_value(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// https://drafts.csswg.org/css-fonts/#propdef-font-variant-caps
|
||||||
|
// normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps
|
||||||
|
|
||||||
|
bool has_token = false;
|
||||||
|
while (tokens.has_next_token()) {
|
||||||
|
if (has_token)
|
||||||
|
break;
|
||||||
|
auto maybe_value = parse_keyword_value(tokens);
|
||||||
|
if (!maybe_value)
|
||||||
|
break;
|
||||||
|
auto value = maybe_value.release_nonnull();
|
||||||
|
auto font_variant = keyword_to_font_variant_caps(value->to_keyword());
|
||||||
|
if (font_variant.has_value()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<CSSStyleValue> Parser::parse_font_variant_east_asian_value(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// 6.10 https://drafts.csswg.org/css-fonts/#propdef-font-variant-east-asian
|
||||||
|
// normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]
|
||||||
|
// <east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
|
||||||
|
// <east-asian-width-values> = [ full-width | proportional-width ]
|
||||||
|
|
||||||
|
StyleValueVector value_list;
|
||||||
|
bool has_ruby = false;
|
||||||
|
bool has_variant = false;
|
||||||
|
bool has_width = false;
|
||||||
|
|
||||||
|
// normal | ...
|
||||||
|
if (auto normal = parse_all_as_single_keyword_value(tokens, Keyword::Normal)) {
|
||||||
|
value_list.append(normal.release_nonnull());
|
||||||
|
} else {
|
||||||
|
while (tokens.has_next_token()) {
|
||||||
|
auto maybe_value = parse_keyword_value(tokens);
|
||||||
|
if (!maybe_value)
|
||||||
|
break;
|
||||||
|
auto value = maybe_value.release_nonnull();
|
||||||
|
auto font_variant = keyword_to_font_variant_east_asian(value->to_keyword());
|
||||||
|
if (!font_variant.has_value()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto keyword = value->to_keyword();
|
||||||
|
if (keyword == Keyword::Ruby) {
|
||||||
|
if (has_ruby)
|
||||||
|
return nullptr;
|
||||||
|
has_ruby = true;
|
||||||
|
} else if (keyword == Keyword::FullWidth || keyword == Keyword::ProportionalWidth) {
|
||||||
|
if (has_width)
|
||||||
|
return nullptr;
|
||||||
|
has_width = true;
|
||||||
|
} else {
|
||||||
|
if (has_variant)
|
||||||
|
return nullptr;
|
||||||
|
has_variant = true;
|
||||||
|
}
|
||||||
|
value_list.append(move(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value_list.is_empty())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return StyleValueList::create(move(value_list), StyleValueList::Separator::Space);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<CSSStyleValue> Parser::parse_font_variant_ligatures_value(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// 6.4 https://drafts.csswg.org/css-fonts/#propdef-font-variant-ligatures
|
||||||
|
// normal | none | [ <common-lig-values> || <discretionary-lig-values> || <historical-lig-values> || <contextual-alt-values> ]
|
||||||
|
// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
|
||||||
|
// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
|
||||||
|
// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
|
||||||
|
// <contextual-alt-values> = [ contextual | no-contextual ]
|
||||||
|
|
||||||
|
StyleValueVector value_list;
|
||||||
|
bool has_common_ligatures = false;
|
||||||
|
bool has_discretionary_ligatures = false;
|
||||||
|
bool has_historical_ligatures = false;
|
||||||
|
bool has_contextual = false;
|
||||||
|
|
||||||
|
// normal | ...
|
||||||
|
if (auto normal = parse_all_as_single_keyword_value(tokens, Keyword::Normal)) {
|
||||||
|
value_list.append(normal.release_nonnull());
|
||||||
|
// none | ...
|
||||||
|
} else if (auto none = parse_all_as_single_keyword_value(tokens, Keyword::None)) {
|
||||||
|
value_list.append(none.release_nonnull());
|
||||||
|
} else {
|
||||||
|
while (tokens.has_next_token()) {
|
||||||
|
auto maybe_value = parse_keyword_value(tokens);
|
||||||
|
if (!maybe_value)
|
||||||
|
break;
|
||||||
|
auto value = maybe_value.release_nonnull();
|
||||||
|
switch (value->to_keyword()) {
|
||||||
|
// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
|
||||||
|
case Keyword::CommonLigatures:
|
||||||
|
case Keyword::NoCommonLigatures:
|
||||||
|
if (has_common_ligatures)
|
||||||
|
return nullptr;
|
||||||
|
has_common_ligatures = true;
|
||||||
|
break;
|
||||||
|
// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
|
||||||
|
case Keyword::DiscretionaryLigatures:
|
||||||
|
case Keyword::NoDiscretionaryLigatures:
|
||||||
|
if (has_discretionary_ligatures)
|
||||||
|
return nullptr;
|
||||||
|
has_discretionary_ligatures = true;
|
||||||
|
break;
|
||||||
|
// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
|
||||||
|
case Keyword::HistoricalLigatures:
|
||||||
|
case Keyword::NoHistoricalLigatures:
|
||||||
|
if (has_historical_ligatures)
|
||||||
|
return nullptr;
|
||||||
|
has_historical_ligatures = true;
|
||||||
|
break;
|
||||||
|
// <contextual-alt-values> = [ contextual | no-contextual ]
|
||||||
|
case Keyword::Contextual:
|
||||||
|
case Keyword::NoContextual:
|
||||||
|
if (has_contextual)
|
||||||
|
return nullptr;
|
||||||
|
has_contextual = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
value_list.append(move(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value_list.is_empty())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return StyleValueList::create(move(value_list), StyleValueList::Separator::Space);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<CSSStyleValue> Parser::parse_font_variant_numeric_value(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// 6.7 https://drafts.csswg.org/css-fonts/#propdef-font-variant-numeric
|
||||||
|
// normal | [ <numeric-figure-values> || <numeric-spacing-values> || <numeric-fraction-values> || ordinal || slashed-zero]
|
||||||
|
// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
|
||||||
|
// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
|
||||||
|
// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
|
||||||
|
|
||||||
|
StyleValueVector value_list;
|
||||||
|
bool has_figures = false;
|
||||||
|
bool has_spacing = false;
|
||||||
|
bool has_fractions = false;
|
||||||
|
bool has_ordinals = false;
|
||||||
|
bool has_slashed_zero = false;
|
||||||
|
|
||||||
|
// normal | ...
|
||||||
|
if (auto normal = parse_all_as_single_keyword_value(tokens, Keyword::Normal)) {
|
||||||
|
value_list.append(normal.release_nonnull());
|
||||||
|
} else {
|
||||||
|
while (tokens.has_next_token()) {
|
||||||
|
auto maybe_value = parse_keyword_value(tokens);
|
||||||
|
if (!maybe_value)
|
||||||
|
break;
|
||||||
|
auto value = maybe_value.release_nonnull();
|
||||||
|
switch (value->to_keyword()) {
|
||||||
|
// ... || ordinal
|
||||||
|
case Keyword::Ordinal:
|
||||||
|
if (has_ordinals)
|
||||||
|
return nullptr;
|
||||||
|
has_ordinals = true;
|
||||||
|
break;
|
||||||
|
// ... || slashed-zero
|
||||||
|
case Keyword::SlashedZero:
|
||||||
|
if (has_slashed_zero)
|
||||||
|
return nullptr;
|
||||||
|
has_slashed_zero = true;
|
||||||
|
break;
|
||||||
|
// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
|
||||||
|
case Keyword::LiningNums:
|
||||||
|
case Keyword::OldstyleNums:
|
||||||
|
if (has_figures)
|
||||||
|
return nullptr;
|
||||||
|
has_figures = true;
|
||||||
|
break;
|
||||||
|
// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
|
||||||
|
case Keyword::ProportionalNums:
|
||||||
|
case Keyword::TabularNums:
|
||||||
|
if (has_spacing)
|
||||||
|
return nullptr;
|
||||||
|
has_spacing = true;
|
||||||
|
break;
|
||||||
|
// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
|
||||||
|
case Keyword::DiagonalFractions:
|
||||||
|
case Keyword::StackedFractions:
|
||||||
|
if (has_fractions)
|
||||||
|
return nullptr;
|
||||||
|
has_fractions = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
value_list.append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value_list.is_empty())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return StyleValueList::create(move(value_list), StyleValueList::Separator::Space);
|
||||||
|
}
|
||||||
|
|
||||||
Vector<ParsedFontFace::Source> Parser::parse_as_font_face_src()
|
Vector<ParsedFontFace::Source> Parser::parse_as_font_face_src()
|
||||||
{
|
{
|
||||||
return parse_font_face_src(m_token_stream);
|
return parse_font_face_src(m_token_stream);
|
||||||
|
@ -8046,6 +8499,30 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue>> Parser::parse_css_value(Prope
|
||||||
if (auto parsed_value = parse_font_variation_settings_value(tokens); parsed_value && !tokens.has_next_token())
|
if (auto parsed_value = parse_font_variation_settings_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
return parsed_value.release_nonnull();
|
return parsed_value.release_nonnull();
|
||||||
return ParseError::SyntaxError;
|
return ParseError::SyntaxError;
|
||||||
|
case PropertyID::FontVariant:
|
||||||
|
if (auto parsed_value = parse_font_variant(tokens); parsed_value && !tokens.has_next_token())
|
||||||
|
return parsed_value.release_nonnull();
|
||||||
|
return ParseError::SyntaxError;
|
||||||
|
case PropertyID::FontVariantAlternates:
|
||||||
|
if (auto parsed_value = parse_font_variant_alternates_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
|
return parsed_value.release_nonnull();
|
||||||
|
return ParseError::SyntaxError;
|
||||||
|
case PropertyID::FontVariantCaps:
|
||||||
|
if (auto parsed_value = parse_font_variant_caps_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
|
return parsed_value.release_nonnull();
|
||||||
|
return ParseError::SyntaxError;
|
||||||
|
case PropertyID::FontVariantEastAsian:
|
||||||
|
if (auto parsed_value = parse_font_variant_east_asian_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
|
return parsed_value.release_nonnull();
|
||||||
|
return ParseError::SyntaxError;
|
||||||
|
case PropertyID::FontVariantLigatures:
|
||||||
|
if (auto parsed_value = parse_font_variant_ligatures_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
|
return parsed_value.release_nonnull();
|
||||||
|
return ParseError::SyntaxError;
|
||||||
|
case PropertyID::FontVariantNumeric:
|
||||||
|
if (auto parsed_value = parse_font_variant_numeric_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
|
return parsed_value.release_nonnull();
|
||||||
|
return ParseError::SyntaxError;
|
||||||
case PropertyID::GridArea:
|
case PropertyID::GridArea:
|
||||||
if (auto parsed_value = parse_grid_area_shorthand_value(tokens); parsed_value && !tokens.has_next_token())
|
if (auto parsed_value = parse_grid_area_shorthand_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
return parsed_value.release_nonnull();
|
return parsed_value.release_nonnull();
|
||||||
|
|
|
@ -330,6 +330,13 @@ private:
|
||||||
RefPtr<CSSStyleValue> parse_font_language_override_value(TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue> parse_font_language_override_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<CSSStyleValue> parse_font_feature_settings_value(TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue> parse_font_feature_settings_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<CSSStyleValue> parse_font_variation_settings_value(TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue> parse_font_variation_settings_value(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<CSSStyleValue> parse_font_variant(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<CSSStyleValue> parse_font_variant_alternates_value(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<CSSStyleValue> parse_font_variant_caps_value(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<CSSStyleValue> parse_font_variant_east_asian_value(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<CSSStyleValue> parse_font_variant_emoji(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<CSSStyleValue> parse_font_variant_ligatures_value(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<CSSStyleValue> parse_font_variant_numeric_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<CSSStyleValue> parse_list_style_value(TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue> parse_list_style_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<CSSStyleValue> parse_math_depth_value(TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue> parse_math_depth_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<CSSStyleValue> parse_overflow_value(TokenStream<ComponentValue>&);
|
RefPtr<CSSStyleValue> parse_overflow_value(TokenStream<ComponentValue>&);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue