mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-29 08:11:13 +00:00
LibWeb/CSS: Replace style-rule iteration methods with a generic one
I didn't want to add another set of boilerplatey tree-walking methods, so here's a general-purpose one. :^) `for_each_effective_rule()` walks the tree of effective style rules, and runs the callback on each one, in either pre- or postorder. The previous `for_each_effective_style/keyframes_rule()` methods of `CSSStyleSheet` are then reimplemented in terms of `for_each_effective_rule()`, and we can get rid of their equivalents elsewhere.
This commit is contained in:
parent
4c98906e2c
commit
cbb4be3e5e
Notes:
github-actions[bot]
2024-09-06 05:50:56 +00:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/LadybirdBrowser/ladybird/commit/cbb4be3e5e2 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1291
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* 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<void(CSSStyleRule const&)> const& callback) const
|
||||
void CSSConditionRule::for_each_effective_rule(TraversalOrder order, Function<void(Web::CSS::CSSRule const&)> const& callback) const
|
||||
{
|
||||
if (condition_matches())
|
||||
CSSGroupingRule::for_each_effective_style_rule(callback);
|
||||
}
|
||||
|
||||
void CSSConditionRule::for_each_effective_keyframes_at_rule(Function<void(CSSKeyframesRule const&)> 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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* 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<void(CSSStyleRule const&)> const& callback) const override;
|
||||
virtual void for_each_effective_keyframes_at_rule(Function<void(CSSKeyframesRule const&)> const& callback) const override;
|
||||
virtual void for_each_effective_rule(TraversalOrder, Function<void(CSSRule const&)> const& callback) const override;
|
||||
|
||||
protected:
|
||||
CSSConditionRule(JS::Realm&, CSSRuleList&);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
@ -47,14 +47,9 @@ WebIDL::ExceptionOr<void> CSSGroupingRule::delete_rule(u32 index)
|
|||
return m_rules->remove_a_css_rule(index);
|
||||
}
|
||||
|
||||
void CSSGroupingRule::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const
|
||||
void CSSGroupingRule::for_each_effective_rule(TraversalOrder order, Function<void(Web::CSS::CSSRule const&)> const& callback) const
|
||||
{
|
||||
m_rules->for_each_effective_style_rule(callback);
|
||||
}
|
||||
|
||||
void CSSGroupingRule::for_each_effective_keyframes_at_rule(Function<void(CSSKeyframesRule const&)> 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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -26,8 +26,7 @@ public:
|
|||
WebIDL::ExceptionOr<u32> insert_rule(StringView rule, u32 index = 0);
|
||||
WebIDL::ExceptionOr<void> delete_rule(u32 index);
|
||||
|
||||
virtual void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const;
|
||||
virtual void for_each_effective_keyframes_at_rule(Function<void(CSSKeyframesRule const&)> const& callback) const;
|
||||
virtual void for_each_effective_rule(TraversalOrder, Function<void(CSSRule const&)> const& callback) const;
|
||||
|
||||
virtual void set_parent_style_sheet(CSSStyleSheet*) override;
|
||||
|
||||
|
|
|
@ -119,64 +119,37 @@ WebIDL::ExceptionOr<void> CSSRuleList::remove_a_css_rule(u32 index)
|
|||
return {};
|
||||
}
|
||||
|
||||
void CSSRuleList::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const
|
||||
void CSSRuleList::for_each_effective_rule(TraversalOrder order, Function<void(Web::CSS::CSSRule const&)> 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<CSSImportRule const&>(*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<CSSGroupingRule const&>(*rule).for_each_effective_style_rule(callback);
|
||||
break;
|
||||
|
||||
case CSSRule::Type::Style:
|
||||
callback(static_cast<CSSStyleRule const&>(*rule));
|
||||
static_cast<CSSGroupingRule const&>(*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<void(CSSKeyframesRule const&)> const& callback) const
|
||||
{
|
||||
for (auto const& rule : m_rules) {
|
||||
switch (rule->type()) {
|
||||
case CSSRule::Type::Import: {
|
||||
auto const& import_rule = static_cast<CSSImportRule const&>(*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<CSSGroupingRule const&>(*rule).for_each_effective_keyframes_at_rule(callback);
|
||||
break;
|
||||
case CSSRule::Type::Keyframes:
|
||||
callback(static_cast<CSSKeyframesRule const&>(*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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
||||
* Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||
*
|
||||
|
@ -14,6 +14,7 @@
|
|||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/CSS/CSSRule.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/TraversalOrder.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
@ -56,10 +57,9 @@ public:
|
|||
WebIDL::ExceptionOr<void> remove_a_css_rule(u32 index);
|
||||
WebIDL::ExceptionOr<unsigned> insert_a_css_rule(Variant<StringView, CSSRule*>, u32 index);
|
||||
|
||||
void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const;
|
||||
void for_each_effective_rule(TraversalOrder, Function<void(CSSRule const&)> 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<void(CSSKeyframesRule const&)> const& callback) const;
|
||||
|
||||
void set_rules(Badge<CSSStyleSheet>, Vector<JS::NonnullGCPtr<CSSRule>> rules) { m_rules = move(rules); }
|
||||
|
||||
|
|
|
@ -294,17 +294,26 @@ WebIDL::ExceptionOr<void> CSSStyleSheet::remove_rule(Optional<WebIDL::UnsignedLo
|
|||
return delete_rule(index.value_or(0));
|
||||
}
|
||||
|
||||
void CSSStyleSheet::for_each_effective_rule(TraversalOrder order, Function<void(Web::CSS::CSSRule const&)> const& callback) const
|
||||
{
|
||||
if (m_media->matches())
|
||||
m_rules->for_each_effective_rule(order, callback);
|
||||
}
|
||||
|
||||
void CSSStyleSheet::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> 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<CSSStyleRule const&>(rule));
|
||||
});
|
||||
}
|
||||
|
||||
void CSSStyleSheet::for_each_effective_keyframes_at_rule(Function<void(CSSKeyframesRule const&)> 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<CSSKeyframesRule const&>(rule));
|
||||
});
|
||||
}
|
||||
|
||||
bool CSSStyleSheet::evaluate_media_queries(HTML::Window const& window)
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
JS::NonnullGCPtr<JS::Promise> replace(String text);
|
||||
WebIDL::ExceptionOr<void> replace_sync(StringView text);
|
||||
|
||||
void for_each_effective_rule(TraversalOrder, Function<void(CSSRule const&)> const& callback) const;
|
||||
void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const;
|
||||
// Returns whether the match state of any media queries changed after evaluation.
|
||||
bool evaluate_media_queries(HTML::Window const&);
|
||||
|
|
16
Userland/Libraries/LibWeb/TraversalOrder.h
Normal file
16
Userland/Libraries/LibWeb/TraversalOrder.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Web {
|
||||
|
||||
enum class TraversalOrder {
|
||||
Preorder,
|
||||
Postorder,
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in a new issue