LibWeb/CSS: Let CSSStyleValue know its CSSStyleSheet

The CSS `fetch_foo()` functions resolve the URL relative to the
CSSStyleSheet if one is provided. So, style values that do so need to
know what CSSStyleSheet they are part of so that, for example, `url
(foo.png)` is loaded relative to the style sheet's URL instead of the
document's one.

That all works without this change because we currently absolutize URLs
during parsing, but we're in the process of stopping that.

This commit adds the infrastructure for telling style values what their
CSSStyleSheet is.
This commit is contained in:
Sam Atkins 2025-04-10 16:35:59 +01:00
parent bf873a2d5b
commit 9f00425dad
Notes: github-actions[bot] 2025-04-15 09:30:34 +00:00
7 changed files with 34 additions and 2 deletions

View file

@ -205,6 +205,16 @@ void CSSStyleRule::clear_caches()
m_cached_absolutized_selectors.clear();
}
void CSSStyleRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet)
{
Base::set_parent_style_sheet(parent_style_sheet);
// This is annoying: Style values that request resources need to know their CSSStyleSheet in order to fetch them.
for (auto const& property : m_declaration->properties()) {
const_cast<CSSStyleValue&>(*property.value).set_style_sheet(parent_style_sheet);
}
}
CSSStyleRule const* CSSStyleRule::parent_style_rule() const
{
for (auto* parent = parent_rule(); parent; parent = parent->parent_rule()) {

View file

@ -42,6 +42,8 @@ private:
virtual void clear_caches() override;
virtual String serialized() const override;
virtual void set_parent_style_sheet(CSSStyleSheet*) override;
CSSStyleRule const* parent_style_rule() const;
SelectorList m_selectors;

View file

@ -381,6 +381,7 @@ public:
[[nodiscard]] int to_font_slope() const;
[[nodiscard]] int to_font_width() const;
virtual void set_style_sheet(GC::Ptr<CSSStyleSheet>) { }
virtual void visit_edges(JS::Cell::Visitor&) const { }
virtual bool equals(CSSStyleValue const& other) const = 0;
@ -400,6 +401,7 @@ private:
template<typename T>
struct StyleValueWithDefaultOperators : public CSSStyleValue {
using CSSStyleValue::CSSStyleValue;
using Base = CSSStyleValue;
virtual bool equals(CSSStyleValue const& other) const override
{

View file

@ -433,4 +433,11 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
}
}
void ShorthandStyleValue::set_style_sheet(GC::Ptr<CSSStyleSheet> style_sheet)
{
Base::set_style_sheet(style_sheet);
for (auto& value : m_properties.values)
const_cast<CSSStyleValue&>(*value).set_style_sheet(style_sheet);
}
}

View file

@ -30,6 +30,8 @@ public:
private:
ShorthandStyleValue(PropertyID shorthand, Vector<PropertyID> sub_properties, Vector<ValueComparingNonnullRefPtr<CSSStyleValue const>> values);
virtual void set_style_sheet(GC::Ptr<CSSStyleSheet>) override;
struct Properties {
PropertyID shorthand_property;
Vector<PropertyID> sub_properties;

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2021-2025, Sam Atkins <sam@ladybird.org>
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
@ -39,4 +39,11 @@ String StyleValueList::to_string(SerializationMode mode) const
return MUST(builder.to_string());
}
void StyleValueList::set_style_sheet(GC::Ptr<CSSStyleSheet> style_sheet)
{
Base::set_style_sheet(style_sheet);
for (auto& value : m_properties.values)
const_cast<CSSStyleValue&>(*value).set_style_sheet(style_sheet);
}
}

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
* Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2021-2025, Sam Atkins <sam@ladybird.org>
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
@ -46,6 +46,8 @@ private:
{
}
virtual void set_style_sheet(GC::Ptr<CSSStyleSheet>) override;
struct Properties {
Separator separator;
StyleValueVector values;