LibWeb: Propagate CSSStyleSheet owning documents and shadow roots

Previously these were only stored on the root style sheet and were
accessed by imported stylesheets via their owner rule.

Propagating these to imported style sheets allows us to more easily know
when they change for said imported style sheets.
This commit is contained in:
Callum Law 2025-10-15 23:45:38 +13:00 committed by Tim Ledbetter
parent 3708fc6aa7
commit 9651969708
Notes: github-actions[bot] 2025-10-16 09:28:43 +00:00
3 changed files with 25 additions and 7 deletions

View file

@ -53,6 +53,12 @@ void CSSImportRule::visit_edges(Cell::Visitor& visitor)
void CSSImportRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet)
{
Base::set_parent_style_sheet(parent_style_sheet);
if (m_style_sheet && parent_style_sheet) {
for (auto owning_document_or_shadow_root : parent_style_sheet->owning_documents_or_shadow_roots())
m_style_sheet->add_owning_document_or_shadow_root(*owning_document_or_shadow_root);
}
// Crude detection of whether we're already fetching.
if (m_style_sheet || m_document_load_event_delayer.has_value())
return;
@ -174,9 +180,15 @@ void CSSImportRule::set_style_sheet(GC::Ref<CSSStyleSheet> style_sheet)
{
m_style_sheet = style_sheet;
m_style_sheet->set_owner_css_rule(this);
m_document->style_computer().invalidate_rule_cache();
m_document->style_computer().load_fonts_from_sheet(*m_style_sheet);
m_document->invalidate_style(DOM::StyleInvalidationReason::CSSImportRule);
if (m_parent_style_sheet) {
for (auto owning_document_or_shadow_root : m_parent_style_sheet->owning_documents_or_shadow_roots())
m_style_sheet->add_owning_document_or_shadow_root(*owning_document_or_shadow_root);
}
m_style_sheet->invalidate_owners(DOM::StyleInvalidationReason::CSSImportRule);
}
// https://drafts.csswg.org/cssom/#dom-cssimportrule-media

View file

@ -321,11 +321,21 @@ void CSSStyleSheet::add_owning_document_or_shadow_root(DOM::Node& document_or_sh
{
VERIFY(document_or_shadow_root.is_document() || document_or_shadow_root.is_shadow_root());
m_owning_documents_or_shadow_roots.set(document_or_shadow_root);
for (auto const& import_rule : m_import_rules) {
if (import_rule->loaded_style_sheet())
import_rule->loaded_style_sheet()->add_owning_document_or_shadow_root(document_or_shadow_root);
}
}
void CSSStyleSheet::remove_owning_document_or_shadow_root(DOM::Node& document_or_shadow_root)
{
m_owning_documents_or_shadow_roots.remove(document_or_shadow_root);
for (auto const& import_rule : m_import_rules) {
if (import_rule->loaded_style_sheet())
import_rule->loaded_style_sheet()->remove_owning_document_or_shadow_root(document_or_shadow_root);
}
}
void CSSStyleSheet::invalidate_owners(DOM::StyleInvalidationReason reason)
@ -342,11 +352,6 @@ GC::Ptr<DOM::Document> CSSStyleSheet::owning_document() const
if (!m_owning_documents_or_shadow_roots.is_empty())
return (*m_owning_documents_or_shadow_roots.begin())->document();
if (m_owner_css_rule && m_owner_css_rule->parent_style_sheet()) {
if (auto document = m_owner_css_rule->parent_style_sheet()->owning_document())
return document;
}
if (auto* element = const_cast<CSSStyleSheet*>(this)->owner_node())
return element->document();

View file

@ -66,6 +66,7 @@ public:
bool evaluate_media_queries(DOM::Document const&);
void for_each_effective_keyframes_at_rule(Function<void(CSSKeyframesRule const&)> const& callback) const;
HashTable<GC::Ptr<DOM::Node>> owning_documents_or_shadow_roots() const { return m_owning_documents_or_shadow_roots; }
void add_owning_document_or_shadow_root(DOM::Node& document_or_shadow_root);
void remove_owning_document_or_shadow_root(DOM::Node& document_or_shadow_root);
void invalidate_owners(DOM::StyleInvalidationReason);