Skip to content

Commit 98eb32c

Browse files
committed
Fix footnote jump behavior on the issue page.
1 parent 3f7dbbd commit 98eb32c

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

modules/markup/html.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Nod
320320
}
321321

322322
processNodeAttrID(node)
323+
processFootnoteID(ctx, node)
324+
processFootnoteBackHref(ctx, node)
323325

324326
if isEmojiNode(node) {
325327
// TextNode emoji will be converted to `<span class="emoji">`, then the next iteration will visit the "span"

modules/markup/html_issue_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func TestRender_IssueList(t *testing.T) {
3030
rctx := markup.NewTestRenderContext(markup.TestAppURL, map[string]string{
3131
"user": "test-user", "repo": "test-repo",
3232
"markupAllowShortIssuePattern": "true",
33+
"issue_comment_id": "12345",
3334
})
3435
out, err := markdown.RenderString(rctx, input)
3536
require.NoError(t, err)
@@ -69,4 +70,22 @@ func TestRender_IssueList(t *testing.T) {
6970
</ul>`,
7071
)
7172
})
73+
74+
t.Run("IssueFootnote", func(t *testing.T) {
75+
test(
76+
"foo[^1][^2]\n\n[^1]: bar\n[^2]: baz",
77+
`<p>foo<sup id="fnref:user-content-1-12345"><a href="#fn:user-content-1-12345" rel="nofollow">1</a></sup><sup id="fnref:user-content-2-12345"><a href="#fn:user-content-2-12345" rel="nofollow">2</a></sup></p>
78+
<div>
79+
<hr/>
80+
<ol>
81+
<li id="fn:user-content-1-12345">
82+
<p>bar <a href="#fnref:user-content-1-12345" rel="nofollow">↩︎</a></p>
83+
</li>
84+
<li id="fn:user-content-2-12345">
85+
<p>baz <a href="#fnref:user-content-2-12345" rel="nofollow">↩︎</a></p>
86+
</li>
87+
</ol>
88+
</div>`,
89+
)
90+
})
7291
}

modules/markup/html_node.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ func isAnchorIDUserContent(s string) bool {
1515
return strings.HasPrefix(s, "user-content-") || strings.Contains(s, ":user-content-")
1616
}
1717

18+
func isAnchorIDFootnote(s string) bool {
19+
return strings.HasPrefix(s, "fnref:user-content-") || strings.HasPrefix(s, "fn:user-content-")
20+
}
21+
22+
func isAnchorHrefFootnote(s string) bool {
23+
return strings.HasPrefix(s, "#fnref:user-content-") || strings.HasPrefix(s, "#fn:user-content-")
24+
}
25+
1826
func processNodeAttrID(node *html.Node) {
1927
// Add user-content- to IDs and "#" links if they don't already have them,
2028
// and convert the link href to a relative link to the host root
@@ -27,6 +35,34 @@ func processNodeAttrID(node *html.Node) {
2735
}
2836
}
2937

38+
func processFootnoteID(ctx *RenderContext, node *html.Node) {
39+
for idx, attr := range node.Attr {
40+
if attr.Key == "id" {
41+
if !isAnchorIDFootnote(attr.Val) {
42+
return
43+
}
44+
if issueNum, ok := ctx.RenderOptions.Metas["issue_comment_id"]; ok {
45+
node.Attr[idx].Val = attr.Val + "-" + issueNum
46+
}
47+
return
48+
}
49+
}
50+
}
51+
52+
func processFootnoteBackHref(ctx *RenderContext, node *html.Node) {
53+
for idx, attr := range node.Attr {
54+
if attr.Key == "href" {
55+
if !isAnchorHrefFootnote(attr.Val) {
56+
return
57+
}
58+
if issueNum, ok := ctx.RenderOptions.Metas["issue_comment_id"]; ok {
59+
node.Attr[idx].Val = attr.Val + "-" + issueNum
60+
}
61+
return
62+
}
63+
}
64+
}
65+
3066
func processNodeA(ctx *RenderContext, node *html.Node) {
3167
for idx, attr := range node.Attr {
3268
if attr.Key == "href" {

routers/web/repo/issue_view.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"net/http"
1010
"net/url"
1111
"sort"
12+
"strconv"
1213

1314
activities_model "code.gitea.io/gitea/models/activities"
1415
"code.gitea.io/gitea/models/db"
@@ -625,6 +626,7 @@ func prepareIssueViewCommentsAndSidebarParticipants(ctx *context.Context, issue
625626

626627
if comment.Type == issues_model.CommentTypeComment || comment.Type == issues_model.CommentTypeReview {
627628
rctx := renderhelper.NewRenderContextRepoComment(ctx, issue.Repo)
629+
rctx.RenderOptions.Metas["issue_comment_id"] = strconv.FormatInt(comment.ID, 10)
628630
comment.RenderedContent, err = markdown.RenderString(rctx, comment.Content)
629631
if err != nil {
630632
ctx.ServerError("RenderString", err)
@@ -982,6 +984,8 @@ func preparePullViewReviewAndMerge(ctx *context.Context, issue *issues_model.Iss
982984
func prepareIssueViewContent(ctx *context.Context, issue *issues_model.Issue) {
983985
var err error
984986
rctx := renderhelper.NewRenderContextRepoComment(ctx, ctx.Repo.Repository)
987+
// the first issue index set to 0
988+
rctx.RenderOptions.Metas["issue_comment_id"] = "0"
985989
issue.RenderedContent, err = markdown.RenderString(rctx, issue.Content)
986990
if err != nil {
987991
ctx.ServerError("RenderString", err)

0 commit comments

Comments
 (0)