From 9f00425dadaa6ee25e6c29fb0d375564740b6025 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 10 Apr 2025 16:35:59 +0100 Subject: [PATCH] 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. --- Libraries/LibWeb/CSS/CSSStyleRule.cpp | 10 ++++++++++ Libraries/LibWeb/CSS/CSSStyleRule.h | 2 ++ Libraries/LibWeb/CSS/CSSStyleValue.h | 2 ++ .../LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp | 7 +++++++ Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.h | 2 ++ Libraries/LibWeb/CSS/StyleValues/StyleValueList.cpp | 9 ++++++++- Libraries/LibWeb/CSS/StyleValues/StyleValueList.h | 4 +++- 7 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Libraries/LibWeb/CSS/CSSStyleRule.cpp b/Libraries/LibWeb/CSS/CSSStyleRule.cpp index 3c42b5d1558..be1b266ceff 100644 --- a/Libraries/LibWeb/CSS/CSSStyleRule.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleRule.cpp @@ -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(*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()) { diff --git a/Libraries/LibWeb/CSS/CSSStyleRule.h b/Libraries/LibWeb/CSS/CSSStyleRule.h index d1f14185f2c..0be243aa834 100644 --- a/Libraries/LibWeb/CSS/CSSStyleRule.h +++ b/Libraries/LibWeb/CSS/CSSStyleRule.h @@ -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; diff --git a/Libraries/LibWeb/CSS/CSSStyleValue.h b/Libraries/LibWeb/CSS/CSSStyleValue.h index 9f122fb8d3d..77b37b4f90c 100644 --- a/Libraries/LibWeb/CSS/CSSStyleValue.h +++ b/Libraries/LibWeb/CSS/CSSStyleValue.h @@ -381,6 +381,7 @@ public: [[nodiscard]] int to_font_slope() const; [[nodiscard]] int to_font_width() const; + virtual void set_style_sheet(GC::Ptr) { } virtual void visit_edges(JS::Cell::Visitor&) const { } virtual bool equals(CSSStyleValue const& other) const = 0; @@ -400,6 +401,7 @@ private: template struct StyleValueWithDefaultOperators : public CSSStyleValue { using CSSStyleValue::CSSStyleValue; + using Base = CSSStyleValue; virtual bool equals(CSSStyleValue const& other) const override { diff --git a/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp index ab60ef84e53..ffa1e55d55a 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.cpp @@ -433,4 +433,11 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const } } +void ShorthandStyleValue::set_style_sheet(GC::Ptr style_sheet) +{ + Base::set_style_sheet(style_sheet); + for (auto& value : m_properties.values) + const_cast(*value).set_style_sheet(style_sheet); +} + } diff --git a/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.h index b50c346744b..ac621742242 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/ShorthandStyleValue.h @@ -30,6 +30,8 @@ public: private: ShorthandStyleValue(PropertyID shorthand, Vector sub_properties, Vector> values); + virtual void set_style_sheet(GC::Ptr) override; + struct Properties { PropertyID shorthand_property; Vector sub_properties; diff --git a/Libraries/LibWeb/CSS/StyleValues/StyleValueList.cpp b/Libraries/LibWeb/CSS/StyleValues/StyleValueList.cpp index f2513cbed28..d958c0387ab 100644 --- a/Libraries/LibWeb/CSS/StyleValues/StyleValueList.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/StyleValueList.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * 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 style_sheet) +{ + Base::set_style_sheet(style_sheet); + for (auto& value : m_properties.values) + const_cast(*value).set_style_sheet(style_sheet); +} + } diff --git a/Libraries/LibWeb/CSS/StyleValues/StyleValueList.h b/Libraries/LibWeb/CSS/StyleValues/StyleValueList.h index 4eef2d141b0..27e6d9a5e35 100644 --- a/Libraries/LibWeb/CSS/StyleValues/StyleValueList.h +++ b/Libraries/LibWeb/CSS/StyleValues/StyleValueList.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause @@ -46,6 +46,8 @@ private: { } + virtual void set_style_sheet(GC::Ptr) override; + struct Properties { Separator separator; StyleValueVector values;