mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-29 16:21:29 +00:00
LibWeb: Only invalidate shadow root when style sheet inside changes
We don't have to invalidate style for the entire document when a style sheet changes inside of a shadow root. To make this possible, StyleSheetList now keeps track of which Document-or-ShadowRoot it corresponds to, instead of just tracking the containing Document. This avoids a lot of style recomputation on pages with lots of shadow DOM content (like GitHub).
This commit is contained in:
parent
e71ed67069
commit
4bc3055c0f
Notes:
github-actions[bot]
2024-08-20 14:11:28 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/4bc3055c0fa Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1139 Reviewed-by: https://github.com/AtkinsSJ
|
@ -108,9 +108,8 @@ void CSSStyleRule::set_selector_text(StringView selector_text)
|
||||||
m_selectors = parsed_selectors.release_value();
|
m_selectors = parsed_selectors.release_value();
|
||||||
if (auto* sheet = parent_style_sheet()) {
|
if (auto* sheet = parent_style_sheet()) {
|
||||||
if (auto style_sheet_list = sheet->style_sheet_list()) {
|
if (auto style_sheet_list = sheet->style_sheet_list()) {
|
||||||
auto& document = style_sheet_list->document();
|
style_sheet_list->document().style_computer().invalidate_rule_cache();
|
||||||
document.style_computer().invalidate_rule_cache();
|
style_sheet_list->document_or_shadow_root().invalidate_style();
|
||||||
document.invalidate_style();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ WebIDL::ExceptionOr<unsigned> CSSStyleSheet::insert_rule(StringView rule, unsign
|
||||||
|
|
||||||
if (m_style_sheet_list) {
|
if (m_style_sheet_list) {
|
||||||
m_style_sheet_list->document().style_computer().invalidate_rule_cache();
|
m_style_sheet_list->document().style_computer().invalidate_rule_cache();
|
||||||
m_style_sheet_list->document().invalidate_style();
|
m_style_sheet_list->document_or_shadow_root().invalidate_style();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ WebIDL::ExceptionOr<void> CSSStyleSheet::delete_rule(unsigned index)
|
||||||
if (!result.is_exception()) {
|
if (!result.is_exception()) {
|
||||||
if (m_style_sheet_list) {
|
if (m_style_sheet_list) {
|
||||||
m_style_sheet_list->document().style_computer().invalidate_rule_cache();
|
m_style_sheet_list->document().style_computer().invalidate_rule_cache();
|
||||||
m_style_sheet_list->document().invalidate_style();
|
m_style_sheet_list->document_or_shadow_root().invalidate_style();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020-2024, Andreas Kling <andreas@ladybird.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -107,9 +107,9 @@ void StyleSheetList::add_sheet(CSSStyleSheet& sheet)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_document->style_computer().invalidate_rule_cache();
|
document().style_computer().invalidate_rule_cache();
|
||||||
m_document->style_computer().load_fonts_from_sheet(sheet);
|
document().style_computer().load_fonts_from_sheet(sheet);
|
||||||
m_document->invalidate_style();
|
document_or_shadow_root().invalidate_style();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleSheetList::remove_sheet(CSSStyleSheet& sheet)
|
void StyleSheetList::remove_sheet(CSSStyleSheet& sheet)
|
||||||
|
@ -123,19 +123,19 @@ void StyleSheetList::remove_sheet(CSSStyleSheet& sheet)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_document->style_computer().invalidate_rule_cache();
|
m_document_or_shadow_root->document().style_computer().invalidate_rule_cache();
|
||||||
m_document->invalidate_style();
|
document_or_shadow_root().invalidate_style();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::NonnullGCPtr<StyleSheetList> StyleSheetList::create(DOM::Document& document)
|
JS::NonnullGCPtr<StyleSheetList> StyleSheetList::create(JS::NonnullGCPtr<DOM::Node> document_or_shadow_root)
|
||||||
{
|
{
|
||||||
auto& realm = document.realm();
|
auto& realm = document_or_shadow_root->realm();
|
||||||
return realm.heap().allocate<StyleSheetList>(realm, document);
|
return realm.heap().allocate<StyleSheetList>(realm, document_or_shadow_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleSheetList::StyleSheetList(DOM::Document& document)
|
StyleSheetList::StyleSheetList(JS::NonnullGCPtr<DOM::Node> document_or_shadow_root)
|
||||||
: Bindings::PlatformObject(document.realm())
|
: Bindings::PlatformObject(document_or_shadow_root->realm())
|
||||||
, m_document(document)
|
, m_document_or_shadow_root(document_or_shadow_root)
|
||||||
{
|
{
|
||||||
m_legacy_platform_object_flags = LegacyPlatformObjectFlags { .supports_indexed_properties = true };
|
m_legacy_platform_object_flags = LegacyPlatformObjectFlags { .supports_indexed_properties = true };
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ void StyleSheetList::initialize(JS::Realm& realm)
|
||||||
void StyleSheetList::visit_edges(Cell::Visitor& visitor)
|
void StyleSheetList::visit_edges(Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
visitor.visit(m_document);
|
visitor.visit(m_document_or_shadow_root);
|
||||||
visitor.visit(m_sheets);
|
visitor.visit(m_sheets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,4 +161,14 @@ Optional<JS::Value> StyleSheetList::item_value(size_t index) const
|
||||||
return m_sheets[index].ptr();
|
return m_sheets[index].ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOM::Document& StyleSheetList::document()
|
||||||
|
{
|
||||||
|
return m_document_or_shadow_root->document();
|
||||||
|
}
|
||||||
|
|
||||||
|
DOM::Document const& StyleSheetList::document() const
|
||||||
|
{
|
||||||
|
return m_document_or_shadow_root->document();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020-2024, Andreas Kling <andreas@ladybird.org>
|
||||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
@ -17,7 +17,7 @@ class StyleSheetList final : public Bindings::PlatformObject {
|
||||||
JS_DECLARE_ALLOCATOR(StyleSheetList);
|
JS_DECLARE_ALLOCATOR(StyleSheetList);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] static JS::NonnullGCPtr<StyleSheetList> create(DOM::Document&);
|
[[nodiscard]] static JS::NonnullGCPtr<StyleSheetList> create(JS::NonnullGCPtr<DOM::Node> document_or_shadow_root);
|
||||||
|
|
||||||
void add_a_css_style_sheet(CSS::CSSStyleSheet&);
|
void add_a_css_style_sheet(CSS::CSSStyleSheet&);
|
||||||
void remove_a_css_style_sheet(CSS::CSSStyleSheet&);
|
void remove_a_css_style_sheet(CSS::CSSStyleSheet&);
|
||||||
|
@ -37,11 +37,14 @@ public:
|
||||||
|
|
||||||
virtual Optional<JS::Value> item_value(size_t index) const override;
|
virtual Optional<JS::Value> item_value(size_t index) const override;
|
||||||
|
|
||||||
DOM::Document& document() { return m_document; }
|
[[nodiscard]] DOM::Document& document();
|
||||||
DOM::Document const& document() const { return m_document; }
|
[[nodiscard]] DOM::Document const& document() const;
|
||||||
|
|
||||||
|
[[nodiscard]] DOM::Node& document_or_shadow_root() { return m_document_or_shadow_root; }
|
||||||
|
[[nodiscard]] DOM::Node const& document_or_shadow_root() const { return m_document_or_shadow_root; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit StyleSheetList(DOM::Document&);
|
explicit StyleSheetList(JS::NonnullGCPtr<DOM::Node> document_or_shadow_root);
|
||||||
|
|
||||||
virtual void initialize(JS::Realm&) override;
|
virtual void initialize(JS::Realm&) override;
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
@ -49,7 +52,7 @@ private:
|
||||||
void add_sheet(CSSStyleSheet&);
|
void add_sheet(CSSStyleSheet&);
|
||||||
void remove_sheet(CSSStyleSheet&);
|
void remove_sheet(CSSStyleSheet&);
|
||||||
|
|
||||||
JS::NonnullGCPtr<DOM::Document> m_document;
|
JS::NonnullGCPtr<DOM::Node> m_document_or_shadow_root;
|
||||||
Vector<JS::NonnullGCPtr<CSSStyleSheet>> m_sheets;
|
Vector<JS::NonnullGCPtr<CSSStyleSheet>> m_sheets;
|
||||||
|
|
||||||
// https://www.w3.org/TR/cssom/#preferred-css-style-sheet-set-name
|
// https://www.w3.org/TR/cssom/#preferred-css-style-sheet-set-name
|
||||||
|
|
|
@ -122,7 +122,7 @@ WebIDL::ExceptionOr<void> ShadowRoot::set_html_unsafe(StringView html)
|
||||||
CSS::StyleSheetList& ShadowRoot::style_sheets()
|
CSS::StyleSheetList& ShadowRoot::style_sheets()
|
||||||
{
|
{
|
||||||
if (!m_style_sheets)
|
if (!m_style_sheets)
|
||||||
m_style_sheets = CSS::StyleSheetList::create(document());
|
m_style_sheets = CSS::StyleSheetList::create(*this);
|
||||||
return *m_style_sheets;
|
return *m_style_sheets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue