mirror of
https://github.com/go-gitea/gitea
synced 2025-07-19 16:58:37 +00:00
Fix footnote jump behavior on the issue page. (#34621)
Close #34511 Close #34590 Add comment ID to the footnote item's id attribute to ensure uniqueness. --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -409,9 +409,9 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt
|
||||
_, _ = w.Write(n.Name)
|
||||
_, _ = w.WriteString(`"><a href="#fn:`)
|
||||
_, _ = w.Write(n.Name)
|
||||
_, _ = w.WriteString(`" class="footnote-ref" role="doc-noteref">`)
|
||||
_, _ = w.WriteString(`" class="footnote-ref" role="doc-noteref">`) // FIXME: here and below, need to keep the classes
|
||||
_, _ = w.WriteString(is)
|
||||
_, _ = w.WriteString(`</a></sup>`)
|
||||
_, _ = w.WriteString(` </a></sup>`) // the style doesn't work at the moment, so add a space to separate the names
|
||||
}
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
@@ -320,6 +320,7 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Nod
|
||||
}
|
||||
|
||||
processNodeAttrID(node)
|
||||
processFootnoteNode(ctx, node) // FIXME: the footnote processing should be done in the "footnote.go" renderer directly
|
||||
|
||||
if isEmojiNode(node) {
|
||||
// TextNode emoji will be converted to `<span class="emoji">`, then the next iteration will visit the "span"
|
||||
|
@@ -30,6 +30,7 @@ func TestRender_IssueList(t *testing.T) {
|
||||
rctx := markup.NewTestRenderContext(markup.TestAppURL, map[string]string{
|
||||
"user": "test-user", "repo": "test-repo",
|
||||
"markupAllowShortIssuePattern": "true",
|
||||
"footnoteContextId": "12345",
|
||||
})
|
||||
out, err := markdown.RenderString(rctx, input)
|
||||
require.NoError(t, err)
|
||||
@@ -69,4 +70,22 @@ func TestRender_IssueList(t *testing.T) {
|
||||
</ul>`,
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("IssueFootnote", func(t *testing.T) {
|
||||
test(
|
||||
"foo[^1][^2]\n\n[^1]: bar\n[^2]: baz",
|
||||
`<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>
|
||||
<div>
|
||||
<hr/>
|
||||
<ol>
|
||||
<li id="fn:user-content-1-12345">
|
||||
<p>bar <a href="#fnref:user-content-1-12345" rel="nofollow">↩︎</a></p>
|
||||
</li>
|
||||
<li id="fn:user-content-2-12345">
|
||||
<p>baz <a href="#fnref:user-content-2-12345" rel="nofollow">↩︎</a></p>
|
||||
</li>
|
||||
</ol>
|
||||
</div>`,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@@ -15,6 +15,14 @@ func isAnchorIDUserContent(s string) bool {
|
||||
return strings.HasPrefix(s, "user-content-") || strings.Contains(s, ":user-content-")
|
||||
}
|
||||
|
||||
func isAnchorIDFootnote(s string) bool {
|
||||
return strings.HasPrefix(s, "fnref:user-content-") || strings.HasPrefix(s, "fn:user-content-")
|
||||
}
|
||||
|
||||
func isAnchorHrefFootnote(s string) bool {
|
||||
return strings.HasPrefix(s, "#fnref:user-content-") || strings.HasPrefix(s, "#fn:user-content-")
|
||||
}
|
||||
|
||||
func processNodeAttrID(node *html.Node) {
|
||||
// Add user-content- to IDs and "#" links if they don't already have them,
|
||||
// and convert the link href to a relative link to the host root
|
||||
@@ -27,6 +35,18 @@ func processNodeAttrID(node *html.Node) {
|
||||
}
|
||||
}
|
||||
|
||||
func processFootnoteNode(ctx *RenderContext, node *html.Node) {
|
||||
for idx, attr := range node.Attr {
|
||||
if (attr.Key == "id" && isAnchorIDFootnote(attr.Val)) ||
|
||||
(attr.Key == "href" && isAnchorHrefFootnote(attr.Val)) {
|
||||
if footnoteContextID := ctx.RenderOptions.Metas["footnoteContextId"]; footnoteContextID != "" {
|
||||
node.Attr[idx].Val = attr.Val + "-" + footnoteContextID
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func processNodeA(ctx *RenderContext, node *html.Node) {
|
||||
for idx, attr := range node.Attr {
|
||||
if attr.Key == "href" {
|
||||
|
@@ -223,7 +223,7 @@ This PR has been generated by [Renovate Bot](https://github.com/renovatebot/reno
|
||||
<dd>This is another definition of the second term.</dd>
|
||||
</dl>
|
||||
<h3 id="user-content-footnotes">Footnotes</h3>
|
||||
<p>Here is a simple footnote,<sup id="fnref:user-content-1"><a href="#fn:user-content-1" rel="nofollow">1</a></sup> and here is a longer one.<sup id="fnref:user-content-bignote"><a href="#fn:user-content-bignote" rel="nofollow">2</a></sup></p>
|
||||
<p>Here is a simple footnote,<sup id="fnref:user-content-1"><a href="#fn:user-content-1" rel="nofollow">1 </a></sup> and here is a longer one.<sup id="fnref:user-content-bignote"><a href="#fn:user-content-bignote" rel="nofollow">2 </a></sup></p>
|
||||
<div>
|
||||
<hr/>
|
||||
<ol>
|
||||
|
Reference in New Issue
Block a user