Merge pull request '[gitea] week 2024-26 cherry pick (gitea/main -> forgejo)' (#4213) from earl-warren/wcp/2024-26 into forgejo

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/4213
Reviewed-by: twenty-panda <twenty-panda@noreply.codeberg.org>
This commit is contained in:
Earl Warren 2024-06-25 06:15:54 +00:00
commit c6a6294046
24 changed files with 190 additions and 68 deletions

View file

@ -24,3 +24,6 @@ exclude_dir = [
] ]
exclude_regex = ["_test.go$", "_gen.go$"] exclude_regex = ["_test.go$", "_gen.go$"]
stop_on_error = true stop_on_error = true
[log]
main_only = true

View file

@ -210,7 +210,6 @@ code.gitea.io/gitea/modules/json
StdJSON.Indent StdJSON.Indent
code.gitea.io/gitea/modules/markup code.gitea.io/gitea/modules/markup
IsSameDomain
GetRendererByType GetRendererByType
RenderString RenderString
IsMarkupFile IsMarkupFile

View file

@ -3,11 +3,11 @@ FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx
FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/golang:1.22-alpine3.20 as build-env FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/golang:1.22-alpine3.20 as build-env
ARG GOPROXY ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct} ENV GOPROXY=${GOPROXY:-direct}
ARG RELEASE_VERSION ARG RELEASE_VERSION
ARG TAGS="sqlite sqlite_unlock_notify" ARG TAGS="sqlite sqlite_unlock_notify"
ENV TAGS "bindata timetzdata $TAGS" ENV TAGS="bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS ARG CGO_EXTRA_CFLAGS
# #
@ -92,8 +92,8 @@ RUN addgroup \
git && \ git && \
echo "git:*" | chpasswd -e echo "git:*" | chpasswd -e
ENV USER git ENV USER=git
ENV GITEA_CUSTOM /data/gitea ENV GITEA_CUSTOM=/data/gitea
VOLUME ["/data"] VOLUME ["/data"]

View file

@ -3,11 +3,11 @@ FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx
FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/golang:1.22-alpine3.20 as build-env FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/golang:1.22-alpine3.20 as build-env
ARG GOPROXY ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct} ENV GOPROXY=${GOPROXY:-direct}
ARG RELEASE_VERSION ARG RELEASE_VERSION
ARG TAGS="sqlite sqlite_unlock_notify" ARG TAGS="sqlite sqlite_unlock_notify"
ENV TAGS "bindata timetzdata $TAGS" ENV TAGS="bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS ARG CGO_EXTRA_CFLAGS
# #
@ -95,17 +95,17 @@ COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_au
#git:git #git:git
USER 1000:1000 USER 1000:1000
ENV GITEA_WORK_DIR /var/lib/gitea ENV GITEA_WORK_DIR=/var/lib/gitea
ENV GITEA_CUSTOM /var/lib/gitea/custom ENV GITEA_CUSTOM=/var/lib/gitea/custom
ENV GITEA_TEMP /tmp/gitea ENV GITEA_TEMP=/tmp/gitea
ENV TMPDIR /tmp/gitea ENV TMPDIR=/tmp/gitea
# Legacy config file for backwards compatibility # Legacy config file for backwards compatibility
# TODO: remove on next major version release # TODO: remove on next major version release
ENV GITEA_APP_INI_LEGACY /etc/gitea/app.ini ENV GITEA_APP_INI_LEGACY=/etc/gitea/app.ini
ENV GITEA_APP_INI ${GITEA_CUSTOM}/conf/app.ini ENV GITEA_APP_INI=${GITEA_CUSTOM}/conf/app.ini
ENV HOME "/var/lib/gitea/git" ENV HOME="/var/lib/gitea/git"
VOLUME ["/var/lib/gitea", "/etc/gitea"] VOLUME ["/var/lib/gitea", "/etc/gitea"]
WORKDIR /var/lib/gitea WORKDIR /var/lib/gitea

View file

