Skip to content

Commit

Permalink
Support quote selected comments to reply (#32431)
Browse files Browse the repository at this point in the history
Many existing tests were quite hacky, these could be improved later.

<details>

![image](https://github.com/user-attachments/assets/93aebb4f-9de5-4cb8-910b-50c64cbcd25a)

</details>
  • Loading branch information
wxiaoguang authored Nov 7, 2024
1 parent 276500c commit 145e266
Show file tree
Hide file tree
Showing 16 changed files with 255 additions and 70 deletions.
5 changes: 4 additions & 1 deletion modules/markup/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,10 @@ func createLink(href, content, class string) *html.Node {
a := &html.Node{
Type: html.ElementNode,
Data: atom.A.String(),
Attr: []html.Attribute{{Key: "href", Val: href}},
Attr: []html.Attribute{
{Key: "href", Val: href},
{Key: "data-markdown-generated-content"},
},
}

if class != "" {
Expand Down
2 changes: 1 addition & 1 deletion modules/markup/html_codepreview_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ func TestRenderCodePreview(t *testing.T) {
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
}
test("http://localhost:3000/owner/repo/src/commit/0123456789/foo/bar.md#L10-L20", "<p><div>code preview</div></p>")
test("http://other/owner/repo/src/commit/0123456789/foo/bar.md#L10-L20", `<p><a href="http://other/owner/repo/src/commit/0123456789/foo/bar.md#L10-L20" rel="nofollow">http://other/owner/repo/src/commit/0123456789/foo/bar.md#L10-L20</a></p>`)
test("http://other/owner/repo/src/commit/0123456789/foo/bar.md#L10-L20", `<p><a href="http://other/owner/repo/src/commit/0123456789/foo/bar.md#L10-L20" data-markdown-generated-content="" rel="nofollow">http://other/owner/repo/src/commit/0123456789/foo/bar.md#L10-L20</a></p>`)
}
12 changes: 6 additions & 6 deletions modules/markup/html_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@ func numericIssueLink(baseURL, class string, index int, marker string) string {

// link an HTML link
func link(href, class, contents string) string {
if class != "" {
class = " class=\"" + class + "\""
}

return fmt.Sprintf("<a href=\"%s\"%s>%s</a>", href, class, contents)
extra := ` data-markdown-generated-content=""`
extra += util.Iif(class != "", ` class="`+class+`"`, "")
return fmt.Sprintf(`<a href="%s"%s>%s</a>`, href, extra, contents)
}

var numericMetas = map[string]string{
Expand Down Expand Up @@ -353,7 +351,9 @@ func TestRender_FullIssueURLs(t *testing.T) {
Metas: localMetas,
}, []processor{fullIssuePatternProcessor}, strings.NewReader(input), &result)
assert.NoError(t, err)
assert.Equal(t, expected, result.String())
actual := result.String()
actual = strings.ReplaceAll(actual, ` data-markdown-generated-content=""`, "")
assert.Equal(t, expected, actual)
}
test("Here is a link https://git.osgeo.org/gogs/postgis/postgis/pulls/6",
"Here is a link https://git.osgeo.org/gogs/postgis/postgis/pulls/6")
Expand Down
16 changes: 12 additions & 4 deletions modules/markup/html_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ func TestRender_CrossReferences(t *testing.T) {
Metas: localMetas,
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
actual := strings.TrimSpace(buffer)
actual = strings.ReplaceAll(actual, ` data-markdown-generated-content=""`, "")
assert.Equal(t, strings.TrimSpace(expected), actual)
}

test(
Expand Down Expand Up @@ -156,7 +158,9 @@ func TestRender_links(t *testing.T) {
},
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
actual := strings.TrimSpace(buffer)
actual = strings.ReplaceAll(actual, ` data-markdown-generated-content=""`, "")
assert.Equal(t, strings.TrimSpace(expected), actual)
}

oldCustomURLSchemes := setting.Markdown.CustomURLSchemes
Expand Down Expand Up @@ -267,7 +271,9 @@ func TestRender_email(t *testing.T) {
},
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(res))
actual := strings.TrimSpace(res)
actual = strings.ReplaceAll(actual, ` data-markdown-generated-content=""`, "")
assert.Equal(t, strings.TrimSpace(expected), actual)
}
// Text that should be turned into email link

Expand Down Expand Up @@ -616,7 +622,9 @@ func TestPostProcess_RenderDocument(t *testing.T) {
Metas: localMetas,
}, strings.NewReader(input), &res)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(res.String()))
actual := strings.TrimSpace(res.String())
actual = strings.ReplaceAll(actual, ` data-markdown-generated-content=""`, "")
assert.Equal(t, strings.TrimSpace(expected), actual)
}

