diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2021-11-18 17:34:53 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-11-18 21:11:19 +0100 |
commit | 738e682ae099c32859ef32e105dac63b5c6bf5c3 (patch) | |
tree | 9f1ecfff9b1330b0b0178e2b26d7227857209520 /Userland | |
parent | ce6fd38e5dedd389233ac3095f1d0f59d3042654 (diff) | |
download | serenity-738e682ae099c32859ef32e105dac63b5c6bf5c3.zip |
LibWeb: Make `@import` rules functional again :^)
The changes in commit d462a6720afe721b6821ce14d5b7802d1890b61f 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.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp | 41 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSImportRule.h | 18 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 2 |
3 files changed, 54 insertions, 7 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp index 2c0485f14b..80822dfa43 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp @@ -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); +} + } diff --git a/Userland/Libraries/LibWeb/CSS/CSSImportRule.h b/Userland/Libraries/LibWeb/CSS/CSSImportRule.h index f633701037..5ab22f9d8d 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSImportRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSImportRule.h @@ -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; }; diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 97188ede9b..498643eaa6 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -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"); |