summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@gmail.com>2021-07-20 16:11:19 +0100
committerAndreas Kling <kling@serenityos.org>2021-07-22 23:09:01 +0200
commita44d7670ab937783e233f7d9a3ef73a39fcd8720 (patch)
tree639c6e8553199aefee9c0e099e814ef3356861be
parentb693a22c2dab20b4c3c74bbf1a1b8e69f44e6ddf (diff)
downloadserenity-a44d7670ab937783e233f7d9a3ef73a39fcd8720.zip
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.
-rw-r--r--Userland/Libraries/LibWeb/CSS/Identifiers.json2
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp1
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleResolver.cpp102
3 files changed, 99 insertions, 6 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Identifiers.json b/Userland/Libraries/LibWeb/CSS/Identifiers.json
index d09767a16f..29490eead7 100644
--- a/Userland/Libraries/LibWeb/CSS/Identifiers.json
+++ b/Userland/Libraries/LibWeb/CSS/Identifiers.json
@@ -99,6 +99,7 @@
"inline",
"inline-block",
"inset",
+ "inside",
"justify",
"large",
"larger",
@@ -125,6 +126,7 @@
"nw-resize",
"nwse-resize",
"outset",
+ "outside",
"overline",
"pointer",
"pre",
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index e99e6f3d9a..108f59b698 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -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)
{
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
// into Properties.json.
auto takes_integer_value = [](PropertyID property_id) -> bool {
diff --git a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp
index 13f7238164..fd641b4cdc 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp
@@ -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)
{
CSS::DeprecatedParsingContext deprecated_context(document);
@@ -1202,17 +1252,59 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
return;
}
- // FIXME: Handle all three parts of ListStyle. (list-style-positon, list-style-image, list-style-type)
if (value.is_value_list()) {
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 (list_style)
- style.set_property(CSS::PropertyID::ListStyleType, *list_style);
+
+ 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);
}
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;
}