Skip to content

Commit b1ad9e7

Browse files
authored
Merge branch 'main' into refactor-packages
2 parents 900f1b7 + f114c38 commit b1ad9e7

File tree

124 files changed

+1509
-2231
lines changed

Some content is hidden

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

124 files changed

+1509
-2231
lines changed

models/git/lfs.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ type LFSMetaObject struct {
112112
ID int64 `xorm:"pk autoincr"`
113113
lfs.Pointer `xorm:"extends"`
114114
RepositoryID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
115-
Existing bool `xorm:"-"`
116115
CreatedUnix timeutil.TimeStamp `xorm:"created"`
117116
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
118117
}
@@ -146,7 +145,6 @@ func NewLFSMetaObject(ctx context.Context, repoID int64, p lfs.Pointer) (*LFSMet
146145
if err != nil {
147146
return nil, err
148147
} else if exist {
149-
m.Existing = true
150148
return m, committer.Commit()
151149
}
152150

models/user/user.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,20 @@ type CountUserFilter struct {
831831
IsActive optional.Option[bool]
832832
}
833833

834+
// HasUsers checks whether there are any users in the database, or only one user exists.
835+
func HasUsers(ctx context.Context) (ret struct {
836+
HasAnyUser, HasOnlyOneUser bool
837+
}, err error,
838+
) {
839+
res, err := db.GetEngine(ctx).Table(&User{}).Cols("id").Limit(2).Query()
840+
if err != nil {
841+
return ret, fmt.Errorf("error checking user existence: %w", err)
842+
}
843+
ret.HasAnyUser = len(res) != 0
844+
ret.HasOnlyOneUser = len(res) == 1
845+
return ret, nil
846+
}
847+
834848
// CountUsers returns number of users.
835849
func CountUsers(ctx context.Context, opts *CountUserFilter) int64 {
836850
return countUsers(ctx, opts)

modules/markup/html_node.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,20 @@ func processNodeA(ctx *RenderContext, node *html.Node) {
6363

6464
func visitNodeImg(ctx *RenderContext, img *html.Node) (next *html.Node) {
6565
next = img.NextSibling
66+
attrSrc, hasLazy := "", false
6667
for i, imgAttr := range img.Attr {
68+
hasLazy = hasLazy || imgAttr.Key == "loading" && imgAttr.Val == "lazy"
6769
if imgAttr.Key != "src" {
70+
attrSrc = imgAttr.Val
6871
continue
6972
}
7073

7174
imgSrcOrigin := imgAttr.Val
7275
isLinkable := imgSrcOrigin != "" && !strings.HasPrefix(imgSrcOrigin, "data:")
7376

7477
// By default, the "<img>" tag should also be clickable,
75-
// because frontend use `<img>` to paste the re-scaled image into the markdown,
76-
// so it must match the default markdown image behavior.
78+
// because frontend uses `<img>` to paste the re-scaled image into the Markdown,
79+
// so it must match the default Markdown image behavior.
7780
cnt := 0
7881
for p := img.Parent; isLinkable && p != nil && cnt < 2; p = p.Parent {
7982
if hasParentAnchor := p.Type == html.ElementNode && p.Data == "a"; hasParentAnchor {
@@ -98,6 +101,9 @@ func visitNodeImg(ctx *RenderContext, img *html.Node) (next *html.Node) {
98101
imgAttr.Val = camoHandleLink(imgAttr.Val)
99102
img.Attr[i] = imgAttr
100103
}
104+
if !RenderBehaviorForTesting.DisableAdditionalAttributes && !hasLazy && !strings.HasPrefix(attrSrc, "data:") {
105+
img.Attr = append(img.Attr, html.Attribute{Key: "loading", Val: "lazy"})
106+
}
101107
return next
102108
}
103109

modules/markup/markdown/markdown_test.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func TestRender_StandardLinks(t *testing.T) {
4747
func TestRender_Images(t *testing.T) {
4848
setting.AppURL = AppURL
4949

50-
test := func(input, expected string) {
50+
render := func(input, expected string) {
5151
buffer, err := markdown.RenderString(markup.NewTestRenderContext(FullURL), input)
5252
assert.NoError(t, err)
5353
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
@@ -59,27 +59,32 @@ func TestRender_Images(t *testing.T) {
5959
result := util.URLJoin(FullURL, url)
6060
// hint: With Markdown v2.5.2, there is a new syntax: [link](URL){:target="_blank"} , but we do not support it now
6161

62-
test(
62+
render(
6363
"!["+title+"]("+url+")",
6464
`<p><a href="`+result+`" target="_blank" rel="nofollow noopener"><img src="`+result+`" alt="`+title+`"/></a></p>`)
6565

66-
test(
66+
render(
6767
"[["+title+"|"+url+"]]",
6868
`<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" title="`+title+`" alt="`+title+`"/></a></p>`)
69-
test(
69+
render(
7070
"[!["+title+"]("+url+")]("+href+")",
7171
`<p><a href="`+href+`" rel="nofollow"><img src="`+result+`" alt="`+title+`"/></a></p>`)
7272

73-
test(
73+
render(
7474
"!["+title+"]("+url+")",
7575
`<p><a href="`+result+`" target="_blank" rel="nofollow noopener"><img src="`+result+`" alt="`+title+`"/></a></p>`)
7676

77-
test(
77+
render(
7878
"[["+title+"|"+url+"]]",
7979
`<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" title="`+title+`" alt="`+title+`"/></a></p>`)
80-
test(
80+
render(
8181
"[!["+title+"]("+url+")]("+href+")",
8282
`<p><a href="`+href+`" rel="nofollow"><img src="`+result+`" alt="`+title+`"/></a></p>`)
83+
84+
defer test.MockVariableValue(&markup.RenderBehaviorForTesting.DisableAdditionalAttributes, false)()
85+
render(
86+
"<a><img src='a.jpg'></a>", // by the way, empty "a" tag will be removed
87+
`<p dir="auto"><img src="http://localhost:3000/user13/repo11/a.jpg" loading="lazy"/></p>`)
8388
}
8489

8590
func TestTotal_RenderString(t *testing.T) {

modules/markup/sanitizer_default.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package markup
55

66
import (
7+
"html/template"
78
"io"
89
"net/url"
910
"regexp"
@@ -52,6 +53,8 @@ func (st *Sanitizer) createDefaultPolicy() *bluemonday.Policy {
5253

5354
policy.AllowAttrs("src", "autoplay", "controls").OnElements("video")
5455

56+
policy.AllowAttrs("loading").OnElements("img")
57+
5558
// Allow generally safe attributes (reference: https://github.com/jch/html-pipeline)
5659
generalSafeAttrs := []string{
5760
"abbr", "accept", "accept-charset",
@@ -90,9 +93,9 @@ func (st *Sanitizer) createDefaultPolicy() *bluemonday.Policy {
9093
return policy
9194
}
9295

93-
// Sanitize takes a string that contains a HTML fragment or document and applies policy whitelist.
94-
func Sanitize(s string) string {
95-
return GetDefaultSanitizer().defaultPolicy.Sanitize(s)
96+
// Sanitize use default sanitizer policy to sanitize a string
97+
func Sanitize(s string) template.HTML {
98+
return template.HTML(GetDefaultSanitizer().defaultPolicy.Sanitize(s))
9699
}
97100

98101
// SanitizeReader sanitizes a Reader

modules/markup/sanitizer_default_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,6 @@ func TestSanitizer(t *testing.T) {
6969
}
7070

7171
for i := 0; i < len(testCases); i += 2 {
72-
assert.Equal(t, testCases[i+1], Sanitize(testCases[i]))
72+
assert.Equal(t, testCases[i+1], string(Sanitize(testCases[i])))
7373
}
7474
}

modules/structs/repo_file.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ func (o *UpdateFileOptions) Branch() string {
6666
return o.FileOptions.BranchName
6767
}
6868

69+
// FIXME: ChangeFileOperation.SHA is NOT required for update or delete if last commit is provided in the options.
70+
6971
// ChangeFileOperation for creating, updating or deleting a file
7072
type ChangeFileOperation struct {
7173
// indicates what to do with the file

modules/templates/helper.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ func safeHTML(s any) template.HTML {
176176
panic(fmt.Sprintf("unexpected type %T", s))
177177
}
178178

179-
// SanitizeHTML sanitizes the input by pre-defined markdown rules
179+
// SanitizeHTML sanitizes the input by default sanitization rules.
180180
func SanitizeHTML(s string) template.HTML {
181-
return template.HTML(markup.Sanitize(s))
181+
return markup.Sanitize(s)
182182
}
183183

184184
func htmlEscape(s any) template.HTML {

options/locale/locale_cs-CZ.ini

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,7 +1330,6 @@ editor.update=Aktualizovat %s
13301330
editor.delete=Odstranit %s
13311331
editor.patch=Použít záplatu
13321332
editor.patching=Záplatování:
1333-
editor.fail_to_apply_patch=Nelze použít záplatu „%s“
13341333
editor.new_patch=Nová záplata
13351334
editor.commit_message_desc=Přidat volitelný rozšířený popis…
13361335
editor.signoff_desc=Přidat Signed-off-by podpis přispěvatele na konec zprávy o commitu.
@@ -1348,17 +1347,13 @@ editor.branch_already_exists=Větev „%s“ již existuje v tomto repozitáři.
13481347
editor.directory_is_a_file=Jméno adresáře „%s“ je již použito jako jméno souboru v tomto repozitáři.
13491348
editor.file_is_a_symlink=`„%s“ je symbolický odkaz. Symbolické odkazy nemohou být upravovány ve webovém editoru`
13501349
editor.filename_is_a_directory=Jméno souboru „%s“ je již použito jako jméno adresáře v tomto repozitáři.
1351-
editor.file_editing_no_longer_exists=Upravovaný soubor „%s“ již není součástí tohoto repozitáře.
1352-
editor.file_deleting_no_longer_exists=Odstraňovaný soubor „%s“ již není součástí tohoto repozitáře.
13531350
editor.file_changed_while_editing=Obsah souboru byl změněn od doby, kdy jste začaly s úpravou. <a target="_blank" rel="noopener noreferrer" href="%s">Klikněte zde</a>, abyste je zobrazili, nebo <strong>potvrďte změny ještě jednou</strong> pro jejich přepsání.
13541351
editor.file_already_exists=Soubor „%s“ již existuje v tomto repozitáři.
13551352
editor.commit_id_not_matching=ID commitu se neshoduje s ID, když jsi začal/a s úpravami. Odevzdat do záplatové větve a poté sloučit.
13561353
editor.push_out_of_date=Nahrání se zdá být zastaralé.
13571354
editor.commit_empty_file_header=Odevzdat prázdný soubor
13581355
editor.commit_empty_file_text=Soubor, který se chystáte odevzdat, je prázdný. Pokračovat?
13591356
editor.no_changes_to_show=Žádné změny k zobrazení.
1360-
editor.fail_to_update_file=Nepodařilo se aktualizovat/vytvořit soubor „%s“.
1361-
editor.fail_to_update_file_summary=Chybové hlášení:
13621357
editor.push_rejected_no_message=Změna byla serverem zamítnuta bez zprávy. Prosím, zkontrolujte háčky Gitu.
13631358
editor.push_rejected=Změna byla serverem zamítnuta. Prosím, zkontrolujte háčky Gitu.
13641359
editor.push_rejected_summary=Úplná zpráva o odmítnutí:
@@ -2780,15 +2775,13 @@ settings.visibility.private_shortname=Soukromý
27802775

27812776
settings.update_settings=Upravit nastavení
27822777
settings.update_setting_success=Nastavení organizace bylo upraveno.
2783-
settings.change_orgname_prompt=Poznámka: Změna názvu organizace také změní adresu URL vaší organizace a uvolní staré jméno této organizace.
2784-
settings.change_orgname_redirect_prompt=Staré jméno bude přesměrovávat, dokud nebude znovu obsazeno.
2778+
2779+
27852780
settings.update_avatar_success=Avatar organizace byl aktualizován.
27862781
settings.delete=Smazat organizaci
27872782
settings.delete_account=Smazat tuto organizaci
27882783
settings.delete_prompt=Organizace bude trvale odstraněna. Tato změna <strong>NEMŮŽE</strong> být vrácena!
27892784
settings.confirm_delete_account=Potvrdit smazání
2790-
settings.delete_org_title=Smazat organizaci
2791-
settings.delete_org_desc=Tato organizace bude trvale smazána. Pokračovat?
27922785
settings.hooks_desc=Přidat webové háčky, které budou spouštěny pro <strong>všechny repozitáře</strong> v této organizaci.
27932786

27942787
settings.labels_desc=Přidejte štítky, které mohou být použity pro úkoly <strong>všech repositářů</strong> v rámci této organizace.

options/locale/locale_de-DE.ini

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,6 @@ editor.update=%s aktualisiert
13521352
editor.delete=%s gelöscht
13531353
editor.patch=Patch anwenden
13541354
editor.patching=Patche:
1355-
editor.fail_to_apply_patch=Patch "%s" nicht anwendbar
13561355
editor.new_patch=Neuer Patch
13571356
editor.commit_message_desc=Eine ausführlichere (optionale) Beschreibung hinzufügen…
13581357
editor.signoff_desc=Am Ende der Commit Nachricht einen Signed-off-by Anhang vom Committer hinzufügen.
@@ -1372,17 +1371,13 @@ editor.branch_already_exists=Branch "%s" existiert bereits in diesem Repository.
13721371
editor.directory_is_a_file=Der Verzeichnisname "%s" wird bereits als Dateiname in diesem Repository verwendet.
13731372
editor.file_is_a_symlink=`"%s" ist ein symbolischer Link. Symbolische Links können mit dem Web-Editor nicht bearbeitet werden`
13741373
editor.filename_is_a_directory=Der Dateiname "%s" wird bereits als Verzeichnisname in diesem Repository verwendet.
1375-
editor.file_editing_no_longer_exists=Die bearbeitete Datei "%s" existiert nicht mehr in diesem Repository.
1376-
editor.file_deleting_no_longer_exists=Die zu löschende Datei "%s" existiert nicht mehr in diesem Repository.
13771374
editor.file_changed_while_editing=Der Inhalt der Datei hat sich seit dem Beginn der Bearbeitung geändert. <a target="_blank" rel="noopener noreferrer" href="%s">Hier klicken</a>, um die Änderungen anzusehen, oder <strong>Änderungen erneut comitten</strong>, um sie zu überschreiben.
13781375
editor.file_already_exists=Eine Datei mit dem Namen '%s' existiert bereits in diesem Repository.
13791376
editor.commit_id_not_matching=Die Commit-ID stimmt nicht mit der ID überein, bei welcher du mit der Bearbeitung begonnen hast. Commite in einen Patch-Branch und merge daraufhin.
13801377
editor.push_out_of_date=Der Push scheint veraltet zu sein.
13811378
editor.commit_empty_file_header=Leere Datei committen
13821379
editor.commit_empty_file_text=Die Datei, die du commiten willst, ist leer. Fortfahren?
13831380
editor.no_changes_to_show=Keine Änderungen vorhanden.
1384-
editor.fail_to_update_file=Fehler beim Aktualisieren/Erstellen der Datei "%s".
1385-
editor.fail_to_update_file_summary=Fehlermeldung:
13861381
editor.push_rejected_no_message=Die Änderung wurde vom Server ohne Nachricht abgelehnt. Bitte überprüfe die Git Hooks.
13871382
editor.push_rejected=Die Änderung wurde vom Server abgelehnt. Bitte überprüfe die Git Hooks.
13881383
editor.push_rejected_summary=Vollständige Ablehnungsmeldung:
@@ -2829,15 +2824,13 @@ settings.visibility.private_shortname=Privat
28292824

28302825
settings.update_settings=Einstellungen speichern
28312826
settings.update_setting_success=Organisationseinstellungen wurden aktualisiert.
2832-
settings.change_orgname_prompt=Hinweis: Das Ändern des Organisationsnamens wird auch die URL deiner Organisation ändern und den alten Namen freigeben.
2833-
settings.change_orgname_redirect_prompt=Der alte Name wird weiterleiten, bis er wieder beansprucht wird.
2827+
2828+
28342829
settings.update_avatar_success=Der Organisationsavatar wurde aktualisiert.
28352830
settings.delete=Organisation löschen
28362831
settings.delete_account=Diese Organisation löschen
28372832
settings.delete_prompt=Die Organisation wird dauerhaft gelöscht. Dies <strong>KANN NICHT</strong> rückgängig gemacht werden!
28382833
settings.confirm_delete_account=Löschen bestätigen
2839-
settings.delete_org_title=Organisation löschen
2840-
settings.delete_org_desc=Diese Organisation wird dauerhaft gelöscht. Fortfahren?
28412834
settings.hooks_desc=Webhooks hinzufügen, die für <strong>alle</strong> Repositories dieser Organisation ausgelöst werden.
28422835

28432836
settings.labels_desc=Labels hinzufügen, die für <strong>alle Repositories</strong> dieser Organisation genutzt werden können.

0 commit comments

Comments
 (0)