From 4065eb169c9d1e1ab4ec1f42291360b493e73c29 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Fri, 30 Jul 2021 17:48:23 +0100 Subject: [PATCH] LibWeb: Implement CSS parsing convenience functions These mostly match the API in `DeprecatedCSSParser.h`. The exception is that `parse_selector()` returns a `SelectorList` instead of just one `Selector`. The only uses of that are in `ParentNode::query_selector[_all]()` which should be matching against a list, according to the spec. `parse_html_length()` is an odd case. It's used for `width="200"` cases in HTML, so is not really CSS related, but does produce a StyleValue. The values allowed in `width/height` in HTML vary per element, but they are a lot more restricted than in CSS, so it's slightly inappropriate to use the CSS parser for them, even though it's convenient. We also ignore a few functions: - `parse_line_width()` - `parse_line_style()` - `parse_color()` These are all only used in `StyleResolver`, when it is given a property value as a String. That won't happen once the old parser is removed. --- .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 50 +++++++++++++++++++ Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 13 +++++ 2 files changed, 63 insertions(+) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index c367dd1b95..509c5594b0 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -1777,6 +1777,13 @@ RefPtr Parser::parse_box_shadow_value(ParsingContext const& context, return BoxShadowStyleValue::create(offset_x, offset_y, blur_radius, color); } +RefPtr Parser::parse_as_css_value(PropertyID property_id) +{ + auto component_values = parse_as_list_of_component_values(); + auto tokens = TokenStream(component_values); + return parse_css_value(property_id, tokens); +} + RefPtr Parser::parse_css_value(PropertyID property_id, TokenStream& tokens) { Vector component_values; @@ -2405,3 +2412,46 @@ OwnPtr Parser::parse_calc_sum(ParsingContext cons } } + +namespace Web { + +RefPtr parse_css(CSS::ParsingContext const& context, StringView const& css) +{ + if (css.is_empty()) + return CSS::CSSStyleSheet::create({}); + CSS::Parser parser(context, css); + return parser.parse_as_stylesheet(); +} + +RefPtr parse_css_declaration(CSS::ParsingContext const& context, StringView const& css) +{ + if (css.is_empty()) + return CSS::CSSStyleDeclaration::create({}, {}); + CSS::Parser parser(context, css); + return parser.parse_as_list_of_declarations(); +} + +RefPtr parse_css_value(CSS::ParsingContext const& context, StringView const& string, CSS::PropertyID property_id) +{ + if (string.is_empty()) + return {}; + CSS::Parser parser(context, string); + return parser.parse_as_css_value(property_id); +} + +Optional parse_selector(CSS::ParsingContext const& context, StringView const& selector_text) +{ + CSS::Parser parser(context, selector_text); + return parser.parse_as_selector(); +} + +RefPtr parse_html_length(DOM::Document const& document, StringView const& string) +{ + auto integer = string.to_int(); + if (integer.has_value()) + return CSS::LengthStyleValue::create(CSS::Length::make_px(integer.value())); + // FIXME: The const_cast is a hack. + return parse_css_value(CSS::ParsingContext(const_cast(document)), string); +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 2e2f35a34d..ffe7d7c223 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -93,6 +93,8 @@ public: Optional parse_as_selector(); Optional parse_as_relative_selector(); + RefPtr parse_as_css_value(PropertyID); + // FIXME: These want to be private, but StyleResolver still uses them for now. RefPtr parse_css_value(PropertyID, TokenStream&); static RefPtr parse_css_value(ParsingContext const&, PropertyID, StyleComponentValueRule const&); @@ -206,3 +208,14 @@ private: }; } + +namespace Web { + +RefPtr parse_css(CSS::ParsingContext const&, StringView const&); +RefPtr parse_css_declaration(CSS::ParsingContext const&, StringView const&); +RefPtr parse_css_value(CSS::ParsingContext const&, StringView const&, CSS::PropertyID property_id = CSS::PropertyID::Invalid); +Optional parse_selector(CSS::ParsingContext const&, StringView const&); + +RefPtr parse_html_length(DOM::Document const&, StringView const&); + +}