mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-14 04:20:42 +02:00
chore: introduce HTMLBuilder (#37688)
This commit is contained in:
parent
701908a945
commit
523822090c
@ -83,3 +83,34 @@ func HTMLPrintTag(w io.Writer, tag template.HTML, attrs map[string]string) (writ
|
||||
written += n
|
||||
return written, err
|
||||
}
|
||||
|
||||
func EscapeString(s string) template.HTML {
|
||||
return template.HTML(template.HTMLEscapeString(s))
|
||||
}
|
||||
|
||||
type HTMLBuilder struct {
|
||||
sb strings.Builder
|
||||
}
|
||||
|
||||
func (b *HTMLBuilder) WriteString(s string) *HTMLBuilder {
|
||||
b.sb.WriteString(template.HTMLEscapeString(s))
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *HTMLBuilder) WriteHTML(s template.HTML) *HTMLBuilder {
|
||||
b.sb.WriteString(string(s))
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *HTMLBuilder) WriteFormat(fmt template.HTML, args ...any) *HTMLBuilder {
|
||||
_, _ = HTMLPrintf(&b.sb, fmt, args...)
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *HTMLBuilder) HTMLString() template.HTML {
|
||||
return template.HTML(b.sb.String())
|
||||
}
|
||||
|
||||
func (b *HTMLBuilder) String() string {
|
||||
return b.sb.String()
|
||||
}
|
||||
|
||||
@ -22,3 +22,10 @@ func TestHTMLFormat(t *testing.T) {
|
||||
assert.Equal(t, template.HTML("<>"), HTMLFormat("%s", template.URL("<>")))
|
||||
assert.Equal(t, template.HTML("&StringMethod &StringMethod"), HTMLFormat("%s %s", testStringer{}, &testStringer{}))
|
||||
}
|
||||
|
||||
func TestHTMLBuilder(t *testing.T) {
|
||||
b := &HTMLBuilder{}
|
||||
b.WriteString("<").WriteHTML("<hr>").WriteFormat("<span>%s%s</span>", ">", EscapeString(">"))
|
||||
assert.Equal(t, "<<hr><span>>></span>", b.String())
|
||||
assert.Equal(t, template.HTML("<<hr><span>>></span>"), b.HTMLString())
|
||||
}
|
||||
|
||||
@ -77,6 +77,7 @@ func (r *RenderInternal) ProtectSafeAttrs(content template.HTML) template.HTML {
|
||||
}
|
||||
|
||||
func (r *RenderInternal) FormatWithSafeAttrs(w io.Writer, fmt template.HTML, a ...any) error {
|
||||
_, err := w.Write([]byte(r.ProtectSafeAttrs(htmlutil.HTMLFormat(fmt, a...))))
|
||||
htmlStr := r.ProtectSafeAttrs(htmlutil.HTMLFormat(fmt, a...))
|
||||
_, err := io.WriteString(w, string(htmlStr))
|
||||
return err
|
||||
}
|
||||
|
||||
@ -106,31 +106,27 @@ func (r *orgWriter) resolveLink(link string) string {
|
||||
// WriteRegularLink renders images, links or videos
|
||||
func (r *orgWriter) WriteRegularLink(l org.RegularLink) {
|
||||
link := r.resolveLink(l.URL)
|
||||
|
||||
printHTML := func(html template.HTML, a ...any) {
|
||||
_, _ = fmt.Fprint(r, htmlutil.HTMLFormat(html, a...))
|
||||
}
|
||||
// Inspired by https://github.com/niklasfasching/go-org/blob/6eb20dbda93cb88c3503f7508dc78cbbc639378f/org/html_writer.go#L406-L427
|
||||
switch l.Kind() {
|
||||
case "image":
|
||||
if l.Description == nil {
|
||||
printHTML(`<img src="%s" alt="%s">`, link, link)
|
||||
_, _ = htmlutil.HTMLPrintf(r, `<img src="%s" alt="%s">`, link, link)
|
||||
} else {
|
||||
imageSrc := r.resolveLink(org.String(l.Description...))
|
||||
printHTML(`<a href="%s"><img src="%s" alt="%s"></a>`, link, imageSrc, imageSrc)
|
||||
_, _ = htmlutil.HTMLPrintf(r, `<a href="%s"><img src="%s" alt="%s"></a>`, link, imageSrc, imageSrc)
|
||||
}
|
||||
case "video":
|
||||
if l.Description == nil {
|
||||
printHTML(`<video src="%s">%s</video>`, link, link)
|
||||
_, _ = htmlutil.HTMLPrintf(r, `<video src="%s">%s</video>`, link, link)
|
||||
} else {
|
||||
videoSrc := r.resolveLink(org.String(l.Description...))
|
||||
printHTML(`<a href="%s"><video src="%s">%s</video></a>`, link, videoSrc, videoSrc)
|
||||
_, _ = htmlutil.HTMLPrintf(r, `<a href="%s"><video src="%s">%s</video></a>`, link, videoSrc, videoSrc)
|
||||
}
|
||||
default:
|
||||
var description any = link
|
||||
if l.Description != nil {
|
||||
description = template.HTML(r.WriteNodesAsString(l.Description...)) // orgmode HTMLWriter outputs HTML content
|
||||
}
|
||||
printHTML(`<a href="%s">%s</a>`, link, description)
|
||||
_, _ = htmlutil.HTMLPrintf(r, `<a href="%s">%s</a>`, link, description)
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,7 +260,7 @@ func (r *Router) normalizeRequestPath(resp http.ResponseWriter, req *http.Reques
|
||||
// do not respond to other requests, to simulate a real sub-path environment
|
||||
resp.Header().Add("Content-Type", "text/html; charset=utf-8")
|
||||
resp.WriteHeader(http.StatusNotFound)
|
||||
_, _ = resp.Write([]byte(htmlutil.HTMLFormat(`404 page not found, sub-path is: <a href="%s">%s</a>`, setting.AppSubURL, setting.AppSubURL)))
|
||||
_, _ = htmlutil.HTMLPrintf(resp, `404 page not found, sub-path is: <a href="%s">%s</a>`, setting.AppSubURL, setting.AppSubURL)
|
||||
return
|
||||
}
|
||||
normalized = true
|
||||
|
||||
@ -276,7 +276,7 @@ func handleRepoViewSubmodule(ctx *context.Context, commitSubmoduleFile *git.Comm
|
||||
redirectLink := submoduleWebLink.CommitWebLink
|
||||
if isViewHomeOnlyContent(ctx) {
|
||||
ctx.Resp.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
_, _ = ctx.Resp.Write([]byte(htmlutil.HTMLFormat(`<a href="%s">%s</a>`, redirectLink, redirectLink)))
|
||||
_, _ = htmlutil.HTMLPrintf(ctx.Resp, `<a href="%s">%s</a>`, redirectLink, redirectLink)
|
||||
} else if !httplib.IsCurrentGiteaSiteURL(ctx, redirectLink) {
|
||||
// don't auto-redirect to external URL, to avoid open redirect or phishing
|
||||
ctx.Data["NotFoundPrompt"] = redirectLink
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user