mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-05 06:32:30 +02:00
LibWeb: Limit <ident> to <custom-ident> in @property/syntax
The definition of syntax in the "css-properties-values-api" spec (which is used for the `@property/syntax` descriptor) is slightly different from the definition of `<syntax>` in the "css-values" spec (which we implement) in that it limits literal idents to exclusively `<custom-ident>`s (i.e. not CSS-wide keywords or "default"). `<custom-ident>`s are also case-sensitive so that behavior is implemented for syntax matching here as well
This commit is contained in:
Notes:
github-actions[bot]
2026-03-26 01:13:01 +00:00
Author: https://github.com/Calme1709 Commit: https://github.com/LadybirdBrowser/ladybird/commit/6afe2ff27bf Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8330 Reviewed-by: https://github.com/AtkinsSJ ✅
@@ -20,7 +20,7 @@
|
||||
|
||||
namespace Web::CSS::Parser {
|
||||
|
||||
static OwnPtr<SyntaxNode> parse_syntax_single_component(TokenStream<ComponentValue>& tokens)
|
||||
static OwnPtr<SyntaxNode> parse_syntax_single_component(TokenStream<ComponentValue>& tokens, LimitSingleComponentIdentToCustomIdent limit_single_component_ident_to_custom_ident)
|
||||
{
|
||||
// <syntax-single-component> = '<' <syntax-type-name> '>' | <ident>
|
||||
// <syntax-type-name> = angle | color | custom-ident | image | integer
|
||||
@@ -34,8 +34,14 @@ static OwnPtr<SyntaxNode> parse_syntax_single_component(TokenStream<ComponentVal
|
||||
// <ident>
|
||||
if (tokens.next_token().is(Token::Type::Ident)) {
|
||||
auto ident = tokens.consume_a_token().token().ident();
|
||||
|
||||
// AD-HOC: Some users (i.e. the @property syntax descriptor) only allow custom idents here,
|
||||
// https://github.com/w3c/csswg-drafts/issues/13614
|
||||
if (limit_single_component_ident_to_custom_ident == LimitSingleComponentIdentToCustomIdent::Yes && !is_valid_custom_ident(ident, {}))
|
||||
return {};
|
||||
|
||||
transaction.commit();
|
||||
return IdentSyntaxNode::create(move(ident));
|
||||
return IdentSyntaxNode::create(ident, limit_single_component_ident_to_custom_ident == LimitSingleComponentIdentToCustomIdent::Yes ? CaseSensitivity::CaseSensitive : CaseSensitivity::CaseInsensitive);
|
||||
}
|
||||
|
||||
// '<' <syntax-type-name> '>'
|
||||
@@ -82,7 +88,7 @@ static Optional<char> parse_syntax_multiplier(TokenStream<ComponentValue>& token
|
||||
return {};
|
||||
}
|
||||
|
||||
static OwnPtr<SyntaxNode> parse_syntax_component(TokenStream<ComponentValue>& tokens)
|
||||
static OwnPtr<SyntaxNode> parse_syntax_component(TokenStream<ComponentValue>& tokens, LimitSingleComponentIdentToCustomIdent limit_single_component_ident_to_custom_ident)
|
||||
{
|
||||
// <syntax-component> = <syntax-single-component> <syntax-multiplier>?
|
||||
// | '<' transform-list '>'
|
||||
@@ -105,7 +111,7 @@ static OwnPtr<SyntaxNode> parse_syntax_component(TokenStream<ComponentValue>& to
|
||||
}
|
||||
|
||||
// <syntax-single-component> <syntax-multiplier>?
|
||||
auto syntax_single_component = parse_syntax_single_component(tokens);
|
||||
auto syntax_single_component = parse_syntax_single_component(tokens, limit_single_component_ident_to_custom_ident);
|
||||
if (!syntax_single_component)
|
||||
return nullptr;
|
||||
|
||||
@@ -143,7 +149,7 @@ static Optional<char> parse_syntax_combinator(TokenStream<ComponentValue>& token
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-values-5/#typedef-syntax
|
||||
OwnPtr<SyntaxNode> parse_as_syntax(Vector<ComponentValue> const& component_values)
|
||||
OwnPtr<SyntaxNode> parse_as_syntax(Vector<ComponentValue> const& component_values, LimitSingleComponentIdentToCustomIdent limit_single_component_ident_to_custom_ident)
|
||||
{
|
||||
// <syntax> = '*' | <syntax-component> [ <syntax-combinator> <syntax-component> ]* | <syntax-string>
|
||||
// <syntax-component> = <syntax-single-component> <syntax-multiplier>?
|
||||
@@ -182,11 +188,11 @@ OwnPtr<SyntaxNode> parse_as_syntax(Vector<ComponentValue> const& component_value
|
||||
return nullptr;
|
||||
|
||||
auto child_component_values = Parser::create(ParsingParams {}, string).parse_as_list_of_component_values();
|
||||
return parse_as_syntax(child_component_values);
|
||||
return parse_as_syntax(child_component_values, limit_single_component_ident_to_custom_ident);
|
||||
}
|
||||
|
||||
// <syntax-component> [ <syntax-combinator> <syntax-component> ]*
|
||||
auto first = parse_syntax_component(tokens);
|
||||
auto first = parse_syntax_component(tokens, limit_single_component_ident_to_custom_ident);
|
||||
if (!first)
|
||||
return nullptr;
|
||||
Vector<NonnullOwnPtr<SyntaxNode>> syntax_components;
|
||||
@@ -196,7 +202,7 @@ OwnPtr<SyntaxNode> parse_as_syntax(Vector<ComponentValue> const& component_value
|
||||
while (tokens.has_next_token()) {
|
||||
auto combinator = parse_syntax_combinator(tokens);
|
||||
tokens.discard_whitespace();
|
||||
auto component = parse_syntax_component(tokens);
|
||||
auto component = parse_syntax_component(tokens, limit_single_component_ident_to_custom_ident);
|
||||
tokens.discard_whitespace();
|
||||
if (!combinator.has_value() || !component) {
|
||||
dbgln("Failed parsing syntax portion, combinator = `{}`, component = `{}`", combinator, component);
|
||||
@@ -234,7 +240,14 @@ RefPtr<StyleValue const> Parser::parse_according_to_syntax_node(TokenStream<Comp
|
||||
case SyntaxNode::NodeType::Ident: {
|
||||
auto const& ident_node = as<IdentSyntaxNode>(syntax_node);
|
||||
tokens.discard_whitespace();
|
||||
if (tokens.consume_a_token().is_ident(ident_node.ident())) {
|
||||
auto token = tokens.consume_a_token();
|
||||
|
||||
if (!token.is(Token::Type::Ident))
|
||||
return nullptr;
|
||||
|
||||
auto ident = token.token().ident();
|
||||
|
||||
if (ident_node.case_sensitivity() == CaseSensitivity::CaseSensitive ? ident == ident_node.ident() : ident.equals_ignoring_ascii_case(ident_node.ident())) {
|
||||
transaction.commit();
|
||||
if (auto keyword = keyword_from_string(ident_node.ident()); keyword.has_value())
|
||||
return KeywordStyleValue::create(keyword.release_value());
|
||||
|
||||
Reference in New Issue
Block a user