From 524ec95bcd1601869ebe96de05d06b52c1099e0c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 9 Sep 2022 11:08:56 +0200 Subject: [PATCH] LibWeb: Keep CSS sheets sorted in document tree order This ensures that style is applied consistently, even if the document has external CSS resources that don't always arrive in the same order. --- .../Libraries/LibWeb/CSS/StyleComputer.cpp | 2 +- .../Libraries/LibWeb/CSS/StyleSheetList.cpp | 20 +++++++++++++++---- .../Libraries/LibWeb/CSS/StyleSheetList.h | 10 ++++++---- Userland/Libraries/LibWeb/DOM/Document.cpp | 2 +- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index 2e4931b45a8..0f4c201f8c3 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -141,7 +141,7 @@ void StyleComputer::for_each_stylesheet(CascadeOrigin cascade_origin, Callback c } if (cascade_origin == CascadeOrigin::Author) { for (auto const& sheet : document().style_sheets().sheets()) { - callback(sheet); + callback(*sheet); } } } diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp b/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp index 02639fe93c5..d2c0b8d7590 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -15,6 +16,8 @@ void StyleSheetList::add_sheet(CSSStyleSheet& sheet) sheet.set_style_sheet_list({}, this); m_sheets.append(sheet); + sort_sheets(); + m_document.style_computer().invalidate_rule_cache(); m_document.style_computer().load_fonts_from_sheet(sheet); m_document.invalidate_style(); @@ -23,7 +26,9 @@ void StyleSheetList::add_sheet(CSSStyleSheet& sheet) void StyleSheetList::remove_sheet(CSSStyleSheet& sheet) { sheet.set_style_sheet_list({}, nullptr); - m_sheets.remove_first_matching([&](auto& entry) { return &entry == &sheet; }); + m_sheets.remove_first_matching([&](auto& entry) { return entry.ptr() == &sheet; }); + + sort_sheets(); m_document.style_computer().invalidate_rule_cache(); m_document.invalidate_style(); @@ -45,8 +50,8 @@ void StyleSheetList::visit_edges(Cell::Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(m_document); - for (auto& sheet : m_sheets) - visitor.visit(&sheet); + for (auto sheet : m_sheets) + visitor.visit(sheet.ptr()); } // https://www.w3.org/TR/cssom/#ref-for-dfn-supported-property-indices%E2%91%A1 @@ -65,7 +70,14 @@ JS::Value StyleSheetList::item_value(size_t index) const if (index >= m_sheets.size()) return JS::js_undefined(); - return &m_sheets[index]; + return m_sheets[index].ptr(); +} + +void StyleSheetList::sort_sheets() +{ + quick_sort(m_sheets, [](JS::NonnullGCPtr a, JS::NonnullGCPtr b) { + return a->owner_node()->is_before(*b->owner_node()); + }); } } diff --git a/Userland/Libraries/LibWeb/CSS/StyleSheetList.h b/Userland/Libraries/LibWeb/CSS/StyleSheetList.h index 35bd63896ac..96f8908a21f 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleSheetList.h +++ b/Userland/Libraries/LibWeb/CSS/StyleSheetList.h @@ -20,14 +20,14 @@ public: void add_sheet(CSSStyleSheet&); void remove_sheet(CSSStyleSheet&); - Vector const& sheets() const { return m_sheets; } - Vector& sheets() { return m_sheets; } + Vector> const& sheets() const { return m_sheets; } + Vector>& sheets() { return m_sheets; } CSSStyleSheet* item(size_t index) const { if (index >= m_sheets.size()) return {}; - return &const_cast(m_sheets[index]); + return const_cast(m_sheets[index].ptr()); } size_t length() const { return m_sheets.size(); } @@ -43,8 +43,10 @@ private: virtual void visit_edges(Cell::Visitor&) override; + void sort_sheets(); + DOM::Document& m_document; - Vector m_sheets; + Vector> m_sheets; }; } diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 5de2904b391..9efe823ab4f 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -1582,7 +1582,7 @@ void Document::evaluate_media_rules() { bool any_media_queries_changed_match_state = false; for (auto& style_sheet : style_sheets().sheets()) { - if (style_sheet.evaluate_media_queries(window())) + if (style_sheet->evaluate_media_queries(window())) any_media_queries_changed_match_state = true; }