LibWeb: Make @import rules functional again :^)

The changes in commit d462a6720a meant
that `CSSLoader::load_next_import_if_needed()` was no longer being
called, so no `@import` rules were loading.

The spec does not seem to mention when that loading should take place,
but WebKit does this at parse time, as each rule is added to the style
sheet. If it works for them, it's probably not that bad. :^)

So, that's what we now do here. The `CSSImportRule` creates a fetch
request when it is constructed, so each one is responsible for its own
contents.
This commit is contained in:
Sam Atkins 2021-11-18 17:34:53 +00:00 committed by Andreas Kling
parent ce6fd38e5d
commit 738e682ae0
3 changed files with 54 additions and 7 deletions

View file

@ -1,18 +1,27 @@
/*
* Copyright (c) 2021, the SerenityOS developers.
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Debug.h>
#include <AK/URL.h>
#include <LibWeb/CSS/CSSImportRule.h>
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/Loader/ResourceLoader.h>
namespace Web::CSS {
CSSImportRule::CSSImportRule(AK::URL url)
CSSImportRule::CSSImportRule(AK::URL url, DOM::Document& document)
: m_url(move(url))
, m_document(document)
{
dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Loading import URL: {}", m_url);
auto request = LoadRequest::create_for_url_on_page(m_url, document.page());
set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request));
m_document_load_event_delayer.emplace(m_document);
}
CSSImportRule::~CSSImportRule()
@ -42,4 +51,32 @@ String CSSImportRule::serialized() const
return builder.to_string();
}
void CSSImportRule::resource_did_fail()
{
dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Resource did fail. URL: {}", resource()->url());
m_document_load_event_delayer.clear();
}
void CSSImportRule::resource_did_load()
{
VERIFY(resource());
m_document_load_event_delayer.clear();
if (!resource()->has_encoded_data()) {
dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Resource did load, no encoded data. URL: {}", resource()->url());
} else {
dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Resource did load, has encoded data. URL: {}", resource()->url());
}
auto sheet = parse_css(CSS::ParsingContext(m_document), resource()->encoded_data());
if (!sheet) {
dbgln_if(CSS_LOADER_DEBUG, "CSSImportRule: Failed to parse stylesheet: {}", resource()->url());
return;
}
m_style_sheet = move(sheet);
}
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2021, the SerenityOS developers.
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -9,17 +10,20 @@
#include <AK/URL.h>
#include <LibWeb/CSS/CSSRule.h>
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/DOM/DocumentLoadEventDelayer.h>
namespace Web::CSS {
class CSSImportRule : public CSSRule {
class CSSImportRule
: public CSSRule
, public ResourceClient {
AK_MAKE_NONCOPYABLE(CSSImportRule);
AK_MAKE_NONMOVABLE(CSSImportRule);
public:
static NonnullRefPtr<CSSImportRule> create(AK::URL url)
static NonnullRefPtr<CSSImportRule> create(AK::URL url, DOM::Document& document)
{
return adopt_ref(*new CSSImportRule(move(url)));
return adopt_ref(*new CSSImportRule(move(url), document));
}
~CSSImportRule();
@ -35,11 +39,17 @@ public:
virtual Type type() const { return Type::Import; };
private:
explicit CSSImportRule(AK::URL);
explicit CSSImportRule(AK::URL, DOM::Document&);
virtual String serialized() const override;
// ^ResourceClient
virtual void resource_did_fail() override;
virtual void resource_did_load() override;
AK::URL m_url;
DOM::Document& m_document;
Optional<DOM::DocumentLoadEventDelayer> m_document_load_event_delayer;
RefPtr<CSSStyleSheet> m_style_sheet;
};

View file

@ -1747,7 +1747,7 @@ RefPtr<CSSRule> Parser::convert_to_rule(NonnullRefPtr<StyleRule> rule)
}
if (url.has_value())
return CSSImportRule::create(url.value());
return CSSImportRule::create(url.value(), const_cast<DOM::Document&>(*m_context.document()));
else
dbgln("Unable to parse url from @import rule");