diff --git a/models/issues/comment_code.go b/models/issues/comment_code.go
index d447d7542cd2..b2179953da50 100644
--- a/models/issues/comment_code.go
+++ b/models/issues/comment_code.go
@@ -109,9 +109,11 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
var err error
if comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: issue.Repo.Link(),
- Metas: issue.Repo.ComposeMetas(),
+ Ctx: ctx,
+ Links: markup.Links{
+ Base: issue.Repo.Link(),
+ },
+ Metas: issue.Repo.ComposeMetas(),
}, comment.Content); err != nil {
return nil, err
}
diff --git a/models/repo/repo.go b/models/repo/repo.go
index b37948fea77a..7baaa7e10a9c 100644
--- a/models/repo/repo.go
+++ b/models/repo/repo.go
@@ -574,8 +574,7 @@ func (repo *Repository) CanEnableEditor() bool {
// DescriptionHTML does special handles to description and return HTML string.
func (repo *Repository) DescriptionHTML(ctx context.Context) template.HTML {
desc, err := markup.RenderDescriptionHTML(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: repo.HTMLURL(),
+ Ctx: ctx,
// Don't use Metas to speedup requests
}, repo.Description)
if err != nil {
diff --git a/modules/markup/external/external.go b/modules/markup/external/external.go
index ffbb6da4dadd..122517ed11c0 100644
--- a/modules/markup/external/external.go
+++ b/modules/markup/external/external.go
@@ -79,9 +79,10 @@ func envMark(envName string) string {
// Render renders the data of the document to HTML via the external tool.
func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
var (
- urlRawPrefix = strings.Replace(ctx.URLPrefix, "/src/", "/raw/", 1)
- command = strings.NewReplacer(envMark("GITEA_PREFIX_SRC"), ctx.URLPrefix,
- envMark("GITEA_PREFIX_RAW"), urlRawPrefix).Replace(p.Command)
+ command = strings.NewReplacer(
+ envMark("GITEA_PREFIX_SRC"), ctx.Links.SrcLink(),
+ envMark("GITEA_PREFIX_RAW"), ctx.Links.RawLink(),
+ ).Replace(p.Command)
commands = strings.Fields(command)
args = commands[1:]
)
@@ -121,14 +122,14 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
ctx.Ctx = graceful.GetManager().ShutdownContext()
}
- processCtx, _, finished := process.GetManager().AddContext(ctx.Ctx, fmt.Sprintf("Render [%s] for %s", commands[0], ctx.URLPrefix))
+ processCtx, _, finished := process.GetManager().AddContext(ctx.Ctx, fmt.Sprintf("Render [%s] for %s", commands[0], ctx.Links.SrcLink()))
defer finished()
cmd := exec.CommandContext(processCtx, commands[0], args...)
cmd.Env = append(
os.Environ(),
- "GITEA_PREFIX_SRC="+ctx.URLPrefix,
- "GITEA_PREFIX_RAW="+urlRawPrefix,
+ "GITEA_PREFIX_SRC="+ctx.Links.SrcLink(),
+ "GITEA_PREFIX_RAW="+ctx.Links.RawLink(),
)
if !p.IsInputFile {
cmd.Stdin = input
diff --git a/modules/markup/html.go b/modules/markup/html.go
index e53ccc6a794a..83c4a6e1652d 100644
--- a/modules/markup/html.go
+++ b/modules/markup/html.go
@@ -80,15 +80,10 @@ const keywordClass = "issue-keyword"
// IsLink reports whether link fits valid format.
func IsLink(link []byte) bool {
- return isLink(link)
-}
-
-// isLink reports whether link fits valid format.
-func isLink(link []byte) bool {
return validLinksPattern.Match(link)
}
-func isLinkStr(link string) bool {
+func IsLinkStr(link string) bool {
return validLinksPattern.MatchString(link)
}
@@ -344,7 +339,7 @@ func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output
node = node.FirstChild
}
- visitNode(ctx, procs, procs, node)
+ visitNode(ctx, procs, node)
newNodes := make([]*html.Node, 0, 5)
@@ -375,7 +370,7 @@ func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output
return nil
}
-func visitNode(ctx *RenderContext, procs, textProcs []processor, node *html.Node) {
+func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
// Add user-content- to IDs and "#" links if they don't already have them
for idx, attr := range node.Attr {
val := strings.TrimPrefix(attr.Val, "#")
@@ -390,35 +385,38 @@ func visitNode(ctx *RenderContext, procs, textProcs []processor, node *html.Node
}
if attr.Key == "class" && attr.Val == "emoji" {
- textProcs = nil
+ procs = nil
}
}
// We ignore code and pre.
switch node.Type {
case html.TextNode:
- textNode(ctx, textProcs, node)
+ textNode(ctx, procs, node)
case html.ElementNode:
if node.Data == "img" {
for i, attr := range node.Attr {
if attr.Key != "src" {
continue
}
- if len(attr.Val) > 0 && !isLinkStr(attr.Val) && !strings.HasPrefix(attr.Val, "data:image/") {
- prefix := ctx.URLPrefix
+ if len(attr.Val) > 0 && !IsLinkStr(attr.Val) && !strings.HasPrefix(attr.Val, "data:image/") {
+ var base string
if ctx.IsWiki {
- prefix = util.URLJoin(prefix, "wiki", "raw")
+ base = ctx.Links.WikiRawLink()
+ } else if ctx.Links.HasBranchInfo() {
+ base = ctx.Links.MediaLink()
+ } else {
+ base = ctx.Links.Base
}
- prefix = strings.Replace(prefix, "/src/", "/media/", 1)
- attr.Val = util.URLJoin(prefix, attr.Val)
+ attr.Val = util.URLJoin(base, attr.Val)
}
attr.Val = camoHandleLink(attr.Val)
node.Attr[i] = attr
}
} else if node.Data == "a" {
// Restrict text in links to emojis
- textProcs = emojiProcessors
+ procs = emojiProcessors
} else if node.Data == "code" || node.Data == "pre" {
return
} else if node.Data == "i" {
@@ -444,7 +442,7 @@ func visitNode(ctx *RenderContext, procs, textProcs []processor, node *html.Node
}
}
for n := node.FirstChild; n != nil; n = n.NextSibling {
- visitNode(ctx, procs, textProcs, n)
+ visitNode(ctx, procs, n)
}
}
// ignore everything else
@@ -641,10 +639,6 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) {
}
func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
- shortLinkProcessorFull(ctx, node, false)
-}
-
-func shortLinkProcessorFull(ctx *RenderContext, node *html.Node, noLink bool) {
next := node.NextSibling
for node != nil && node != next {
m := shortLinkPattern.FindStringSubmatchIndex(node.Data)
@@ -665,7 +659,7 @@ func shortLinkProcessorFull(ctx *RenderContext, node *html.Node, noLink bool) {
if equalPos := strings.IndexByte(v, '='); equalPos == -1 {
// There is no equal in this argument; this is a mandatory arg
if props["name"] == "" {
- if isLinkStr(v) {
+ if IsLinkStr(v) {
// If we clearly see it is a link, we save it so
// But first we need to ensure, that if both mandatory args provided
@@ -740,7 +734,7 @@ func shortLinkProcessorFull(ctx *RenderContext, node *html.Node, noLink bool) {
DataAtom: atom.A,
}
childNode.Parent = linkNode
- absoluteLink := isLinkStr(link)
+ absoluteLink := IsLinkStr(link)
if !absoluteLink {
if image {
link = strings.ReplaceAll(link, " ", "+")
@@ -751,16 +745,18 @@ func shortLinkProcessorFull(ctx *RenderContext, node *html.Node, noLink bool) {
link = url.PathEscape(link)
}
}
- urlPrefix := ctx.URLPrefix
if image {
+ var base string
+ if ctx.IsWiki {
+ base = ctx.Links.WikiRawLink()
+ } else if ctx.Links.HasBranchInfo() {
+ base = ctx.Links.RawLink()
+ } else {
+ base = ctx.Links.Base
+ }
+
if !absoluteLink {
- if IsSameDomain(urlPrefix) {
- urlPrefix = strings.Replace(urlPrefix, "/src/", "/raw/", 1)
- }
- if ctx.IsWiki {
- link = util.URLJoin("wiki", "raw", link)
- }
- link = util.URLJoin(urlPrefix, link)
+ link = util.URLJoin(base, link)
}
title := props["title"]
if title == "" {
@@ -789,18 +785,15 @@ func shortLinkProcessorFull(ctx *RenderContext, node *html.Node, noLink bool) {
} else {
if !absoluteLink {
if ctx.IsWiki {
- link = util.URLJoin("wiki", link)
+ link = util.URLJoin(ctx.Links.WikiLink(), link)
+ } else {
+ link = util.URLJoin(ctx.Links.SrcLink(), link)
}
- link = util.URLJoin(urlPrefix, link)
}
childNode.Type = html.TextNode
childNode.Data = name
}
- if noLink {
- linkNode = childNode
- } else {
- linkNode.Attr = []html.Attribute{{Key: "href", Val: link}}
- }
+ linkNode.Attr = []html.Attribute{{Key: "href", Val: link}}
replaceContent(node, m[0], m[1], linkNode)
node = node.NextSibling.NextSibling
}
diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go
index 7b7f6df70106..5ba956191561 100644
--- a/modules/markup/html_internal_test.go
+++ b/modules/markup/html_internal_test.go
@@ -287,8 +287,8 @@ func TestRender_IssueIndexPattern_Document(t *testing.T) {
}
func testRenderIssueIndexPattern(t *testing.T, input, expected string, ctx *RenderContext) {
- if ctx.URLPrefix == "" {
- ctx.URLPrefix = TestAppURL
+ if ctx.Links.Base == "" {
+ ctx.Links.Base = TestRepoURL
}
var buf strings.Builder
@@ -303,19 +303,23 @@ func TestRender_AutoLink(t *testing.T) {
test := func(input, expected string) {
var buffer strings.Builder
err := PostProcess(&RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: TestRepoURL,
- Metas: localMetas,
+ Ctx: git.DefaultContext,
+ Links: Links{
+ Base: TestRepoURL,
+ },
+ Metas: localMetas,
}, strings.NewReader(input), &buffer)
assert.Equal(t, err, nil)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer.String()))
buffer.Reset()
err = PostProcess(&RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: TestRepoURL,
- Metas: localMetas,
- IsWiki: true,
+ Ctx: git.DefaultContext,
+ Links: Links{
+ Base: TestRepoURL,
+ },
+ Metas: localMetas,
+ IsWiki: true,
}, strings.NewReader(input), &buffer)
assert.Equal(t, err, nil)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer.String()))
@@ -342,9 +346,11 @@ func TestRender_FullIssueURLs(t *testing.T) {
test := func(input, expected string) {
var result strings.Builder
err := postProcess(&RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: TestRepoURL,
- Metas: localMetas,
+ Ctx: git.DefaultContext,
+ Links: Links{
+ Base: TestRepoURL,
+ },
+ Metas: localMetas,
}, []processor{fullIssuePatternProcessor}, strings.NewReader(input), &result)
assert.NoError(t, err)
assert.Equal(t, expected, result.String())
diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go
index 9156bc63312b..e3e0191c43f0 100644
--- a/modules/markup/html_test.go
+++ b/modules/markup/html_test.go
@@ -42,8 +42,10 @@ func TestRender_Commits(t *testing.T) {
buffer, err := RenderString(&RenderContext{
Ctx: git.DefaultContext,
RelativePath: ".md",
- URLPrefix: TestRepoURL,
- Metas: localMetas,
+ Links: Links{
+ Base: TestRepoURL,
+ },
+ Metas: localMetas,
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
@@ -93,8 +95,10 @@ func TestRender_CrossReferences(t *testing.T) {
buffer, err := RenderString(&RenderContext{
Ctx: git.DefaultContext,
RelativePath: "a.md",
- URLPrefix: setting.AppSubURL,
- Metas: localMetas,
+ Links: Links{
+ Base: setting.AppSubURL,
+ },
+ Metas: localMetas,
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
@@ -138,7 +142,9 @@ func TestRender_links(t *testing.T) {
buffer, err := RenderString(&RenderContext{
Ctx: git.DefaultContext,
RelativePath: "a.md",
- URLPrefix: TestRepoURL,
+ Links: Links{
+ Base: TestRepoURL,
+ },
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
@@ -238,7 +244,9 @@ func TestRender_email(t *testing.T) {
res, err := RenderString(&RenderContext{
Ctx: git.DefaultContext,
RelativePath: "a.md",
- URLPrefix: TestRepoURL,
+ Links: Links{
+ Base: TestRepoURL,
+ },
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(res))
@@ -297,7 +305,9 @@ func TestRender_emoji(t *testing.T) {
buffer, err := RenderString(&RenderContext{
Ctx: git.DefaultContext,
RelativePath: "a.md",
- URLPrefix: TestRepoURL,
+ Links: Links{
+ Base: TestRepoURL,
+ },
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
@@ -359,16 +369,21 @@ func TestRender_ShortLinks(t *testing.T) {
test := func(input, expected, expectedWiki string) {
buffer, err := markdown.RenderString(&RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: tree,
+ Ctx: git.DefaultContext,
+ Links: Links{
+ Base: TestRepoURL,
+ BranchPath: "master",
+ },
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
buffer, err = markdown.RenderString(&RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: TestRepoURL,
- Metas: localMetas,
- IsWiki: true,
+ Ctx: git.DefaultContext,
+ Links: Links{
+ Base: TestRepoURL,
+ },
+ Metas: localMetas,
+ IsWiki: true,
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer))
@@ -463,21 +478,25 @@ func TestRender_ShortLinks(t *testing.T) {
func TestRender_RelativeImages(t *testing.T) {
setting.AppURL = TestAppURL
- tree := util.URLJoin(TestRepoURL, "src", "master")
test := func(input, expected, expectedWiki string) {
buffer, err := markdown.RenderString(&RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: tree,
- Metas: localMetas,
+ Ctx: git.DefaultContext,
+ Links: Links{
+ Base: TestRepoURL,
+ BranchPath: "master",
+ },
+ Metas: localMetas,
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
buffer, err = markdown.RenderString(&RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: TestRepoURL,
- Metas: localMetas,
- IsWiki: true,
+ Ctx: git.DefaultContext,
+ Links: Links{
+ Base: TestRepoURL,
+ },
+ Metas: localMetas,
+ IsWiki: true,
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer))
@@ -509,9 +528,11 @@ func Test_ParseClusterFuzz(t *testing.T) {
var res strings.Builder
err := PostProcess(&RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: "https://example.com",
- Metas: localMetas,
+ Ctx: git.DefaultContext,
+ Links: Links{
+ Base: "https://example.com",
+ },
+ Metas: localMetas,
}, strings.NewReader(data), &res)
assert.NoError(t, err)
assert.NotContains(t, res.String(), " 0 && !markup.IsLink(link) {
- prefix := pc.Get(urlPrefixKey).(string)
- if pc.Get(isWikiKey).(bool) {
- prefix = giteautil.URLJoin(prefix, "wiki", "raw")
+ var base string
+ if ctx.IsWiki {
+ base = ctx.Links.WikiRawLink()
+ } else if ctx.Links.HasBranchInfo() {
+ base = ctx.Links.MediaLink()
+ } else {
+ base = ctx.Links.Base
}
- prefix = strings.Replace(prefix, "/src/", "/media/", 1)
-
- lnk := strings.TrimLeft(string(link), "/")
- lnk = giteautil.URLJoin(prefix, lnk)
- link = []byte(lnk)
+ v.Destination = []byte(giteautil.URLJoin(base, string(link)))
}
- v.Destination = link
parent := n.Parent()
// Create a link around image only if parent is not already a link
@@ -107,7 +106,7 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
// Create a link wrapper
wrap := ast.NewLink()
- wrap.Destination = link
+ wrap.Destination = v.Destination
wrap.Title = v.Title
wrap.SetAttributeString("target", []byte("_blank"))
@@ -143,11 +142,15 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
link[0] != '#' && !bytes.HasPrefix(link, byteMailto) {
// special case: this is not a link, a hash link or a mailto:, so it's a
// relative URL
- lnk := string(link)
- if pc.Get(isWikiKey).(bool) {
- lnk = giteautil.URLJoin("wiki", lnk)
+
+ var base string
+ if ctx.IsWiki {
+ base = ctx.Links.WikiLink()
+ } else {
+ base = ctx.Links.Base
}
- link = []byte(giteautil.URLJoin(pc.Get(urlPrefixKey).(string), lnk))
+
+ link = []byte(giteautil.URLJoin(base, string(link)))
}
if len(link) > 0 && link[0] == '#' {
link = []byte("#user-content-" + string(link)[1:])
@@ -188,9 +191,7 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
applyElementDir(v)
case *ast.Text:
if v.SoftLineBreak() && !v.HardLineBreak() {
- renderMetas := pc.Get(renderMetasKey).(map[string]string)
- mode := renderMetas["mode"]
- if mode != "document" {
+ if ctx.Metas["mode"] != "document" {
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInComments)
} else {
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInDocuments)
diff --git a/modules/markup/markdown/markdown.go b/modules/markup/markdown/markdown.go
index 43885889d125..771162b9a3f1 100644
--- a/modules/markup/markdown/markdown.go
+++ b/modules/markup/markdown/markdown.go
@@ -34,9 +34,6 @@ var (
)
var (
- urlPrefixKey = parser.NewContextKey()
- isWikiKey = parser.NewContextKey()
- renderMetasKey = parser.NewContextKey()
renderContextKey = parser.NewContextKey()
renderConfigKey = parser.NewContextKey()
)
@@ -66,9 +63,6 @@ func (l *limitWriter) Write(data []byte) (int, error) {
// newParserContext creates a parser.Context with the render context set
func newParserContext(ctx *markup.RenderContext) parser.Context {
pc := parser.NewContext(parser.WithIDs(newPrefixedIDs()))
- pc.Set(urlPrefixKey, ctx.URLPrefix)
- pc.Set(isWikiKey, ctx.IsWiki)
- pc.Set(renderMetasKey, ctx.Metas)
pc.Set(renderContextKey, ctx)
return pc
}
diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go
index f2322b25544b..c2aaa8409679 100644
--- a/modules/markup/markdown/markdown_test.go
+++ b/modules/markup/markdown/markdown_test.go
@@ -52,16 +52,20 @@ func TestRender_StandardLinks(t *testing.T) {
test := func(input, expected, expectedWiki string) {
buffer, err := RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: setting.AppSubURL,
+ Ctx: git.DefaultContext,
+ Links: markup.Links{
+ Base: setting.AppSubURL,
+ },
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
buffer, err = RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: setting.AppSubURL,
- IsWiki: true,
+ Ctx: git.DefaultContext,
+ Links: markup.Links{
+ Base: setting.AppSubURL,
+ },
+ IsWiki: true,
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(buffer))
@@ -83,8 +87,10 @@ func TestRender_Images(t *testing.T) {
test := func(input, expected string) {
buffer, err := RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: setting.AppSubURL,
+ Ctx: git.DefaultContext,
+ Links: markup.Links{
+ Base: setting.AppSubURL,
+ },
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
@@ -107,7 +113,6 @@ func TestRender_Images(t *testing.T) {
"[!["+title+"]("+url+")]("+href+")",
`
`)
- url = "/../../.images/src/02/train.jpg"
test(
"!["+title+"]("+url+")",
`
`)
@@ -286,14 +291,16 @@ func TestTotal_RenderWiki(t *testing.T) {
setting.AppURL = AppURL
setting.AppSubURL = AppSubURL
- answers := testAnswers(util.URLJoin(AppSubURL, "wiki/"), util.URLJoin(AppSubURL, "wiki", "raw/"))
+ answers := testAnswers(util.URLJoin(AppSubURL, "wiki"), util.URLJoin(AppSubURL, "wiki", "raw"))
for i := 0; i < len(sameCases); i++ {
line, err := RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: AppSubURL,
- Metas: localMetas,
- IsWiki: true,
+ Ctx: git.DefaultContext,
+ Links: markup.Links{
+ Base: setting.AppSubURL,
+ },
+ Metas: localMetas,
+ IsWiki: true,
}, sameCases[i])
assert.NoError(t, err)
assert.Equal(t, answers[i], line)
@@ -314,9 +321,11 @@ func TestTotal_RenderWiki(t *testing.T) {
for i := 0; i < len(testCases); i += 2 {
line, err := RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: AppSubURL,
- IsWiki: true,
+ Ctx: git.DefaultContext,
+ Links: markup.Links{
+ Base: setting.AppSubURL,
+ },
+ IsWiki: true,
}, testCases[i])
assert.NoError(t, err)
assert.Equal(t, testCases[i+1], line)
@@ -327,13 +336,16 @@ func TestTotal_RenderString(t *testing.T) {
setting.AppURL = AppURL
setting.AppSubURL = AppSubURL
- answers := testAnswers(util.URLJoin(AppSubURL, "src", "master/"), util.URLJoin(AppSubURL, "raw", "master/"))
+ answers := testAnswers(util.URLJoin(AppSubURL, "src", "master"), util.URLJoin(AppSubURL, "raw", "master"))
for i := 0; i < len(sameCases); i++ {
line, err := RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: util.URLJoin(AppSubURL, "src", "master/"),
- Metas: localMetas,
+ Ctx: git.DefaultContext,
+ Links: markup.Links{
+ Base: AppSubURL,
+ BranchPath: "master",
+ },
+ Metas: localMetas,
}, sameCases[i])
assert.NoError(t, err)
assert.Equal(t, answers[i], line)
@@ -343,8 +355,10 @@ func TestTotal_RenderString(t *testing.T) {
for i := 0; i < len(testCases); i += 2 {
line, err := RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: AppSubURL,
+ Ctx: git.DefaultContext,
+ Links: markup.Links{
+ Base: AppSubURL,
+ },
}, testCases[i])
assert.NoError(t, err)
assert.Equal(t, testCases[i+1], line)
@@ -556,3 +570,369 @@ foo: bar
assert.Equal(t, test.expected, res, "Unexpected result in testcase %q", test.testcase)
}
}
+
+func TestRenderLinks(t *testing.T) {
+ input := ` space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+[local link](file.bin)
+[remote link](https://example.com)
+[[local link|file.bin]]
+[[remote link|https://example.com]]
+![local image](image.jpg)
+![remote image](https://example.com/image.jpg)
+[[local image|image.jpg]]
+[[remote link|https://example.com/image.jpg]]
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+:+1:
+mail@domain.com
+@mention-user test
+#123
+ space
+`
+ cases := []struct {
+ Links markup.Links
+ IsWiki bool
+ Expected string
+ }{
+ {
+ Links: markup.Links{},
+ IsWiki: false,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{},
+ IsWiki: true,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "https://gitea.io/",
+ },
+ IsWiki: false,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "https://gitea.io/",
+ },
+ IsWiki: true,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "/relative/path",
+ },
+ IsWiki: false,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "/relative/path",
+ },
+ IsWiki: true,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "/user/repo",
+ BranchPath: "branch/main",
+ },
+ IsWiki: false,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "/relative/path",
+ BranchPath: "branch/main",
+ },
+ IsWiki: true,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "/user/repo",
+ TreePath: "sub/folder",
+ },
+ IsWiki: false,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "/relative/path",
+ TreePath: "sub/folder",
+ },
+ IsWiki: true,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "/user/repo",
+ BranchPath: "branch/main",
+ TreePath: "sub/folder",
+ },
+ IsWiki: false,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ {
+ Links: markup.Links{
+ Base: "/relative/path",
+ BranchPath: "branch/main",
+ TreePath: "sub/folder",
+ },
+ IsWiki: true,
+ Expected: `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`,
+ },
+ }
+
+ log.Error(setting.AppURL)
+
+ for i, c := range cases {
+ result, err := RenderString(&markup.RenderContext{Ctx: context.Background(), Links: c.Links, IsWiki: c.IsWiki}, input)
+ assert.NoError(t, err, "Unexpected error in testcase: %v", i)
+ assert.Equal(t, c.Expected, result, "Unexpected result in testcase %v", i)
+ }
+}
diff --git a/modules/markup/orgmode/orgmode.go b/modules/markup/orgmode/orgmode.go
index a6dac120398c..94b1f99605e1 100644
--- a/modules/markup/orgmode/orgmode.go
+++ b/modules/markup/orgmode/orgmode.go
@@ -4,7 +4,6 @@
package markup
import (
- "bytes"
"fmt"
"html"
"io"
@@ -101,8 +100,7 @@ func Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error
w := &Writer{
HTMLWriter: htmlWriter,
- URLPrefix: ctx.URLPrefix,
- IsWiki: ctx.IsWiki,
+ Ctx: ctx,
}
htmlWriter.ExtendingWriter = w
@@ -132,50 +130,41 @@ func (Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Wri
// Writer implements org.Writer
type Writer struct {
*org.HTMLWriter
- URLPrefix string
- IsWiki bool
+ Ctx *markup.RenderContext
}
-var byteMailto = []byte("mailto:")
+const mailto = "mailto:"
// WriteRegularLink renders images, links or videos
func (r *Writer) WriteRegularLink(l org.RegularLink) {
- link := []byte(html.EscapeString(l.URL))
+ link := html.EscapeString(l.URL)
if l.Protocol == "file" {
link = link[len("file:"):]
}
- if len(link) > 0 && !markup.IsLink(link) &&
- link[0] != '#' && !bytes.HasPrefix(link, byteMailto) {
- lnk := string(link)
- if r.IsWiki {
- lnk = util.URLJoin("wiki", lnk)
+ if len(link) > 0 && !markup.IsLinkStr(link) &&
+ link[0] != '#' && !strings.HasPrefix(link, mailto) {
+ base := r.Ctx.Links.Base
+ switch l.Kind() {
+ case "image", "video":
+ if r.Ctx.IsWiki {
+ base = r.Ctx.Links.WikiRawLink()
+ } else if r.Ctx.Links.HasBranchInfo() {
+ base = r.Ctx.Links.MediaLink()
+ }
}
- link = []byte(util.URLJoin(r.URLPrefix, lnk))
+ link = util.URLJoin(base, link)
}
- description := string(link)
+ description := link
if l.Description != nil {
description = r.WriteNodesAsString(l.Description...)
}
switch l.Kind() {
case "image":
- imageSrc := getMediaURL(link)
- fmt.Fprintf(r, ``, imageSrc, description, description)
+ fmt.Fprintf(r, ``, link, description, description)
case "video":
- videoSrc := getMediaURL(link)
- fmt.Fprintf(r, ``, videoSrc, description, description)
+ fmt.Fprintf(r, ``, link, description, description)
default:
fmt.Fprintf(r, `%s`, link, description, description)
}
}
-
-func getMediaURL(l []byte) string {
- srcURL := string(l)
-
- // Check if link is valid
- if len(srcURL) > 0 && !markup.IsLink(l) {
- srcURL = strings.Replace(srcURL, "/src/", "/media/", 1)
- }
-
- return srcURL
-}
diff --git a/modules/markup/orgmode/orgmode_test.go b/modules/markup/orgmode/orgmode_test.go
index d6467c36f714..6c21f9bb6c05 100644
--- a/modules/markup/orgmode/orgmode_test.go
+++ b/modules/markup/orgmode/orgmode_test.go
@@ -27,8 +27,10 @@ func TestRender_StandardLinks(t *testing.T) {
test := func(input, expected string) {
buffer, err := RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: setting.AppSubURL,
+ Ctx: git.DefaultContext,
+ Links: markup.Links{
+ Base: setting.AppSubURL,
+ },
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
@@ -48,8 +50,10 @@ func TestRender_Images(t *testing.T) {
test := func(input, expected string) {
buffer, err := RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: setting.AppSubURL,
+ Ctx: git.DefaultContext,
+ Links: markup.Links{
+ Base: setting.AppSubURL,
+ },
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
@@ -68,8 +72,7 @@ func TestRender_Source(t *testing.T) {
test := func(input, expected string) {
buffer, err := RenderString(&markup.RenderContext{
- Ctx: git.DefaultContext,
- URLPrefix: setting.AppSubURL,
+ Ctx: git.DefaultContext,
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go
index 0331c3742ab1..39d0fabd804e 100644
--- a/modules/markup/renderer.go
+++ b/modules/markup/renderer.go
@@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
"github.com/yuin/goldmark/ast"
)
@@ -69,7 +70,7 @@ type RenderContext struct {
RelativePath string // relative path from tree root of the branch
Type string
IsWiki bool
- URLPrefix string
+ Links Links
Metas map[string]string
DefaultLink string
GitRepo *git.Repository
@@ -80,6 +81,36 @@ type RenderContext struct {
InStandalonePage bool // used by external render. the router "/org/repo/render/..." will output the rendered content in a standalone page
}
+type Links struct {
+ Base string
+ BranchPath string
+ TreePath string
+}
+
+func (ctx *Links) HasBranchInfo() bool {
+ return ctx.BranchPath != ""
+}
+
+func (ctx *Links) SrcLink() string {
+ return util.URLJoin(ctx.Base, "src", ctx.BranchPath, ctx.TreePath)
+}
+
+func (ctx *Links) MediaLink() string {
+ return util.URLJoin(ctx.Base, "media", ctx.BranchPath, ctx.TreePath)
+}
+
+func (ctx *Links) RawLink() string {
+ return util.URLJoin(ctx.Base, "raw", ctx.BranchPath, ctx.TreePath)
+}
+
+func (ctx *Links) WikiLink() string {
+ return util.URLJoin(ctx.Base, "wiki")
+}
+
+func (ctx *Links) WikiRawLink() string {
+ return util.URLJoin(ctx.Base, "wiki/raw")
+}
+
// Cancel runs any cleanup functions that have been registered for this Ctx
func (ctx *RenderContext) Cancel() {
if ctx == nil {
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 8fedc4076a4d..b18ba6795874 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -158,7 +158,6 @@ func NewFuncMap() template.FuncMap {
"RenderEmoji": RenderEmoji,
"RenderEmojiPlain": emoji.ReplaceAliases,
"ReactionToEmoji": ReactionToEmoji,
- "RenderNote": RenderNote,
"RenderMarkdownToHtml": RenderMarkdownToHtml,
"RenderLabel": RenderLabel,
diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go
index d23103ce1bc5..a1788204c042 100644
--- a/modules/templates/util_render.go
+++ b/modules/templates/util_render.go
@@ -24,21 +24,13 @@ import (
)
// RenderCommitMessage renders commit message with XSS-safe and special links.
-func RenderCommitMessage(ctx context.Context, msg, urlPrefix string, metas map[string]string) template.HTML {
- return RenderCommitMessageLink(ctx, msg, urlPrefix, "", metas)
-}
-
-// RenderCommitMessageLink renders commit message as a XXS-safe link to the provided
-// default url, handling for special links.
-func RenderCommitMessageLink(ctx context.Context, msg, urlPrefix, urlDefault string, metas map[string]string) template.HTML {
+func RenderCommitMessage(ctx context.Context, msg string, metas map[string]string) template.HTML {
cleanMsg := template.HTMLEscapeString(msg)
// we can safely assume that it will not return any error, since there
// shouldn't be any special HTML.
fullMessage, err := markup.RenderCommitMessage(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: urlPrefix,
- DefaultLink: urlDefault,
- Metas: metas,
+ Ctx: ctx,
+ Metas: metas,
}, cleanMsg)
if err != nil {
log.Error("RenderCommitMessage: %v", err)
@@ -51,9 +43,9 @@ func RenderCommitMessageLink(ctx context.Context, msg, urlPrefix, urlDefault str
return template.HTML(msgLines[0])
}
-// RenderCommitMessageLinkSubject renders commit message as a XXS-safe link to
+// RenderCommitMessageLinkSubject renders commit message as a XSS-safe link to
// the provided default url, handling for special links without email to links.
-func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlPrefix, urlDefault string, metas map[string]string) template.HTML {
+func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlDefault string, metas map[string]string) template.HTML {
msgLine := strings.TrimLeftFunc(msg, unicode.IsSpace)
lineEnd := strings.IndexByte(msgLine, '\n')
if lineEnd > 0 {
@@ -68,7 +60,6 @@ func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlPrefix, urlDefa
// shouldn't be any special HTML.
renderedMessage, err := markup.RenderCommitMessageSubject(&markup.RenderContext{
Ctx: ctx,
- URLPrefix: urlPrefix,
DefaultLink: urlDefault,
Metas: metas,
}, template.HTMLEscapeString(msgLine))
@@ -80,7 +71,7 @@ func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlPrefix, urlDefa
}
// RenderCommitBody extracts the body of a commit message without its title.
-func RenderCommitBody(ctx context.Context, msg, urlPrefix string, metas map[string]string) template.HTML {
+func RenderCommitBody(ctx context.Context, msg string, metas map[string]string) template.HTML {
msgLine := strings.TrimSpace(msg)
lineEnd := strings.IndexByte(msgLine, '\n')
if lineEnd > 0 {
@@ -94,9 +85,8 @@ func RenderCommitBody(ctx context.Context, msg, urlPrefix string, metas map[stri
}
renderedMessage, err := markup.RenderCommitMessage(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: urlPrefix,
- Metas: metas,
+ Ctx: ctx,
+ Metas: metas,
}, template.HTMLEscapeString(msgLine))
if err != nil {
log.Error("RenderCommitMessage: %v", err)
@@ -116,11 +106,10 @@ func RenderCodeBlock(htmlEscapedTextToRender template.HTML) template.HTML {
}
// RenderIssueTitle renders issue/pull title with defined post processors
-func RenderIssueTitle(ctx context.Context, text, urlPrefix string, metas map[string]string) template.HTML {
+func RenderIssueTitle(ctx context.Context, text string, metas map[string]string) template.HTML {
renderedText, err := markup.RenderIssueTitle(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: urlPrefix,
- Metas: metas,
+ Ctx: ctx,
+ Metas: metas,
}, template.HTMLEscapeString(text))
if err != nil {
log.Error("RenderIssueTitle: %v", err)
@@ -212,25 +201,9 @@ func ReactionToEmoji(reaction string) template.HTML {
return template.HTML(fmt.Sprintf(``, reaction, setting.StaticURLPrefix, url.PathEscape(reaction)))
}
-// RenderNote renders the contents of a git-notes file as a commit message.
-func RenderNote(ctx context.Context, msg, urlPrefix string, metas map[string]string) template.HTML {
- cleanMsg := template.HTMLEscapeString(msg)
- fullMessage, err := markup.RenderCommitMessage(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: urlPrefix,
- Metas: metas,
- }, cleanMsg)
- if err != nil {
- log.Error("RenderNote: %v", err)
- return ""
- }
- return template.HTML(fullMessage)
-}
-
func RenderMarkdownToHtml(ctx context.Context, input string) template.HTML { //nolint:revive
output, err := markdown.RenderString(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: setting.AppSubURL,
+ Ctx: ctx,
}, input)
if err != nil {
log.Error("RenderString: %v", err)
diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go
index 29d3ed3a56c4..fe5655a82f6b 100644
--- a/modules/templates/util_render_test.go
+++ b/modules/templates/util_render_test.go
@@ -6,17 +6,64 @@ package templates
import (
"context"
"html/template"
+ "os"
"testing"
+ "code.gitea.io/gitea/models/unittest"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+
"github.com/stretchr/testify/assert"
)
+const testInput = ` space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+[local link](file.bin)
+[remote link](https://example.com)
+[[local link|file.bin]]
+[[remote link|https://example.com]]
+![local image](image.jpg)
+![remote image](https://example.com/image.jpg)
+[[local image|image.jpg]]
+[[remote link|https://example.com/image.jpg]]
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+:+1:
+mail@domain.com
+@mention-user test
+#123
+ space
+`
+
+var testMetas = map[string]string{
+ "user": "user13",
+ "repo": "repo11",
+ "repoPath": "../../tests/gitea-repositories-meta/user13/repo11.git/",
+ "mode": "comment",
+}
+
+func TestMain(m *testing.M) {
+ unittest.InitSettings()
+ if err := git.InitSimple(context.Background()); err != nil {
+ log.Fatal("git init failed, err: %v", err)
+ }
+ markup.Init(&markup.ProcessorHelper{
+ IsUsernameMentionable: func(ctx context.Context, username string) bool {
+ return username == "mention-user"
+ },
+ })
+ os.Exit(m.Run())
+}
+
func TestRenderCommitBody(t *testing.T) {
type args struct {
- ctx context.Context
- msg string
- urlPrefix string
- metas map[string]string
+ ctx context.Context
+ msg string
+ metas map[string]string
}
tests := []struct {
name string
@@ -50,7 +97,91 @@ func TestRenderCommitBody(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- assert.Equalf(t, tt.want, RenderCommitBody(tt.args.ctx, tt.args.msg, tt.args.urlPrefix, tt.args.metas), "RenderCommitBody(%v, %v, %v, %v)", tt.args.ctx, tt.args.msg, tt.args.urlPrefix, tt.args.metas)
+ assert.Equalf(t, tt.want, RenderCommitBody(tt.args.ctx, tt.args.msg, tt.args.metas), "RenderCommitBody(%v, %v, %v)", tt.args.ctx, tt.args.msg, tt.args.metas)
})
}
+
+ expected := `/just/a/path.bin
+https://example.com/file.bin
+[local link](file.bin)
+[remote link](https://example.com)
+[[local link|file.bin]]
+[[remote link|https://example.com]]
+![local image](image.jpg)
+![remote image](https://example.com/image.jpg)
+[[local image|image.jpg]]
+[[remote link|https://example.com/image.jpg]]
+88fc37a3c0...12fc37a3c0 (hash)
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+88fc37a3c0
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+ space`
+
+ assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput, testMetas))
+}
+
+func TestRenderCommitMessage(t *testing.T) {
+ expected := `space @mention-user `
+
+ assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput, testMetas))
+}
+
+func TestRenderCommitMessageLinkSubject(t *testing.T) {
+ expected := `space @mention-user`
+
+ assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput, "https://example.com/link", testMetas))
+}
+
+func TestRenderIssueTitle(t *testing.T) {
+ expected := ` space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+[local link](file.bin)
+[remote link](https://example.com)
+[[local link|file.bin]]
+[[remote link|https://example.com]]
+![local image](image.jpg)
+![remote image](https://example.com/image.jpg)
+[[local image|image.jpg]]
+[[remote link|https://example.com/image.jpg]]
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+ space
+`
+ assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput, testMetas))
+}
+
+func TestRenderMarkdownToHtml(t *testing.T) {
+ expected := `space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+local link
+remote link
+local link
+remote link
+
+
+
+
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+👍
+mail@domain.com
+@mention-user test
+#123
+space
+`
+ assert.EqualValues(t, expected, RenderMarkdownToHtml(context.Background(), testInput))
}
diff --git a/routers/common/markup.go b/routers/common/markup.go
index 5f412014d7e7..e2e206f0c91b 100644
--- a/routers/common/markup.go
+++ b/routers/common/markup.go
@@ -32,8 +32,10 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
case "markdown":
// Raw markdown
if err := markdown.RenderRaw(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: urlPrefix,
+ Ctx: ctx,
+ Links: markup.Links{
+ Base: urlPrefix,
+ },
}, strings.NewReader(text), ctx.Resp); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
}
@@ -75,8 +77,10 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
}
if err := markup.Render(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: urlPrefix,
+ Ctx: ctx,
+ Links: markup.Links{
+ Base: urlPrefix,
+ },
Metas: meta,
IsWiki: wiki,
Type: markupType,
diff --git a/routers/web/feed/convert.go b/routers/web/feed/convert.go
index 3775ba495a0d..66ddfd0c618f 100644
--- a/routers/web/feed/convert.go
+++ b/routers/web/feed/convert.go
@@ -51,9 +51,11 @@ func toReleaseLink(act *activities_model.Action) string {
// If rendering fails, the original markdown text is returned
func renderMarkdown(ctx *context.Context, act *activities_model.Action, content string) string {
markdownCtx := &markup.RenderContext{
- Ctx: ctx,
- URLPrefix: act.GetRepoLink(),
- Type: markdown.MarkupName,
+ Ctx: ctx,
+ Links: markup.Links{
+ Base: act.GetRepoLink(),
+ },
+ Type: markdown.MarkupName,
Metas: map[string]string{
"user": act.GetRepoUserName(),
"repo": act.GetRepoName(),
@@ -199,7 +201,6 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
switch act.OpType {
case activities_model.ActionCommitRepo, activities_model.ActionMirrorSyncPush:
push := templates.ActionContent2Commits(act)
- repoLink := act.GetRepoAbsoluteLink()
for _, commit := range push.Commits {
if len(desc) != 0 {
@@ -208,7 +209,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
desc += fmt.Sprintf("%s\n%s",
html.EscapeString(fmt.Sprintf("%s/commit/%s", act.GetRepoAbsoluteLink(), commit.Sha1)),
commit.Sha1,
- templates.RenderCommitMessage(ctx, commit.Message, repoLink, nil),
+ templates.RenderCommitMessage(ctx, commit.Message, nil),
)
}
@@ -288,9 +289,11 @@ func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release, i
link := &feeds.Link{Href: rel.HTMLURL()}
content, err = markdown.RenderString(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: rel.Repo.Link(),
- Metas: rel.Repo.ComposeMetas(),
+ Ctx: ctx,
+ Links: markup.Links{
+ Base: rel.Repo.Link(),
+ },
+ Metas: rel.Repo.ComposeMetas(),
}, rel.Note)
if err != nil {
diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go
index ce86727e2482..04f84c0c8d40 100644
--- a/routers/web/feed/profile.go
+++ b/routers/web/feed/profile.go
@@ -42,8 +42,10 @@ func showUserFeed(ctx *context.Context, formatType string) {
}
ctxUserDescription, err := markdown.RenderString(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: ctx.ContextUser.HTMLURL(),
+ Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.ContextUser.HTMLURL(),
+ },
Metas: map[string]string{
"user": ctx.ContextUser.GetDisplayName(),
},
diff --git a/routers/web/org/home.go b/routers/web/org/home.go
index 613dff2182bd..605b8014a41e 100644
--- a/routers/web/org/home.go
+++ b/routers/web/org/home.go
@@ -44,10 +44,8 @@ func Home(ctx *context.Context) {
ctx.Data["Title"] = org.DisplayName()
if len(org.Description) != 0 {
desc, err := markdown.RenderString(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: ctx.Repo.RepoLink,
- Metas: map[string]string{"mode": "document"},
- GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
+ Metas: map[string]string{"mode": "document"},
}, org.Description)
if err != nil {
ctx.ServerError("RenderString", err)
diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go
index 7513f9360b1d..5c08439a7441 100644
--- a/routers/web/repo/commit.go
+++ b/routers/web/repo/commit.go
@@ -7,7 +7,9 @@ package repo
import (
"errors"
"fmt"
+ "html/template"
"net/http"
+ "path"
"strings"
asymkey_model "code.gitea.io/gitea/models/asymkey"
@@ -21,7 +23,9 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitgraph"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/gitdiff"
git_service "code.gitea.io/gitea/services/repository"
)
@@ -373,9 +377,21 @@ func Diff(ctx *context.Context) {
note := &git.Note{}
err = git.GetNote(ctx, ctx.Repo.GitRepo, commitID, note)
if err == nil {
- ctx.Data["Note"] = string(charset.ToUTF8WithFallback(note.Message))
ctx.Data["NoteCommit"] = note.Commit
ctx.Data["NoteAuthor"] = user_model.ValidateCommitWithEmail(ctx, note.Commit)
+ ctx.Data["NoteRendered"], err = markup.RenderCommitMessage(&markup.RenderContext{
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ BranchPath: path.Join("commit", util.PathEscapeSegments(commitID)),
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
+ }, template.HTMLEscapeString(string(charset.ToUTF8WithFallback(note.Message))))
+ if err != nil {
+ ctx.ServerError("RenderCommitMessage", err)
+ return
+ }
}
ctx.Data["BranchName"], err = commit.GetBranchName()
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index 488c97b0eb6e..64013e7ec920 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -1383,12 +1383,13 @@ func ViewIssue(ctx *context.Context) {
}
}
ctx.Data["IssueWatch"] = iw
-
issue.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, issue.Content)
if err != nil {
ctx.ServerError("RenderString", err)
@@ -1548,10 +1549,12 @@ func ViewIssue(ctx *context.Context) {
}
comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, comment.Content)
if err != nil {
ctx.ServerError("RenderString", err)
@@ -1625,10 +1628,12 @@ func ViewIssue(ctx *context.Context) {
}
} else if comment.Type.HasContentSupport() {
comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, comment.Content)
if err != nil {
ctx.ServerError("RenderString", err)
@@ -2183,10 +2188,12 @@ func UpdateIssueContent(ctx *context.Context) {
}
content, err := markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, issue.Content)
if err != nil {
ctx.ServerError("RenderString", err)
@@ -3081,10 +3088,12 @@ func UpdateCommentContent(ctx *context.Context) {
}
content, err := markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.FormString("context"), // FIXME: <- IS THIS SAFE ?
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, comment.Content)
if err != nil {
ctx.ServerError("RenderString", err)
diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go
index ad355ce5d7d9..fec958efd203 100644
--- a/routers/web/repo/milestone.go
+++ b/routers/web/repo/milestone.go
@@ -81,10 +81,12 @@ func Milestones(ctx *context.Context) {
}
for _, m := range miles {
m.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, m.Content)
if err != nil {
ctx.ServerError("RenderString", err)
@@ -274,10 +276,12 @@ func MilestoneIssuesAndPulls(ctx *context.Context) {
}
milestone.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, milestone.Content)
if err != nil {
ctx.ServerError("RenderString", err)
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index eef57f46272f..9431c2b83b3d 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -86,10 +86,12 @@ func Projects(ctx *context.Context) {
for i := range projects {
projects[i].RenderedContent, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, projects[i].Description)
if err != nil {
ctx.ServerError("RenderString", err)
@@ -352,10 +354,12 @@ func ViewProject(ctx *context.Context) {
ctx.Data["LinkedPRs"] = linkedPrsMap
project.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, project.Description)
if err != nil {
ctx.ServerError("RenderString", err)
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index 957cf56972ce..dc56bac5e23c 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -175,10 +175,12 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
}
r.Note, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, r.Note)
if err != nil {
ctx.ServerError("RenderString", err)
@@ -281,10 +283,12 @@ func SingleRelease(ctx *context.Context) {
}
}
release.Note, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeMetas(),
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ Metas: ctx.Repo.Repository.ComposeMetas(),
+ GitRepo: ctx.Repo.GitRepo,
+ Ctx: ctx,
}, release.Note)
if err != nil {
ctx.ServerError("RenderString", err)
diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go
index f07b4e8c113c..c6bc0dcf1959 100644
--- a/routers/web/repo/render.go
+++ b/routers/web/repo/render.go
@@ -57,16 +57,15 @@ func RenderFile(ctx *context.Context) {
return
}
- treeLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
- if ctx.Repo.TreePath != "" {
- treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
- }
-
ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'; sandbox allow-scripts")
err = markup.Render(&markup.RenderContext{
- Ctx: ctx,
- RelativePath: ctx.Repo.TreePath,
- URLPrefix: path.Dir(treeLink),
+ Ctx: ctx,
+ RelativePath: ctx.Repo.TreePath,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ BranchPath: ctx.Repo.BranchNameSubURL(),
+ TreePath: path.Dir(ctx.Repo.TreePath),
+ },
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
GitRepo: ctx.Repo.GitRepo,
InStandalonePage: true,
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 15c85f6427ce..da3a4ad5df13 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -156,7 +156,7 @@ func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry, try
return "", readmeFile, nil
}
-func renderDirectory(ctx *context.Context, treeLink string) {
+func renderDirectory(ctx *context.Context) {
entries := renderDirectoryFiles(ctx, 1*time.Second)
if ctx.Written() {
return
@@ -173,7 +173,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
return
}
- renderReadmeFile(ctx, subfolder, readmeFile, treeLink)
+ renderReadmeFile(ctx, subfolder, readmeFile)
}
// localizedExtensions prepends the provided language code with and without a
@@ -257,7 +257,7 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte,
return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil
}
-func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.TreeEntry, readmeTreelink string) {
+func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.TreeEntry) {
target := readmeFile
if readmeFile != nil && readmeFile.IsLink() {
target, _ = readmeFile.FollowLinks()
@@ -310,9 +310,13 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr
ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
Ctx: ctx,
RelativePath: path.Join(ctx.Repo.TreePath, readmeFile.Name()), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path).
- URLPrefix: path.Join(readmeTreelink, subfolder),
- Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
- GitRepo: ctx.Repo.GitRepo,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ BranchPath: ctx.Repo.BranchNameSubURL(),
+ TreePath: path.Join(ctx.Repo.TreePath, subfolder),
+ },
+ Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
+ GitRepo: ctx.Repo.GitRepo,
}, rd)
if err != nil {
log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.Name(), ctx.Repo.Repository, err)
@@ -332,7 +336,7 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr
}
}
-func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink string) {
+func renderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["IsViewFile"] = true
ctx.Data["HideRepoInfo"] = true
blob := entry.Blob()
@@ -346,7 +350,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefName)
ctx.Data["FileIsSymlink"] = entry.IsLink()
ctx.Data["FileName"] = blob.Name()
- ctx.Data["RawFileLink"] = rawLink + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
+ ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
if ctx.Repo.TreePath == ".editorconfig" {
_, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit)
@@ -474,9 +478,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
Ctx: ctx,
Type: markupType,
RelativePath: ctx.Repo.TreePath,
- URLPrefix: path.Dir(treeLink),
- Metas: metas,
- GitRepo: ctx.Repo.GitRepo,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ BranchPath: ctx.Repo.BranchNameSubURL(),
+ TreePath: path.Dir(ctx.Repo.TreePath),
+ },
+ Metas: metas,
+ GitRepo: ctx.Repo.GitRepo,
}, rd)
if err != nil {
ctx.ServerError("Render", err)
@@ -575,9 +583,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
Ctx: ctx,
RelativePath: ctx.Repo.TreePath,
- URLPrefix: path.Dir(treeLink),
- Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
- GitRepo: ctx.Repo.GitRepo,
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ BranchPath: ctx.Repo.BranchNameSubURL(),
+ TreePath: path.Dir(ctx.Repo.TreePath),
+ },
+ Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
+ GitRepo: ctx.Repo.GitRepo,
}, rd)
if err != nil {
ctx.ServerError("Render", err)
@@ -954,14 +966,6 @@ func renderCode(ctx *context.Context) {
}
ctx.Data["Title"] = title
- branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
- treeLink := branchLink
- rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL()
-
- if len(ctx.Repo.TreePath) > 0 {
- treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
- }
-
// Get Topics of this repo
renderRepoTopics(ctx)
if ctx.Written() {
@@ -986,9 +990,9 @@ func renderCode(ctx *context.Context) {
}
if entry.IsDir() {
- renderDirectory(ctx, treeLink)
+ renderDirectory(ctx)
} else {
- renderFile(ctx, entry, treeLink, rawLink)
+ renderFile(ctx, entry)
}
if ctx.Written() {
return
@@ -1029,6 +1033,12 @@ func renderCode(ctx *context.Context) {
}
ctx.Data["Paths"] = paths
+
+ branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
+ treeLink := branchLink
+ if len(ctx.Repo.TreePath) > 0 {
+ treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
+ }
ctx.Data["TreeLink"] = treeLink
ctx.Data["TreeNames"] = treeNames
ctx.Data["BranchLink"] = branchLink
diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go
index 4de24e2a3898..61b4a9a45cb4 100644
--- a/routers/web/repo/wiki.go
+++ b/routers/web/repo/wiki.go
@@ -238,10 +238,12 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
}
rctx := &markup.RenderContext{
- Ctx: ctx,
- URLPrefix: ctx.Repo.RepoLink,
- Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
- IsWiki: true,
+ Ctx: ctx,
+ Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
+ Links: markup.Links{
+ Base: ctx.Repo.RepoLink,
+ },
+ IsWiki: true,
}
buf := &strings.Builder{}
diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go
index 9b1918ed16b4..a37e8e349948 100644
--- a/routers/web/shared/user/header.go
+++ b/routers/web/shared/user/header.go
@@ -44,10 +44,8 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
if len(ctx.ContextUser.Description) != 0 {
content, err := markdown.RenderString(&markup.RenderContext{
- URLPrefix: ctx.Repo.RepoLink,
- Metas: map[string]string{"mode": "document"},
- GitRepo: ctx.Repo.GitRepo,
- Ctx: ctx,
+ Metas: map[string]string{"mode": "document"},
+ Ctx: ctx,
}, ctx.ContextUser.Description)
if err != nil {
ctx.ServerError("RenderString", err)
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index 8cc9cccc29f7..36b5dc255ad1 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -245,9 +245,11 @@ func Milestones(ctx *context.Context) {
}
milestones[i].RenderedContent, err = markdown.RenderString(&markup.RenderContext{
- URLPrefix: milestones[i].Repo.Link(),
- Metas: milestones[i].Repo.ComposeMetas(),
- Ctx: ctx,
+ Links: markup.Links{
+ Base: milestones[i].Repo.Link(),
+ },
+ Metas: milestones[i].Repo.ComposeMetas(),
+ Ctx: ctx,
}, milestones[i].Content)
if err != nil {
ctx.ServerError("RenderString", err)
diff --git a/services/mailer/mail.go b/services/mailer/mail.go
index 50d59a44527d..5c26254ab999 100644
--- a/services/mailer/mail.go
+++ b/services/mailer/mail.go
@@ -233,9 +233,11 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
// This is the body of the new issue or comment, not the mail body
body, err := markdown.RenderString(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: ctx.Issue.Repo.HTMLURL(),
- Metas: ctx.Issue.Repo.ComposeMetas(),
+ Ctx: ctx,
+ Links: markup.Links{
+ Base: ctx.Issue.Repo.HTMLURL(),
+ },
+ Metas: ctx.Issue.Repo.ComposeMetas(),
}, ctx.Content)
if err != nil {
return nil, err
diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go
index fb638ebd42cf..859a3b3fa556 100644
--- a/services/mailer/mail_release.go
+++ b/services/mailer/mail_release.go
@@ -58,9 +58,11 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo
var err error
rel.RenderedNote, err = markdown.RenderString(&markup.RenderContext{
- Ctx: ctx,
- URLPrefix: rel.Repo.Link(),
- Metas: rel.Repo.ComposeMetas(),
+ Ctx: ctx,
+ Links: markup.Links{
+ Base: rel.Repo.Link(),
+ },
+ Metas: rel.Repo.ComposeMetas(),
}, rel.Note)
if err != nil {
log.Error("markdown.RenderString(%d): %v", rel.RepoID, err)
diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl
index bd045995b29b..9ff5b960c13f 100644
--- a/templates/repo/branch/list.tmpl
+++ b/templates/repo/branch/list.tmpl
@@ -27,7 +27,7 @@
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}}
- {{svg "octicon-git-commit" 16 "gt-mr-2"}}{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}} · {{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage .RepoLink .Repository.ComposeMetas}} · {{.locale.Tr "org.repo_updated"}} {{TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime .locale}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}
+ {{svg "octicon-git-commit" 16 "gt-mr-2"}}{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}} · {{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage .Repository.ComposeMetas}} · {{.locale.Tr "org.repo_updated"}} {{TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime .locale}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}
{{if and $.IsWriter (not $.Repository.IsArchived) (not .IsDeleted)}}
@@ -94,7 +94,7 @@
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DBBranch.CommitID)}}
- {{svg "octicon-git-commit" 16 "gt-mr-2"}}{{ShortSha .DBBranch.CommitID}} · {{RenderCommitMessage $.Context .DBBranch.CommitMessage $.RepoLink $.Repository.ComposeMetas}} · {{$.locale.Tr "org.repo_updated"}} {{TimeSince .DBBranch.CommitTime.AsTime $.locale}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}
+ {{svg "octicon-git-commit" 16 "gt-mr-2"}}{{ShortSha .DBBranch.CommitID}} · {{RenderCommitMessage $.Context .DBBranch.CommitMessage $.Repository.ComposeMetas}} · {{$.locale.Tr "org.repo_updated"}} {{TimeSince .DBBranch.CommitTime.AsTime $.locale}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}
{{end}}
|
diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl
index 06b8f1ba155e..07bdf3496b48 100644
--- a/templates/repo/commit_page.tmpl
+++ b/templates/repo/commit_page.tmpl
@@ -19,7 +19,7 @@
{{end}}
{{end}}
- {{if .Note}}
+ {{if .NoteRendered}}
- {{RenderNote $.Context .Note $.RepoLink $.Repository.ComposeMetas}}
+ {{.NoteRendered | Str2html}}
{{end}}
{{template "repo/diff/box" .}}
diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl
index b9b42ebb235d..05c5e04ed4c2 100644
--- a/templates/repo/commits_list.tmpl
+++ b/templates/repo/commits_list.tmpl
@@ -70,7 +70,7 @@
{{.Summary | RenderEmoji $.Context}}
{{else}}
{{$commitLink:= printf "%s/commit/%s" $commitRepoLink (PathEscape .ID.String)}}
- {{RenderCommitMessageLinkSubject $.Context .Message $commitRepoLink $commitLink $.Repository.ComposeMetas}}
+ {{RenderCommitMessageLinkSubject $.Context .Message $commitLink $.Repository.ComposeMetas}}
{{end}}
{{if IsMultilineCommitMessage .Message}}
@@ -78,7 +78,7 @@
{{end}}
{{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses "root" $}}
{{if IsMultilineCommitMessage .Message}}
- {{RenderCommitBody $.Context .Message $commitRepoLink $.Repository.ComposeMetas}}
+ {{RenderCommitBody $.Context .Message $.Repository.ComposeMetas}}
{{end}}
|
{{if .Committer}}
diff --git a/templates/repo/commits_list_small.tmpl b/templates/repo/commits_list_small.tmpl
index ff65d0288538..7506975647f6 100644
--- a/templates/repo/commits_list_small.tmpl
+++ b/templates/repo/commits_list_small.tmpl
@@ -38,12 +38,12 @@
- {{RenderCommitMessageLinkSubject $.root.Context .Message ($.comment.Issue.PullRequest.BaseRepo.Link|Escape) $commitLink $.comment.Issue.PullRequest.BaseRepo.ComposeMetas}}
+ {{RenderCommitMessageLinkSubject $.root.Context .Message $commitLink $.comment.Issue.PullRequest.BaseRepo.ComposeMetas}}
{{if IsMultilineCommitMessage .Message}}
{{end}}
{{if IsMultilineCommitMessage .Message}}
- {{RenderCommitBody $.root.Context .Message ($.comment.Issue.PullRequest.BaseRepo.Link|Escape) $.comment.Issue.PullRequest.BaseRepo.ComposeMetas}}
+ {{RenderCommitBody $.root.Context .Message $.comment.Issue.PullRequest.BaseRepo.ComposeMetas}}
{{end}}
{{end}}
diff --git a/templates/repo/diff/compare.tmpl b/templates/repo/diff/compare.tmpl
index 3bb7c2e81f89..5baa60d4a3f9 100644
--- a/templates/repo/diff/compare.tmpl
+++ b/templates/repo/diff/compare.tmpl
@@ -194,7 +194,7 @@
{{.locale.Tr "repo.pulls.has_pull_request" (print (Escape $.RepoLink) "/pulls/" .PullRequest.Issue.Index) (Escape $.RepoRelPath) .PullRequest.Index | Safe}}
- {{RenderIssueTitle $.Context .PullRequest.Issue.Title $.RepoLink $.Repository.ComposeMetas}}
+ {{RenderIssueTitle $.Context .PullRequest.Issue.Title $.Repository.ComposeMetas}}
#{{.PullRequest.Issue.Index}}
diff --git a/templates/repo/graph/commits.tmpl b/templates/repo/graph/commits.tmpl
index 0a21aec9c082..10228fc2bf62 100644
--- a/templates/repo/graph/commits.tmpl
+++ b/templates/repo/graph/commits.tmpl
@@ -29,7 +29,7 @@
- {{RenderCommitMessage $.Context $commit.Subject $.RepoLink $.Repository.ComposeMetas}}
+ {{RenderCommitMessage $.Context $commit.Subject $.Repository.ComposeMetas}}
{{range $commit.Refs}}
diff --git a/templates/repo/issue/view_title.tmpl b/templates/repo/issue/view_title.tmpl
index c1dd265e5837..5c50f3ac54cf 100644
--- a/templates/repo/issue/view_title.tmpl
+++ b/templates/repo/issue/view_title.tmpl
@@ -6,7 +6,7 @@