1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 04:07:44 +00:00

LibWeb: Handle dependency cycles in CSS var()s :^)

We now detect situations like this, where variables infinitely recur,
without crashing:

```css
div {
  --a: var(--b);
  --b: var(--a);
  background: var(--a);
}

p {
  --foo: var(--foo);
  background: var(--foo);
}
```
This commit is contained in:
Sam Atkins 2021-12-03 20:00:31 +00:00 committed by Andreas Kling
parent 3df0bf2c8d
commit c3437bccb3
2 changed files with 80 additions and 9 deletions

View file

@ -1,11 +1,13 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/HashMap.h>
#include <AK/NonnullRefPtrVector.h>
#include <AK/OwnPtr.h>
#include <LibWeb/CSS/CSSStyleDeclaration.h>
@ -23,6 +25,24 @@ struct MatchingRule {
u32 specificity { 0 };
};
class PropertyDependencyNode : public RefCounted<PropertyDependencyNode> {
public:
static NonnullRefPtr<PropertyDependencyNode> create(String name)
{
return adopt_ref(*new PropertyDependencyNode(move(name)));
}
void add_child(NonnullRefPtr<PropertyDependencyNode>);
bool has_cycles();
private:
explicit PropertyDependencyNode(String name);
String m_name;
NonnullRefPtrVector<PropertyDependencyNode> m_children;
bool m_marked { false };
};
class StyleComputer {
public:
explicit StyleComputer(DOM::Document&);
@ -62,7 +82,7 @@ private:
void compute_defaulted_property_value(StyleProperties&, DOM::Element const*, CSS::PropertyID) const;
RefPtr<StyleValue> resolve_unresolved_style_value(DOM::Element&, PropertyID, UnresolvedStyleValue const&) const;
bool expand_unresolved_values(DOM::Element&, Vector<StyleComponentValueRule> const& source, Vector<StyleComponentValueRule>& dest, size_t source_start_index = 0) const;
bool expand_unresolved_values(DOM::Element&, StringView property_name, HashMap<String, NonnullRefPtr<PropertyDependencyNode>>& dependencies, Vector<StyleComponentValueRule> const& source, Vector<StyleComponentValueRule>& dest, size_t source_start_index = 0) const;
template<typename Callback>
void for_each_stylesheet(CascadeOrigin, Callback) const;