mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 05:25:09 +00:00
LibWeb: Parse the content
property
For now, we only understand `none`, `normal`, `<image>` and `<string>`. The various other functions and identifiers can be added later. We can *almost* use a StyleValueList for this, except it's divided into two parts - the content, and the optional "alt text". So, I've added a new StyleValue for it.
This commit is contained in:
parent
a9ad72cc0f
commit
adaab23149
6 changed files with 120 additions and 0 deletions
|
@ -3280,6 +3280,66 @@ RefPtr<StyleValue> Parser::parse_single_box_shadow_value(TokenStream<StyleCompon
|
|||
return BoxShadowStyleValue::create(color.release_value(), offset_x.release_value(), offset_y.release_value(), blur_radius.release_value(), spread_distance.release_value(), placement.release_value());
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_content_value(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
// FIXME: `content` accepts several kinds of function() type, which we don't handle in property_accepts_value() yet.
|
||||
|
||||
auto is_single_value_identifier = [](ValueID identifier) -> bool {
|
||||
switch (identifier) {
|
||||
case ValueID::None:
|
||||
case ValueID::Normal:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
if (component_values.size() == 1) {
|
||||
if (auto identifier = parse_identifier_value(component_values.first())) {
|
||||
if (is_single_value_identifier(identifier->to_identifier()))
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
|
||||
NonnullRefPtrVector<StyleValue> content_values;
|
||||
NonnullRefPtrVector<StyleValue> alt_text_values;
|
||||
bool in_alt_text = false;
|
||||
|
||||
for (auto const& value : component_values) {
|
||||
if (value.is(Token::Type::Delim) && value.token().delim() == "/"sv) {
|
||||
if (in_alt_text || content_values.is_empty())
|
||||
return {};
|
||||
in_alt_text = true;
|
||||
continue;
|
||||
}
|
||||
auto style_value = parse_css_value(value);
|
||||
if (style_value && property_accepts_value(PropertyID::Content, *style_value)) {
|
||||
if (is_single_value_identifier(style_value->to_identifier()))
|
||||
return {};
|
||||
|
||||
if (in_alt_text) {
|
||||
alt_text_values.append(style_value.release_nonnull());
|
||||
} else {
|
||||
content_values.append(style_value.release_nonnull());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
if (content_values.is_empty())
|
||||
return {};
|
||||
if (in_alt_text && alt_text_values.is_empty())
|
||||
return {};
|
||||
|
||||
RefPtr<StyleValueList> alt_text;
|
||||
if (!alt_text_values.is_empty())
|
||||
alt_text = StyleValueList::create(move(alt_text_values), StyleValueList::Separator::Space);
|
||||
|
||||
return ContentStyleValue::create(StyleValueList::create(move(content_values), StyleValueList::Separator::Space), move(alt_text));
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_flex_value(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
if (component_values.size() == 1) {
|
||||
|
@ -3864,6 +3924,10 @@ Result<NonnullRefPtr<StyleValue>, Parser::ParsingResult> Parser::parse_css_value
|
|||
if (auto parsed_value = parse_box_shadow_value(component_values))
|
||||
return parsed_value.release_nonnull();
|
||||
return ParsingResult::SyntaxError;
|
||||
case PropertyID::Content:
|
||||
if (auto parsed_value = parse_content_value(component_values))
|
||||
return parsed_value.release_nonnull();
|
||||
return ParsingResult::SyntaxError;
|
||||
case PropertyID::Flex:
|
||||
if (auto parsed_value = parse_flex_value(component_values))
|
||||
return parsed_value.release_nonnull();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue