Skip to content

Commit b0f926d

Browse files
tcl3awesomekling
authored andcommitted
LibWeb: Resolve SVG gradient references within shadow trees
Previously, the `linked_gradient()` lookup only searched the document for gradient IDs, so gradients inheriting stops via href inside a shadow DOM would fail to find the correct target and be rendered black. We now check any containing shadow root first, before checking the document for linked gradient IDs.
1 parent 402e151 commit b0f926d

3 files changed

Lines changed: 27 additions & 2 deletions

File tree

Libraries/LibWeb/SVG/SVGGradientElement.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ void SVGGradientElement::add_color_stops(Painting::GradientPaintStyle& paint_sty
132132
GC::Ptr<SVGGradientElement const> SVGGradientElement::linked_gradient(GC::RootHashTable<SVGGradientElement const*>& seen_gradients) const
133133
{
134134
// FIXME: This entire function is an ad-hoc hack!
135-
// It can only resolve #<ids> in the same document.
136135

137136
auto link = has_attribute(AttributeNames::href) ? get_attribute(AttributeNames::href) : get_attribute("xlink:href"_fly_string);
138137
if (auto href = link; href.has_value() && !link->is_empty()) {
@@ -142,7 +141,11 @@ GC::Ptr<SVGGradientElement const> SVGGradientElement::linked_gradient(GC::RootHa
142141
auto id = url->fragment();
143142
if (!id.has_value() || id->is_empty())
144143
return {};
145-
auto element = document().get_element_by_id(id.value());
144+
GC::Ptr<DOM::Element> element;
145+
if (auto containing_shadow = containing_shadow_root())
146+
element = containing_shadow->get_element_by_id(id.value());
147+
if (!element)
148+
element = document().get_element_by_id(id.value());
146149
if (!element)
147150
return {};
148151
if (element == this)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!DOCTYPE html>
2+
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
3+
<rect width="100" height="100" fill="green"/>
4+
</svg>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<link rel="match" href="../../expected/svg/gradient-in-shadow-dom-ref.html" />
3+
<div id="host"></div>
4+
<script>
5+
const host = document.getElementById('host');
6+
const shadow = host.attachShadow({ mode: 'open' });
7+
shadow.innerHTML = `
8+
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
9+
<defs>
10+
<linearGradient id="base" x1="0" y1="0" x2="0" y2="1">
11+
<stop offset="0" stop-color="green"/>
12+
<stop offset="1" stop-color="green"/>
13+
</linearGradient>
14+
<linearGradient id="ref" href="#base"/>
15+
</defs>
16+
<rect width="100" height="100" fill="url(#ref)"/>
17+
</svg>`;
18+
</script>

0 commit comments

Comments
 (0)