1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-15 09:57:35 +00:00

LibWeb: Resolve CSS list-style from value list

This resolves the three sub-properties, appearing in any order:

- list-style-image
- list-style-position
- list-style-type

Added `list-style-position` values to support this, though they are not
yet used in rendering.
This commit is contained in:
Sam Atkins 2021-07-20 16:11:19 +01:00 committed by Andreas Kling
parent b693a22c2d
commit a44d7670ab
3 changed files with 99 additions and 6 deletions

View file

@ -99,6 +99,7 @@
"inline", "inline",
"inline-block", "inline-block",
"inset", "inset",
"inside",
"justify", "justify",
"large", "large",
"larger", "larger",
@ -125,6 +126,7 @@
"nw-resize", "nw-resize",
"nwse-resize", "nwse-resize",
"outset", "outset",
"outside",
"overline", "overline",
"pointer", "pointer",
"pre", "pre",

View file

@ -1621,7 +1621,6 @@ RefPtr<StyleValue> Parser::parse_css_value(PropertyID property_id, TokenStream<S
RefPtr<StyleValue> Parser::parse_css_value(ParsingContext const& context, PropertyID property_id, StyleComponentValueRule const& component_value) RefPtr<StyleValue> Parser::parse_css_value(ParsingContext const& context, PropertyID property_id, StyleComponentValueRule const& component_value)
{ {
dbgln_if(CSS_PARSER_TRACE, "Parser::parse_css_value '{}'", component_value.to_debug_string()); dbgln_if(CSS_PARSER_TRACE, "Parser::parse_css_value '{}'", component_value.to_debug_string());
// FIXME: Figure out if we still need takes_integer_value, and if so, move this information // FIXME: Figure out if we still need takes_integer_value, and if so, move this information
// into Properties.json. // into Properties.json.
auto takes_integer_value = [](PropertyID property_id) -> bool { auto takes_integer_value = [](PropertyID property_id) -> bool {

View file

@ -335,6 +335,56 @@ static inline bool is_line_width(StyleValue const& value)
} }
} }
static inline bool is_list_style_image(StyleValue const& value)
{
if (value.is_builtin_or_dynamic())
return true;
if (value.is_image())
return true;
if (value.is_identifier() && value.to_identifier() == ValueID::None)
return true;
return false;
}
static inline bool is_list_style_position(StyleValue const& value)
{
if (value.is_builtin_or_dynamic())
return true;
switch (value.to_identifier()) {
case ValueID::Inside:
case ValueID::Outside:
return true;
default:
return false;
}
}
static inline bool is_list_style_type(StyleValue const& value)
{
if (value.is_builtin_or_dynamic())
return true;
// FIXME: Handle strings and symbols("...") syntax
switch (value.to_identifier()) {
case CSS::ValueID::None:
case CSS::ValueID::Disc:
case CSS::ValueID::Circle:
case CSS::ValueID::Square:
case CSS::ValueID::Decimal:
case CSS::ValueID::DecimalLeadingZero:
case CSS::ValueID::LowerAlpha:
case CSS::ValueID::LowerLatin:
case CSS::ValueID::UpperAlpha:
case CSS::ValueID::UpperLatin:
case CSS::ValueID::UpperRoman:
case CSS::ValueID::LowerRoman:
return true;
default:
return true;
}
}
static void set_property_expanding_shorthands(StyleProperties& style, CSS::PropertyID property_id, StyleValue const& value, DOM::Document& document, bool is_internally_generated_pseudo_property = false) static void set_property_expanding_shorthands(StyleProperties& style, CSS::PropertyID property_id, StyleValue const& value, DOM::Document& document, bool is_internally_generated_pseudo_property = false)
{ {
CSS::DeprecatedParsingContext deprecated_context(document); CSS::DeprecatedParsingContext deprecated_context(document);
@ -1202,17 +1252,59 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
return; return;
} }
// FIXME: Handle all three parts of ListStyle. (list-style-positon, list-style-image, list-style-type)
if (value.is_value_list()) { if (value.is_value_list()) {
auto parts = static_cast<CSS::ValueListStyleValue const&>(value).values(); auto parts = static_cast<CSS::ValueListStyleValue const&>(value).values();
if (!parts.is_empty()) {
auto list_style = Parser::parse_css_value(context, property_id, parts[0]); if (!parts.is_empty() && parts.size() <= 3) {
if (list_style) RefPtr<StyleValue> position_value;
style.set_property(CSS::PropertyID::ListStyleType, *list_style); RefPtr<StyleValue> image_value;
RefPtr<StyleValue> type_value;
// FIXME: `none` is ambiguous as it is a valid value for ListStyleImage and ListStyleType,
// so requires special handling. https://www.w3.org/TR/css-lists-3/#propdef-list-style
for (auto& part : parts) {
auto value = Parser::parse_css_value(context, property_id, part);
if (!value)
return;
if (is_list_style_position(*value)) {
if (position_value)
return;
position_value = move(value);
continue;
}
if (is_list_style_image(*value)) {
if (image_value)
return;
image_value = move(value);
continue;
}
if (is_list_style_type(*value)) {
if (type_value)
return;
type_value = move(value);
continue;
}
}
if (position_value)
style.set_property(CSS::PropertyID::ListStylePosition, *position_value);
if (image_value)
style.set_property(CSS::PropertyID::ListStyleImage, *image_value);
if (type_value)
style.set_property(CSS::PropertyID::ListStyleType, *type_value);
} }
return; return;
} }
if (is_list_style_position(value))
style.set_property(CSS::PropertyID::ListStylePosition, value);
else if (is_list_style_image(value))
style.set_property(CSS::PropertyID::ListStyleImage, value);
else if (is_list_style_type(value))
style.set_property(CSS::PropertyID::ListStyleType, value);
return; return;
} }