diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index 0a83e2195c4ef5..c8d8fa92793669 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -402,4 +402,13 @@ Optional CSSStyleSheet::source_text(Badge) const return m_source_text; } +bool CSSStyleSheet::has_associated_font_loader(FontLoader& font_loader) const +{ + for (auto& loader : m_associated_font_loaders) { + if (loader.ptr() == &font_loader) + return true; + } + return false; +} + } diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h index f6d77d2b9df999..837bbfd6115cb1 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h @@ -18,6 +18,7 @@ namespace Web::CSS { class CSSImportRule; +class FontLoader; struct CSSStyleSheetInit { Optional base_url {}; @@ -84,6 +85,12 @@ class CSSStyleSheet final : public StyleSheet { void set_source_text(String); Optional source_text(Badge) const; + void add_associated_font_loader(WeakPtr font_loader) + { + m_associated_font_loaders.append(font_loader); + } + bool has_associated_font_loader(FontLoader& font_loader) const; + private: CSSStyleSheet(JS::Realm&, CSSRuleList&, MediaList&, Optional location); @@ -110,6 +117,8 @@ class CSSStyleSheet final : public StyleSheet { bool m_constructed { false }; bool m_disallow_modification { false }; Optional m_did_match; + + Vector> m_associated_font_loaders; }; } diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index b2dafd7d9aa3e5..04613cb064bffd 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -2740,12 +2740,24 @@ Optional StyleComputer::load_font_face(ParsedFontFace const& font_f return loader_ref; } -void StyleComputer::load_fonts_from_sheet(CSSStyleSheet const& sheet) +void StyleComputer::load_fonts_from_sheet(CSSStyleSheet& sheet) { for (auto const& rule : sheet.rules()) { if (!is(*rule)) continue; - (void)load_font_face(static_cast(*rule).font_face()); + auto font_loader = load_font_face(static_cast(*rule).font_face()); + if (font_loader.has_value()) { + sheet.add_associated_font_loader(font_loader.value()); + } + } +} + +void StyleComputer::unload_fonts_from_sheet(CSSStyleSheet& sheet) +{ + for (auto& [_, font_loader_list] : m_loaded_fonts) { + font_loader_list.remove_all_matching([&](auto& font_loader) { + return sheet.has_associated_font_loader(*font_loader); + }); } } diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.h b/Userland/Libraries/LibWeb/CSS/StyleComputer.h index 408098caca8e81..7d0b950dc17487 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h @@ -144,7 +144,8 @@ class StyleComputer { Optional load_font_face(ParsedFontFace const&, ESCAPING Function on_load = {}, ESCAPING Function on_fail = {}); - void load_fonts_from_sheet(CSSStyleSheet const&); + void load_fonts_from_sheet(CSSStyleSheet&); + void unload_fonts_from_sheet(CSSStyleSheet&); RefPtr compute_font_for_style_values(DOM::Element const* element, Optional pseudo_element, CSSStyleValue const& font_family, CSSStyleValue const& font_size, CSSStyleValue const& font_style, CSSStyleValue const& font_weight, CSSStyleValue const& font_stretch, int math_depth = 0) const; diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp b/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp index 50c9d169823f34..89ae41f1dc0a44 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp @@ -123,6 +123,7 @@ void StyleSheetList::remove_sheet(CSSStyleSheet& sheet) return; } + m_document_or_shadow_root->document().style_computer().unload_fonts_from_sheet(sheet); m_document_or_shadow_root->document().style_computer().invalidate_rule_cache(); document_or_shadow_root().invalidate_style(DOM::StyleInvalidationReason::StyleSheetListRemoveSheet); }