Skip to content

Commit 8be1004

Browse files
Ahmad-S792Ahmad Saleem
authored andcommitted
:visited link color does not propagate to SVG through currentColor
https://bugs.webkit.org/show_bug.cgi?id=244025 rdar://98776770 Reviewed by Nikolas Zimmermann and Antti Koivisto. This patch aligns WebKit with Blink / Chromium. When an SVG element uses fill="currentColor" or stroke="currentColor" inside a :visited link, the color should resolve to the visited link color, not the unvisited link color. Previously, the code would skip currentColor handling in the visited link block because it assumed the color was already resolved correctly. However, the initial color resolution always used the non-visited style, causing currentColor to resolve to the wrong color for visited links. This fix explicitly handles the currentColor case within the visited link block, ensuring it resolves to style.visitedLinkColor() for both fill and stroke attributes. Credits to `Masataka Yakura` for Test Case. NOTE: This patch fixes the bug in both LegacySVG and Layer Based SVG engine. Test: imported/w3c/web-platform-tests/svg/pservers/reftests/css-color-visited-currentcolor-svg-fill.html imported/w3c/web-platform-tests/svg/pservers/scripted/svg-fill-currentcolor-visited-getcomputedstyle.html * LayoutTests/imported/w3c/web-platform-tests/svg/pservers/reftests/css-color-visited-currentcolor-svg-fill-expected.xht: Added. * LayoutTests/imported/w3c/web-platform-tests/svg/pservers/reftests/css-color-visited-currentcolor-svg-fill.html: Added. * LayoutTests/imported/w3c/web-platform-tests/svg/pservers/scripted/svg-fill-currentcolor-visited-getcomputedstyle-expected.txt: Added. * LayoutTests/imported/w3c/web-platform-tests/svg/pservers/scripted/svg-fill-currentcolor-visited-getcomputedstyle.html: Added. * Source/WebCore/rendering/svg/SVGPaintServerHandlingInlines.h: (WebCore::SVGPaintServerHandling::resolveColorFromStyle): * Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResource.cpp: (WebCore::requestPaintingResource): Canonical link: https://commits.webkit.org/306387@main
1 parent ce294ca commit 8be1004

File tree

6 files changed

+79
-6
lines changed

6 files changed

+79
-6
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2+
<html xmlns="http://www.w3.org/1999/xhtml">
3+
<head>
4+
<title>CSS Reftest Reference</title>
5+
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
6+
<style type="text/css"><![CDATA[
7+
div
8+
{
9+
background-color: green;
10+
height: 100px;
11+
width: 100px;
12+
}
13+
]]></style>
14+
</head>
15+
<body>
16+
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
17+
<div></div>
18+
</body>
19+
</html>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<meta charset="UTF-8">
3+
<title>CSS test: propagate `:visited` link color to an SVG element thorough `fill="currentColor"`</title>
4+
<link rel="help" href="https://www.w3.org/TR/selectors-4/#link">
5+
<link rel="help" href="https://www.w3.org/TR/css-color-4/#currentcolor-color">
6+
<link rel="help" href="https://www.w3.org/TR/css-color-4/#resolving-other-colors">
7+
<link rel="help" href="https://www.w3.org/TR/SVG2/painting.html#SpecifyingFillPaint">
8+
<link rel="author" title="Masataka Yakura" href="mailto:[email protected]">
9+
<link rel="match" href="../../css/reference/ref-filled-green-100px-square.xht">
10+
<style>
11+
:any-link {
12+
color: red;
13+
}
14+
:visited {
15+
color: green;
16+
}
17+
</style>
18+
<body>
19+
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
20+
<a href="">
21+
<svg width="100" height="100">
22+
<rect width="100%" height="100%" fill="currentColor"/>
23+
</svg>
24+
</a>
25+
</body>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
PASS Property fill value 'currentColor' should not leak :visited for SVG fill with currentColor
3+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>SVG paint servers with :visited don't leak information via getComputedStyle</title>
4+
<link rel="help" href="https://www.w3.org/TR/css-color-4/#currentcolor-color">
5+
<link rel="help" href="https://www.w3.org/TR/SVG2/painting.html#SpecifyingFillPaint">
6+
<script src="/resources/testharness.js"></script>
7+
<script src="/resources/testharnessreport.js"></script>
8+
<script src="/css/support/computed-testcommon.js"></script>
9+
10+
<style>
11+
a:link { color: red; }
12+
a:visited { color: green; }
13+
</style>
14+
15+
<a href="">
16+
<svg width="100" height="100">
17+
<rect id="target" width="100%" height="100%" fill="currentColor"/>
18+
</svg>
19+
</a>
20+
21+
<script>
22+
test_computed_value("fill", "currentColor", "rgb(255, 0, 0)", "should not leak :visited for SVG fill with currentColor");
23+
</script>

