Files
ladybird/Libraries/LibWeb/CSS/CSSFontFaceRule.h
Aliaksandr Kalenik 09d0278561 LibWeb/CSS: Don't track @font-face rules as critical subresources
CSSFontFaceRule inherited from CSSStyleSheet::Subresource, which made
each face a critical subresource of its parent stylesheet. New
subresources start in the Unloaded state, and the stylesheet's
loading_state() treats Unloaded as Loading.

When a @font-face declares a unicode-range and no codepoint in that
range is ever rendered, FontComputer only registers the face for
matching and never calls FontFace::load() on it. The face stays
Unloaded, so the parent stylesheet stays stuck reporting Loading,
which keeps HTMLLinkElement's load-event delayer alive and prevents
the document load event from firing. HTMLParserEndState then times
out in phase 2 (WaitingForLoadEventDelay) after 15 seconds.

Decouple @font-face from the stylesheet's loading state. Font loading
remains tracked by FontFaceSet, which is the correct place.
2026-04-28 00:15:30 +02:00

56 lines
1.7 KiB
C++

/*
* Copyright (c) 2022-2025, Sam Atkins <sam@ladybird.org>
* Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/CSS/CSSFontFaceDescriptors.h>
#include <LibWeb/CSS/CSSRule.h>
#include <LibWeb/CSS/ParsedFontFace.h>
namespace Web::CSS {
class FontFace;
class CSSFontFaceRule final : public CSSRule {
WEB_PLATFORM_OBJECT(CSSFontFaceRule, CSSRule);
GC_DECLARE_ALLOCATOR(CSSFontFaceRule);
public:
[[nodiscard]] static GC::Ref<CSSFontFaceRule> create(JS::Realm&, GC::Ref<CSSFontFaceDescriptors>);
virtual ~CSSFontFaceRule() override = default;
bool is_valid() const;
ParsedFontFace font_face() const;
GC::Ref<CSSStyleDeclaration> style() { return m_style; }
GC::Ref<CSSFontFaceDescriptors> descriptors() { return m_style; }
GC::Ref<CSSFontFaceDescriptors const> descriptors() const { return m_style; }
GC::Ptr<FontFace> css_connected_font_face() const { return m_css_connected_font_face; }
void set_css_connected_font_face(GC::Ptr<FontFace> font_face) { m_css_connected_font_face = font_face; }
void handle_descriptor_change(FlyString const& property);
void disconnect_font_face();
private:
CSSFontFaceRule(JS::Realm&, GC::Ref<CSSFontFaceDescriptors>);
virtual void initialize(JS::Realm&) override;
virtual String serialized() const override;
virtual void visit_edges(Visitor&) override;
virtual void dump(StringBuilder&, int indent_levels) const override;
void handle_src_descriptor_change();
GC::Ref<CSSFontFaceDescriptors> m_style;
GC::Ptr<FontFace> m_css_connected_font_face;
};
template<>
inline bool CSSRule::fast_is<CSSFontFaceRule>() const { return type() == CSSRule::Type::FontFace; }
}