gitea源码

svg.go 2.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package svg
  4. import (
  5. "fmt"
  6. "html/template"
  7. "path"
  8. "strings"
  9. gitea_html "code.gitea.io/gitea/modules/htmlutil"
  10. "code.gitea.io/gitea/modules/log"
  11. "code.gitea.io/gitea/modules/public"
  12. )
  13. var svgIcons map[string]string
  14. const defaultSize = 16
  15. // Init discovers SVG icons and populates the `svgIcons` variable
  16. func Init() error {
  17. const svgAssetsPath = "assets/img/svg"
  18. files, err := public.AssetFS().ListFiles(svgAssetsPath)
  19. if err != nil {
  20. return err
  21. }
  22. svgIcons = make(map[string]string, len(files))
  23. for _, file := range files {
  24. if path.Ext(file) != ".svg" {
  25. continue
  26. }
  27. bs, err := public.AssetFS().ReadFile(svgAssetsPath, file)
  28. if err != nil {
  29. log.Error("Failed to read SVG file %s: %v", file, err)
  30. } else {
  31. svgIcons[file[:len(file)-4]] = string(Normalize(bs, defaultSize))
  32. }
  33. }
  34. return nil
  35. }
  36. func MockIcon(icon string) func() {
  37. if svgIcons == nil {
  38. svgIcons = make(map[string]string)
  39. }
  40. orig, exist := svgIcons[icon]
  41. svgIcons[icon] = fmt.Sprintf(`<svg class="svg %s" width="%d" height="%d"></svg>`, icon, defaultSize, defaultSize)
  42. return func() {
  43. if exist {
  44. svgIcons[icon] = orig
  45. } else {
  46. delete(svgIcons, icon)
  47. }
  48. }
  49. }
  50. // RenderHTML renders icons - arguments icon name (string), size (int), class (string)
  51. func RenderHTML(icon string, others ...any) template.HTML {
  52. size, class := gitea_html.ParseSizeAndClass(defaultSize, "", others...)
  53. if svgStr, ok := svgIcons[icon]; ok {
  54. // the code is somewhat hacky, but it just works, because the SVG contents are all normalized
  55. if size != defaultSize {
  56. svgStr = strings.Replace(svgStr, fmt.Sprintf(`width="%d"`, defaultSize), fmt.Sprintf(`width="%d"`, size), 1)
  57. svgStr = strings.Replace(svgStr, fmt.Sprintf(`height="%d"`, defaultSize), fmt.Sprintf(`height="%d"`, size), 1)
  58. }
  59. if class != "" {
  60. svgStr = strings.Replace(svgStr, `class="`, fmt.Sprintf(`class="%s `, class), 1)
  61. }
  62. return template.HTML(svgStr)
  63. }
  64. // during test (or something wrong happens), there is no SVG loaded, so use a dummy span to tell that the icon is missing
  65. return template.HTML(fmt.Sprintf("<span>%s(%d/%s)</span>", template.HTMLEscapeString(icon), size, template.HTMLEscapeString(class)))
  66. }