From 61106557418ce2e311f8bf98ae057be18a4fcfbf Mon Sep 17 00:00:00 2001 From: Salim B Date: Tue, 24 Oct 2023 05:18:04 +0200 Subject: [PATCH] Fix and improve inline SVG assembly - Add missing closing outer `` tag. - Set filename (prefixed with `svg-`) as `id` attribute instead of adding it as `class`. The `id` argument to the shortcode has precedence over the prefixed filename, so users can supply a custom `id`. - Add support for `role` attribute via the `role` argument to the shortcode. Defaults to [`role="img"`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/img_role#svg_and_roleimg) if none is provided. - Set `aria-labelledby` to`` elements `id` (or the `ariaLabelledby` shortcode argument, if supplied). - Add support for the [`<desc>` element](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/desc) via the `desc` arg to the shortcode and sets the the corresponding `aria-describedby ` to its `id` (or the `ariaDescribedby` shortcode argument, if supplied). - Add `<title>` and `<desc>` elements as first/second (instead of last) child to the outer `<svg>` element for [backwards compatbility with SVG 1.1](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title). - Fix removal of existing attributes (ensure to only remove them from the outer `svg` element and not its children). - Improve other regular expressions to be more precise and avoid unnecessary minification. --- layouts/partials/_inline-svg.html | 57 +++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/layouts/partials/_inline-svg.html b/layouts/partials/_inline-svg.html index 5706e4c..32a3189 100644 --- a/layouts/partials/_inline-svg.html +++ b/layouts/partials/_inline-svg.html @@ -1,15 +1,16 @@ {{/* .src could also be a resource */}} {{ $svg := .src }} {{ $srcIsString := eq (printf "%T" .src) "string" }} -{{ $classes := slice }} +{{ $path := "" }} {{ if $srcIsString }} - {{ $path := strings.TrimSuffix ".svg" .src }} + {{ $path = strings.TrimSuffix ".svg" .src }} {{ $svg = resources.Get (printf "%s.svg" $path) }} - {{ $classes = slice (path.Base $path) }} {{ else }} - {{ $path := strings.TrimSuffix ".svg" .src.Name }} - {{ $classes = slice (path.Base $path) }} + {{ $path = strings.TrimSuffix ".svg" .src.Name }} {{ end }} +{{ $id := .id | default (print "svg-" (path.Base $path)) }} +{{ $role := .role | default "img" }} +{{ $classes := slice }} {{/* If src doesn't exist in the site, fallback to icon set */}} {{ if and (not $svg) $srcIsString }} @@ -23,7 +24,6 @@ {{ $markup := "" }} {{ with $svg }} - {{ $svg = $svg | minify }} {{ $markup = $svg.Content }} {{ $classes = $classes | append "svg-inline" }} @@ -34,29 +34,50 @@ {{ range $k, $v := $ }}{{ $s.Set $k $v }}{{ end }} {{ $s.Delete "src" }} {{ $s.Delete "title" }} + {{ $s.Set "id" $id }} + {{ $s.Set "role" $role }} {{ $s.Set "class" (delimit $classes " ") }} + {{ $attributes := slice }} - {{/* Override markup with passed title */}} + {{/* Assemble markup for passed title */}} + {{ $patternSvgTagOpen := `<svg(?:\s+[^>]*)?` }} + {{ $patternSvgTag := print "(" $patternSvgTagOpen ")(>)" }} + {{ $markupTitle := "" }} {{ with $.title }} - {{ $markup = $markup | replaceRE "<title.*" "" }} - {{ $markup = replace $markup "" (printf "%s" .) }} + {{ $titleId := print "title-" $id }} + {{ $markupTitle = printf `%s` $titleId . }} + {{ $ariaLabelledby := $.ariaLabelledby | default $titleId }} + {{ $attributes = $attributes | append (printf `aria-labelledby="%s"` $ariaLabelledby) }} + {{/* Remove possibly existing title tag (that immediately follows the svg tag) from SVG */}} + {{ $markup = replaceRE (print $patternSvgTag `\s*][\s\S]*?(?:)`) "$1$2" $markup 1 }} + {{ end }} + + {{/* Assemble markup for passed desc */}} + {{ $markupDesc := "" }} + {{ with $.desc }} + {{ $descId := print "desc-" $id }} + {{ $markupDesc = printf `%s` $descId . }} + {{ $ariaDescribedby := $.ariaDescribedby | default $descId }} + {{ $attributes = $attributes | append (printf `aria-describedby="%s"` $ariaDescribedby) }} + {{/* Remove possibly existing desc tag (that immediately follows the svg tag) from SVG */}} + {{ $markup = replaceRE (print $patternSvgTag `\s*][\s\S]*?(?:)`) "$1$2" $markup 1 }} {{ end }} + {{/* Add title and desc markup to SVG */}} + {{ $replacement := print "$1$2" $markupTitle $markupDesc }} + {{ $markup = replaceRE $patternSvgTag $replacement $markup 1 }} + {{/* Override markup with passed attributes */}} - {{ $attributes := slice }} {{ range $k, $v := $s.Values }} - {{ $matches := findRE (printf `%s=".*?"` $k) $markup 1 }} - {{ if len $matches }} - {{ $markup = replace $markup (index $matches 0) "" 1 }} - {{ end }} + {{ $pattern := printf `(%s) %s="[\s\S]*?"` $patternSvgTagOpen $k }} + {{ $markup = replaceRE $pattern "$1" $markup 1 }} {{ $attributes = $attributes | append (printf `%s="%s"` $k $v) }} {{ end }} - - {{ $pattern := `` }} - {{ $replacement := printf `` (delimit $attributes " ") }} - {{ $markup = replaceRE $pattern $replacement $markup 1 | safeHTML }} + {{ $replacement = print "$1 " (delimit $attributes " ") "$2" }} + {{ $markup = replaceRE $patternSvgTag $replacement $markup 1 }} {{ else }} {{ warnf "Could not find src '%s'." .src }} {{ end }} +{{ $markup = safeHTML $markup }} {{ return $markup }}