1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 03:18:11 +00:00

LibWeb: Implement and use ListStyleStyleValue

Yes, the name is silly, but it's a StyleValue for list-style, so...
yeah. :^)

Since `list-style-type` and `list-style-image` can both have `none` as a
value, and can appear in any order, we have to handle it separately, and
then assign either or both of those to `none` depending on how many
`none`s there are, and whether those sub-properties already have values.

Added some extra test cases to lists.html to cover list-style-image and
list-style-position parts of the list-style shorthand, and the `none`
values.
This commit is contained in:
Sam Atkins 2021-08-03 15:56:51 +01:00 committed by Andreas Kling
parent dcbfb61816
commit 0e15561df0
7 changed files with 246 additions and 98 deletions

View file

@ -336,56 +336,6 @@ 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 inline bool is_text_decoration_line(StyleValue const& value)
{
if (value.is_builtin_or_dynamic())
@ -868,59 +818,19 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
}
if (property_id == CSS::PropertyID::ListStyle) {
if (value.is_component_value_list()) {
auto parts = static_cast<CSS::ValueListStyleValue const&>(value).values();
if (!parts.is_empty() && parts.size() <= 3) {
RefPtr<StyleValue> position_value;
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);
}
if (value.is_list_style()) {
auto& list_style = static_cast<CSS::ListStyleStyleValue const&>(value);
style.set_property(CSS::PropertyID::ListStylePosition, list_style.position());
style.set_property(CSS::PropertyID::ListStyleImage, list_style.image());
style.set_property(CSS::PropertyID::ListStyleType, list_style.style_type());
return;
}
if (is_list_style_position(value))
if (value.is_builtin()) {
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;
}