LibWeb: Move style sheet parsing into create_a_css_style_sheet()

The spec is unclear about when exactly we should parse the style sheet.
Previously we'd do so before calling this algorithm, which was
error-prone, as seen by the bug fixed by the previous commit. The spec
for step 1 of "create a CSS style sheet" says:

1. Create a new CSS style sheet object and set its properties as
   specified.

The definitions linked are UA-defined enough that it seems reasonable to
put the parsing here. That simplifies the user code a little and makes
it harder to mess up. It does raise the question of what to do if
parsing fails. I've matched our previous behaviour by just logging and
returning in that case.

While I'm modifying this method, I've also converted the bool params to
enums so they're a little clearer to read.
This commit is contained in:
Sam Atkins 2025-04-14 13:53:11 +01:00
parent f29a95e2fe
commit 2a96a81e68
Notes: github-actions[bot] 2025-04-15 08:41:41 +00:00
4 changed files with 74 additions and 50 deletions

View file

@ -486,26 +486,18 @@ void HTMLLinkElement::process_stylesheet_resource(bool success, Fetch::Infrastru
dbgln("Style sheet {} claimed to be '{}' but decoding failed", response.url().value_or(URL::URL()), encoding);
dispatch_event(*DOM::Event::create(realm(), HTML::EventNames::error));
} else {
auto const decoded_string = maybe_decoded_string.release_value();
VERIFY(!response.url_list().is_empty());
auto location = response.url_list().first();
m_loaded_style_sheet = parse_css_stylesheet(CSS::Parser::ParsingParams(document(), location), decoded_string, location);
if (m_loaded_style_sheet) {
document_or_shadow_root_style_sheets().create_a_css_style_sheet(
"text/css"_string,
this,
attribute(HTML::AttributeNames::media).value_or({}),
in_a_document_tree() ? attribute(HTML::AttributeNames::title).value_or({}) : String {},
m_relationship & Relationship::Alternate && !m_explicitly_enabled,
true,
move(location),
nullptr,
nullptr,
*m_loaded_style_sheet);
} else {
dbgln_if(CSS_LOADER_DEBUG, "HTMLLinkElement: Failed to parse stylesheet: {}", resource()->url());
}
m_loaded_style_sheet = document_or_shadow_root_style_sheets().create_a_css_style_sheet(
maybe_decoded_string.release_value(),
"text/css"_string,
this,
attribute(HTML::AttributeNames::media).value_or({}),
in_a_document_tree() ? attribute(HTML::AttributeNames::title).value_or({}) : String {},
(m_relationship & Relationship::Alternate && !m_explicitly_enabled) ? CSS::StyleSheetList::Alternate::Yes : CSS::StyleSheetList::Alternate::No,
CSS::StyleSheetList::OriginClean::Yes,
response.url_list().first(),
nullptr,
nullptr);
// 2. Fire an event named load at el.
dispatch_event(*DOM::Event::create(realm(), HTML::EventNames::load));