// Issue index shouldn't be post processing in a document.
Expand Down
12 changes: 8 additions & 4 deletions modules/markup/markdown/markdown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,8 @@ func TestTotal_RenderWiki(t *testing.T) {
IsWiki: true,
}, sameCases[i])
assert.NoError(t, err)
assert.Equal(t, template.HTML(answers[i]), line)
actual := strings.ReplaceAll(string(line), ` data-markdown-generated-content=""`, "")
assert.Equal(t, answers[i], actual)
}

testCases := []string{
Expand All @@ -336,7 +337,8 @@ func TestTotal_RenderWiki(t *testing.T) {
IsWiki: true,
}, testCases[i])
assert.NoError(t, err)
assert.Equal(t, template.HTML(testCases[i+1]), line)
actual := strings.ReplaceAll(string(line), ` data-markdown-generated-content=""`, "")
assert.EqualValues(t, testCases[i+1], actual)
}
}

Expand All @@ -356,7 +358,8 @@ func TestTotal_RenderString(t *testing.T) {
Metas: localMetas,
}, sameCases[i])
assert.NoError(t, err)
assert.Equal(t, template.HTML(answers[i]), line)
actual := strings.ReplaceAll(string(line), ` data-markdown-generated-content=""`, "")
assert.Equal(t, answers[i], actual)
}

testCases := []string{}
Expand Down Expand Up @@ -996,7 +999,8 @@ space</p>
for i, c := range cases {
result, err := markdown.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, string(result), "Unexpected result in testcase %v", i)
actual := strings.ReplaceAll(string(result), ` data-markdown-generated-content=""`, "")
assert.Equal(t, c.Expected, actual, "Unexpected result in testcase %v", i)
}
}

Expand Down
1 change: 1 addition & 0 deletions modules/markup/sanitizer_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func (st *Sanitizer) createDefaultPolicy() *bluemonday.Policy {
"start", "summary", "tabindex", "target",
"title", "type", "usemap", "valign", "value",
"vspace", "width", "itemprop",
"data-markdown-generated-content",
}

generalSafeElements := []string{
Expand Down
16 changes: 9 additions & 7 deletions modules/templates/util_render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,18 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
<a href="/mention-user" class="mention">@mention-user</a> test
<a href="/user13/repo11/issues/123" class="ref-issue">#123</a>
space`

assert.EqualValues(t, expected, newTestRenderUtils().RenderCommitBody(testInput(), testMetas))
actual := strings.ReplaceAll(string(newTestRenderUtils().RenderCommitBody(testInput(), testMetas)), ` data-markdown-generated-content=""`, "")
assert.EqualValues(t, expected, actual)
}

func TestRenderCommitMessage(t *testing.T) {
expected := `space <a href="/mention-user" class="mention">@mention-user</a> `
expected := `space <a href="/mention-user" data-markdown-generated-content="" class="mention">@mention-user</a> `

assert.EqualValues(t, expected, newTestRenderUtils().RenderCommitMessage(testInput(), testMetas))
}

func TestRenderCommitMessageLinkSubject(t *testing.T) {
expected := `<a href="https://example.com/link" class="default-link muted">space </a><a href="/mention-user" class="mention">@mention-user</a>`
expected := `<a href="https://example.com/link" class="default-link muted">space </a><a href="/mention-user" data-markdown-generated-content="" class="mention">@mention-user</a>`

assert.EqualValues(t, expected, newTestRenderUtils().RenderCommitMessageLinkSubject(testInput(), "https://example.com/link", testMetas))
}
Expand Down Expand Up @@ -168,7 +168,8 @@ [email protected]
space<SPACE><SPACE>
`
expected = strings.ReplaceAll(expected, "<SPACE>", " ")
assert.EqualValues(t, expected, newTestRenderUtils().RenderIssueTitle(testInput(), testMetas))
actual := strings.ReplaceAll(string(newTestRenderUtils().RenderIssueTitle(testInput(), testMetas)), ` data-markdown-generated-content=""`, "")
assert.EqualValues(t, expected, actual)
}

