Skip to content

Commit

Permalink
LibWeb: Remove all font loaders linked to a StyleSheet when it's deleted
Browse files Browse the repository at this point in the history
When a style sheet is removed, all font loaders created from that style
sheet should also be removed.

(cherry picked from commit 74588a0a16fd3a2cb10c50a58f47b9f5695bc2ff)
  • Loading branch information
kalenikaliaksandr authored and nico committed Nov 16, 2024
1 parent 726e001 commit cd091af
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 3 deletions.
9 changes: 9 additions & 0 deletions Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

}
9 changes: 9 additions & 0 deletions Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
namespace Web::CSS {

class CSSImportRule;
class FontLoader;

struct CSSStyleSheetInit {
Optional<String> base_url {};
Expand Down Expand Up @@ -84,6 +85,12 @@ class CSSStyleSheet final : public StyleSheet {
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);

Expand All @@ -110,6 +117,8 @@ class CSSStyleSheet final : public StyleSheet {
bool m_constructed { false };
bool m_disallow_modification { false };
Optional<bool> m_did_match;

Vector<WeakPtr<FontLoader const>> m_associated_font_loaders;
};

}
16 changes: 14 additions & 2 deletions Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2740,12 +2740,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);
});
}
}

Expand Down
3 changes: 2 additions & 1 deletion Userland/Libraries/LibWeb/CSS/StyleComputer.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ class StyleComputer {

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;

Expand Down
1 change: 1 addition & 0 deletions Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit cd091af

Please sign in to comment.