Skip to content

Commit

Permalink
Fix and improve inline SVG assembly
Browse files Browse the repository at this point in the history
- Add missing closing outer `</svg>` 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`<title>` 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.
  • Loading branch information
salim-b committed Oct 25, 2023
1 parent 0f22b43 commit 6110655
Showing 1 changed file with 39 additions and 18 deletions.
57 changes: 39 additions & 18 deletions layouts/partials/_inline-svg.html
Original file line number Diff line number Diff line change
@@ -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 }}
Expand All @@ -23,7 +24,6 @@

{{ $markup := "" }}
{{ with $svg }}
{{ $svg = $svg | minify }}
{{ $markup = $svg.Content }}

{{ $classes = $classes | append "svg-inline" }}
Expand All @@ -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.*</title>" "" }}
{{ $markup = replace $markup "</svg>" (printf "<title>%s</title>" .) }}
{{ $titleId := print "title-" $id }}
{{ $markupTitle = printf `<title id="%s">%s</title>` $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*<title[\s>][\s\S]*?(?:</title>)`) "$1$2" $markup 1 }}
{{ end }}

{{/* Assemble markup for passed desc */}}
{{ $markupDesc := "" }}
{{ with $.desc }}
{{ $descId := print "desc-" $id }}
{{ $markupDesc = printf `<desc id="%s">%s</desc>` $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*<desc[\s>][\s\S]*?(?:</desc>)`) "$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 := `<svg([\s\S]*)?>` }}
{{ $replacement := printf `<svg %s ${1}>` (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 }}

0 comments on commit 6110655

Please sign in to comment.