From 3f86f38b5d23b963bcb40bd73fec51e3273f5076 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 8 Nov 2022 11:11:19 +0800 Subject: [PATCH 1/6] move svg html render to modules/svg --- modules/svg/svg.go | 57 +++++++++++++++++++++++++++++++++++++ modules/templates/helper.go | 54 +++++------------------------------ 2 files changed, 64 insertions(+), 47 deletions(-) diff --git a/modules/svg/svg.go b/modules/svg/svg.go index 1d1f8a90ebe5c..ad40eaa376f9a 100644 --- a/modules/svg/svg.go +++ b/modules/svg/svg.go @@ -4,6 +4,13 @@ package svg +import ( + "fmt" + "html/template" + "regexp" + "strings" +) + // SVGs contains discovered SVGs var SVGs map[string]string @@ -11,3 +18,53 @@ var SVGs map[string]string func Init() { SVGs = Discover() } + +var ( + widthRe = regexp.MustCompile(`width="[0-9]+?"`) + heightRe = regexp.MustCompile(`height="[0-9]+?"`) +) + +// ParseOthers get size and class from string with default values +func ParseOthers(defaultSize int, defaultClass string, others ...interface{}) (int, string) { + if len(others) == 0 { + return defaultSize, defaultClass + } + + size := defaultSize + _size, ok := others[0].(int) + if ok && _size != 0 { + size = _size + } + + if len(others) == 1 { + return size, defaultClass + } + + class := defaultClass + if _class, ok := others[1].(string); ok && _class != "" { + if defaultClass == "" { + class = _class + } else { + class = defaultClass + " " + _class + } + } + + return size, class +} + +// Render render icons - arguments icon name (string), size (int), class (string) +func RenderHTML(icon string, others ...interface{}) template.HTML { + size, class := ParseOthers(16, "", others...) + + if svgStr, ok := SVGs[icon]; ok { + if size != 16 { + svgStr = widthRe.ReplaceAllString(svgStr, fmt.Sprintf(`width="%d"`, size)) + svgStr = heightRe.ReplaceAllString(svgStr, fmt.Sprintf(`height="%d"`, size)) + } + if class != "" { + svgStr = strings.Replace(svgStr, `class="`, fmt.Sprintf(`class="%s `, class), 1) + } + return template.HTML(svgStr) + } + return template.HTML("") +} diff --git a/modules/templates/helper.go b/modules/templates/helper.go index a127b98dc2ed9..5da208a2642d7 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -348,7 +348,7 @@ func NewFuncMap() []template.FuncMap { } return false }, - "svg": SVG, + "svg": svg.RenderHTML, "avatar": Avatar, "avatarHTML": AvatarHTML, "avatarByAction": AvatarByAction, @@ -363,17 +363,17 @@ func NewFuncMap() []template.FuncMap { if len(urlSort) == 0 && isDefault { // if sort is sorted as default add arrow tho this table header if isDefault { - return SVG("octicon-triangle-down", 16) + return svg.RenderHTML("octicon-triangle-down", 16) } } else { // if sort arg is in url test if it correlates with column header sort arguments // the direction of the arrow should indicate the "current sort order", up means ASC(normal), down means DESC(rev) if urlSort == normSort { // the table is sorted with this header normal - return SVG("octicon-triangle-up", 16) + return svg.RenderHTML("octicon-triangle-up", 16) } else if urlSort == revSort { // the table is sorted with this header reverse - return SVG("octicon-triangle-down", 16) + return svg.RenderHTML("octicon-triangle-down", 16) } } // the table is NOT sorted with this header @@ -594,29 +594,6 @@ func NewTextFuncMap() []texttmpl.FuncMap { }} } -var ( - widthRe = regexp.MustCompile(`width="[0-9]+?"`) - heightRe = regexp.MustCompile(`height="[0-9]+?"`) -) - -func parseOthers(defaultSize int, defaultClass string, others ...interface{}) (int, string) { - size := defaultSize - if len(others) > 0 && others[0].(int) != 0 { - size = others[0].(int) - } - - class := defaultClass - if len(others) > 1 && others[1].(string) != "" { - if defaultClass == "" { - class = others[1].(string) - } else { - class = defaultClass + " " + others[1].(string) - } - } - - return size, class -} - // AvatarHTML creates the HTML for an avatar func AvatarHTML(src string, size int, class, name string) template.HTML { sizeStr := fmt.Sprintf(`%d`, size) @@ -628,26 +605,9 @@ func AvatarHTML(src string, size int, class, name string) template.HTML { return template.HTML(``) } -// SVG render icons - arguments icon name (string), size (int), class (string) -func SVG(icon string, others ...interface{}) template.HTML { - size, class := parseOthers(16, "", others...) - - if svgStr, ok := svg.SVGs[icon]; ok { - if size != 16 { - svgStr = widthRe.ReplaceAllString(svgStr, fmt.Sprintf(`width="%d"`, size)) - svgStr = heightRe.ReplaceAllString(svgStr, fmt.Sprintf(`height="%d"`, size)) - } - if class != "" { - svgStr = strings.Replace(svgStr, `class="`, fmt.Sprintf(`class="%s `, class), 1) - } - return template.HTML(svgStr) - } - return template.HTML("") -} - // Avatar renders user avatars. args: user, size (int), class (string) func Avatar(item interface{}, others ...interface{}) template.HTML { - size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar vm", others...) + size, class := svg.ParseOthers(avatars.DefaultAvatarPixelSize, "ui avatar vm", others...) switch t := item.(type) { case *user_model.User: @@ -678,7 +638,7 @@ func AvatarByAction(action *activities_model.Action, others ...interface{}) temp // RepoAvatar renders repo avatars. args: repo, size(int), class (string) func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTML { - size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar", others...) + size, class := svg.ParseOthers(avatars.DefaultAvatarPixelSize, "ui avatar", others...) src := repo.RelAvatarLink() if src != "" { @@ -689,7 +649,7 @@ func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTM // AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string) func AvatarByEmail(email, name string, others ...interface{}) template.HTML { - size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar", others...) + size, class := svg.ParseOthers(avatars.DefaultAvatarPixelSize, "ui avatar", others...) src := avatars.GenerateEmailAvatarFastLink(email, size*setting.Avatar.RenderedSizeFactor) if src != "" { From c1c0d8eed345d8a1c20e11eeca1a9d0c0eb35a59 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 8 Nov 2022 11:15:06 +0800 Subject: [PATCH 2/6] group vaiables --- modules/svg/svg.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/svg/svg.go b/modules/svg/svg.go index ad40eaa376f9a..c3b0490b775a3 100644 --- a/modules/svg/svg.go +++ b/modules/svg/svg.go @@ -11,19 +11,19 @@ import ( "strings" ) -// SVGs contains discovered SVGs -var SVGs map[string]string +var ( + // SVGs contains discovered SVGs + SVGs map[string]string + + widthRe = regexp.MustCompile(`width="[0-9]+?"`) + heightRe = regexp.MustCompile(`height="[0-9]+?"`) +) // Init discovers SVGs and populates the `SVGs` variable func Init() { SVGs = Discover() } -var ( - widthRe = regexp.MustCompile(`width="[0-9]+?"`) - heightRe = regexp.MustCompile(`height="[0-9]+?"`) -) - // ParseOthers get size and class from string with default values func ParseOthers(defaultSize int, defaultClass string, others ...interface{}) (int, string) { if len(others) == 0 { From 87cd1b8eb2d838dbff951fd3bed69bc8ea718cf4 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 8 Nov 2022 18:21:30 +0800 Subject: [PATCH 3/6] Use new name ParseSizeAndClass --- modules/svg/svg.go | 7 ++++--- modules/templates/helper.go | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/svg/svg.go b/modules/svg/svg.go index c3b0490b775a3..94ded4ea9b90c 100644 --- a/modules/svg/svg.go +++ b/modules/svg/svg.go @@ -24,8 +24,9 @@ func Init() { SVGs = Discover() } -// ParseOthers get size and class from string with default values -func ParseOthers(defaultSize int, defaultClass string, others ...interface{}) (int, string) { +// ParseSizeAndClass get size and class from string with default values +// If present, "others" expects the new size first and then the classes to use +func ParseSizeAndClass(defaultSize int, defaultClass string, others ...interface{}) (int, string) { if len(others) == 0 { return defaultSize, defaultClass } @@ -54,7 +55,7 @@ func ParseOthers(defaultSize int, defaultClass string, others ...interface{}) (i // Render render icons - arguments icon name (string), size (int), class (string) func RenderHTML(icon string, others ...interface{}) template.HTML { - size, class := ParseOthers(16, "", others...) + size, class := ParseSizeAndClass(16, "", others...) if svgStr, ok := SVGs[icon]; ok { if size != 16 { diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 5da208a2642d7..f0960467c9854 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -607,7 +607,7 @@ func AvatarHTML(src string, size int, class, name string) template.HTML { // Avatar renders user avatars. args: user, size (int), class (string) func Avatar(item interface{}, others ...interface{}) template.HTML { - size, class := svg.ParseOthers(avatars.DefaultAvatarPixelSize, "ui avatar vm", others...) + size, class := svg.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar vm", others...) switch t := item.(type) { case *user_model.User: @@ -638,7 +638,7 @@ func AvatarByAction(action *activities_model.Action, others ...interface{}) temp // RepoAvatar renders repo avatars. args: repo, size(int), class (string) func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTML { - size, class := svg.ParseOthers(avatars.DefaultAvatarPixelSize, "ui avatar", others...) + size, class := svg.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar", others...) src := repo.RelAvatarLink() if src != "" { @@ -649,7 +649,7 @@ func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTM // AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string) func AvatarByEmail(email, name string, others ...interface{}) template.HTML { - size, class := svg.ParseOthers(avatars.DefaultAvatarPixelSize, "ui avatar", others...) + size, class := svg.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar", others...) src := avatars.GenerateEmailAvatarFastLink(email, size*setting.Avatar.RenderedSizeFactor) if src != "" { From 824060d6377f9f5987a3bdca6569348fca0f0c31 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 8 Nov 2022 18:26:59 +0800 Subject: [PATCH 4/6] Move ParseSizeAndCSS to modules/html --- modules/html/html.go | 34 ++++++++++++++++++++++++++++++++++ modules/svg/svg.go | 33 +++------------------------------ modules/templates/helper.go | 7 ++++--- 3 files changed, 41 insertions(+), 33 deletions(-) create mode 100644 modules/html/html.go diff --git a/modules/html/html.go b/modules/html/html.go new file mode 100644 index 0000000000000..e7e5a04e6d509 --- /dev/null +++ b/modules/html/html.go @@ -0,0 +1,34 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package html + +// ParseSizeAndClass get size and class from string with default values +// If present, "others" expects the new size first and then the classes to use +func ParseSizeAndClass(defaultSize int, defaultClass string, others ...interface{}) (int, string) { + if len(others) == 0 { + return defaultSize, defaultClass + } + + size := defaultSize + _size, ok := others[0].(int) + if ok && _size != 0 { + size = _size + } + + if len(others) == 1 { + return size, defaultClass + } + + class := defaultClass + if _class, ok := others[1].(string); ok && _class != "" { + if defaultClass == "" { + class = _class + } else { + class = defaultClass + " " + _class + } + } + + return size, class +} diff --git a/modules/svg/svg.go b/modules/svg/svg.go index 94ded4ea9b90c..3dfb04310544d 100644 --- a/modules/svg/svg.go +++ b/modules/svg/svg.go @@ -9,6 +9,8 @@ import ( "html/template" "regexp" "strings" + + "code.gitea.io/gitea/modules/html" ) var ( @@ -24,38 +26,9 @@ func Init() { SVGs = Discover() } -// ParseSizeAndClass get size and class from string with default values -// If present, "others" expects the new size first and then the classes to use -func ParseSizeAndClass(defaultSize int, defaultClass string, others ...interface{}) (int, string) { - if len(others) == 0 { - return defaultSize, defaultClass - } - - size := defaultSize - _size, ok := others[0].(int) - if ok && _size != 0 { - size = _size - } - - if len(others) == 1 { - return size, defaultClass - } - - class := defaultClass - if _class, ok := others[1].(string); ok && _class != "" { - if defaultClass == "" { - class = _class - } else { - class = defaultClass + " " + _class - } - } - - return size, class -} - // Render render icons - arguments icon name (string), size (int), class (string) func RenderHTML(icon string, others ...interface{}) template.HTML { - size, class := ParseSizeAndClass(16, "", others...) + size, class := html.ParseSizeAndClass(16, "", others...) if svgStr, ok := SVGs[icon]; ok { if size != 16 { diff --git a/modules/templates/helper.go b/modules/templates/helper.go index f0960467c9854..c5434b7c632ed 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -35,6 +35,7 @@ import ( "code.gitea.io/gitea/modules/emoji" "code.gitea.io/gitea/modules/git" giturl "code.gitea.io/gitea/modules/git/url" + gitea_html "code.gitea.io/gitea/modules/html" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" @@ -607,7 +608,7 @@ func AvatarHTML(src string, size int, class, name string) template.HTML { // Avatar renders user avatars. args: user, size (int), class (string) func Avatar(item interface{}, others ...interface{}) template.HTML { - size, class := svg.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar vm", others...) + size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar vm", others...) switch t := item.(type) { case *user_model.User: @@ -638,7 +639,7 @@ func AvatarByAction(action *activities_model.Action, others ...interface{}) temp // RepoAvatar renders repo avatars. args: repo, size(int), class (string) func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTML { - size, class := svg.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar", others...) + size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar", others...) src := repo.RelAvatarLink() if src != "" { @@ -649,7 +650,7 @@ func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTM // AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string) func AvatarByEmail(email, name string, others ...interface{}) template.HTML { - size, class := svg.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar", others...) + size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, "ui avatar", others...) src := avatars.GenerateEmailAvatarFastLink(email, size*setting.Avatar.RenderedSizeFactor) if src != "" { From c439f8bfae80f260630779a40e7a790a87aa0f2e Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 8 Nov 2022 20:38:09 +0800 Subject: [PATCH 5/6] Update modules/html/html.go Co-authored-by: silverwind --- modules/html/html.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/html/html.go b/modules/html/html.go index e7e5a04e6d509..dafdb503b676d 100644 --- a/modules/html/html.go +++ b/modules/html/html.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. +// Copyright 2022 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. From fad12ad31cd38866dfcb392e58908665ee1c8c3f Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 8 Nov 2022 22:16:56 +0800 Subject: [PATCH 6/6] use const for default size --- modules/svg/svg.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/svg/svg.go b/modules/svg/svg.go index 3dfb04310544d..4e13d92d414d6 100644 --- a/modules/svg/svg.go +++ b/modules/svg/svg.go @@ -21,6 +21,8 @@ var ( heightRe = regexp.MustCompile(`height="[0-9]+?"`) ) +const defaultSize = 16 + // Init discovers SVGs and populates the `SVGs` variable func Init() { SVGs = Discover() @@ -28,10 +30,10 @@ func Init() { // Render render icons - arguments icon name (string), size (int), class (string) func RenderHTML(icon string, others ...interface{}) template.HTML { - size, class := html.ParseSizeAndClass(16, "", others...) + size, class := html.ParseSizeAndClass(defaultSize, "", others...) if svgStr, ok := SVGs[icon]; ok { - if size != 16 { + if size != defaultSize { svgStr = widthRe.ReplaceAllString(svgStr, fmt.Sprintf(`width="%d"`, size)) svgStr = heightRe.ReplaceAllString(svgStr, fmt.Sprintf(`height="%d"`, size)) }