Skip to content

Commit 795c253

Browse files
committed
fix
1 parent ba921fd commit 795c253

29 files changed

+236
-282
lines changed

models/renderhelper/repo_comment.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ func (r *RepoComment) IsCommitIDExisting(commitID string) bool {
2828
return r.commitChecker.IsCommitIDExisting(commitID)
2929
}
3030

31-
func (r *RepoComment) ResolveLink(link string, likeType markup.LinkType) (finalLink string) {
32-
switch likeType {
33-
case markup.LinkTypeApp:
34-
finalLink = r.ctx.ResolveLinkApp(link)
31+
func (r *RepoComment) ResolveLink(link, preferLinkType string) string {
32+
linkType, link := markup.ParseRenderedLink(link, preferLinkType)
33+
switch linkType {
34+
case markup.LinkTypeRoot:
35+
return r.ctx.ResolveLinkRoot(link)
3536
default:
36-
finalLink = r.ctx.ResolveLinkRelative(r.repoLink, r.opts.CurrentRefPath, link)
37+
return r.ctx.ResolveLinkRelative(r.repoLink, r.opts.CurrentRefPath, link)
3738
}
38-
return finalLink
3939
}
4040

4141
var _ markup.RenderHelper = (*RepoComment)(nil)

models/renderhelper/repo_file.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@ func (r *RepoFile) IsCommitIDExisting(commitID string) bool {
2929
return r.commitChecker.IsCommitIDExisting(commitID)
3030
}
3131

32-
func (r *RepoFile) ResolveLink(link string, likeType markup.LinkType) string {
33-
finalLink := link
34-
switch likeType {
35-
case markup.LinkTypeApp:
36-
finalLink = r.ctx.ResolveLinkApp(link)
37-
case markup.LinkTypeDefault:
38-
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "src", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
32+
func (r *RepoFile) ResolveLink(link, preferLinkType string) (finalLink string) {
33+
linkType, link := markup.ParseRenderedLink(link, preferLinkType)
34+
switch linkType {
35+
case markup.LinkTypeRoot:
36+
finalLink = r.ctx.ResolveLinkRoot(link)
3937
case markup.LinkTypeRaw:
4038
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "raw", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
4139
case markup.LinkTypeMedia:
4240
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "media", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
41+
default:
42+
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "src", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link)
4343
}
4444
return finalLink
4545
}

models/renderhelper/repo_file_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ func TestRepoFile(t *testing.T) {
4848
assert.Equal(t,
4949
`<p><a href="/user2/repo1/src/branch/main/test" rel="nofollow">/test</a>
5050
<a href="/user2/repo1/src/branch/main/test" rel="nofollow">./test</a>
51-
<a href="/user2/repo1/media/branch/main/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/branch/main/image" alt="/image"/></a>
52-
<a href="/user2/repo1/media/branch/main/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/branch/main/image" alt="./image"/></a></p>
51+
<a href="/user2/repo1/src/branch/main/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/branch/main/image" alt="/image"/></a>
52+
<a href="/user2/repo1/src/branch/main/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/branch/main/image" alt="./image"/></a></p>
5353
`, rendered)
5454
})
5555

@@ -62,7 +62,7 @@ func TestRepoFile(t *testing.T) {
6262
`)
6363
assert.NoError(t, err)
6464
assert.Equal(t, `<p><a href="/user2/repo1/src/commit/1234/test" rel="nofollow">/test</a>
65-
<a href="/user2/repo1/media/commit/1234/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/commit/1234/image" alt="/image"/></a></p>
65+
<a href="/user2/repo1/src/commit/1234/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/commit/1234/image" alt="/image"/></a></p>
6666
`, rendered)
6767
})
6868

@@ -77,7 +77,7 @@ func TestRepoFile(t *testing.T) {
7777
<video src="LINK">
7878
`)
7979
assert.NoError(t, err)
80-
assert.Equal(t, `<a href="/user2/repo1/media/commit/1234/my-dir/LINK" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/commit/1234/my-dir/LINK"/></a>
80+
assert.Equal(t, `<a href="/user2/repo1/src/commit/1234/my-dir/LINK" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/media/commit/1234/my-dir/LINK"/></a>
8181
<video src="/user2/repo1/media/commit/1234/my-dir/LINK">
8282
</video>`, rendered)
8383
})
@@ -100,7 +100,7 @@ func TestRepoFileOrgMode(t *testing.T) {
100100
assert.NoError(t, err)
101101
assert.Equal(t, `<p>
102102
<a href="https://google.com/" rel="nofollow">https://google.com/</a>
103-
<a href="/user2/repo1/media/commit/1234/my-dir/ImageLink.svg" rel="nofollow">The Image Desc</a></p>
103+
<a href="/user2/repo1/src/commit/1234/my-dir/ImageLink.svg" rel="nofollow">The Image Desc</a></p>
104104
`, rendered)
105105
})
106106

models/renderhelper/repo_wiki.go

+8-10
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,16 @@ func (r *RepoWiki) IsCommitIDExisting(commitID string) bool {
3030
return r.commitChecker.IsCommitIDExisting(commitID)
3131
}
3232

33-
func (r *RepoWiki) ResolveLink(link string, likeType markup.LinkType) string {
34-
finalLink := link
35-
switch likeType {
36-
case markup.LinkTypeApp:
37-
finalLink = r.ctx.ResolveLinkApp(link)
38-
case markup.LinkTypeDefault:
39-
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "wiki", r.opts.currentRefPath), r.opts.currentTreePath, link)
40-
case markup.LinkTypeMedia:
33+
func (r *RepoWiki) ResolveLink(link, preferLinkType string) (finalLink string) {
34+
linkType, link := markup.ParseRenderedLink(link, preferLinkType)
35+
switch linkType {
36+
case markup.LinkTypeRoot:
37+
finalLink = r.ctx.ResolveLinkRoot(link)
38+
case markup.LinkTypeMedia, markup.LinkTypeRaw:
4139
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "wiki/raw", r.opts.currentRefPath), r.opts.currentTreePath, link)
42-
case markup.LinkTypeRaw: // wiki doesn't use it
40+
default:
41+
finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "wiki", r.opts.currentRefPath), r.opts.currentTreePath, link)
4342
}
44-
4543
return finalLink
4644
}
4745

models/renderhelper/repo_wiki_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ func TestRepoWiki(t *testing.T) {
4545
assert.Equal(t,
4646
`<p><a href="/user2/repo1/wiki/test" rel="nofollow">/test</a>
4747
<a href="/user2/repo1/wiki/test" rel="nofollow">./test</a>
48-
<a href="/user2/repo1/wiki/raw/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/wiki/raw/image" alt="/image"/></a>
49-
<a href="/user2/repo1/wiki/raw/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/wiki/raw/image" alt="./image"/></a></p>
48+
<a href="/user2/repo1/wiki/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/wiki/raw/image" alt="/image"/></a>
49+
<a href="/user2/repo1/wiki/image" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/wiki/raw/image" alt="./image"/></a></p>
5050
`, rendered)
5151
})
5252

@@ -57,7 +57,7 @@ func TestRepoWiki(t *testing.T) {
5757
<video src="LINK">
5858
`)
5959
assert.NoError(t, err)
60-
assert.Equal(t, `<a href="/user2/repo1/wiki/raw/LINK" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/wiki/raw/LINK"/></a>
60+
assert.Equal(t, `<a href="/user2/repo1/wiki/LINK" target="_blank" rel="nofollow noopener"><img src="/user2/repo1/wiki/raw/LINK"/></a>
6161
<video src="/user2/repo1/wiki/raw/LINK">
6262
</video>`, rendered)
6363
})

models/renderhelper/simple_document.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,14 @@ type SimpleDocument struct {
1515
baseLink string
1616
}
1717

18-
func (r *SimpleDocument) ResolveLink(link string, likeType markup.LinkType) string {
19-
return r.ctx.ResolveLinkRelative(r.baseLink, "", link)
18+
func (r *SimpleDocument) ResolveLink(link, preferLinkType string) string {
19+
linkType, link := markup.ParseRenderedLink(link, preferLinkType)
20+
switch linkType {
21+
case markup.LinkTypeRoot:
22+
return r.ctx.ResolveLinkRoot(link)
23+
default:
24+
return r.ctx.ResolveLinkRelative(r.baseLink, "", link)
25+
}
2026
}
2127

2228
var _ markup.RenderHelper = (*SimpleDocument)(nil)

models/renderhelper/simple_document_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestSimpleDocument(t *testing.T) {
3030
assert.Equal(t,
3131
`<p>65f1bf27bc3bf70f64657658635e66094edbcb4d
3232
#1
33-
<a href="/base/user2" rel="nofollow">@user2</a></p>
33+
<a href="/user2" rel="nofollow">@user2</a></p>
3434
<p><a href="/base/test" rel="nofollow">/test</a>
3535
<a href="/base/test" rel="nofollow">./test</a>
3636
<a href="/base/image" target="_blank" rel="nofollow noopener"><img src="/base/image" alt="/image"/></a>

modules/markup/csv/csv.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"bufio"
88
"html"
99
"io"
10+
"path"
1011
"strconv"
1112

1213
"code.gitea.io/gitea/modules/csv"
@@ -133,7 +134,7 @@ func (r Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.W
133134
// Check if maxRows or maxSize is reached, and if true, warn.
134135
if (row >= maxRows && maxRows != 0) || (rd.InputOffset() >= maxSize && maxSize != 0) {
135136
warn := `<table class="data-table"><tr><td>`
136-
rawLink := ` <a href="` + ctx.RenderHelper.ResolveLink(util.PathEscapeSegments(ctx.RenderOptions.RelativePath), markup.LinkTypeRaw) + `">`
137+
rawLink := ` <a href="` + path.Join("/:raw", util.PathEscapeSegments(ctx.RenderOptions.RelativePath)) + `">`
137138

138139
// Try to get the user translation
139140
if locale, ok := ctx.Value(translation.ContextKey).(translation.Locale); ok {

modules/markup/external/external.go

+11-11
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ func envMark(envName string) string {
7777

7878
// Render renders the data of the document to HTML via the external tool.
7979
func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
80-
var (
81-
command = strings.NewReplacer(
82-
envMark("GITEA_PREFIX_SRC"), ctx.RenderHelper.ResolveLink("", markup.LinkTypeDefault),
83-
envMark("GITEA_PREFIX_RAW"), ctx.RenderHelper.ResolveLink("", markup.LinkTypeRaw),
84-
).Replace(p.Command)
85-
commands = strings.Fields(command)
86-
args = commands[1:]
87-
)
80+
baseLinkSrc := ctx.RenderHelper.ResolveLink("", markup.LinkTypeDefault)
81+
baseLinkRaw := ctx.RenderHelper.ResolveLink("", markup.LinkTypeRaw)
82+
command := strings.NewReplacer(
83+
envMark("GITEA_PREFIX_SRC"), baseLinkSrc,
84+
envMark("GITEA_PREFIX_RAW"), baseLinkRaw,
85+
).Replace(p.Command)
86+
commands := strings.Fields(command)
87+
args := commands[1:]
8888

8989
if p.IsInputFile {
9090
// write to temp file
@@ -112,14 +112,14 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
112112
args = append(args, f.Name())
113113
}
114114

115-
processCtx, _, finished := process.GetManager().AddContext(ctx, fmt.Sprintf("Render [%s] for %s", commands[0], ctx.RenderHelper.ResolveLink("", markup.LinkTypeDefault)))
115+
processCtx, _, finished := process.GetManager().AddContext(ctx, fmt.Sprintf("Render [%s] for %s", commands[0], baseLinkSrc))
116116
defer finished()
117117

118118
cmd := exec.CommandContext(processCtx, commands[0], args...)
119119
cmd.Env = append(
120120
os.Environ(),
121-
"GITEA_PREFIX_SRC="+ctx.RenderHelper.ResolveLink("", markup.LinkTypeDefault),
122-
"GITEA_PREFIX_RAW="+ctx.RenderHelper.ResolveLink("", markup.LinkTypeRaw),
121+
"GITEA_PREFIX_SRC="+baseLinkSrc,
122+
"GITEA_PREFIX_RAW="+baseLinkRaw,
123123
)
124124
if !p.IsInputFile {
125125
cmd.Stdin = input

modules/markup/html.go

+29-44
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ type globalVarsType struct {
3232
comparePattern *regexp.Regexp
3333
fullURLPattern *regexp.Regexp
3434
emailRegex *regexp.Regexp
35-
blackfridayExtRegex *regexp.Regexp
3635
emojiShortCodeRegex *regexp.Regexp
3736
issueFullPattern *regexp.Regexp
3837
filesChangedFullPattern *regexp.Regexp
@@ -74,9 +73,6 @@ var globalVars = sync.OnceValue(func() *globalVarsType {
7473
// https://html.spec.whatwg.org/multipage/input.html#e-mail-state-(type%3Demail)
7574
v.emailRegex = regexp.MustCompile("(?:\\s|^|\\(|\\[)([a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9]{2,}(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+)(?:\\s|$|\\)|\\]|;|,|\\?|!|\\.(\\s|$))")
7675

77-
// blackfridayExtRegex is for blackfriday extensions create IDs like fn:user-content-footnote
78-
v.blackfridayExtRegex = regexp.MustCompile(`[^:]*:user-content-`)
79-
8076
// emojiShortCodeRegex find emoji by alias like :smile:
8177
v.emojiShortCodeRegex = regexp.MustCompile(`:[-+\w]+:`)
8278

@@ -94,17 +90,12 @@ var globalVars = sync.OnceValue(func() *globalVarsType {
9490
return v
9591
})
9692

97-
// IsFullURLBytes reports whether link fits valid format.
98-
func IsFullURLBytes(link []byte) bool {
99-
return globalVars().fullURLPattern.Match(link)
100-
}
101-
10293
func IsFullURLString(link string) bool {
10394
return globalVars().fullURLPattern.MatchString(link)
10495
}
10596

10697
func IsNonEmptyRelativePath(link string) bool {
107-
return link != "" && !IsFullURLString(link) && link[0] != '/' && link[0] != '?' && link[0] != '#'
98+
return link != "" && !IsFullURLString(link) && link[0] != '?' && link[0] != '#'
10899
}
109100

110101
// CustomLinkURLSchemes allows for additional schemes to be detected when parsing links within text
@@ -316,44 +307,38 @@ func isEmojiNode(node *html.Node) bool {
316307
}
317308

318309
func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Node {
319-
// Add user-content- to IDs and "#" links if they don't already have them
320-
for idx, attr := range node.Attr {
321-
val := strings.TrimPrefix(attr.Val, "#")
322-
notHasPrefix := !(strings.HasPrefix(val, "user-content-") || globalVars().blackfridayExtRegex.MatchString(val))
323-
324-
if attr.Key == "id" && notHasPrefix {
325-
node.Attr[idx].Val = "user-content-" + attr.Val
326-
}
327-
328-
if attr.Key == "href" && strings.HasPrefix(attr.Val, "#") && notHasPrefix {
329-
node.Attr[idx].Val = "#user-content-" + val
330-
}
331-
}
332-
333-
switch node.Type {
334-
case html.TextNode:
310+
if node.Type == html.TextNode {
335311
for _, proc := range procs {
336312
proc(ctx, node) // it might add siblings
337313
}
314+
return node.NextSibling
315+
}
316+
if node.Type != html.ElementNode {
317+
return node.NextSibling
318+
}
338319

339-
case html.ElementNode:
340-
if isEmojiNode(node) {
341-
// TextNode emoji will be converted to `<span class="emoji">`, then the next iteration will visit the "span"
342-
// if we don't stop it, it will go into the TextNode again and create an infinite recursion
343-
return node.NextSibling
344-
} else if node.Data == "code" || node.Data == "pre" {
345-
return node.NextSibling // ignore code and pre nodes
346-
} else if node.Data == "img" {
347-
return visitNodeImg(ctx, node)
348-
} else if node.Data == "video" {
349-
return visitNodeVideo(ctx, node)
350-
} else if node.Data == "a" {
351-
procs = emojiProcessors // Restrict text in links to emojis
352-
}
353-
for n := node.FirstChild; n != nil; {
354-
n = visitNode(ctx, procs, n)
355-
}
356-
default:
320+
processNodeAttrID(node)
321+
322+
if isEmojiNode(node) {
323+
// TextNode emoji will be converted to `<span class="emoji">`, then the next iteration will visit the "span"
324+
// if we don't stop it, it will go into the TextNode again and create an infinite recursion
325+
return node.NextSibling
326+
} else if node.Data == "code" || node.Data == "pre" {
327+
return node.NextSibling // ignore code and pre nodes
328+
} else if node.Data == "img" {
329+
return visitNodeImg(ctx, node)
330+
} else if node.Data == "video" {
331+
return visitNodeVideo(ctx, node)
332+
}
333+
334+
if node.Data == "a" {
335+
processNodeA(ctx, node)
336+
// only use emoji processors for the content in the "A" tag,
337+
// because the content there is not processable, for example: the content is a commit id or a full URL.
338+
procs = emojiProcessors
339+
}
340+
for n := node.FirstChild; n != nil; {
341+
n = visitNode(ctx, procs, n)
357342
}
358343
return node.NextSibling
359344
}

modules/markup/html_commit.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ func createCodeLink(href, content, class string) *html.Node {
4343
code := &html.Node{
4444
Type: html.ElementNode,
4545
Data: atom.Code.String(),
46-
Attr: []html.Attribute{{Key: "class", Val: "nohighlight"}},
4746
}
4847

4948
code.AppendChild(text)
@@ -189,7 +188,7 @@ func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
189188
continue
190189
}
191190

192-
link := ctx.RenderHelper.ResolveLink(util.URLJoin(ctx.RenderOptions.Metas["user"], ctx.RenderOptions.Metas["repo"], "commit", hash), LinkTypeApp)
191+
link := "/:root/" + util.URLJoin(ctx.RenderOptions.Metas["user"], ctx.RenderOptions.Metas["repo"], "commit", hash)
193192
replaceContent(node, m[2], m[3], createCodeLink(link, base.ShortSha(hash), "commit"))
194193
start = 0
195194
node = node.NextSibling.NextSibling
@@ -205,9 +204,9 @@ func commitCrossReferencePatternProcessor(ctx *RenderContext, node *html.Node) {
205204
return
206205
}
207206

208-
reftext := ref.Owner + "/" + ref.Name + "@" + base.ShortSha(ref.CommitSha)
209-
linkHref := ctx.RenderHelper.ResolveLink(util.URLJoin(ref.Owner, ref.Name, "commit", ref.CommitSha), LinkTypeApp)
210-
link := createLink(ctx, linkHref, reftext, "commit")
207+
refText := ref.Owner + "/" + ref.Name + "@" + base.ShortSha(ref.CommitSha)
208+
linkHref := "/:root/" + util.URLJoin(ref.Owner, ref.Name, "commit", ref.CommitSha)
209+
link := createLink(ctx, linkHref, refText, "commit")
211210

212211
replaceContent(node, ref.RefLocation.Start, ref.RefLocation.End, link)
213212
node = node.NextSibling.NextSibling

modules/markup/html_internal_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) {
107107
isExternal := false
108108
if marker == "!" {
109109
path = "pulls"
110-
prefix = "http://localhost:3000/someUser/someRepo/pulls/"
110+
prefix = "/someUser/someRepo/pulls/"
111111
} else {
112112
path = "issues"
113113
prefix = "https://someurl.com/someUser/someRepo/"
@@ -116,7 +116,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) {
116116

117117
links := make([]any, len(indices))
118118
for i, index := range indices {
119-
links[i] = numericIssueLink(util.URLJoin(TestRepoURL, path), "ref-issue", index, marker)
119+
links[i] = numericIssueLink(util.URLJoin("/test-owner/test-repo", path), "ref-issue", index, marker)
120120
}
121121
expectedNil := fmt.Sprintf(expectedFmt, links...)
122122
testRenderIssueIndexPattern(t, s, expectedNil, NewTestRenderContext(TestAppURL, localMetas))
@@ -293,13 +293,13 @@ func TestRender_AutoLink(t *testing.T) {
293293

294294
// render valid commit URLs
295295
tmp := util.URLJoin(TestRepoURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae")
296-
test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code class=\"nohighlight\">d8a994ef24</code></a>")
296+
test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code>d8a994ef24</code></a>")
297297
tmp += "#diff-2"
298-
test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code class=\"nohighlight\">d8a994ef24 (diff-2)</code></a>")
298+
test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code>d8a994ef24 (diff-2)</code></a>")
299299

300300
// render other commit URLs
301301
tmp = "https://external-link.gitea.io/go-gitea/gitea/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2"
302-
test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code class=\"nohighlight\">d8a994ef24 (diff-2)</code></a>")
302+
test(tmp, "<a href=\""+tmp+"\" class=\"commit\"><code>d8a994ef24 (diff-2)</code></a>")
303303
}
304304

305305
func TestRender_FullIssueURLs(t *testing.T) {

modules/markup/html_issue.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
162162
issueOwner := util.Iif(ref.Owner == "", ctx.RenderOptions.Metas["user"], ref.Owner)
163163
issueRepo := util.Iif(ref.Owner == "", ctx.RenderOptions.Metas["repo"], ref.Name)
164164
issuePath := util.Iif(ref.IsPull, "pulls", "issues")
165-
linkHref := ctx.RenderHelper.ResolveLink(util.URLJoin(issueOwner, issueRepo, issuePath, ref.Issue), LinkTypeApp)
165+
linkHref := "/:root/" + util.URLJoin(issueOwner, issueRepo, issuePath, ref.Issue)
166166

167167
// at the moment, only render the issue index in a full line (or simple line) as icon+title
168168
// otherwise it would be too noisy for "take #1 as an example" in a sentence

0 commit comments

Comments
 (0)