LibWeb/CSS: Make fetch_a_style_resource() work with no CSSStyleSheet

See the spec issue in the comments for details. There are situations
where we will need to call this but don't have a CSSStyleSheet to pass
in, but we always have a Document, so use that where possible.
This commit is contained in:
Sam Atkins 2025-04-10 12:09:39 +01:00
parent f4cfdd704b
commit 43950c7342
Notes: github-actions[bot] 2025-04-15 09:31:05 +00:00
3 changed files with 22 additions and 9 deletions

View file

@ -116,7 +116,7 @@ void CSSImportRule::fetch()
m_document_load_event_delayer.emplace(*m_document);
// 4. Fetch a style resource from parsedUrl, with stylesheet parentStylesheet, destination "style", CORS mode "no-cors", and processResponse being the following steps given response response and byte stream, null or failure byteStream:
fetch_a_style_resource(parsed_url.value(), parent_style_sheet, Fetch::Infrastructure::Request::Destination::Style, CorsMode::NoCors,
fetch_a_style_resource(parsed_url.value(), { parent_style_sheet }, Fetch::Infrastructure::Request::Destination::Style, CorsMode::NoCors,
[strong_this = GC::Ref { *this }, parent_style_sheet = GC::Ref { parent_style_sheet }, parsed_url = parsed_url.value()](auto response, auto maybe_byte_stream) {
// AD-HOC: Stop delaying the load event.
ScopeGuard guard = [strong_this] {

View file

@ -7,20 +7,26 @@
#include <LibURL/Parser.h>
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/Fetch.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/Fetch/Fetching/Fetching.h>
namespace Web::CSS {
// https://drafts.csswg.org/css-values-4/#fetch-a-style-resource
void fetch_a_style_resource(StyleResourceURL const& url_value, CSSStyleSheet const& sheet, Fetch::Infrastructure::Request::Destination destination, CorsMode cors_mode, Fetch::Infrastructure::FetchAlgorithms::ProcessResponseConsumeBodyFunction process_response)
void fetch_a_style_resource(StyleResourceURL const& url_value, StyleSheetOrDocument sheet_or_document, Fetch::Infrastructure::Request::Destination destination, CorsMode cors_mode, Fetch::Infrastructure::FetchAlgorithms::ProcessResponseConsumeBodyFunction process_response)
{
auto& vm = sheet.vm();
// AD-HOC: Not every caller has a CSSStyleSheet, so allow passing a Document in instead for URL completion.
// Spec issue: https://github.com/w3c/csswg-drafts/issues/12065
auto& vm = sheet_or_document.visit([](auto& it) -> JS::VM& { return it->vm(); });
// 1. Let environmentSettings be sheets relevant settings object.
auto& environment_settings = HTML::relevant_settings_object(sheet);
auto& environment_settings = HTML::relevant_settings_object(sheet_or_document.visit([](auto& it) -> JS::Object& { return it; }));
// 2. Let base be sheets stylesheet base URL if it is not null, otherwise environmentSettingss API base URL. [CSSOM]
auto base = sheet.base_url().value_or(environment_settings.api_base_url());
auto base = sheet_or_document.visit(
[&](GC::Ref<CSSStyleSheet> const& sheet) { return sheet->base_url().value_or(environment_settings.api_base_url()); },
[](GC::Ref<DOM::Document> const& document) { return document->base_url(); });
// 3. Let parsedUrl be the result of the URL parser steps with urlValues url and base. If the algorithm returns an error, return.
auto url_string = url_value.visit(
@ -47,11 +53,15 @@ void fetch_a_style_resource(StyleResourceURL const& url_value, CSSStyleSheet con
// FIXME: No specs seem to define these yet. When they do, implement them.
// 6. If reqs mode is "cors", set reqs referrer to sheets location. [CSSOM]
if (request->mode() == Fetch::Infrastructure::Request::Mode::CORS)
request->set_referrer(sheet.location().value());
if (request->mode() == Fetch::Infrastructure::Request::Mode::CORS) {
auto location = sheet_or_document.visit(
[](GC::Ref<CSSStyleSheet> const& sheet) { return sheet->location().value(); },
[](GC::Ref<DOM::Document> const& document) { return document->url(); });
request->set_referrer(move(location));
}
// 7. If sheets origin-clean flag is set, set reqs initiator type to "css". [CSSOM]
if (sheet.is_origin_clean())
if (auto* sheet = sheet_or_document.get_pointer<GC::Ref<CSSStyleSheet>>(); sheet && (*sheet)->is_origin_clean())
request->set_initiator_type(Fetch::Infrastructure::Request::InitiatorType::CSS);
// 8. Fetch req, with processresponseconsumebody set to processResponse.

View file

@ -20,7 +20,10 @@ enum class CorsMode {
using StyleResourceURL = Variant<::URL::URL, CSS::URL>;
// AD-HOC: See comment inside fetch_a_style_resource() implementation.
using StyleSheetOrDocument = Variant<GC::Ref<CSSStyleSheet>, GC::Ref<DOM::Document>>;
// https://drafts.csswg.org/css-values-4/#fetch-a-style-resource
void fetch_a_style_resource(StyleResourceURL const& url, CSSStyleSheet const&, Fetch::Infrastructure::Request::Destination, CorsMode, Fetch::Infrastructure::FetchAlgorithms::ProcessResponseConsumeBodyFunction process_response);
void fetch_a_style_resource(StyleResourceURL const& url, StyleSheetOrDocument, Fetch::Infrastructure::Request::Destination, CorsMode, Fetch::Infrastructure::FetchAlgorithms::ProcessResponseConsumeBodyFunction process_response);
}