1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 06:17:35 +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)); 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. // 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); // NOTE: We create the StyleRule fully initialized when we return it instead.
rule->m_at_rule_name = ((Token)name_ident).at_keyword(); FlyString at_rule_name = ((Token)name_ident).at_keyword();
Vector<ComponentValue> prelude;
RefPtr<Block> block;
// Repeatedly consume the next input token: // Repeatedly consume the next input token:
for (;;) { for (;;) {
@ -1607,21 +1609,21 @@ NonnullRefPtr<StyleRule> Parser::consume_an_at_rule(TokenStream<T>& tokens)
// <semicolon-token> // <semicolon-token>
if (token.is(Token::Type::Semicolon)) { if (token.is(Token::Type::Semicolon)) {
// Return the at-rule. // Return the at-rule.
return rule; return StyleRule::make_at_rule(move(at_rule_name), move(prelude), move(block));
} }
// <EOF-token> // <EOF-token>
if (token.is(Token::Type::EndOfFile)) { if (token.is(Token::Type::EndOfFile)) {
// This is a parse error. Return the at-rule. // This is a parse error. Return the at-rule.
log_parse_error(); log_parse_error();
return rule; return StyleRule::make_at_rule(move(at_rule_name), move(prelude), move(block));
} }
// <{-token> // <{-token>
if (token.is(Token::Type::OpenCurly)) { if (token.is(Token::Type::OpenCurly)) {
// Consume a simple block and assign it to the at-rules block. Return the at-rule. // Consume a simple block and assign it to the at-rules block. Return the at-rule.
rule->m_block = consume_a_simple_block(tokens); block = consume_a_simple_block(tokens);
return rule; return StyleRule::make_at_rule(move(at_rule_name), move(prelude), move(block));
} }
// simple block with an associated token of <{-token> // 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; ComponentValue const& component_value = token;
if (component_value.is_block() && component_value.block().is_curly()) { if (component_value.is_block() && component_value.block().is_curly()) {
// Assign the block to the at-rules block. Return the at-rule. // Assign the block to the at-rules block. Return the at-rule.
rule->m_block = component_value.block(); block = component_value.block();
return rule; 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. // Reconsume the current input token.
tokens.reconsume_current_input_token(); tokens.reconsume_current_input_token();
// Consume a component value. Append the returned value to the at-rules prelude. // 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: // 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. // 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: // Repeatedly consume the next input token:
for (;;) { for (;;) {
@ -1668,8 +1672,8 @@ RefPtr<StyleRule> Parser::consume_a_qualified_rule(TokenStream<T>& tokens)
// <{-token> // <{-token>
if (token.is(Token::Type::OpenCurly)) { if (token.is(Token::Type::OpenCurly)) {
// Consume a simple block and assign it to the qualified rules block. Return the qualified rule. // Consume a simple block and assign it to the qualified rules block. Return the qualified rule.
rule->m_block = consume_a_simple_block(tokens); block = consume_a_simple_block(tokens);
return rule; return StyleRule::make_qualified_rule(move(prelude), move(block));
} }
// simple block with an associated token of <{-token> // 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; ComponentValue const& component_value = token;
if (component_value.is_block() && component_value.block().is_curly()) { if (component_value.is_block() && component_value.block().is_curly()) {
// Assign the block to the qualified rules block. Return the qualified rule. // Assign the block to the qualified rules block. Return the qualified rule.
rule->m_block = component_value.block(); block = component_value.block();
return rule; 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(); tokens.reconsume_current_input_token();
// Consume a component value. Append the returned value to the qualified rules prelude. // 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 // 5.4.4. Consume a style blocks contents

View file

@ -10,10 +10,14 @@
namespace Web::CSS::Parser { 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_type(type)
, m_at_rule_name(move(name))
, m_prelude(move(prelude))
, m_block(move(block))
{ {
} }
StyleRule::~StyleRule() = default; StyleRule::~StyleRule() = default;
String StyleRule::to_string() const String StyleRule::to_string() const

View file

@ -16,15 +16,22 @@
namespace Web::CSS::Parser { namespace Web::CSS::Parser {
class StyleRule : public RefCounted<StyleRule> { class StyleRule : public RefCounted<StyleRule> {
friend class Parser;
public: public:
enum class Type { enum class Type {
At, At,
Qualified, 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(); ~StyleRule();
bool is_qualified_rule() const { return m_type == Type::Qualified; } bool is_qualified_rule() const { return m_type == Type::Qualified; }
@ -37,6 +44,8 @@ public:
String to_string() const; String to_string() const;
private: private:
StyleRule(Type, FlyString name, Vector<ComponentValue> prelude, RefPtr<Block>);
Type const m_type; Type const m_type;
FlyString m_at_rule_name; FlyString m_at_rule_name;
Vector<ComponentValue> m_prelude; Vector<ComponentValue> m_prelude;