Skip to content

Commit d4e4925

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Add `lint-go-gopls` (go-gitea#30729) Make blockquote attention recognize more syntaxes (go-gitea#31240) Fix admin oauth2 custom URL settings (go-gitea#31246) Replace `gt-word-break` with `tw-break-anywhere` (go-gitea#31183) Make pasted "img" tag has the same behavior as markdown image (go-gitea#31235) Remove .segment from .project-column (go-gitea#31204) Fix overflow on push notification (go-gitea#31179) Fix NuGet Package API for $filter with Id equality (go-gitea#31188) Fix overflow on notifications (go-gitea#31178) Update chroma to v2.14.0 (go-gitea#31177) Update air package path (go-gitea#31233) Bump `@github/relative-time-element` to v4.4.1 (go-gitea#31232)
2 parents e7da210 + 8162222 commit d4e4925

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+373
-174
lines changed

Makefile

+10-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ COMMA := ,
2525

2626
XGO_VERSION := go-1.22.x
2727

28-
AIR_PACKAGE ?= github.com/cosmtrek/air@v1
28+
AIR_PACKAGE ?= github.com/air-verse/air@v1
2929
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/[email protected]
3030
GOFUMPT_PACKAGE ?= mvdan.cc/[email protected]
3131
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/[email protected]
@@ -36,6 +36,7 @@ XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
3636
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1
3737
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1
3838
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1
39+
GOPLS_PACKAGE ?= golang.org/x/tools/[email protected]
3940

4041
DOCKER_IMAGE ?= gitea/gitea
4142
DOCKER_TAG ?= latest
@@ -213,6 +214,7 @@ help:
213214
@echo " - lint-go lint go files"
214215
@echo " - lint-go-fix lint go files and fix issues"
215216
@echo " - lint-go-vet lint go files with vet"
217+
@echo " - lint-go-gopls lint go files with gopls"
216218
@echo " - lint-js lint js files"
217219
@echo " - lint-js-fix lint js files and fix issues"
218220
@echo " - lint-css lint css files"
@@ -366,7 +368,7 @@ lint-frontend: lint-js lint-css
366368
lint-frontend-fix: lint-js-fix lint-css-fix
367369

368370
.PHONY: lint-backend
369-
lint-backend: lint-go lint-go-vet lint-editorconfig
371+
lint-backend: lint-go lint-go-vet lint-go-gopls lint-editorconfig
370372

371373
.PHONY: lint-backend-fix
372374
lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig
@@ -424,6 +426,11 @@ lint-go-vet:
424426
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet
425427
@$(GO) vet -vettool=gitea-vet ./...
426428

429+
.PHONY: lint-go-gopls
430+
lint-go-gopls:
431+
@echo "Running gopls check..."
432+
@GO=$(GO) GOPLS_PACKAGE=$(GOPLS_PACKAGE) tools/lint-go-gopls.sh $(GO_SOURCES_NO_BINDATA)
433+
427434
.PHONY: lint-editorconfig
428435
lint-editorconfig:
429436
@$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) $(EDITORCONFIG_FILES)
@@ -864,6 +871,7 @@ deps-tools:
864871
$(GO) install $(GO_LICENSES_PACKAGE)
865872
$(GO) install $(GOVULNCHECK_PACKAGE)
866873
$(GO) install $(ACTIONLINT_PACKAGE)
874+
$(GO) install $(GOPLS_PACKAGE)
867875

868876
node_modules: package-lock.json
869877
npm install --no-save

docs/content/contributing/guidelines-frontend.en-us.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h
4747
9. Avoid unnecessary `!important` in CSS, add comments to explain why it's necessary if it can't be avoided.
4848
10. Avoid mixing different events in one event listener, prefer to use individual event listeners for every event.
4949
11. Custom event names are recommended to use `ce-` prefix.
50-
12. Prefer using Tailwind CSS which is available via `tw-` prefix, e.g. `tw-relative`. Gitea's helper CSS classes use `gt-` prefix (`gt-word-break`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`).
50+
12. Prefer using Tailwind CSS which is available via `tw-` prefix, e.g. `tw-relative`. Gitea's helper CSS classes use `gt-` prefix (`gt-ellipsis`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`).
5151
13. Avoid inline scripts & styles as much as possible, it's recommended to put JS code into JS files and use CSS classes. If inline scripts & styles are unavoidable, explain the reason why it can't be avoided.
5252

