mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-30 12:21:06 +00:00
HTML render fix
This commit is contained in:
parent
74dfe439c2
commit
126228d146
|
@ -14,6 +14,7 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Unknwon/com"
|
||||||
"github.com/russross/blackfriday"
|
"github.com/russross/blackfriday"
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
|
|
||||||
|
@ -99,14 +100,27 @@ func (options *CustomRender) Link(out *bytes.Buffer, link []byte, title []byte,
|
||||||
options.Renderer.Link(out, link, title, content)
|
options.Renderer.Link(out, link, title, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
svgSuffix = []byte(".svg")
|
||||||
|
svgSuffixWithMark = []byte(".svg?")
|
||||||
|
)
|
||||||
|
|
||||||
func (options *CustomRender) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
|
func (options *CustomRender) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
|
||||||
prefix := strings.Replace(options.urlPrefix, "/src/", "/raw/", 1)
|
prefix := strings.Replace(options.urlPrefix, "/src/", "/raw/", 1)
|
||||||
if len(link) > 0 && !isLink(link) {
|
if len(link) > 0 {
|
||||||
|
if isLink(link) {
|
||||||
|
// External link with .svg suffix usually means CI status.
|
||||||
|
if bytes.HasSuffix(link, svgSuffix) || bytes.Contains(link, svgSuffixWithMark) {
|
||||||
|
options.Renderer.Image(out, link, title, alt)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if link[0] != '/' {
|
if link[0] != '/' {
|
||||||
prefix += "/"
|
prefix += "/"
|
||||||
}
|
}
|
||||||
link = []byte(prefix + string(link))
|
link = []byte(prefix + string(link))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out.WriteString(`<a href="`)
|
out.WriteString(`<a href="`)
|
||||||
out.Write(link)
|
out.Write(link)
|
||||||
|
@ -236,12 +250,16 @@ var (
|
||||||
rightAngleBracket = []byte(">")
|
rightAngleBracket = []byte(">")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var noEndTags = []string{"img", "input", "br", "hr"}
|
||||||
|
|
||||||
// PostProcessMarkdown treats different types of HTML differently,
|
// PostProcessMarkdown treats different types of HTML differently,
|
||||||
// and only renders special links for plain text blocks.
|
// and only renders special links for plain text blocks.
|
||||||
func PostProcessMarkdown(rawHtml []byte, urlPrefix string) []byte {
|
func PostProcessMarkdown(rawHtml []byte, urlPrefix string) []byte {
|
||||||
var startTag string
|
startTags := make([]string, 0, 5)
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
tokenizer := html.NewTokenizer(bytes.NewReader(rawHtml))
|
tokenizer := html.NewTokenizer(bytes.NewReader(rawHtml))
|
||||||
|
|
||||||
|
OUTER_LOOP:
|
||||||
for html.ErrorToken != tokenizer.Next() {
|
for html.ErrorToken != tokenizer.Next() {
|
||||||
token := tokenizer.Token()
|
token := tokenizer.Token()
|
||||||
switch token.Type {
|
switch token.Type {
|
||||||
|
@ -249,26 +267,32 @@ func PostProcessMarkdown(rawHtml []byte, urlPrefix string) []byte {
|
||||||
buf.Write(RenderSpecialLink([]byte(token.String()), urlPrefix))
|
buf.Write(RenderSpecialLink([]byte(token.String()), urlPrefix))
|
||||||
|
|
||||||
case html.StartTagToken:
|
case html.StartTagToken:
|
||||||
startTag = token.Data
|
|
||||||
buf.WriteString(token.String())
|
buf.WriteString(token.String())
|
||||||
tagName := token.Data
|
tagName := token.Data
|
||||||
// If this is an excluded tag, we skip processing all output until a close tag is encountered.
|
// If this is an excluded tag, we skip processing all output until a close tag is encountered.
|
||||||
if strings.EqualFold("a", tagName) || strings.EqualFold("code", tagName) || strings.EqualFold("pre", tagName) {
|
if strings.EqualFold("a", tagName) || strings.EqualFold("code", tagName) || strings.EqualFold("pre", tagName) {
|
||||||
for html.ErrorToken != tokenizer.Next() {
|
for html.ErrorToken != tokenizer.Next() {
|
||||||
token = tokenizer.Token()
|
token = tokenizer.Token()
|
||||||
|
|
||||||
// Copy the token to the output verbatim
|
// Copy the token to the output verbatim
|
||||||
buf.WriteString(token.String())
|
buf.WriteString(token.String())
|
||||||
// If this is the close tag, we are done
|
// If this is the close tag, we are done
|
||||||
if html.EndTagToken == token.Type && strings.EqualFold(tagName, token.Data) {
|
if token.Type == html.EndTagToken && strings.EqualFold(tagName, token.Data) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
continue OUTER_LOOP
|
||||||
|
}
|
||||||
|
|
||||||
|
if !com.IsSliceContainsStr(noEndTags, token.Data) {
|
||||||
|
startTags = append(startTags, token.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
case html.EndTagToken:
|
case html.EndTagToken:
|
||||||
buf.Write(leftAngleBracket)
|
buf.Write(leftAngleBracket)
|
||||||
buf.WriteString(startTag)
|
buf.WriteString(startTags[len(startTags)-1])
|
||||||
buf.Write(rightAngleBracket)
|
buf.Write(rightAngleBracket)
|
||||||
|
startTags = startTags[:len(startTags)-1]
|
||||||
default:
|
default:
|
||||||
buf.WriteString(token.String())
|
buf.WriteString(token.String())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue