diff --git a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.cpp index b926ffc521f..4ba1b732ede 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause @@ -16,16 +16,10 @@ CSSConditionRule::CSSConditionRule(JS::Realm& realm, CSSRuleList& rules) { } -void CSSConditionRule::for_each_effective_style_rule(Function const& callback) const +void CSSConditionRule::for_each_effective_rule(TraversalOrder order, Function const& callback) const { if (condition_matches()) - CSSGroupingRule::for_each_effective_style_rule(callback); -} - -void CSSConditionRule::for_each_effective_keyframes_at_rule(Function const& callback) const -{ - if (condition_matches()) - CSSGroupingRule::for_each_effective_keyframes_at_rule(callback); + CSSGroupingRule::for_each_effective_rule(order, callback); } void CSSConditionRule::initialize(JS::Realm& realm) diff --git a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.h b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.h index e2924370073..f1215b87a23 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSConditionRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSConditionRule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -21,8 +21,7 @@ public: virtual String condition_text() const = 0; virtual bool condition_matches() const = 0; - virtual void for_each_effective_style_rule(Function const& callback) const override; - virtual void for_each_effective_keyframes_at_rule(Function const& callback) const override; + virtual void for_each_effective_rule(TraversalOrder, Function const& callback) const override; protected: CSSConditionRule(JS::Realm&, CSSRuleList&); diff --git a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp index b0f36ff0f39..ad57a3e1d6e 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause @@ -47,14 +47,9 @@ WebIDL::ExceptionOr CSSGroupingRule::delete_rule(u32 index) return m_rules->remove_a_css_rule(index); } -void CSSGroupingRule::for_each_effective_style_rule(Function const& callback) const +void CSSGroupingRule::for_each_effective_rule(TraversalOrder order, Function const& callback) const { - m_rules->for_each_effective_style_rule(callback); -} - -void CSSGroupingRule::for_each_effective_keyframes_at_rule(Function const& callback) const -{ - m_rules->for_each_effective_keyframes_at_rule(callback); + m_rules->for_each_effective_rule(order, callback); } void CSSGroupingRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet) diff --git a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h index f4c3eea68ce..b5c22d54812 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -26,8 +26,7 @@ public: WebIDL::ExceptionOr insert_rule(StringView rule, u32 index = 0); WebIDL::ExceptionOr delete_rule(u32 index); - virtual void for_each_effective_style_rule(Function const& callback) const; - virtual void for_each_effective_keyframes_at_rule(Function const& callback) const; + virtual void for_each_effective_rule(TraversalOrder, Function const& callback) const; virtual void set_parent_style_sheet(CSSStyleSheet*) override; diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp index 5e5f0845f39..e3bfb2c6e3d 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp @@ -119,64 +119,37 @@ WebIDL::ExceptionOr CSSRuleList::remove_a_css_rule(u32 index) return {}; } -void CSSRuleList::for_each_effective_style_rule(Function const& callback) const +void CSSRuleList::for_each_effective_rule(TraversalOrder order, Function const& callback) const { for (auto const& rule : m_rules) { + if (order == TraversalOrder::Preorder) + callback(rule); + switch (rule->type()) { case CSSRule::Type::Import: { auto const& import_rule = static_cast(*rule); if (import_rule.loaded_style_sheet()) - import_rule.loaded_style_sheet()->for_each_effective_style_rule(callback); + import_rule.loaded_style_sheet()->for_each_effective_rule(order, callback); break; } case CSSRule::Type::LayerBlock: case CSSRule::Type::Media: case CSSRule::Type::Supports: - static_cast(*rule).for_each_effective_style_rule(callback); - break; - - case CSSRule::Type::Style: - callback(static_cast(*rule)); + static_cast(*rule).for_each_effective_rule(order, callback); break; case CSSRule::Type::FontFace: case CSSRule::Type::Keyframe: case CSSRule::Type::Keyframes: case CSSRule::Type::LayerStatement: - case CSSRule::Type::Namespace: - break; - } - } -} - -void CSSRuleList::for_each_effective_keyframes_at_rule(Function const& callback) const -{ - for (auto const& rule : m_rules) { - switch (rule->type()) { - case CSSRule::Type::Import: { - auto const& import_rule = static_cast(*rule); - if (import_rule.loaded_style_sheet()) - import_rule.loaded_style_sheet()->for_each_effective_keyframes_at_rule(callback); - break; - } - - case CSSRule::Type::LayerBlock: - case CSSRule::Type::Media: - case CSSRule::Type::Supports: - static_cast(*rule).for_each_effective_keyframes_at_rule(callback); - break; - case CSSRule::Type::Keyframes: - callback(static_cast(*rule)); - break; - - case CSSRule::Type::FontFace: - case CSSRule::Type::Keyframe: - case CSSRule::Type::LayerStatement: case CSSRule::Type::Namespace: case CSSRule::Type::Style: break; } + + if (order == TraversalOrder::Postorder) + callback(rule); } } diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h index 00eb564f4ba..c11cadf78d8 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.h +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Sam Atkins + * Copyright (c) 2021-2024, Sam Atkins * Copyright (c) 2022, Andreas Kling * Copyright (c) 2023, Luke Wilde * @@ -14,6 +14,7 @@ #include #include #include +#include #include namespace Web::CSS { @@ -56,10 +57,9 @@ public: WebIDL::ExceptionOr remove_a_css_rule(u32 index); WebIDL::ExceptionOr insert_a_css_rule(Variant, u32 index); - void for_each_effective_style_rule(Function const& callback) const; + void for_each_effective_rule(TraversalOrder, Function const& callback) const; // Returns whether the match state of any media queries changed after evaluation. bool evaluate_media_queries(HTML::Window const&); - void for_each_effective_keyframes_at_rule(Function const& callback) const; void set_rules(Badge, Vector> rules) { m_rules = move(rules); } diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index 70a6f386583..439d1490e29 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -294,17 +294,26 @@ WebIDL::ExceptionOr CSSStyleSheet::remove_rule(Optional const& callback) const +{ + if (m_media->matches()) + m_rules->for_each_effective_rule(order, callback); +} + void CSSStyleSheet::for_each_effective_style_rule(Function const& callback) const { - if (m_media->matches()) { - m_rules->for_each_effective_style_rule(callback); - } + for_each_effective_rule(TraversalOrder::Preorder, [&](CSSRule const& rule) { + if (rule.type() == CSSRule::Type::Style) + callback(static_cast(rule)); + }); } void CSSStyleSheet::for_each_effective_keyframes_at_rule(Function const& callback) const { - if (m_media->matches()) - m_rules->for_each_effective_keyframes_at_rule(callback); + for_each_effective_rule(TraversalOrder::Preorder, [&](CSSRule const& rule) { + if (rule.type() == CSSRule::Type::Keyframes) + callback(static_cast(rule)); + }); } bool CSSStyleSheet::evaluate_media_queries(HTML::Window const& window) diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h index 90383b9834e..f6d77d2b9df 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h @@ -55,6 +55,7 @@ public: JS::NonnullGCPtr replace(String text); WebIDL::ExceptionOr replace_sync(StringView text); + void for_each_effective_rule(TraversalOrder, Function const& callback) const; void for_each_effective_style_rule(Function const& callback) const; // Returns whether the match state of any media queries changed after evaluation. bool evaluate_media_queries(HTML::Window const&); diff --git a/Userland/Libraries/LibWeb/TraversalOrder.h b/Userland/Libraries/LibWeb/TraversalOrder.h new file mode 100644 index 00000000000..8e6eb0efafd --- /dev/null +++ b/Userland/Libraries/LibWeb/TraversalOrder.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace Web { + +enum class TraversalOrder { + Preorder, + Postorder, +}; + +}