LibWeb/CSS: Ask CSSNestedDeclarations for selectors and layer directly
This is preparation for nested declarations inside `@scope`. User code no longer makes assumptions about there being a style rule parent, as there may not be one. We cache the absolutized selectors because `@scope` will require us to modify the parent's selectors instead of using them directly.
This commit is contained in:
parent
43f4ecde5c
commit
c67172f368
4 changed files with 30 additions and 5 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024-2025, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2024-2026, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -45,6 +45,27 @@ void CSSNestedDeclarations::visit_edges(Cell::Visitor& visitor)
|
|||
visitor.visit(m_parent_style_rule);
|
||||
}
|
||||
|
||||
static SelectorList absolutize_parent_selectors(CSSNestedDeclarations const& nested_declarations)
|
||||
{
|
||||
for (auto const* parent_rule = nested_declarations.parent_rule(); parent_rule; parent_rule = parent_rule->parent_rule()) {
|
||||
if (auto const* parent_style_rule = as_if<CSSStyleRule>(parent_rule))
|
||||
return parent_style_rule->absolutized_selectors();
|
||||
}
|
||||
|
||||
// NB: CSSNestedDeclarations can only exist inside an ancestor rule that provides selectors, so we cannot get here
|
||||
// unless something has gone very wrong.
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
SelectorList const& CSSNestedDeclarations::absolutized_selectors() const
|
||||
{
|
||||
if (m_cached_absolutized_selectors.has_value())
|
||||
return m_cached_absolutized_selectors.value();
|
||||
|
||||
m_cached_absolutized_selectors = absolutize_parent_selectors(*this);
|
||||
return m_cached_absolutized_selectors.value();
|
||||
}
|
||||
|
||||
GC::Ref<CSSStyleProperties> CSSNestedDeclarations::style()
|
||||
{
|
||||
return m_declaration;
|
||||
|
|
@ -79,6 +100,7 @@ void CSSNestedDeclarations::clear_caches()
|
|||
{
|
||||
Base::clear_caches();
|
||||
m_parent_style_rule = nullptr;
|
||||
m_cached_absolutized_selectors.clear();
|
||||
}
|
||||
|
||||
void CSSNestedDeclarations::dump(StringBuilder& builder, int indent_levels) const
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024-2025, Sam Atkins <sam@ladybird.org>
|
||||
* Copyright (c) 2024-2026, Sam Atkins <sam@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -22,6 +22,8 @@ public:
|
|||
|
||||
virtual ~CSSNestedDeclarations() override = default;
|
||||
|
||||
SelectorList const& absolutized_selectors() const;
|
||||
[[nodiscard]] FlyString const& qualified_layer_name() const { return parent_layer_internal_qualified_name(); }
|
||||
CSSStyleProperties const& declaration() const { return m_declaration; }
|
||||
|
||||
GC::Ref<CSSStyleProperties> style();
|
||||
|
|
@ -39,6 +41,7 @@ private:
|
|||
|
||||
GC::Ref<CSSStyleProperties> m_declaration;
|
||||
GC::Ptr<CSSStyleRule const> mutable m_parent_style_rule;
|
||||
mutable Optional<SelectorList> m_cached_absolutized_selectors;
|
||||
};
|
||||
|
||||
template<>
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ SelectorList const& MatchingRule::absolutized_selectors() const
|
|||
if (rule->type() == CSSRule::Type::Style)
|
||||
return static_cast<CSSStyleRule const&>(*rule).absolutized_selectors();
|
||||
if (rule->type() == CSSRule::Type::NestedDeclarations)
|
||||
return static_cast<CSSNestedDeclarations const&>(*rule).parent_style_rule().absolutized_selectors();
|
||||
return static_cast<CSSNestedDeclarations const&>(*rule).absolutized_selectors();
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ FlyString const& MatchingRule::qualified_layer_name() const
|
|||
if (rule->type() == CSSRule::Type::Style)
|
||||
return static_cast<CSSStyleRule const&>(*rule).qualified_layer_name();
|
||||
if (rule->type() == CSSRule::Type::NestedDeclarations)
|
||||
return static_cast<CSSNestedDeclarations const&>(*rule).parent_style_rule().qualified_layer_name();
|
||||
return static_cast<CSSNestedDeclarations const&>(*rule).qualified_layer_name();
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ void StyleScope::make_rule_cache_for_cascade_origin(CascadeOrigin cascade_origin
|
|||
if (rule.type() == CSSRule::Type::Style)
|
||||
return static_cast<CSSStyleRule const&>(rule).absolutized_selectors();
|
||||
if (rule.type() == CSSRule::Type::NestedDeclarations)
|
||||
return static_cast<CSSNestedDeclarations const&>(rule).parent_style_rule().absolutized_selectors();
|
||||
return static_cast<CSSNestedDeclarations const&>(rule).absolutized_selectors();
|
||||
VERIFY_NOT_REACHED();
|
||||
}();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue