summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-09-09 11:08:56 +0200
committerAndreas Kling <kling@serenityos.org>2022-09-09 15:20:10 +0200
commit524ec95bcd1601869ebe96de05d06b52c1099e0c (patch)
treeb9fb26425e8217a56e808e5d3d97af7aff68a0bd
parent32c99313a6d3e2cc551c79f2dd35a17a6f35ba3e (diff)
downloadserenity-524ec95bcd1601869ebe96de05d06b52c1099e0c.zip
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.
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleComputer.cpp2
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleSheetList.cpp20
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleSheetList.h10
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.cpp2
4 files changed, 24 insertions, 10 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
index 2e4931b45a..0f4c201f8c 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 02639fe93c..d2c0b8d759 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 <AK/QuickSort.h>
#include <LibWeb/Bindings/StyleSheetListPrototype.h>
#include <LibWeb/CSS/StyleSheetList.h>
#include <LibWeb/DOM/Document.h>
@@ -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<StyleSheet> a, JS::NonnullGCPtr<StyleSheet> 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 35bd63896a..96f8908a21 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<CSSStyleSheet&> const& sheets() const { return m_sheets; }
- Vector<CSSStyleSheet&>& sheets() { return m_sheets; }
+ Vector<JS::NonnullGCPtr<CSSStyleSheet>> const& sheets() const { return m_sheets; }
+ Vector<JS::NonnullGCPtr<CSSStyleSheet>>& sheets() { return m_sheets; }
CSSStyleSheet* item(size_t index) const
{
if (index >= m_sheets.size())
return {};
- return &const_cast<CSSStyleSheet&>(m_sheets[index]);
+ return const_cast<CSSStyleSheet*>(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<CSSStyleSheet&> m_sheets;
+ Vector<JS::NonnullGCPtr<CSSStyleSheet>> m_sheets;
};
}
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp
index 5de2904b39..9efe823ab4 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;
}