From 7d99a92135060be953200e58f80f805e64fd0f2b Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 3 Jun 2025 07:22:28 -0400 Subject: [PATCH] LibWeb: Absolutize CSS image URLs for computed style resolution For getComputedStyle(), we must return an absolute URL for image style values. We currently return the raw parsed URL. This fixes loading the marker icons on https://usermap.serenityos.org. --- .../CSS/StyleValues/ImageStyleValue.cpp | 30 +++++++++++++++++++ .../LibWeb/CSS/StyleValues/ImageStyleValue.h | 1 + .../urls/resolve-relative-to-base.sub.txt | 5 ++-- .../urls/resolve-relative-to-stylesheet.txt | 5 ++-- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.cpp index 0ac05c64444..7dea984d7fd 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.cpp @@ -7,6 +7,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -182,4 +183,33 @@ void ImageStyleValue::set_style_sheet(GC::Ptr style_sheet) m_style_sheet = style_sheet; } +ValueComparingNonnullRefPtr ImageStyleValue::absolutized(CSSPixelRect const&, Length::FontMetrics const&, Length::FontMetrics const&) const +{ + if (m_url.url().is_empty()) + return *this; + + // FIXME: The spec has been updated to handle this better. The computation of the base URL here is roughly based on: + // https://drafts.csswg.org/css-values-4/#style-resource-base-url + // https://github.com/w3c/csswg-drafts/pull/12261 + auto base_url = [&]() -> Optional<::URL::URL> { + if (m_style_sheet) { + return m_style_sheet->base_url() + .value_or_lazy_evaluated_optional([&]() { return m_style_sheet->location(); }) + .value_or_lazy_evaluated_optional([&]() { return HTML::relevant_settings_object(*m_style_sheet).api_base_url(); }); + } + + if (m_document) + return m_document->base_url(); + + return {}; + }(); + + if (base_url.has_value()) { + if (auto resolved_url = ::URL::Parser::basic_parse(m_url.url(), *base_url); resolved_url.has_value()) + return ImageStyleValue::create(*resolved_url); + } + + return *this; +} + } diff --git a/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.h index 5ae0b6913ad..94ee15eac53 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.h @@ -53,6 +53,7 @@ private: ImageStyleValue(URL const&); virtual void set_style_sheet(GC::Ptr) override; + virtual ValueComparingNonnullRefPtr absolutized(CSSPixelRect const& viewport_rect, Length::FontMetrics const& font_metrics, Length::FontMetrics const& root_font_metrics) const override; void animate(); Gfx::ImmutableBitmap const* bitmap(size_t frame_index, Gfx::IntSize = {}) const; diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/urls/resolve-relative-to-base.sub.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/urls/resolve-relative-to-base.sub.txt index a5813c16f8b..225a265d1e1 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/urls/resolve-relative-to-base.sub.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/urls/resolve-relative-to-base.sub.txt @@ -2,6 +2,7 @@ Harness status: OK Found 2 tests -2 Fail -Fail base-relative URL: relative-image-url +1 Pass +1 Fail +Pass base-relative URL: relative-image-url Fail base-relative URL: relative-image-variable-url \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/urls/resolve-relative-to-stylesheet.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/urls/resolve-relative-to-stylesheet.txt index 3bd7e184d55..2a6ff96d061 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-values/urls/resolve-relative-to-stylesheet.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-values/urls/resolve-relative-to-stylesheet.txt @@ -2,7 +2,8 @@ Harness status: OK Found 3 tests -3 Fail -Fail stylesheet-relative URL: stylesheet-relative-image +1 Pass +2 Fail +Pass stylesheet-relative URL: stylesheet-relative-image Fail stylesheet-relative URL: stylesheet-relative-variable-image Fail stylesheet-relative URL: stylesheet-relative-document-variable-image \ No newline at end of file