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.
This commit is contained in:
parent
402e151b62
commit
b0f926d16b
3 changed files with 27 additions and 2 deletions
|
|
@ -132,7 +132,6 @@ void SVGGradientElement::add_color_stops(Painting::GradientPaintStyle& paint_sty
|
|||
GC::Ptr<SVGGradientElement const> SVGGradientElement::linked_gradient(GC::RootHashTable<SVGGradientElement const*>& seen_gradients) const
|
||||
{
|
||||
// FIXME: This entire function is an ad-hoc hack!
|
||||
// It can only resolve #<ids> in the same document.
|
||||
|
||||
auto link = has_attribute(AttributeNames::href) ? get_attribute(AttributeNames::href) : get_attribute("xlink:href"_fly_string);
|
||||
if (auto href = link; href.has_value() && !link->is_empty()) {
|
||||
|
|
@ -142,7 +141,11 @@ GC::Ptr<SVGGradientElement const> SVGGradientElement::linked_gradient(GC::RootHa
|
|||
auto id = url->fragment();
|
||||
if (!id.has_value() || id->is_empty())
|
||||
return {};
|
||||
auto element = document().get_element_by_id(id.value());
|
||||
GC::Ptr<DOM::Element> element;
|
||||
if (auto containing_shadow = containing_shadow_root())
|
||||
element = containing_shadow->get_element_by_id(id.value());
|
||||
if (!element)
|
||||
element = document().get_element_by_id(id.value());
|
||||
if (!element)
|
||||
return {};
|
||||
if (element == this)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100" height="100" fill="green"/>
|
||||
</svg>
|
||||
18
Tests/LibWeb/Ref/input/svg/gradient-in-shadow-dom.html
Normal file
18
Tests/LibWeb/Ref/input/svg/gradient-in-shadow-dom.html
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="match" href="../../expected/svg/gradient-in-shadow-dom-ref.html" />
|
||||
<div id="host"></div>
|
||||
<script>
|
||||
const host = document.getElementById('host');
|
||||
const shadow = host.attachShadow({ mode: 'open' });
|
||||
shadow.innerHTML = `
|
||||
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="base" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0" stop-color="green"/>
|
||||
<stop offset="1" stop-color="green"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="ref" href="#base"/>
|
||||
</defs>
|
||||
<rect width="100" height="100" fill="url(#ref)"/>
|
||||
</svg>`;
|
||||
</script>
|
||||
Loading…
Reference in a new issue