@ -6,6 +6,7 @@ package cache
import ( import (
"fmt" "fmt"
"strconv" "strconv"
"time"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -40,6 +41,37 @@ func Init() error {
return err return err
} }
const (
testCacheKey = "DefaultCache.TestKey"
SlowCacheThreshold = 100 * time.Microsecond
)
func Test() (time.Duration, error) {
if conn == nil {
return 0, fmt.Errorf("default cache not initialized")
}
testData := fmt.Sprintf("%x", make([]byte, 500))
start := time.Now()
if err := conn.Delete(testCacheKey); err != nil {
return 0, fmt.Errorf("expect cache to delete data based on key if exist but got: %w", err)
}
if err := conn.Put(testCacheKey, testData, 10); err != nil {
return 0, fmt.Errorf("expect cache to store data but got: %w", err)
}
testVal := conn.Get(testCacheKey)
if testVal == nil {
return 0, fmt.Errorf("expect cache hit but got none")
}
if testVal != testData {
return 0, fmt.Errorf("expect cache to return same value as stored but got other")
}
return time.Since(start), nil
}
// GetCache returns the currently configured cache // GetCache returns the currently configured cache
func GetCache() mc.Cache { func GetCache() mc.Cache {
return conn return conn

View file

@ -9,6 +9,7 @@ import (
"time" "time"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -34,6 +35,18 @@ func TestNewContext(t *testing.T) {
assert.Nil(t, con) assert.Nil(t, con)
} }
func TestTest(t *testing.T) {
defer test.MockVariableValue(&conn, nil)()
_, err := Test()
assert.Error(t, err)
createTestCache()
elapsed, err := Test()
assert.NoError(t, err)
// mem cache should take from 300ns up to 1ms on modern hardware ...
assert.Less(t, elapsed, SlowCacheThreshold)
}
func TestGetCache(t *testing.T) { func TestGetCache(t *testing.T) {
createTestCache() createTestCache()

View file

@ -143,20 +143,6 @@ func CustomLinkURLSchemes(schemes []string) {
common.LinkRegex, _ = xurls.StrictMatchingScheme(strings.Join(withAuth, "|")) common.LinkRegex, _ = xurls.StrictMatchingScheme(strings.Join(withAuth, "|"))
} }
// IsSameDomain checks if given url string has the same hostname as current Gitea instance
func IsSameDomain(s string) bool {
if strings.HasPrefix(s, "/") {
return true
}
if uapp, err := url.Parse(setting.AppURL); err == nil {
if u, err := url.Parse(s); err == nil {
return u.Host == uapp.Host
}
return false
}
return false
}
type postProcessError struct { type postProcessError struct {
context string context string
err error err error
@ -393,7 +379,7 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
// We ignore code and pre. // We ignore code and pre.
switch node.Type { switch node.Type {
case html.TextNode: case html.TextNode:
textNode(ctx, procs, node) processTextNodes(ctx, procs, node)
case html.ElementNode: case html.ElementNode:
if node.Data == "img" { if node.Data == "img" {
for i, attr := range node.Attr { for i, attr := range node.Attr {
@ -436,15 +422,16 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) {
for n := node.FirstChild; n != nil; n = n.NextSibling { for n := node.FirstChild; n != nil; n = n.NextSibling {
visitNode(ctx, procs, n) visitNode(ctx, procs, n)
} }
default:
} }
// ignore everything else // ignore everything else
} }
// textNode runs the passed node through various processors, in order to handle // processTextNodes runs the passed node through various processors, in order to handle
// all kinds of special links handled by the post-processing. // all kinds of special links handled by the post-processing.
func textNode(ctx *RenderContext, procs []processor, node *html.Node) { func processTextNodes(ctx *RenderContext, procs []processor, node *html.Node) {
for _, processor := range procs { for _, p := range procs {
processor(ctx, node) p(ctx, node)
} }
} }

View file

@ -135,17 +135,6 @@ func TestRender_CrossReferences(t *testing.T) {
`<p><a href="`+urlWithQuery+`" rel="nofollow"><code>`+sha[:10]+`/README.md (L1-L5)</code></a></p>`) `<p><a href="`+urlWithQuery+`" rel="nofollow"><code>`+sha[:10]+`/README.md (L1-L5)</code></a></p>`)
} }
func TestMisc_IsSameDomain(t *testing.T) {
setting.AppURL = markup.TestAppURL
sha := "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
commit := util.URLJoin(markup.TestRepoURL, "commit", sha)
assert.True(t, markup.IsSameDomain(commit))
assert.False(t, markup.IsSameDomain("http://google.com/ncr"))
assert.False(t, markup.IsSameDomain("favicon.ico"))
}
func TestRender_links(t *testing.T) { func TestRender_links(t *testing.T) {
setting.AppURL = markup.TestAppURL setting.AppURL = markup.TestAppURL

View file

@ -548,6 +548,10 @@ func TestMathBlock(t *testing.T) {
`$$a`, `$$a`,
`<p>$$a</p>` + nl, `<p>$$a</p>` + nl,
}, },
{
"$a$ ($b$) [$c$] {$d$}",
`<p><code class="language-math is-loading">a</code> (<code class="language-math is-loading">b</code>) [$c$] {$d$}</p>` + nl,
},
} }
for _, test := range testcases { for _, test := range testcases {

View file

@ -45,6 +45,10 @@ func isPunctuation(b byte) bool {
return b == '.' || b == '!' || b == '?' || b == ',' || b == ';' || b == ':' return b == '.' || b == '!' || b == '?' || b == ',' || b == ';' || b == ':'
} }
func isBracket(b byte) bool {
return b == ')'
}
func isAlphanumeric(b byte) bool { func isAlphanumeric(b byte) bool {
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9') return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9')
} }
@ -84,7 +88,7 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser.
break break
} }
suceedingCharacter := line[pos] suceedingCharacter := line[pos]
if !isPunctuation(suceedingCharacter) && !(suceedingCharacter == ' ') { if !isPunctuation(suceedingCharacter) && !(suceedingCharacter == ' ') && !isBracket(suceedingCharacter) {
return nil return nil
} }
if line[ender-1] != '\\' { if line[ender-1] != '\\' {

View file

@ -24,7 +24,7 @@ type Team struct {
// CreateTeamOption options for creating a team // CreateTeamOption options for creating a team
type CreateTeamOption struct { type CreateTeamOption struct {
// required: true // required: true
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"` Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(255)"`
Description string `json:"description" binding:"MaxSize(255)"` Description string `json:"description" binding:"MaxSize(255)"`
IncludesAllRepositories bool `json:"includes_all_repositories"` IncludesAllRepositories bool `json:"includes_all_repositories"`
// enum: read,write,admin // enum: read,write,admin
@ -40,7 +40,7 @@ type CreateTeamOption struct {
// EditTeamOption options for editing a team // EditTeamOption options for editing a team
type EditTeamOption struct { type EditTeamOption struct {
// required: true // required: true
Name string `json:"name" binding:"AlphaDashDot;MaxSize(30)"` Name string `json:"name" binding:"AlphaDashDot;MaxSize(255)"`
Description *string `json:"description" binding:"MaxSize(255)"` Description *string `json:"description" binding:"MaxSize(255)"`
IncludesAllRepositories *bool `json:"includes_all_repositories"` IncludesAllRepositories *bool `json:"includes_all_repositories"`
// enum: read,write,admin // enum: read,write,admin

47
options/gitignore/IAR Normal file
View file

@ -0,0 +1,47 @@
# Compiled binaries
*.o
*.bin
*.elf
*.hex
*.map
*.out
*.obj
# Trash
*.bak
thumbs.db
*.~*
# IAR Settings
**/settings/*.crun
**/settings/*.dbgdt
**/settings/*.cspy
**/settings/*.cspy.*
**/settings/*.xcl
**/settings/*.dni
**/settings/*.wsdt
**/settings/*.wspos
# IAR Debug Exe
**/Exe/*.sim
# IAR Debug Obj
**/Obj/*.pbd
**/Obj/*.pbd.*
**/Obj/*.pbi
**/Obj/*.pbi.*
# IAR project "Debug" directory
Debug/
# IAR project "Release" directory
Release/
# IAR project settings directory
settings/
# IAR backup files
Backup*
# IAR .dep files
*.dep

View file

@ -42,10 +42,3 @@ fastlane/report.xml
fastlane/Preview.html fastlane/Preview.html
fastlane/screenshots/**/*.png fastlane/screenshots/**/*.png
fastlane/test_output fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/

View file

@ -35,6 +35,3 @@ override.tf.json
# Ignore CLI configuration files # Ignore CLI configuration files
.terraformrc .terraformrc
terraform.rc terraform.rc
# Ignore hcl file
.terraform.lock.hcl

View file

@ -93,6 +93,7 @@ remove_all = Remove all
remove_label_str = Remove item "%s" remove_label_str = Remove item "%s"
edit = Edit edit = Edit
view = View view = View
test = Test
enabled = Enabled enabled = Enabled
disabled = Disabled disabled = Disabled
@ -3322,6 +3323,11 @@ config.cache_interval = Cache interval
config.cache_conn = Cache connection config.cache_conn = Cache connection
config.cache_item_ttl = Cache item TTL config.cache_item_ttl = Cache item TTL
config.cache_test = Test Cache
config.cache_test_failed = Failed to probe the cache: %v.
config.cache_test_slow = Cache test successful, but response is slow: %s.
config.cache_test_succeeded = Cache test successful, got a response in %s.
config.session_config = Session configuration config.session_config = Session configuration
config.session_provider = Session provider config.session_provider = Session provider
config.provider_config = Provider config config.provider_config = Provider config

View file

@ -14,6 +14,7 @@ import (
activities_model "code.gitea.io/gitea/models/activities" activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -211,6 +212,14 @@ func SelfCheck(ctx *context.Context) {
ctx.Data["DatabaseCheckHasProblems"] = hasProblem ctx.Data["DatabaseCheckHasProblems"] = hasProblem
} }
elapsed, err := cache.Test()
if err != nil {
ctx.Data["CacheError"] = err
} else if elapsed > cache.SlowCacheThreshold {
ctx.Data["CacheSlow"] = fmt.Sprint(elapsed)
}
ctx.HTML(http.StatusOK, tplSelfCheck) ctx.HTML(http.StatusOK, tplSelfCheck)
} }

View file

@ -12,6 +12,7 @@ import (
system_model "code.gitea.io/gitea/models/system" system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -42,6 +43,22 @@ func SendTestMail(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/admin/config") ctx.Redirect(setting.AppSubURL + "/admin/config")
} }
// TestCache test the cache settings
func TestCache(ctx *context.Context) {
elapsed, err := cache.Test()
if err != nil {
ctx.Flash.Error(ctx.Tr("admin.config.cache_test_failed", err))
} else {
if elapsed > cache.SlowCacheThreshold {
ctx.Flash.Warning(ctx.Tr("admin.config.cache_test_slow", elapsed))
} else {
ctx.Flash.Info(ctx.Tr("admin.config.cache_test_succeeded", elapsed))
}
}
ctx.Redirect(setting.AppSubURL + "/admin/config")
}
func shadowPasswordKV(cfgItem, splitter string) string { func shadowPasswordKV(cfgItem, splitter string) string {
fields := strings.Split(cfgItem, splitter) fields := strings.Split(cfgItem, splitter)
for i := 0; i < len(fields); i++ { for i := 0; i < len(fields); i++ {

View file

@ -665,6 +665,7 @@ func registerRoutes(m *web.Route) {
m.Get("", admin.Config) m.Get("", admin.Config)
m.Post("", admin.ChangeConfig) m.Post("", admin.ChangeConfig)
m.Post("/test_mail", admin.SendTestMail) m.Post("/test_mail", admin.SendTestMail)
m.Post("/test_cache", admin.TestCache)
m.Get("/settings", admin.ConfigSettings) m.Get("/settings", admin.ConfigSettings)
}) })

View file

@ -5,6 +5,7 @@ package externalaccount
import ( import (
"context" "context"
"strconv"
"strings" "strings"
"code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/auth"
@ -82,6 +83,11 @@ func UpdateExternalUser(ctx context.Context, user *user_model.User, gothUser got
// UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID // UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID
func UpdateMigrationsByType(ctx context.Context, tp structs.GitServiceType, externalUserID string, userID int64) error { func UpdateMigrationsByType(ctx context.Context, tp structs.GitServiceType, externalUserID string, userID int64) error {
// Skip update if externalUserID is not a valid numeric ID or exceeds int64
if _, err := strconv.ParseInt(externalUserID, 10, 64); err != nil {
return nil
}
if err := issues_model.UpdateIssuesMigrationsByType(ctx, tp, externalUserID, userID); err != nil { if err := issues_model.UpdateIssuesMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
return err return err
} }

View file

@ -233,8 +233,8 @@
<dt>{{ctx.Locale.Tr "admin.config.mailer_user"}}</dt> <dt>{{ctx.Locale.Tr "admin.config.mailer_user"}}</dt>
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd> <dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd>
<div class="divider"></div> <div class="divider"></div>
<dt class="tw-py-1">{{ctx.Locale.Tr "admin.config.send_test_mail"}}</dt> <dt class="tw-py-1 tw-flex tw-items-center">{{ctx.Locale.Tr "admin.config.send_test_mail"}}</dt>
<dd> <dd class="tw-py-0">
<form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_mail" method="post"> <form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_mail" method="post">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<div class="ui tiny input"> <div class="ui tiny input">
@ -264,6 +264,14 @@
<dt>{{ctx.Locale.Tr "admin.config.cache_item_ttl"}}</dt> <dt>{{ctx.Locale.Tr "admin.config.cache_item_ttl"}}</dt>
<dd><code>{{.CacheItemTTL}}</code></dd> <dd><code>{{.CacheItemTTL}}</code></dd>
{{end}} {{end}}
<div class="divider"></div>
<dt class="tw-py-1 tw-flex tw-items-center">{{ctx.Locale.Tr "admin.config.cache_test"}}</dt>
<dd class="tw-py-0">
<form class="ui form ignore-dirty" action="{{AppSubUrl}}/admin/config/test_cache" method="post">
{{.CsrfTokenHtml}}
<button class="ui tiny primary button">{{ctx.Locale.Tr "test"}}</button>
</form>
</dd>
</dl> </dl>
</div> </div>

View file

@ -28,6 +28,13 @@
{{else}} {{else}}
<div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.no_problem_found"}}</div> <div class="tw-p-2">{{ctx.Locale.Tr "admin.self_check.no_problem_found"}}</div>
{{end}} {{end}}
{{if .CacheError}}
<div class="ui red message">{{ctx.Locale.Tr "admin.config.cache_test_failed" .CacheError}}</div>
{{end}}
{{if .CacheSlow}}
<div class="ui warning message">{{ctx.Locale.Tr "admin.config.cache_test_slow" .CacheSlow}}</div>
{{end}}
</div> </div>
</div> </div>

View file

@ -2,7 +2,7 @@
{{$revsFileLink := URLJoin .RepoLink "src" .BranchNameSubURL "/.git-blame-ignore-revs"}} {{$revsFileLink := URLJoin .RepoLink "src" .BranchNameSubURL "/.git-blame-ignore-revs"}}
{{if .UsesIgnoreRevs}} {{if .UsesIgnoreRevs}}
<div class="ui info message"> <div class="ui info message">
<p>{{ctx.Locale.Tr "repo.blame.ignore_revs" $revsFileLink (print $revsFileLink "?bypass-blame-ignore=true")}}</p> <p>{{ctx.Locale.Tr "repo.blame.ignore_revs" $revsFileLink "?bypass-blame-ignore=true"}}</p>
</div> </div>
{{else}} {{else}}
<div class="ui error message"> <div class="ui error message">

View file

@ -51,17 +51,17 @@
<td colspan="2" class="lines-num"> <td colspan="2" class="lines-num">
<div class="tw-flex"> <div class="tw-flex">
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}} {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}}
<button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?data-query={{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}"> <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=down&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
{{svg "octicon-fold-down"}} {{svg "octicon-fold-down"}}
</button> </button>
{{end}} {{end}}
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4)}} {{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4)}}
<button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?data-query={{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}"> <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=up&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
{{svg "octicon-fold-up"}} {{svg "octicon-fold-up"}}
</button> </button>
{{end}} {{end}}
{{if eq $line.GetExpandDirection 2}} {{if eq $line.GetExpandDirection 2}}
<button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?data-query={{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}"> <button class="code-expander-button" hx-target="closest tr" hx-get="{{$.RepoLink}}/blob_excerpt/{{PathEscape $.AfterCommitID}}?{{$line.GetBlobExcerptQuery}}&style=unified&direction=&wiki={{$.PageIsWiki}}&anchor={{$.Anchor}}">
{{svg "octicon-fold"}} {{svg "octicon-fold"}}
</button> </button>
{{end}} {{end}}

View file

@ -79,6 +79,11 @@
white-space: nowrap; white-space: nowrap;
} }
.repository .issue-content-right .filter.menu {
max-height: 500px;
overflow-x: auto;
}
.repository .filter.menu.labels .label-filter .menu .info { .repository .filter.menu.labels .label-filter .menu .info {
display: inline-block; display: inline-block;
padding: 0.5rem 0; padding: 0.5rem 0;
@ -581,11 +586,6 @@ td .commit-summary {
font-size: 14px; font-size: 14px;
} }
.repository.new.issue .comment.form .issue-content-right .filter.menu {
max-height: 500px;
overflow-x: auto;
}
.repository.view.issue .instruct-toggle { .repository.view.issue .instruct-toggle {
display: inline-block; display: inline-block;
} }