func TestRenderMarkdownToHtml(t *testing.T) {
Expand All @@ -193,7 +194,8 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
#123
space</p>
`
assert.Equal(t, expected, string(newTestRenderUtils().MarkdownToHtml(testInput())))
actual := strings.ReplaceAll(string(newTestRenderUtils().MarkdownToHtml(testInput())), ` data-markdown-generated-content=""`, "")
assert.Equal(t, expected, actual)
}

func TestRenderLabels(t *testing.T) {
Expand All @@ -211,5 +213,5 @@ func TestRenderLabels(t *testing.T) {

func TestUserMention(t *testing.T) {
rendered := newTestRenderUtils().MarkdownToHtml("@no-such-user @mention-user @mention-user")
assert.EqualValues(t, `<p>@no-such-user <a href="/mention-user" rel="nofollow">@mention-user</a> <a href="/mention-user" rel="nofollow">@mention-user</a></p>`, strings.TrimSpace(string(rendered)))
assert.EqualValues(t, `<p>@no-such-user <a href="/mention-user" data-markdown-generated-content="" rel="nofollow">@mention-user</a> <a href="/mention-user" data-markdown-generated-content="" rel="nofollow">@mention-user</a></p>`, strings.TrimSpace(string(rendered)))
}
6 changes: 4 additions & 2 deletions routers/api/v1/misc/markup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ func testRenderMarkup(t *testing.T, mode string, wiki bool, filePath, text, expe
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markup")
web.SetForm(ctx, &options)
Markup(ctx)
assert.Equal(t, expectedBody, resp.Body.String())
actual := strings.ReplaceAll(resp.Body.String(), ` data-markdown-generated-content=""`, "")
assert.Equal(t, expectedBody, actual)
assert.Equal(t, expectedCode, resp.Code)
resp.Body.Reset()
}
Expand All @@ -58,7 +59,8 @@ func testRenderMarkdown(t *testing.T, mode string, wiki bool, text, responseBody
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markdown")
web.SetForm(ctx, &options)
Markdown(ctx)
assert.Equal(t, responseBody, resp.Body.String())
actual := strings.ReplaceAll(resp.Body.String(), ` data-markdown-generated-content=""`, "")
assert.Equal(t, responseBody, actual)
assert.Equal(t, responseCode, resp.Code)
resp.Body.Reset()
}
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/diff/comments.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
{{end}}
{{end}}
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.root.RepoLink .ID)}}
{{template "repo/issue/view_content/context_menu" dict "ctxData" $.root "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}
{{template "repo/issue/view_content/context_menu" dict "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}
</div>
</div>
<div class="ui attached segment comment-body">
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/issue/view_content.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
{{if not $.Repository.IsArchived}}
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index)}}
{{end}}
{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" .Issue "delete" false "issue" true "diff" false "IsCommentPoster" $.IsIssuePoster}}
{{template "repo/issue/view_content/context_menu" dict "item" .Issue "delete" false "issue" true "diff" false "IsCommentPoster" $.IsIssuePoster}}
</div>
</div>
<div class="ui attached segment comment-body" role="article">
Expand Down
4 changes: 2 additions & 2 deletions templates/repo/issue/view_content/comments.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
{{if not $.Repository.IsArchived}}
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
{{end}}
{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
{{template "repo/issue/view_content/context_menu" dict "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
</div>
</div>
<div class="ui attached segment comment-body" role="article">
Expand Down Expand Up @@ -430,7 +430,7 @@
{{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}}
{{if not $.Repository.IsArchived}}
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" false "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
{{template "repo/issue/view_content/context_menu" dict "item" . "delete" false "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
{{end}}
</div>
</div>
Expand Down
18 changes: 9 additions & 9 deletions templates/repo/issue/view_content/context_menu.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@
<div class="menu">
{{$referenceUrl := ""}}
{{if .issue}}
{{$referenceUrl = printf "%s#%s" .ctxData.Issue.Link .item.HashTag}}
{{$referenceUrl = printf "%s#%s" ctx.RootData.Issue.Link .item.HashTag}}
{{else}}
{{$referenceUrl = printf "%s/files#%s" .ctxData.Issue.Link .item.HashTag}}
{{$referenceUrl = printf "%s/files#%s" ctx.RootData.Issue.Link .item.HashTag}}
{{end}}
<div class="item context js-aria-clickable" data-clipboard-text-type="url" data-clipboard-text="{{$referenceUrl}}">{{ctx.Locale.Tr "repo.issues.context.copy_link"}}</div>
{{if .ctxData.IsSigned}}
{{if ctx.RootData.IsSigned}}
{{$needDivider := false}}
{{if not .ctxData.Repository.IsArchived}}
{{if not ctx.RootData.Repository.IsArchived}}
{{$needDivider = true}}
<div class="item context js-aria-clickable quote-reply {{if .diff}}quote-reply-diff{{end}}" data-target="{{.item.HashTag}}-raw">{{ctx.Locale.Tr "repo.issues.context.quote_reply"}}</div>
{{if not ctx.Consts.RepoUnitTypeIssues.UnitGlobalDisabled}}
<div class="item context js-aria-clickable reference-issue" data-target="{{.item.HashTag}}-raw" data-modal="#reference-issue-modal" data-poster="{{.item.Poster.GetDisplayName}}" data-poster-username="{{.item.Poster.Name}}" data-reference="{{$referenceUrl}}">{{ctx.Locale.Tr "repo.issues.context.reference_issue"}}</div>
{{end}}
{{if or .ctxData.Permission.IsAdmin .IsCommentPoster .ctxData.HasIssuesOrPullsWritePermission}}
{{if or ctx.RootData.Permission.IsAdmin .IsCommentPoster ctx.RootData.HasIssuesOrPullsWritePermission}}
<div class="divider"></div>
<div class="item context js-aria-clickable edit-content">{{ctx.Locale.Tr "repo.issues.context.edit"}}</div>
{{if .delete}}
<div class="item context js-aria-clickable delete-comment" data-comment-id={{.item.HashTag}} data-url="{{.ctxData.RepoLink}}/comments/{{.item.ID}}/delete" data-locale="{{ctx.Locale.Tr "repo.issues.delete_comment_confirm"}}">{{ctx.Locale.Tr "repo.issues.context.delete"}}</div>
<div class="item context js-aria-clickable delete-comment" data-comment-id={{.item.HashTag}} data-url="{{ctx.RootData.RepoLink}}/comments/{{.item.ID}}/delete" data-locale="{{ctx.Locale.Tr "repo.issues.delete_comment_confirm"}}">{{ctx.Locale.Tr "repo.issues.context.delete"}}</div>
{{end}}
{{end}}
{{end}}
{{$canUserBlock := call .ctxData.CanBlockUser .ctxData.SignedUser .item.Poster}}
{{$canOrgBlock := and .ctxData.Repository.Owner.IsOrganization (call .ctxData.CanBlockUser .ctxData.Repository.Owner .item.Poster)}}
{{$canUserBlock := call ctx.RootData.CanBlockUser ctx.RootData.SignedUser .item.Poster}}
{{$canOrgBlock := and ctx.RootData.Repository.Owner.IsOrganization (call ctx.RootData.CanBlockUser ctx.RootData.Repository.Owner .item.Poster)}}
{{if or $canOrgBlock $canUserBlock}}
{{if $needDivider}}
<div class="divider"></div>
Expand All @@ -36,7 +36,7 @@
<div class="item context js-aria-clickable show-modal" data-modal="#block-user-modal" data-modal-modal-blockee="{{.item.Poster.Name}}" data-modal-modal-blockee-name="{{.item.Poster.GetDisplayName}}" data-modal-modal-form.action="{{AppSubUrl}}/user/settings/blocked_users">{{ctx.Locale.Tr "user.block.block.user"}}</div>
{{end}}
{{if $canOrgBlock}}
<div class="item context js-aria-clickable show-modal" data-modal="#block-user-modal" data-modal-modal-blockee="{{.item.Poster.Name}}" data-modal-modal-blockee-name="{{.item.Poster.GetDisplayName}}" data-modal-modal-form.action="{{.ctxData.Repository.Owner.OrganisationLink}}/settings/blocked_users">{{ctx.Locale.Tr "user.block.block.org"}}</div>
<div class="item context js-aria-clickable show-modal" data-modal="#block-user-modal" data-modal-modal-blockee="{{.item.Poster.Name}}" data-modal-modal-blockee-name="{{.item.Poster.GetDisplayName}}" data-modal-modal-form.action="{{ctx.RootData.Repository.Owner.OrganisationLink}}/settings/blocked_users">{{ctx.Locale.Tr "user.block.block.org"}}</div>
{{end}}
{{end}}
{{end}}
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/issue/view_content/conversation.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
{{template "repo/issue/view_content/show_role" dict "ShowRole" .ShowRole}}
{{if not $.Repository.IsArchived}}
{{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.RepoLink .ID)}}
{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
{{template "repo/issue/view_content/context_menu" dict "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}}
{{end}}
</div>
</div>
Expand Down
Loading

0 comments on commit 145e266

Please sign in to comment.