mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-08-20 09:21:11 +00:00
Merge remote-tracking branch 'origin/forgejo' into fix-context-timeout
This commit is contained in:
commit
e736b6a571
19 changed files with 114 additions and 72 deletions
|
@ -168,6 +168,6 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
|
|||
|
||||
// warn if the setting is set to false explicitly
|
||||
if sectionHasDisableQueryAuthToken && !DisableQueryAuthToken {
|
||||
log.Warn("Enabling Query API Auth tokens is not recommended. DISABLE_QUERY_AUTH_TOKEN will default to true in gitea 1.23 and will be removed in gitea 1.24.")
|
||||
log.Warn("Enabling Query API Auth tokens is not recommended. DISABLE_QUERY_AUTH_TOKEN will be removed in Forgejo v13.0.0.")
|
||||
}
|
||||
}
|
||||
|
|
23
modules/templates/context.go
Normal file
23
modules/templates/context.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package templates
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"forgejo.org/modules/translation"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
context.Context
|
||||
Locale translation.Locale
|
||||
AvatarUtils *AvatarUtils
|
||||
Data map[string]any
|
||||
}
|
||||
|
||||
var _ context.Context = Context{}
|
||||
|
||||
func NewContext(ctx context.Context) *Context {
|
||||
return &Context{Context: ctx}
|
||||
}
|
18
modules/templates/context_test.go
Normal file
18
modules/templates/context_test.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
package templates
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestContext(t *testing.T) {
|
||||
type ctxKey struct{}
|
||||
|
||||
// Test that the original context is used for its context functions.
|
||||
ctx := NewContext(context.WithValue(t.Context(), ctxKey{}, "there"))
|
||||
assert.Equal(t, "there", ctx.Value(ctxKey{}))
|
||||
}
|
|
@ -22,7 +22,6 @@ import (
|
|||
"forgejo.org/modules/markup"
|
||||
"forgejo.org/modules/markup/markdown"
|
||||
"forgejo.org/modules/setting"
|
||||
"forgejo.org/modules/translation"
|
||||
"forgejo.org/modules/util"
|
||||
)
|
||||
|
||||
|
@ -145,7 +144,7 @@ func RenderRefIssueTitle(ctx context.Context, text string) template.HTML {
|
|||
|
||||
// RenderLabel renders a label
|
||||
// locale is needed due to an import cycle with our context providing the `Tr` function
|
||||
func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_model.Label) template.HTML {
|
||||
func RenderLabel(ctx *Context, label *issues_model.Label) template.HTML {
|
||||
var (
|
||||
archivedCSSClass string
|
||||
textColor = util.ContrastColor(label.Color)
|
||||
|
@ -156,7 +155,7 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m
|
|||
|
||||
if label.IsArchived() {
|
||||
archivedCSSClass = "archived-label"
|
||||
description = locale.TrString("repo.issues.archived_label_description", description)
|
||||
description = ctx.Locale.TrString("repo.issues.archived_label_description", description)
|
||||
}
|
||||
|
||||
if labelScope == "" {
|
||||
|
@ -246,7 +245,7 @@ func RenderMarkdownToHtml(ctx context.Context, input string) template.HTML { //n
|
|||
return output
|
||||
}
|
||||
|
||||
func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issues_model.Label, repoLink string, isPull bool) template.HTML {
|
||||
func RenderLabels(ctx *Context, labels []*issues_model.Label, repoLink string, isPull bool) template.HTML {
|
||||
htmlCode := `<span class="labels-list">`
|
||||
for _, label := range labels {
|
||||
// Protect against nil value in labels - shouldn't happen but would cause a panic if so
|
||||
|
@ -259,7 +258,7 @@ func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issu
|
|||
issuesOrPull = "pulls"
|
||||
}
|
||||
htmlCode += fmt.Sprintf("<a href='%s/%s?labels=%d' rel='nofollow'>%s</a> ",
|
||||
repoLink, issuesOrPull, label.ID, RenderLabel(ctx, locale, label))
|
||||
repoLink, issuesOrPull, label.ID, RenderLabel(ctx, label))
|
||||
}
|
||||
htmlCode += "</span>"
|
||||
return template.HTML(htmlCode)
|
||||
|
|
|
@ -223,23 +223,26 @@ func TestRenderLabels(t *testing.T) {
|
|||
labelMalicious := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 11})
|
||||
labelArchived := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 12})
|
||||
|
||||
rendered := RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", false)
|
||||
ctx := NewContext(t.Context())
|
||||
ctx.Locale = tr
|
||||
|
||||
rendered := RenderLabels(ctx, []*issues_model.Label{label}, "user2/repo1", false)
|
||||
assert.Contains(t, rendered, "user2/repo1/issues?labels=1")
|
||||
assert.Contains(t, rendered, ">label1<")
|
||||
assert.Contains(t, rendered, "title='First label'")
|
||||
rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{label}, "user2/repo1", true)
|
||||
rendered = RenderLabels(ctx, []*issues_model.Label{label}, "user2/repo1", true)
|
||||
assert.Contains(t, rendered, "user2/repo1/pulls?labels=1")
|
||||
assert.Contains(t, rendered, ">label1<")
|
||||
rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelScoped}, "user2/repo1", false)
|
||||
rendered = RenderLabels(ctx, []*issues_model.Label{labelScoped}, "user2/repo1", false)
|
||||
assert.Contains(t, rendered, "user2/repo1/issues?labels=7")
|
||||
assert.Contains(t, rendered, ">scope<")
|
||||
assert.Contains(t, rendered, ">label1<")
|
||||
rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelMalicious}, "user2/repo1", false)
|
||||
rendered = RenderLabels(ctx, []*issues_model.Label{labelMalicious}, "user2/repo1", false)
|
||||
assert.Contains(t, rendered, "user2/repo1/issues?labels=11")
|
||||
assert.Contains(t, rendered, "> <script>malicious</script> <")
|
||||
assert.Contains(t, rendered, ">'?&<")
|
||||
assert.Contains(t, rendered, "title='Malicious label ' <script>malicious</script>'")
|
||||
rendered = RenderLabels(db.DefaultContext, tr, []*issues_model.Label{labelArchived}, "user2/repo1", false)
|
||||
rendered = RenderLabels(ctx, []*issues_model.Label{labelArchived}, "user2/repo1", false)
|
||||
assert.Contains(t, rendered, "user2/repo1/issues?labels=12")
|
||||
assert.Contains(t, rendered, ">archived label<><")
|
||||
assert.Contains(t, rendered, "title='repo.issues.archived_label_description'")
|
||||
|
|
24
release-notes-published/12.0.1.md
Normal file
24
release-notes-published/12.0.1.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
Insecure authentication methods have been deprecated since 2023. They were [removed in v12.0.0](https://codeberg.org/forgejo/forgejo/pulls/7924) but they were [restored in v12.0.1](https://codeberg.org/forgejo/forgejo/pulls/8653). Certain OAuth2 clients and packages in the Forgejo ecosystem still rely on these methods and it was premature to remove them.
|
||||
|
||||
<!--start release-notes-assistant-->
|
||||
|
||||
## Release notes
|
||||
<!--URL:https://codeberg.org/forgejo/forgejo-->
|
||||
- User Interface bug fixes
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8575) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8576)): <!--number 8576 --><!--line 0 --><!--description Zml4OiBhbGxvdyBmb3IgdHJhY2tlZCB0aW1lIHRvIGJlIHJlbW92ZWQgYWdhaW4=-->allow for tracked time to be removed again<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8565) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8574)): <!--number 8574 --><!--line 0 --><!--description Zml4OiBjb3JyZWN0IGltYWdlIHNvdXJjZSBmb3IgcXVvdGVkIHJlcGx5-->correct image source for quoted reply<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8553) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8555)): <!--number 8555 --><!--line 0 --><!--description Zml4KHVpKTogcHJldmVudCByZW5kZXIgZmFpbHVyZSBvbiBmYXVsdHkgb3JnIHNldHRpbmdzIHBvc3Q=-->prevent render failure on faulty org settings post<!--description-->
|
||||
- Bug fixes
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8633) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8653)): <!--number 8653 --><!--line 0 --><!--description UmV2ZXJ0ICJmZWF0OiByZW1vdmUgQVBJIGF1dGhlbnRpY2F0aW9uIG1ldGhvZHMgdGhhdCB1c2VzIHRoZSBVUkwgcXVlcnkgKCM3OTI0KSI=-->Revert "feat: remove API authentication methods that uses the URL query (#7924)"<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8644) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8646)): <!--number 8646 --><!--line 0 --><!--description Zml4KHVpKTogdXBkYXRlIGkxOG4gdXNhZ2UgaW4gY29tbWVudHM=-->update i18n usage in comments<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8609) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8613)): <!--number 8613 --><!--line 0 --><!--description Zml4OiB1cGdyYWRlIGZhaWxzIG9yIGhhbmcgYXQgbWlncmF0aW9uWzMxXTogTWlncmF0ZSBtYXZlbiBwYWNrYWdlIG5hbWUgY29uY2F0ZW5hdGlvbg==-->upgrade fails or hang at migration[31]: Migrate maven package name concatenation<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8622) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8624)): <!--number 8624 --><!--line 0 --><!--description Zml4OiByZWJhc2UgYW5kIGZhc3QgZm9yd2FyZCBtZXJnZSBicmVha3MgY29tbWl0IHNpZ25hdHVyZXM=-->rebase and fast forward merge breaks commit signatures<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8617) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8618)): <!--number 8618 --><!--line 0 --><!--description Zml4OiBtYWtlIHRoZSBhY3Rpb24gZmVlZCByZXNpbGllbnQgdG8gZGF0YWJhc2UgaW5jb25zaXN0ZW5jaWVz-->make the action feed resilient to database inconsistencies<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8533) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8584)): <!--number 8584 --><!--line 0 --><!--description Zml4OiBtYWtlIHN1cmUgdG8gdXNlIHVuYWx0ZXJlZCBmaWVsZHMgd2hlbiBzYXZpbmcgYSBzaGFkb3cgY29weSBmb3IgdXBkYXRlZCBwcm9maWxlcyBvciBjb21tZW50cw==-->make sure to use unaltered fields when saving a shadow copy for updated profiles or comments<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8596) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8610)): <!--number 8610 --><!--line 0 --><!--description Zml4OiBmb2xsb3cgc3ltbGlua3MgZm9yIGxvY2FsIGFzc2V0cw==-->follow symlinks for local assets<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8550) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8552)): <!--number 8552 --><!--line 0 --><!--description Zml4OiB1c2UgY29ycmVjdCBBQ01FIGRlZmF1bHQ=-->use correct ACME default<!--description-->
|
||||
- Included for completeness but not user-facing (chores, etc.)
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8638) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8641)): <!--number 8641 --><!--line 0 --><!--description UmV2ZXJ0ICJmaXgoY2kpOiBwdWxsIHN0eWx1cyBmcm9tIGdpdGh1YjpzdHlsdXMvc3R5bHVzIzAuNTcuMCAoIzg2MjUpIg==-->Revert "fix(ci): pull stylus from github:stylus/stylus#0.57.0 (#8625)"<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8625) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8627)): <!--number 8627 --><!--line 0 --><!--description Zml4KGNpKTogcHVsbCBzdHlsdXMgZnJvbSBnaXRodWI6c3R5bHVzL3N0eWx1cyMwLjU3LjA=-->fix(ci): pull stylus from github:stylus/stylus#0.57.0<!--description-->
|
||||
- [PR](https://codeberg.org/forgejo/forgejo/pulls/8611) ([backported](https://codeberg.org/forgejo/forgejo/pulls/8616)): <!--number 8616 --><!--line 0 --><!--description Y2hvcmU6IGRpc2FibGUgRTJFIHRlc3QgZm9yIHdlYmtpdA==-->chore: disable E2E test for webkit<!--description-->
|
||||
<!--end release-notes-assistant-->
|
|
@ -130,7 +130,7 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.APIC
|
|||
// check for and warn against deprecated authentication options
|
||||
func checkDeprecatedAuthMethods(ctx *context.APIContext) {
|
||||
if ctx.FormString("token") != "" || ctx.FormString("access_token") != "" {
|
||||
ctx.Resp.Header().Set("Warning", "token and access_token API authentication is deprecated and will be removed in gitea 1.23. Please use AuthorizationHeaderToken instead. Existing queries will continue to work but without authorization.")
|
||||
ctx.Resp.Header().Set("Warning", "token and access_token API authentication is deprecated and will be removed in Forgejo v13.0.0. Please use AuthorizationHeaderToken instead. Existing queries will continue to work but without authorization.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"forgejo.org/modules/templates"
|
||||
"forgejo.org/modules/web/middleware"
|
||||
"forgejo.org/modules/web/routing"
|
||||
"forgejo.org/services/context"
|
||||
)
|
||||
|
||||
const tplStatus500 base.TplName = "status/500"
|
||||
|
@ -36,8 +35,8 @@ func RenderPanicErrorPage(w http.ResponseWriter, req *http.Request, err any) {
|
|||
httpcache.SetCacheControlInHeader(w.Header(), 0, "no-transform")
|
||||
w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
||||
|
||||
tmplCtx := context.TemplateContext{}
|
||||
tmplCtx["Locale"] = middleware.Locale(w, req)
|
||||
tmplCtx := templates.NewContext(req.Context())
|
||||
tmplCtx.Locale = middleware.Locale(w, req)
|
||||
ctxData := middleware.GetContextData(req.Context())
|
||||
|
||||
// This recovery handler could be called without Gitea's web context, so we shouldn't touch that context too much.
|
||||
|
|
|
@ -41,7 +41,7 @@ type Render interface {
|
|||
type Context struct {
|
||||
*Base
|
||||
|
||||
TemplateContext TemplateContext
|
||||
TemplateContext *templates.Context
|
||||
|
||||
Render Render
|
||||
PageData map[string]any // data used by JavaScript modules in one page, it's `window.config.pageData`
|
||||
|
@ -64,8 +64,6 @@ type Context struct {
|
|||
Package *Package
|
||||
}
|
||||
|
||||
type TemplateContext map[string]any
|
||||
|
||||
func init() {
|
||||
web.RegisterResponseStatusProvider[*Context](func(req *http.Request) web_types.ResponseStatusProvider {
|
||||
return req.Context().Value(WebContextKey).(*Context)
|
||||
|
@ -98,10 +96,11 @@ func GetValidateContext(req *http.Request) (ctx *ValidateContext) {
|
|||
return ctx
|
||||
}
|
||||
|
||||
func NewTemplateContextForWeb(ctx *Context) TemplateContext {
|
||||
tmplCtx := NewTemplateContext(ctx)
|
||||
tmplCtx["Locale"] = ctx.Locale
|
||||
tmplCtx["AvatarUtils"] = templates.NewAvatarUtils(ctx)
|
||||
func NewTemplateContextForWeb(ctx *Context) *templates.Context {
|
||||
tmplCtx := templates.NewContext(ctx)
|
||||
tmplCtx.Locale = ctx.Locale
|
||||
tmplCtx.AvatarUtils = templates.NewAvatarUtils(ctx)
|
||||
tmplCtx.Data = ctx.Data
|
||||
return tmplCtx
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ context.Context = TemplateContext(nil)
|
||||
|
||||
func NewTemplateContext(ctx context.Context) TemplateContext {
|
||||
return TemplateContext{"_ctx": ctx}
|
||||
}
|
||||
|
||||
func (c TemplateContext) parentContext() context.Context {
|
||||
return c["_ctx"].(context.Context)
|
||||
}
|
||||
|
||||
func (c TemplateContext) Deadline() (deadline time.Time, ok bool) {
|
||||
return c.parentContext().Deadline()
|
||||
}
|
||||
|
||||
func (c TemplateContext) Done() <-chan struct{} {
|
||||
return c.parentContext().Done()
|
||||
}
|
||||
|
||||
func (c TemplateContext) Err() error {
|
||||
return c.parentContext().Err()
|
||||
}
|
||||
|
||||
func (c TemplateContext) Value(key any) any {
|
||||
return c.parentContext().Value(key)
|
||||
}
|
|
@ -65,7 +65,7 @@
|
|||
<div class="issue-card-bottom">
|
||||
<div class="labels-list">
|
||||
{{range .Labels}}
|
||||
<a target="_blank" href="{{$.Issue.Repo.Link}}/issues?labels={{.ID}}">{{RenderLabel ctx ctx.Locale .}}</a>
|
||||
<a target="_blank" href="{{$.Issue.Repo.Link}}/issues?labels={{.ID}}">{{RenderLabel ctx .}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="issue-card-assignees">
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
{{end}}
|
||||
{{$previousExclusiveScope = $exclusiveScope}}
|
||||
<div class="item issue-action tw-flex tw-justify-between" data-action="toggle" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/labels">
|
||||
{{if SliceUtils.Contains $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel $.Context ctx.Locale .}}
|
||||
{{if SliceUtils.Contains $.SelLabelIDs .ID}}{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}{{end}} {{RenderLabel ctx .}}
|
||||
{{template "repo/issue/labels/label_archived" .}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -4,5 +4,5 @@
|
|||
href="{{.root.RepoLink}}/{{if or .root.IsPull .root.Issue.IsPull}}pulls{{else}}issues{{end}}?labels={{.label.ID}}"{{/* FIXME: use .root.Issue.Link or create .root.Link */}}
|
||||
rel="nofollow"
|
||||
>
|
||||
{{- RenderLabel $.Context ctx.Locale .label -}}
|
||||
{{- RenderLabel ctx .label -}}
|
||||
</a>
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
{{range .Labels}}
|
||||
<li class="item">
|
||||
<div class="label-title">
|
||||
{{RenderLabel $.Context ctx.Locale .}}
|
||||
{{RenderLabel ctx .}}
|
||||
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
|
||||
</div>
|
||||
<div class="label-issues">
|
||||
|
@ -72,7 +72,7 @@
|
|||
{{range .OrgLabels}}
|
||||
<li class="item org-label">
|
||||
<div class="label-title">
|
||||
{{RenderLabel $.Context ctx.Locale .}}
|
||||
{{RenderLabel ctx .}}
|
||||
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
|
||||
</div>
|
||||
<div class="label-issues">
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<div class="divider"></div>
|
||||
{{end}}
|
||||
{{$previousExclusiveScope = $exclusiveScope}}
|
||||
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span> {{RenderLabel $.Context ctx.Locale .}}
|
||||
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span> {{RenderLabel ctx .}}
|
||||
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
|
||||
<p class="archived-label-hint">{{template "repo/issue/labels/label_archived" .}}</p>
|
||||
</a>
|
||||
|
@ -34,7 +34,7 @@
|
|||
<div class="divider"></div>
|
||||
{{end}}
|
||||
{{$previousExclusiveScope = $exclusiveScope}}
|
||||
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span> {{RenderLabel $.Context ctx.Locale .}}
|
||||
<a class="{{if .IsChecked}}checked{{end}} item" href="#" data-id="{{.ID}}" {{if .IsArchived}}data-is-archived{{end}} data-id-selector="#label_{{.ID}}" data-scope="{{$exclusiveScope}}"><span class="octicon-check {{if not .IsChecked}}tw-invisible{{end}}">{{if $exclusiveScope}}{{svg "octicon-dot-fill"}}{{else}}{{svg "octicon-check"}}{{end}}</span> {{RenderLabel ctx .}}
|
||||
{{if .Description}}<br><small class="desc">{{.Description | RenderEmoji $.Context}}</small>{{end}}
|
||||
<p class="archived-label-hint">{{template "repo/issue/labels/label_archived" .}}</p>
|
||||
</a>
|
||||
|
|
|
@ -176,11 +176,11 @@
|
|||
<span class="text grey muted-links">
|
||||
{{template "shared/user/authorlink" .Poster}}
|
||||
{{if and .AddedLabels (not .RemovedLabels)}}
|
||||
{{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink .Issue.IsPull) $createdStr}}
|
||||
{{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels ctx .AddedLabels $.RepoLink .Issue.IsPull) $createdStr}}
|
||||
{{else if and (not .AddedLabels) .RemovedLabels}}
|
||||
{{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink .Issue.IsPull) $createdStr}}
|
||||
{{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels ctx .RemovedLabels $.RepoLink .Issue.IsPull) $createdStr}}
|
||||
{{else}}
|
||||
{{ctx.Locale.Tr "repo.issues.add_remove_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink .Issue.IsPull) (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink .Issue.IsPull) $createdStr}}
|
||||
{{ctx.Locale.Tr "repo.issues.add_remove_labels" (RenderLabels ctx .AddedLabels $.RepoLink .Issue.IsPull) (RenderLabels ctx .RemovedLabels $.RepoLink .Issue.IsPull) $createdStr}}
|
||||
{{end}}
|
||||
</span>
|
||||
</div>
|
||||
|
@ -742,11 +742,11 @@
|
|||
<li>
|
||||
<span class="badge">{{svg "octicon-tag" 20}}</span>
|
||||
{{if and .AddedLabels (not .RemovedLabels)}}
|
||||
{{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink .Issue.IsPull) ""}}
|
||||
{{ctx.Locale.TrN (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels" (RenderLabels ctx .AddedLabels $.RepoLink .Issue.IsPull) ""}}
|
||||
{{else if and (not .AddedLabels) .RemovedLabels}}
|
||||
{{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink .Issue.IsPull) ""}}
|
||||
{{ctx.Locale.TrN (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels" (RenderLabels ctx .RemovedLabels $.RepoLink .Issue.IsPull) ""}}
|
||||
{{else}}
|
||||
{{ctx.Locale.Tr "repo.issues.add_remove_labels" (RenderLabels $.Context ctx.Locale .AddedLabels $.RepoLink .Issue.IsPull) (RenderLabels $.Context ctx.Locale .RemovedLabels $.RepoLink .Issue.IsPull) ""}}
|
||||
{{ctx.Locale.Tr "repo.issues.add_remove_labels" (RenderLabels ctx .AddedLabels $.RepoLink .Issue.IsPull) (RenderLabels ctx .RemovedLabels $.RepoLink .Issue.IsPull) ""}}
|
||||
{{end}}
|
||||
</li>
|
||||
{{end}}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
{{end}}
|
||||
<span class="labels-list tw-ml-1">
|
||||
{{range .Labels}}
|
||||
<a href="?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}{{if ne $.listType "milestone"}}&milestone={{$.MilestoneID}}{{end}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}" rel="nofollow">{{RenderLabel $.Context ctx.Locale .}}</a>
|
||||
<a href="?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}{{if ne $.listType "milestone"}}&milestone={{$.MilestoneID}}{{end}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}" rel="nofollow">{{RenderLabel ctx .}}</a>
|
||||
{{end}}
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
{{svg "octicon-check"}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{RenderLabel $.Context ctx.Locale .}}
|
||||
{{RenderLabel ctx .}}
|
||||
<p class="tw-ml-auto">{{template "repo/issue/labels/label_archived" .}}</p>
|
||||
</a>
|
||||
{{end}}
|
||||
|
|
|
@ -1524,3 +1524,15 @@ func TestIssuePostersSearch(t *testing.T) {
|
|||
assert.EqualValues(t, 1, data.Results[0].UserID)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIssueTimelineLabels(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
req := NewRequest(t, "GET", "/user2/repo1/issues/1")
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
assert.NotContains(t, resp.Body.String(), `status-page-500`)
|
||||
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
filterLinks := htmlDoc.Find(".timeline .labels-list a")
|
||||
assert.Equal(t, 9, filterLinks.Length())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue