1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 14:28:12 +00:00

LibWeb: Make CSSRule and all its subclasses GC-allocated

This commit is contained in:
Andreas Kling 2022-08-07 15:46:44 +02:00
parent 5d6cb9cbdb
commit 12042f0757
39 changed files with 338 additions and 236 deletions

View file

@ -44,6 +44,11 @@ ParsingContext::ParsingContext()
{
}
ParsingContext::ParsingContext(Bindings::WindowObject& window_object)
: m_window_object(window_object)
{
}
ParsingContext::ParsingContext(DOM::Document const& document, AK::URL url)
: m_window_object(document.preferred_window_object())
, m_document(&document)
@ -194,15 +199,16 @@ CSSStyleSheet* Parser::parse_as_css_stylesheet(Optional<AK::URL> location)
auto style_sheet = parse_a_stylesheet(m_token_stream, {});
// Interpret all of the resulting top-level qualified rules as style rules, defined below.
NonnullRefPtrVector<CSSRule> rules;
JS::MarkedVector<CSSRule*> rules(m_context.window_object().heap());
for (auto& raw_rule : style_sheet.rules) {
auto rule = convert_to_rule(raw_rule);
auto* rule = convert_to_rule(raw_rule);
// If any style rule is invalid, or any at-rule is not recognized or is invalid according to its grammar or context, its a parse error. Discard that rule.
if (rule)
rules.append(*rule);
rules.append(rule);
}
return CSSStyleSheet::create(m_context.window_object(), move(rules), move(location));
auto* rule_list = CSSRuleList::create(m_context.window_object(), move(rules));
return CSSStyleSheet::create(m_context.window_object(), *rule_list, move(location));
}
Optional<SelectorList> Parser::parse_as_selector(SelectorParsingMode parsing_mode)
@ -2096,7 +2102,7 @@ Vector<DeclarationOrAtRule> Parser::consume_a_list_of_declarations(TokenStream<T
}
}
RefPtr<CSSRule> Parser::parse_as_css_rule()
CSSRule* Parser::parse_as_css_rule()
{
auto maybe_rule = parse_a_rule(m_token_stream);
if (maybe_rule)
@ -2593,7 +2599,7 @@ RefPtr<StyleValue> Parser::parse_linear_gradient_function(ComponentValue const&
return LinearGradientStyleValue::create(gradient_direction, move(color_stops), gradient_type, repeating_gradient);
}
RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule)
CSSRule* Parser::convert_to_rule(NonnullRefPtr<Rule> rule)
{
if (rule->is_at_rule()) {
if (has_ignored_vendor_prefix(rule->at_rule_name())) {
@ -2625,8 +2631,7 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule)
if (url.has_value())
return CSSImportRule::create(url.value(), const_cast<DOM::Document&>(*m_context.document()));
else
dbgln_if(CSS_PARSER_DEBUG, "Unable to parse url from @import rule");
dbgln_if(CSS_PARSER_DEBUG, "Unable to parse url from @import rule");
} else if (rule->at_rule_name().equals_ignoring_case("media"sv)) {
@ -2637,13 +2642,13 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule)
auto child_tokens = TokenStream { rule->block()->values() };
auto parser_rules = parse_a_list_of_rules(child_tokens);
NonnullRefPtrVector<CSSRule> child_rules;
JS::MarkedVector<CSSRule*> child_rules(m_context.window_object().heap());
for (auto& raw_rule : parser_rules) {
if (auto child_rule = convert_to_rule(raw_rule))
child_rules.append(*child_rule);
child_rules.append(child_rule);
}
return CSSMediaRule::create(MediaList::create(move(media_query_list)), move(child_rules));
auto* rule_list = CSSRuleList::create(m_context.window_object(), move(child_rules));
return CSSMediaRule::create(m_context.window_object(), MediaList::create(move(media_query_list)), *rule_list);
} else if (rule->at_rule_name().equals_ignoring_case("supports"sv)) {
@ -2661,13 +2666,14 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule)
return {};
auto child_tokens = TokenStream { rule->block()->values() };
auto parser_rules = parse_a_list_of_rules(child_tokens);
NonnullRefPtrVector<CSSRule> child_rules;
JS::MarkedVector<CSSRule*> child_rules(m_context.window_object().heap());
for (auto& raw_rule : parser_rules) {
if (auto child_rule = convert_to_rule(raw_rule))
child_rules.append(*child_rule);
child_rules.append(child_rule);
}
return CSSSupportsRule::create(supports.release_nonnull(), move(child_rules));
auto* rule_list = CSSRuleList::create(m_context.window_object(), move(child_rules));
return CSSSupportsRule::create(m_context.window_object(), supports.release_nonnull(), *rule_list);
} else {
dbgln_if(CSS_PARSER_DEBUG, "Unrecognized CSS at-rule: @{}", rule->at_rule_name());
@ -2706,7 +2712,7 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<Rule> rule)
return {};
}
return CSSStyleRule::create(move(selectors.value()), move(*declaration));
return CSSStyleRule::create(m_context.window_object(), move(selectors.value()), move(*declaration));
}
return {};
@ -4690,7 +4696,7 @@ RefPtr<StyleValue> Parser::parse_font_family_value(Vector<ComponentValue> const&
return StyleValueList::create(move(font_families), StyleValueList::Separator::Comma);
}
RefPtr<CSSRule> Parser::parse_font_face_rule(TokenStream<ComponentValue>& tokens)
CSSRule* Parser::parse_font_face_rule(TokenStream<ComponentValue>& tokens)
{
auto declarations_and_at_rules = parse_a_list_of_declarations(tokens);
@ -4791,7 +4797,7 @@ RefPtr<CSSRule> Parser::parse_font_face_rule(TokenStream<ComponentValue>& tokens
unicode_range.empend(0x0u, 0x10FFFFu);
}
return CSSFontFaceRule::create(FontFace { font_family.release_value(), move(src), move(unicode_range) });
return CSSFontFaceRule::create(m_context.window_object(), FontFace { font_family.release_value(), move(src), move(unicode_range) });
}
Vector<FontFace::Source> Parser::parse_font_face_src(TokenStream<ComponentValue>& component_values)
@ -6385,7 +6391,7 @@ namespace Web {
CSS::CSSStyleSheet* parse_css_stylesheet(CSS::Parser::ParsingContext const& context, StringView css, Optional<AK::URL> location)
{
if (css.is_empty())
return CSS::CSSStyleSheet::create(context.window_object(), {}, location);
return CSS::CSSStyleSheet::create(context.window_object(), *CSS::CSSRuleList::create_empty(context.window_object()), location);
CSS::Parser::Parser parser(context, css);
return parser.parse_as_css_stylesheet(location);
}
@ -6406,7 +6412,7 @@ RefPtr<CSS::StyleValue> parse_css_value(CSS::Parser::ParsingContext const& conte
return parser.parse_as_css_value(property_id);
}
RefPtr<CSS::CSSRule> parse_css_rule(CSS::Parser::ParsingContext const& context, StringView css_text)
CSS::CSSRule* parse_css_rule(CSS::Parser::ParsingContext const& context, StringView css_text)
{
CSS::Parser::Parser parser(context, css_text);
return parser.parse_as_css_rule();