1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- // Copyright 2023 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package svg
-
- import (
- "bytes"
- "fmt"
- "regexp"
- "sync"
- )
-
- type normalizeVarsStruct struct {
- reXMLDoc,
- reComment,
- reAttrXMLNs,
- reAttrSize,
- reAttrClassPrefix *regexp.Regexp
- }
-
- var (
- normalizeVars *normalizeVarsStruct
- normalizeVarsOnce sync.Once
- )
-
- // Normalize normalizes the SVG content: set default width/height, remove unnecessary tags/attributes
- // It's designed to work with valid SVG content. For invalid SVG content, the returned content is not guaranteed.
- func Normalize(data []byte, size int) []byte {
- normalizeVarsOnce.Do(func() {
- normalizeVars = &normalizeVarsStruct{
- reXMLDoc: regexp.MustCompile(`(?s)<\?xml.*?>`),
- reComment: regexp.MustCompile(`(?s)<!--.*?-->`),
-
- reAttrXMLNs: regexp.MustCompile(`(?s)\s+xmlns\s*=\s*"[^"]*"`),
- reAttrSize: regexp.MustCompile(`(?s)\s+(width|height)\s*=\s*"[^"]+"`),
- reAttrClassPrefix: regexp.MustCompile(`(?s)\s+class\s*=\s*"`),
- }
- })
- data = normalizeVars.reXMLDoc.ReplaceAll(data, nil)
- data = normalizeVars.reComment.ReplaceAll(data, nil)
-
- data = bytes.TrimSpace(data)
- svgTag, svgRemaining, ok := bytes.Cut(data, []byte(">"))
- if !ok || !bytes.HasPrefix(svgTag, []byte(`<svg`)) {
- return data
- }
- normalized := bytes.Clone(svgTag)
- normalized = normalizeVars.reAttrXMLNs.ReplaceAll(normalized, nil)
- normalized = normalizeVars.reAttrSize.ReplaceAll(normalized, nil)
- normalized = normalizeVars.reAttrClassPrefix.ReplaceAll(normalized, []byte(` class="`))
- normalized = bytes.TrimSpace(normalized)
- normalized = fmt.Appendf(normalized, ` width="%d" height="%d"`, size, size)
- if !bytes.Contains(normalized, []byte(` class="`)) {
- normalized = append(normalized, ` class="svg"`...)
- }
- normalized = append(normalized, '>')
- normalized = append(normalized, svgRemaining...)
- return normalized
- }
|