Source/WebCore/rendering/svg/SVGPaintServerHandlingInlines.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Copyright (C) 2023, 2024 Igalia S.L.
33
* Copyright (C) 2025 Samuel Weinig <[email protected]>
4+
* Copyright (C) 2026 Apple Inc. All rights reserved.
45
*
56
* This library is free software; you can redistribute it and/or
67
* modify it under the terms of the GNU Library General Public
@@ -163,9 +164,10 @@ inline Color SVGPaintServerHandling::resolveColorFromStyle(const RenderStyle& st
163164
auto color = colorResolver.colorResolvingCurrentColor(paint.colorDisregardingType());
164165
if (style.insideLink() == InsideLink::InsideVisited) {
165166
// FIXME: This code doesn't support the uri component of the visited link paint, https://bugs.webkit.org/show_bug.cgi?id=70006
166-
// FIXME: This code is resolving the visit link paint color with RenderStyle::color(), rather than the more commonly used RenderStyle::visitedLinkColor(). If this is intentional, we should document that, otherwise, we should use RenderStyle::visitedLinkColor().
167167
if (auto visitedLinkPaintColor = visitedLinkPaint.tryColor()) {
168-
if (auto visitedColor = colorResolver.colorResolvingCurrentColor(*visitedLinkPaintColor); visitedColor.isValid())
168+
if (visitedLinkPaintColor->isCurrentColor())
169+
color = style.visitedLinkColor();
170+
else if (auto visitedColor = colorResolver.colorResolvingCurrentColor(*visitedLinkPaintColor); visitedColor.isValid())
169171
color = visitedColor.colorWithAlpha(color.alphaAsFloat());
170172
}
171173
}

Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResource.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Copyright (C) 2007 Rob Buis <[email protected]>
44
* Copyright (C) 2008 Dirk Schulze <[email protected]>
55
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
6-
* Copyright (C) 2023-2025 Apple Inc. All rights reserved.
6+
* Copyright (C) 2023-2026 Apple Inc. All rights reserved.
77
* Copyright (C) 2014 Google Inc. All rights reserved.
88
*
99
* This library is free software; you can redistribute it and/or
@@ -80,9 +80,10 @@ static inline LegacyRenderSVGResource* requestPaintingResource(RenderSVGResource
8080
// FIXME: This code doesn't support the uri component of the visited link paint, https://bugs.webkit.org/show_bug.cgi?id=70006
8181
auto& visitedPaint = applyToFill ? style.visitedLinkFill() : style.visitedLinkStroke();
8282

83-
// For `currentcolor`, 'color' already contains the 'visitedColor'.
84-
if (auto visitedPaintColor = visitedPaint.tryColor(); visitedPaintColor && !visitedPaintColor->isCurrentColor()) {
85-
if (auto visitedColor = colorResolver.colorResolvingCurrentColor(*visitedPaintColor); visitedColor.isValid())
83+
if (auto visitedPaintColor = visitedPaint.tryColor()) {
84+
if (visitedPaintColor->isCurrentColor())
85+
color = style.visitedLinkColor();
86+
else if (auto visitedColor = colorResolver.colorResolvingCurrentColor(*visitedPaintColor); visitedColor.isValid())
8687
color = visitedColor.colorWithAlpha(color.alphaAsFloat());
8788
}
8889
}

0 commit comments

Comments
 (0)