5353
### Accessibility / ARIA

docs/content/contributing/guidelines-frontend.zh-cn.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ HTML 页面由[Go HTML Template](https://pkg.go.dev/html/template)渲染。
4747
9. 避免在 CSS 中使用不必要的`!important`,如果无法避免,添加注释解释为什么需要它。
4848
10. 避免在一个事件监听器中混合不同的事件,优先为每个事件使用独立的事件监听器。
4949
11. 推荐使用自定义事件名称前缀`ce-`
50-
12. 建议使用 Tailwind CSS,它可以通过 `tw-` 前缀获得,例如 `tw-relative`. Gitea 自身的助手类 CSS 使用 `gt-` 前缀(`gt-word-break`),Gitea 自身的私有框架级 CSS 类使用 `g-` 前缀(`g-modal-confirm`)。
50+
12. 建议使用 Tailwind CSS,它可以通过 `tw-` 前缀获得,例如 `tw-relative`. Gitea 自身的助手类 CSS 使用 `gt-` 前缀(`gt-ellipsis`),Gitea 自身的私有框架级 CSS 类使用 `g-` 前缀(`g-modal-confirm`)。
5151
13. 尽量避免内联脚本和样式,建议将JS代码放入JS文件中并使用CSS类。如果内联脚本和样式不可避免,请解释无法避免的原因。
5252

5353
### 可访问性 / ARIA

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ require (
2020
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358
2121
github.com/ProtonMail/go-crypto v1.0.0
2222
github.com/PuerkitoBio/goquery v1.9.1
23-
github.com/alecthomas/chroma/v2 v2.13.0
23+
github.com/alecthomas/chroma/v2 v2.14.0
2424
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
2525
github.com/blevesearch/bleve/v2 v2.3.10
2626
github.com/buildkite/terminal-to-html/v3 v3.11.0

go.sum

+4-4
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06
8282
github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
8383
github.com/RoaringBitmap/roaring v1.9.0 h1:lwKhr90/j0jVXJyh5X+vQN1VVn77rQFfYnh6RDRGCcE=
8484
github.com/RoaringBitmap/roaring v1.9.0/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
85-
github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU=
86-
github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
85+
github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE=
86+
github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
8787
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
88-
github.com/alecthomas/chroma/v2 v2.13.0 h1:VP72+99Fb2zEcYM0MeaWJmV+xQvz5v5cxRHd+ooU1lI=
89-
github.com/alecthomas/chroma/v2 v2.13.0/go.mod h1:BUGjjsD+ndS6eX37YgTchSEG+Jg9Jv1GiZs9sqPqztk=
88+
github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E=
89+
github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I=
9090
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
9191
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
9292
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=

modules/markup/html.go

+44-16
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,42 @@ func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output
372372
return nil
373373
}
374374

375-
func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
375+
func handleNodeImg(ctx *RenderContext, img *html.Node) {
376+
for i, attr := range img.Attr {
377+
if attr.Key != "src" {
378+
continue
379+
}
380+
381+
if attr.Val != "" && !IsFullURLString(attr.Val) && !strings.HasPrefix(attr.Val, "/") {
382+
attr.Val = util.URLJoin(ctx.Links.ResolveMediaLink(ctx.IsWiki), attr.Val)
383+
384+
// By default, the "<img>" tag should also be clickable,
385+
// because frontend use `<img>` to paste the re-scaled image into the markdown,
386+
// so it must match the default markdown image behavior.
387+
hasParentAnchor := false
388+
for p := img.Parent; p != nil; p = p.Parent {
389+
if hasParentAnchor = p.Type == html.ElementNode && p.Data == "a"; hasParentAnchor {
390+
break
391+
}
392+
}
393+
if !hasParentAnchor {
394+
imgA := &html.Node{Type: html.ElementNode, Data: "a", Attr: []html.Attribute{
395+
{Key: "href", Val: attr.Val},
396+
{Key: "target", Val: "_blank"},
397+
}}
398+
parent := img.Parent
399+
imgNext := img.NextSibling
400+
parent.RemoveChild(img)
401+
parent.InsertBefore(imgA, imgNext)
402+
imgA.AppendChild(img)
403+
}
404+
}
405+
attr.Val = camoHandleLink(attr.Val)
406+
img.Attr[i] = attr
407+
}
408+
}
409+
410+
func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Node {
376411
// Add user-content- to IDs and "#" links if they don't already have them
377412
for idx, attr := range node.Attr {
378413
val := strings.TrimPrefix(attr.Val, "#")
@@ -397,21 +432,14 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
397432
textNode(ctx, procs, node)
398433
case html.ElementNode:
399434
if node.Data == "img" {
400-
for i, attr := range node.Attr {
401-
if attr.Key != "src" {
402-
continue
403-
}
404-
if len(attr.Val) > 0 && !IsFullURLString(attr.Val) && !strings.HasPrefix(attr.Val, "data:image/") {
405-
attr.Val = util.URLJoin(ctx.Links.ResolveMediaLink(ctx.IsWiki), attr.Val)
406-
}
407-
attr.Val = camoHandleLink(attr.Val)
408-
node.Attr[i] = attr
409-
}
435+
next := node.NextSibling
436+
handleNodeImg(ctx, node)
437+
return next
410438
} else if node.Data == "a" {
411439
// Restrict text in links to emojis
412440
procs = emojiProcessors
413441
} else if node.Data == "code" || node.Data == "pre" {
414-
return
442+
return node.NextSibling
415443
} else if node.Data == "i" {
416444
for _, attr := range node.Attr {
417445
if attr.Key != "class" {
@@ -434,11 +462,11 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
434462
}
435463
}
436464
}
437-
for n := node.FirstChild; n != nil; n = n.NextSibling {
438-
visitNode(ctx, procs, n)
465+
for n := node.FirstChild; n != nil; {
466+
n = visitNode(ctx, procs, n)
439467
}
440468
}
441-
// ignore everything else
469+
return node.NextSibling
442470
}
443471

444472
// textNode runs the passed node through various processors, in order to handle
@@ -851,7 +879,7 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
851879

852880
// FIXME: the use of "mode" is quite dirty and hacky, for example: what is a "document"? how should it be rendered?
853881
// The "mode" approach should be refactored to some other more clear&reliable way.
854-
crossLinkOnly := (ctx.Metas["mode"] == "document" && !ctx.IsWiki)
882+
crossLinkOnly := ctx.Metas["mode"] == "document" && !ctx.IsWiki
855883

856884
var (
857885
found bool

modules/markup/html_internal_test.go

+9-10
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ import (
1818

1919
const (
2020
TestAppURL = "http://localhost:3000/"
21-
TestOrgRepo = "gogits/gogs"
22-
TestRepoURL = TestAppURL + TestOrgRepo + "/"
21+
TestRepoURL = TestAppURL + "test-owner/test-repo/"
2322
)
2423

2524
// externalIssueLink an HTML link to an alphanumeric-style issue
@@ -64,8 +63,8 @@ var regexpMetas = map[string]string{
6463

6564
// these values should match the TestOrgRepo const above
6665
var localMetas = map[string]string{
67-
"user": "gogits",
68-
"repo": "gogs",
66+
"user": "test-owner",
67+
"repo": "test-repo",
6968
}
7069

7170
func TestRender_IssueIndexPattern(t *testing.T) {
@@ -362,12 +361,12 @@ func TestRender_FullIssueURLs(t *testing.T) {
362361
`Look here <a href="http://localhost:3000/person/repo/issues/4" class="ref-issue">person/repo#4</a>`)
363362
test("http://localhost:3000/person/repo/issues/4#issuecomment-1234",
364363
`<a href="http://localhost:3000/person/repo/issues/4#issuecomment-1234" class="ref-issue">person/repo#4 (comment)</a>`)
365-
test("http://localhost:3000/gogits/gogs/issues/4",
366-
`<a href="http://localhost:3000/gogits/gogs/issues/4" class="ref-issue">#4</a>`)
367-
test("http://localhost:3000/gogits/gogs/issues/4 test",
368-
`<a href="http://localhost:3000/gogits/gogs/issues/4" class="ref-issue">#4</a> test`)
369-
test("http://localhost:3000/gogits/gogs/issues/4?a=1&b=2#comment-123 test",
370-
`<a href="http://localhost:3000/gogits/gogs/issues/4?a=1&amp;b=2#comment-123" class="ref-issue">#4 (comment)</a> test`)
364+
test("http://localhost:3000/test-owner/test-repo/issues/4",
365+
`<a href="http://localhost:3000/test-owner/test-repo/issues/4" class="ref-issue">#4</a>`)
366+
test("http://localhost:3000/test-owner/test-repo/issues/4 test",
367+
`<a href="http://localhost:3000/test-owner/test-repo/issues/4" class="ref-issue">#4</a> test`)
368+
test("http://localhost:3000/test-owner/test-repo/issues/4?a=1&b=2#comment-123 test",
369+
`<a href="http://localhost:3000/test-owner/test-repo/issues/4?a=1&amp;b=2#comment-123" class="ref-issue">#4 (comment)</a> test`)
371370
test("http://localhost:3000/testOrg/testOrgRepo/pulls/2/files#issuecomment-24",
372371
"http://localhost:3000/testOrg/testOrgRepo/pulls/2/files#issuecomment-24")
373372
test("http://localhost:3000/testOrg/testOrgRepo/pulls/2/files",

modules/markup/html_test.go

+20-31
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ func TestRender_CrossReferences(t *testing.T) {
120120
}
121121

122122
test(
123-
"gogits/gogs#12345",
124-
`<p><a href="`+util.URLJoin(markup.TestAppURL, "gogits", "gogs", "issues", "12345")+`" class="ref-issue" rel="nofollow">gogits/gogs#12345</a></p>`)
123+
"test-owner/test-repo#12345",
124+
`<p><a href="`+util.URLJoin(markup.TestAppURL, "test-owner", "test-repo", "issues", "12345")+`" class="ref-issue" rel="nofollow">test-owner/test-repo#12345</a></p>`)
125125
test(
126126
"go-gitea/gitea#12345",
127127
`<p><a href="`+util.URLJoin(markup.TestAppURL, "go-gitea", "gitea", "issues", "12345")+`" class="ref-issue" rel="nofollow">go-gitea/gitea#12345</a></p>`)
@@ -530,43 +530,31 @@ func TestRender_ShortLinks(t *testing.T) {
530530
}
531531

532532
func TestRender_RelativeImages(t *testing.T) {
533-
setting.AppURL = markup.TestAppURL
534-
535-
test := func(input, expected, expectedWiki string) {
533+
render := func(input string, isWiki bool, links markup.Links) string {
536534
buffer, err := markdown.RenderString(&markup.RenderContext{
537-
Ctx: git.DefaultContext,
538-
Links: markup.Links{
539-
Base: markup.TestRepoURL,
540-
BranchPath: "master",
541-
},
542-
Metas: localMetas,
543-
}, input)
544-
assert.NoError(t, err)
545-
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
546-
buffer, err = markdown.RenderString(&markup.RenderContext{
547-
Ctx: git.DefaultContext,
548-
Links: markup.Links{
549-
Base: markup.TestRepoURL,
550-
},
535+
Ctx: git.DefaultContext,
536+
Links: links,
551537
Metas: localMetas,
552-
IsWiki: true,
538+
IsWiki: isWiki,
553539
}, input)
554540
assert.NoError(t, err)
555-
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
541+
return strings.TrimSpace(string(buffer))
556542
}
557543

558-
rawwiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw")
559-
mediatree := util.URLJoin(markup.TestRepoURL, "media", "master")
544+
out := render(`<img src="LINK">`, false, markup.Links{Base: "/test-owner/test-repo"})
545+
assert.Equal(t, `<a href="/test-owner/test-repo/LINK" target="_blank" rel="nofollow noopener"><img src="/test-owner/test-repo/LINK"/></a>`, out)
560546

561-
test(
562-
`<img src="Link">`,
563-
`<img src="`+util.URLJoin(mediatree, "Link")+`"/>`,
564-
`<img src="`+util.URLJoin(rawwiki, "Link")+`"/>`)
547+
out = render(`<img src="LINK">`, true, markup.Links{Base: "/test-owner/test-repo"})
548+
assert.Equal(t, `<a href="/test-owner/test-repo/wiki/raw/LINK" target="_blank" rel="nofollow noopener"><img src="/test-owner/test-repo/wiki/raw/LINK"/></a>`, out)
565549

566-
test(
567-
`<img src="./icon.png">`,
568-
`<img src="`+util.URLJoin(mediatree, "icon.png")+`"/>`,
569-
`<img src="`+util.URLJoin(rawwiki, "icon.png")+`"/>`)
550+
out = render(`<img src="LINK">`, false, markup.Links{Base: "/test-owner/test-repo", BranchPath: "test-branch"})
551+
assert.Equal(t, `<a href="/test-owner/test-repo/media/test-branch/LINK" target="_blank" rel="nofollow noopener"><img src="/test-owner/test-repo/media/test-branch/LINK"/></a>`, out)
552+
553+
out = render(`<img src="LINK">`, true, markup.Links{Base: "/test-owner/test-repo", BranchPath: "test-branch"})
554+
assert.Equal(t, `<a href="/test-owner/test-repo/wiki/raw/LINK" target="_blank" rel="nofollow noopener"><img src="/test-owner/test-repo/wiki/raw/LINK"/></a>`, out)
555+
556+
out = render(`<img src="/LINK">`, true, markup.Links{Base: "/test-owner/test-repo", BranchPath: "test-branch"})
557+
assert.Equal(t, `<img src="/LINK"/>`, out)
570558
}
571559

572560
func Test_ParseClusterFuzz(t *testing.T) {
@@ -719,5 +707,6 @@ func TestIssue18471(t *testing.T) {
719707
func TestIsFullURL(t *testing.T) {
720708
assert.True(t, markup.IsFullURLString("https://example.com"))
721709
assert.True(t, markup.IsFullURLString("mailto:[email protected]"))
710+
assert.True(t, markup.IsFullURLString("data:image/11111"))
722711
assert.False(t, markup.IsFullURLString("/foo:bar"))
723712
}

modules/markup/markdown/markdown_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -1019,4 +1019,10 @@ func TestAttention(t *testing.T) {
10191019
test(`> [!important]`, renderAttention("important", "octicon-report")+"\n</blockquote>")
10201020
test(`> [!warning]`, renderAttention("warning", "octicon-alert")+"\n</blockquote>")
10211021
test(`> [!caution]`, renderAttention("caution", "octicon-stop")+"\n</blockquote>")
1022+
1023+
// escaped by mdformat
1024+
test(`> \[!NOTE\]`, renderAttention("note", "octicon-info")+"\n</blockquote>")
1025+
1026+
// legacy GitHub style
1027+
test(`> **warning**`, renderAttention("warning", "octicon-alert")+"\n</blockquote>")
10221028
}

modules/markup/markdown/math/block_parser.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,16 @@ func (b *blockParser) Open(parent ast.Node, reader text.Reader, pc parser.Contex
3131
return nil, parser.NoChildren
3232
}
3333

34-
dollars := false
34+
var dollars bool
3535
if b.parseDollars && line[pos] == '$' && line[pos+1] == '$' {
3636
dollars = true
37-
} else if line[pos] != '\\' || line[pos+1] != '[' {
37+
} else if line[pos] == '\\' && line[pos+1] == '[' {
38+
if len(line[pos:]) >= 3 && line[pos+2] == '!' && bytes.Contains(line[pos:], []byte(`\]`)) {
39+
// do not process escaped attention block: "> \[!NOTE\]"
40+
return nil, parser.NoChildren
41+
}
42+
dollars = false
43+
} else {
3844
return nil, parser.NoChildren
3945
}
4046

0 commit comments

Comments
 (0)