1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 13:38:11 +00:00

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.
This commit is contained in:
Sam Atkins 2021-07-30 17:48:23 +01:00 committed by Ali Mohammad Pur
parent eadcdd21e3
commit 4065eb169c
2 changed files with 63 additions and 0 deletions

View file

@ -1777,6 +1777,13 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(ParsingContext const& context,
return BoxShadowStyleValue::create(offset_x, offset_y, blur_radius, color);
}
RefPtr<StyleValue> 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<StyleValue> Parser::parse_css_value(PropertyID property_id, TokenStream<StyleComponentValueRule>& tokens)
{
Vector<StyleComponentValueRule> component_values;
@ -2405,3 +2412,46 @@ OwnPtr<CalculatedStyleValue::CalcSum> Parser::parse_calc_sum(ParsingContext cons
}
}
namespace Web {
RefPtr<CSS::CSSStyleSheet> 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<CSS::CSSStyleDeclaration> 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<CSS::StyleValue> 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<CSS::SelectorList> parse_selector(CSS::ParsingContext const& context, StringView const& selector_text)
{
CSS::Parser parser(context, selector_text);
return parser.parse_as_selector();
}
RefPtr<CSS::StyleValue> 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<DOM::Document&>(document)), string);
}
}