From 74588a0a16fd3a2cb10c50a58f47b9f5695bc2ff Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Sun, 22 Sep 2024 18:10:46 +0200 Subject: [PATCH] LibWeb: Remove all font loaders linked to a StyleSheet when it's deleted When a style sheet is removed, all font loaders created from that style sheet should also be removed. --- Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp | 9 +++++++++ Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h | 9 +++++++++ Userland/Libraries/LibWeb/CSS/StyleComputer.cpp | 16 ++++++++++++++-- Userland/Libraries/LibWeb/CSS/StyleComputer.h | 3 ++- Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp | 1 + 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index 0a83e2195c4..c8d8fa92793 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 f6d77d2b9df..837bbfd6115 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 @@ public: 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 @@ private: 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 606b7f7e424..fa9322f2cb0 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -2794,12 +2794,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 66e1b4ee0ff..a9bc777cef7 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h @@ -144,7 +144,8 @@ public: 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 50c9d169823..89ae41f1dc0 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); }