summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/CSS/Parser
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@gmail.com>2021-08-03 15:56:51 +0100
committerAndreas Kling <kling@serenityos.org>2021-08-14 12:45:01 +0200
commit0e15561df08a5fe0d080cbd3a2dcb1b0c750a24b (patch)
treeb5324674ba0a4e1bec888b166859d0478e32b895 /Userland/Libraries/LibWeb/CSS/Parser
parentdcbfb618169858dcea1a654505c55f72b6e277b7 (diff)
downloadserenity-0e15561df08a5fe0d080cbd3a2dcb1b0c750a24b.zip
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.
Diffstat (limited to 'Userland/Libraries/LibWeb/CSS/Parser')
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp114
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.h1
2 files changed, 115 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index b222f02453..d933b8bcc5 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -2063,6 +2063,116 @@ RefPtr<StyleValue> Parser::parse_font_value(ParsingContext const& context, Vecto
return FontStyleValue::create(font_style.release_nonnull(), font_weight.release_nonnull(), font_size.release_nonnull(), line_height.release_nonnull(), move(font_families));
}
+RefPtr<StyleValue> Parser::parse_list_style_value(ParsingContext const& context, Vector<StyleComponentValueRule> const& component_values)
+{
+ auto is_list_style_image = [](StyleValue const& value) -> bool {
+ if (value.is_image())
+ return true;
+ if (value.is_identifier() && value.to_identifier() == ValueID::None)
+ return true;
+
+ return false;
+ };
+
+ auto is_list_style_position = [](StyleValue const& value) -> bool {
+ switch (value.to_identifier()) {
+ case ValueID::Inside:
+ case ValueID::Outside:
+ return true;
+ default:
+ return false;
+ }
+ };
+
+ auto is_list_style_type = [](StyleValue const& value) -> bool {
+ // 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 false;
+ }
+ };
+
+ if (component_values.size() > 3)
+ return nullptr;
+
+ RefPtr<StyleValue> list_position;
+ RefPtr<StyleValue> list_image;
+ RefPtr<StyleValue> list_type;
+ int found_nones = 0;
+
+ for (auto& part : component_values) {
+ auto value = parse_css_value(context, PropertyID::ListStyle, part);
+ if (!value)
+ return nullptr;
+
+ if (value->to_identifier() == ValueID::None) {
+ found_nones++;
+ continue;
+ }
+
+ if (is_list_style_position(*value)) {
+ if (list_position)
+ return nullptr;
+ list_position = value.release_nonnull();
+ continue;
+ }
+ if (is_list_style_image(*value)) {
+ if (list_image)
+ return nullptr;
+ list_image = value.release_nonnull();
+ continue;
+ }
+ if (is_list_style_type(*value)) {
+ if (list_type)
+ return nullptr;
+ list_type = value.release_nonnull();
+ continue;
+ }
+ }
+
+ if (found_nones > 2)
+ return nullptr;
+
+ if (found_nones == 2) {
+ if (list_image || list_type)
+ return nullptr;
+ auto none = IdentifierStyleValue::create(ValueID::None);
+ list_image = none;
+ list_type = none;
+
+ } else if (found_nones == 1) {
+ if (list_image && list_type)
+ return nullptr;
+ auto none = IdentifierStyleValue::create(ValueID::None);
+ if (!list_image)
+ list_image = none;
+ if (!list_type)
+ list_type = none;
+ }
+
+ if (!list_position)
+ list_position = IdentifierStyleValue::create(ValueID::Outside);
+ if (!list_image)
+ list_image = IdentifierStyleValue::create(ValueID::None);
+ if (!list_type)
+ list_type = IdentifierStyleValue::create(ValueID::Disc);
+
+ return ListStyleStyleValue::create(list_position.release_nonnull(), list_image.release_nonnull(), list_type.release_nonnull());
+}
+
RefPtr<StyleValue> Parser::parse_as_css_value(PropertyID property_id)
{
auto component_values = parse_as_list_of_component_values();
@@ -2105,6 +2215,10 @@ RefPtr<StyleValue> Parser::parse_css_value(PropertyID property_id, TokenStream<S
if (auto parsed_value = parse_font_value(m_context, component_values))
return parsed_value;
break;
+ case PropertyID::ListStyle:
+ if (auto parsed_value = parse_list_style_value(m_context, component_values))
+ return parsed_value;
+ break;
default:
break;
}
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
index 2a4c4d51d9..5e666be8ca 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
@@ -178,6 +178,7 @@ private:
static RefPtr<StyleValue> parse_background_value(ParsingContext const&, Vector<StyleComponentValueRule> const&);
static RefPtr<StyleValue> parse_box_shadow_value(ParsingContext const&, Vector<StyleComponentValueRule> const&);
static RefPtr<StyleValue> parse_font_value(ParsingContext const&, Vector<StyleComponentValueRule> const&);
+ static RefPtr<StyleValue> parse_list_style_value(ParsingContext const&, Vector<StyleComponentValueRule> const&);
// calc() parsing, according to https://www.w3.org/TR/css-values-3/#calc-syntax
static OwnPtr<CalculatedStyleValue::CalcSum> parse_calc_sum(ParsingContext const&, TokenStream<StyleComponentValueRule>&);