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>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* 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())
|
if (condition_matches())
|
||||||
CSSGroupingRule::for_each_effective_style_rule(callback);
|
CSSGroupingRule::for_each_effective_rule(order, 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSSConditionRule::initialize(JS::Realm& realm)
|
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
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -21,8 +21,7 @@ public:
|
||||||
virtual String condition_text() const = 0;
|
virtual String condition_text() const = 0;
|
||||||
virtual bool condition_matches() 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_rule(TraversalOrder, Function<void(CSSRule const&)> const& callback) const override;
|
||||||
virtual void for_each_effective_keyframes_at_rule(Function<void(CSSKeyframesRule const&)> const& callback) const override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CSSConditionRule(JS::Realm&, CSSRuleList&);
|
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>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* 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);
|
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);
|
m_rules->for_each_effective_rule(order, 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSSGroupingRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet)
|
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
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -26,8 +26,7 @@ public:
|
||||||
WebIDL::ExceptionOr<u32> insert_rule(StringView rule, u32 index = 0);
|
WebIDL::ExceptionOr<u32> insert_rule(StringView rule, u32 index = 0);
|
||||||
WebIDL::ExceptionOr<void> delete_rule(u32 index);
|
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_rule(TraversalOrder, Function<void(CSSRule const&)> const& callback) const;
|
||||||
virtual void for_each_effective_keyframes_at_rule(Function<void(CSSKeyframesRule const&)> const& callback) const;
|
|
||||||
|
|
||||||
virtual void set_parent_style_sheet(CSSStyleSheet*) override;
|
virtual void set_parent_style_sheet(CSSStyleSheet*) override;
|
||||||
|
|
||||||
|
|
|
@ -119,64 +119,37 @@ WebIDL::ExceptionOr<void> CSSRuleList::remove_a_css_rule(u32 index)
|
||||||
return {};
|
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) {
|
for (auto const& rule : m_rules) {
|
||||||
|
if (order == TraversalOrder::Preorder)
|
||||||
|
callback(rule);
|
||||||
|
|
||||||
switch (rule->type()) {
|
switch (rule->type()) {
|
||||||
case CSSRule::Type::Import: {
|
case CSSRule::Type::Import: {
|
||||||
auto const& import_rule = static_cast<CSSImportRule const&>(*rule);
|
auto const& import_rule = static_cast<CSSImportRule const&>(*rule);
|
||||||
if (import_rule.loaded_style_sheet())
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CSSRule::Type::LayerBlock:
|
case CSSRule::Type::LayerBlock:
|
||||||
case CSSRule::Type::Media:
|
case CSSRule::Type::Media:
|
||||||
case CSSRule::Type::Supports:
|
case CSSRule::Type::Supports:
|
||||||
static_cast<CSSGroupingRule const&>(*rule).for_each_effective_style_rule(callback);
|
static_cast<CSSGroupingRule const&>(*rule).for_each_effective_rule(order, callback);
|
||||||
break;
|
|
||||||
|
|
||||||
case CSSRule::Type::Style:
|
|
||||||
callback(static_cast<CSSStyleRule const&>(*rule));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSSRule::Type::FontFace:
|
case CSSRule::Type::FontFace:
|
||||||
case CSSRule::Type::Keyframe:
|
case CSSRule::Type::Keyframe:
|
||||||
case CSSRule::Type::Keyframes:
|
case CSSRule::Type::Keyframes:
|
||||||
case CSSRule::Type::LayerStatement:
|
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::Namespace:
|
||||||
case CSSRule::Type::Style:
|
case CSSRule::Type::Style:
|
||||||
break;
|
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) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
#include <LibWeb/Bindings/PlatformObject.h>
|
#include <LibWeb/Bindings/PlatformObject.h>
|
||||||
#include <LibWeb/CSS/CSSRule.h>
|
#include <LibWeb/CSS/CSSRule.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
|
#include <LibWeb/TraversalOrder.h>
|
||||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
@ -56,10 +57,9 @@ public:
|
||||||
WebIDL::ExceptionOr<void> remove_a_css_rule(u32 index);
|
WebIDL::ExceptionOr<void> remove_a_css_rule(u32 index);
|
||||||
WebIDL::ExceptionOr<unsigned> insert_a_css_rule(Variant<StringView, CSSRule*>, 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.
|
// Returns whether the match state of any media queries changed after evaluation.
|
||||||
bool evaluate_media_queries(HTML::Window const&);
|
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); }
|
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));
|
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
|
void CSSStyleSheet::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const
|
||||||
{
|
{
|
||||||
if (m_media->matches()) {
|
for_each_effective_rule(TraversalOrder::Preorder, [&](CSSRule const& rule) {
|
||||||
m_rules->for_each_effective_style_rule(callback);
|
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
|
void CSSStyleSheet::for_each_effective_keyframes_at_rule(Function<void(CSSKeyframesRule const&)> const& callback) const
|
||||||
{
|
{
|
||||||
if (m_media->matches())
|
for_each_effective_rule(TraversalOrder::Preorder, [&](CSSRule const& rule) {
|
||||||
m_rules->for_each_effective_keyframes_at_rule(callback);
|
if (rule.type() == CSSRule::Type::Keyframes)
|
||||||
|
callback(static_cast<CSSKeyframesRule const&>(rule));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSSStyleSheet::evaluate_media_queries(HTML::Window const& window)
|
bool CSSStyleSheet::evaluate_media_queries(HTML::Window const& window)
|
||||||
|
|
|
@ -55,6 +55,7 @@ public:
|
||||||
JS::NonnullGCPtr<JS::Promise> replace(String text);
|
JS::NonnullGCPtr<JS::Promise> replace(String text);
|
||||||
WebIDL::ExceptionOr<void> replace_sync(StringView 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;
|
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.
|
// Returns whether the match state of any media queries changed after evaluation.
|
||||||
bool evaluate_media_queries(HTML::Window const&);
|
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