diff --git a/Classes/ViewHelpers/RenderSvgViewHelper.php b/Classes/ViewHelpers/RenderSvgViewHelper.php index e69eb5f89614b17fc296f47b309f9d393653494e..511056b042d80d1592e38f21a8de12a6a395d3ea 100644 --- a/Classes/ViewHelpers/RenderSvgViewHelper.php +++ b/Classes/ViewHelpers/RenderSvgViewHelper.php @@ -41,6 +41,9 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper { * @api */ protected $tagName = 'svg'; + /** + * @var string + */ protected $xmlInfo = '<?xml version="1.0"?>'; /** @@ -106,6 +109,11 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper { FALSE, FALSE ); + $this->registerArgument('aria-label', 'string', 'The HTML aria-label attribute'); + $this->registerArgument('aria-labelledby', 'string', 'The HTML aria-labelledby attribute'); + $this->registerArgument('role', 'string', 'The HTML role attribute'); + $this->registerArgument('aria-hidden', 'string', 'The HTML aria-hidden attribute'); + $this->registerArgument('focusable', 'string', 'The HTML focusable attribute'); } /** @@ -131,6 +139,11 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper { $createNewInstance = $this->arguments['createNewInstance']; $preserveColors = $this->arguments['preserveColors']; $createColorAttribute = $this->arguments['createColorAttribute']; + $ariaLabel = $this->arguments['aria-label']; + $ariaLabelledby = $this->arguments['aria-labelledby']; + $role = $this->arguments['role']; + $ariaHidden = $this->arguments['aria-hidden']; + $focusable = $this->arguments['focusable']; $src = $path ?? $this->directoryPath . '/' . $name . '.svg'; @@ -142,9 +155,13 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper { $id = 'svg-' . md5($src . $width . $height . $color); } + $clipPathId = 'clipPath-' . md5($src . $width . $height . $class . $id); + // Load the SVG into a SimpleXMLElement object $svg = new SimpleXMLElement($content); + $this->makeClipPathIdUnique($svg, $clipPathId); + // Set the attributes of the SVG element if ($width > 0) { $this->addOrReplaceAttribute($svg, 'width', $width); @@ -196,6 +213,26 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper { return str_replace($this->xmlInfo, '', $svg->asXML()); } + if ($ariaLabel) { + $this->addOrReplaceAttribute($svg, 'aria-label', $ariaLabel); + } + + if ($ariaLabelledby) { + $this->addOrReplaceAttribute($svg, 'aria-labelledby', $ariaLabelledby); + } + + if ($role) { + $this->addOrReplaceAttribute($svg, 'role', $role); + } + + if ($ariaHidden) { + $this->addOrReplaceAttribute($svg, 'aria-hidden', $ariaHidden); + } + + if ($focusable) { + $this->addOrReplaceAttribute($svg, 'focusable', $focusable); + } + // Extract the SVG contents $contents = $this->getContents($svg, TRUE); @@ -340,4 +377,27 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper { $element->addAttribute($attributeName, $attributeValue); } + + /** + * Makes the clipPath ID unique + */ + private function makeClipPathIdUnique(SimpleXMLElement $xml, $newId): void { + // Loop through the children to find the <g> element and update the clip-path attribute + foreach ($xml->children() as $child) { + if ($child->getName() === 'g') { + $this->addOrReplaceAttribute($child, 'clip-path', "url(#$newId)"); + } + } + + // Now loop through <defs> to find <clipPath> and update its id + foreach ($xml->children() as $child) { + if ($child->getName() === 'defs') { + foreach ($child->children() as $defChild) { + if ($defChild->getName() === 'clipPath') { + $this->addOrReplaceAttribute($defChild, 'id', $newId); + } + } + } + } + } }