1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 06:18:12 +00:00

LibWeb: Break friendship between CSS StyleRule and Parser

As before, this requires deviating from the spec slightly to create the
StyleRule fully-formed instead of creating it empty and then modifying
its internals.
This commit is contained in:
Sam Atkins 2022-04-12 17:03:14 +01:00 committed by Andreas Kling
parent 4bdfc2bb32
commit cf24dc2e0c
3 changed files with 36 additions and 21 deletions

View file

@ -1597,8 +1597,10 @@ NonnullRefPtr<StyleRule> Parser::consume_an_at_rule(TokenStream<T>& tokens)
VERIFY(name_ident.is(Token::Type::AtKeyword));
// Create a new at-rule with its name set to the value of the current input token, its prelude initially set to an empty list, and its value initially set to nothing.
auto rule = make_ref_counted<StyleRule>(StyleRule::Type::At);
rule->m_at_rule_name = ((Token)name_ident).at_keyword();
// NOTE: We create the StyleRule fully initialized when we return it instead.
FlyString at_rule_name = ((Token)name_ident).at_keyword();
Vector<ComponentValue> prelude;
RefPtr<Block> block;
// Repeatedly consume the next input token:
for (;;) {
@ -1607,21 +1609,21 @@ NonnullRefPtr<StyleRule> Parser::consume_an_at_rule(TokenStream<T>& tokens)
// <semicolon-token>
if (token.is(Token::Type::Semicolon)) {
// Return the at-rule.
return rule;
return StyleRule::make_at_rule(move(at_rule_name), move(prelude), move(block));
}
// <EOF-token>
if (token.is(Token::Type::EndOfFile)) {
// This is a parse error. Return the at-rule.
log_parse_error();
return rule;
return StyleRule::make_at_rule(move(at_rule_name), move(prelude), move(block));
}
// <{-token>
if (token.is(Token::Type::OpenCurly)) {
// Consume a simple block and assign it to the at-rules block. Return the at-rule.
rule->m_block = consume_a_simple_block(tokens);
return rule;
block = consume_a_simple_block(tokens);
return StyleRule::make_at_rule(move(at_rule_name), move(prelude), move(block));
}
// simple block with an associated token of <{-token>
@ -1629,8 +1631,8 @@ NonnullRefPtr<StyleRule> Parser::consume_an_at_rule(TokenStream<T>& tokens)
ComponentValue const& component_value = token;
if (component_value.is_block() && component_value.block().is_curly()) {
// Assign the block to the at-rules block. Return the at-rule.
rule->m_block = component_value.block();
return rule;
block = component_value.block();
return StyleRule::make_at_rule(move(at_rule_name), move(prelude), move(block));
}
}
@ -1639,7 +1641,7 @@ NonnullRefPtr<StyleRule> Parser::consume_an_at_rule(TokenStream<T>& tokens)
// Reconsume the current input token.
tokens.reconsume_current_input_token();
// Consume a component value. Append the returned value to the at-rules prelude.
rule->m_prelude.append(consume_a_component_value(tokens));
prelude.append(consume_a_component_value(tokens));
}
}
}
@ -1652,7 +1654,9 @@ RefPtr<StyleRule> Parser::consume_a_qualified_rule(TokenStream<T>& tokens)
// To consume a qualified rule:
// Create a new qualified rule with its prelude initially set to an empty list, and its value initially set to nothing.
auto rule = make_ref_counted<StyleRule>(StyleRule::Type::Qualified);
// NOTE: We create the StyleRule fully initialized when we return it instead.
Vector<ComponentValue> prelude;
RefPtr<Block> block;
// Repeatedly consume the next input token:
for (;;) {
@ -1668,8 +1672,8 @@ RefPtr<StyleRule> Parser::consume_a_qualified_rule(TokenStream<T>& tokens)
// <{-token>
if (token.is(Token::Type::OpenCurly)) {
// Consume a simple block and assign it to the qualified rules block. Return the qualified rule.
rule->m_block = consume_a_simple_block(tokens);
return rule;
block = consume_a_simple_block(tokens);
return StyleRule::make_qualified_rule(move(prelude), move(block));
}
// simple block with an associated token of <{-token>
@ -1677,8 +1681,8 @@ RefPtr<StyleRule> Parser::consume_a_qualified_rule(TokenStream<T>& tokens)
ComponentValue const& component_value = token;
if (component_value.is_block() && component_value.block().is_curly()) {
// Assign the block to the qualified rules block. Return the qualified rule.
rule->m_block = component_value.block();
return rule;
block = component_value.block();
return StyleRule::make_qualified_rule(move(prelude), move(block));
}
}
@ -1688,11 +1692,9 @@ RefPtr<StyleRule> Parser::consume_a_qualified_rule(TokenStream<T>& tokens)
tokens.reconsume_current_input_token();
// Consume a component value. Append the returned value to the qualified rules prelude.
rule->m_prelude.append(consume_a_component_value(tokens));
prelude.append(consume_a_component_value(tokens));
}
}
return rule;
}
// 5.4.4. Consume a style blocks contents

View file

@ -10,10 +10,14 @@
namespace Web::CSS::Parser {
StyleRule::StyleRule(StyleRule::Type type)
StyleRule::StyleRule(StyleRule::Type type, FlyString name, Vector<ComponentValue> prelude, RefPtr<Block> block)
: m_type(type)
, m_at_rule_name(move(name))
, m_prelude(move(prelude))
, m_block(move(block))
{
}
StyleRule::~StyleRule() = default;
String StyleRule::to_string() const

View file

@ -16,15 +16,22 @@
namespace Web::CSS::Parser {
class StyleRule : public RefCounted<StyleRule> {
friend class Parser;
public:
enum class Type {
At,
Qualified,
};
StyleRule(Type);
static NonnullRefPtr<StyleRule> make_at_rule(FlyString name, Vector<ComponentValue> prelude, RefPtr<Block> block)
{
return adopt_ref(*new StyleRule(Type::At, move(name), move(prelude), move(block)));
}
static NonnullRefPtr<StyleRule> make_qualified_rule(Vector<ComponentValue> prelude, RefPtr<Block> block)
{
return adopt_ref(*new StyleRule(Type::Qualified, {}, move(prelude), move(block)));
}
~StyleRule();
bool is_qualified_rule() const { return m_type == Type::Qualified; }
@ -37,6 +44,8 @@ public:
String to_string() const;
private:
StyleRule(Type, FlyString name, Vector<ComponentValue> prelude, RefPtr<Block>);
Type const m_type;
FlyString m_at_rule_name;
Vector<ComponentValue> m_prelude;