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.
This commit is contained in:
Aliaksandr Kalenik 2024-09-22 18:10:46 +02:00 committed by Alexander Kalenik
parent 8472b2b1fb
commit 74588a0a16
Notes: github-actions[bot] 2024-09-22 18:11:26 +00:00
5 changed files with 35 additions and 3 deletions

View file

@ -402,4 +402,13 @@ Optional<String> CSSStyleSheet::source_text(Badge<DOM::Document>) 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;
}
}

View file

@ -18,6 +18,7 @@
namespace Web::CSS {
class CSSImportRule;
class FontLoader;
struct CSSStyleSheetInit {
Optional<String> base_url {};
@ -84,6 +85,12 @@ public:
void set_source_text(String);
Optional<String> source_text(Badge<DOM::Document>) const;
void add_associated_font_loader(WeakPtr<FontLoader const> 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<URL::URL> location);
@ -110,6 +117,8 @@ private:
bool m_constructed { false };
bool m_disallow_modification { false };
Optional<bool> m_did_match;
Vector<WeakPtr<FontLoader const>> m_associated_font_loaders;
};
}

View file

@ -2794,12 +2794,24 @@ Optional<FontLoader&> 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<CSSFontFaceRule>(*rule))
continue;
(void)load_font_face(static_cast<CSSFontFaceRule const&>(*rule).font_face());
auto font_loader = load_font_face(static_cast<CSSFontFaceRule const&>(*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);
});
}
}

View file

@ -144,7 +144,8 @@ public:
Optional<FontLoader&> load_font_face(ParsedFontFace const&, ESCAPING Function<void(FontLoader const&)> on_load = {}, ESCAPING Function<void()> on_fail = {});
void load_fonts_from_sheet(CSSStyleSheet const&);
void load_fonts_from_sheet(CSSStyleSheet&);
void unload_fonts_from_sheet(CSSStyleSheet&);
RefPtr<Gfx::FontCascadeList const> compute_font_for_style_values(DOM::Element const* element, Optional<CSS::Selector::PseudoElement::Type> 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;

View file

@ -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);
}