Skip to content

Commit 41ecde1

Browse files
authored
Merge branch 'main' into refactor-mail
2 parents 9303415 + 27bf63a commit 41ecde1

File tree

13 files changed

+169
-139
lines changed

13 files changed

+169
-139
lines changed

models/issues/pull_list.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func listPullRequestStatement(ctx context.Context, baseRepoID int64, opts *PullR
6161
}
6262

6363
// GetUnmergedPullRequestsByHeadInfo returns all pull requests that are open and has not been merged
64-
func GetUnmergedPullRequestsByHeadInfo(ctx context.Context, repoID int64, branch string) ([]*PullRequest, error) {
64+
func GetUnmergedPullRequestsByHeadInfo(ctx context.Context, repoID int64, branch string) (PullRequestList, error) {
6565
prs := make([]*PullRequest, 0, 2)
6666
sess := db.GetEngine(ctx).
6767
Join("INNER", "issue", "issue.id = pull_request.issue_id").
@@ -116,7 +116,7 @@ func HasUnmergedPullRequestsByHeadInfo(ctx context.Context, repoID int64, branch
116116

117117
// GetUnmergedPullRequestsByBaseInfo returns all pull requests that are open and has not been merged
118118
// by given base information (repo and branch).
119-
func GetUnmergedPullRequestsByBaseInfo(ctx context.Context, repoID int64, branch string) ([]*PullRequest, error) {
119+
func GetUnmergedPullRequestsByBaseInfo(ctx context.Context, repoID int64, branch string) (PullRequestList, error) {
120120
prs := make([]*PullRequest, 0, 2)
121121
return prs, db.GetEngine(ctx).
122122
Where("base_repo_id=? AND base_branch=? AND has_merged=? AND issue.is_closed=?",

models/issues/pull_list_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ import (
1616
func TestPullRequestList_LoadAttributes(t *testing.T) {
1717
assert.NoError(t, unittest.PrepareTestDatabase())
1818

19-
prs := []*issues_model.PullRequest{
19+
prs := issues_model.PullRequestList{
2020
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}),
2121
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}),
2222
}
23-
assert.NoError(t, issues_model.PullRequestList(prs).LoadAttributes(db.DefaultContext))
23+
assert.NoError(t, prs.LoadAttributes(db.DefaultContext))
2424
for _, pr := range prs {
2525
assert.NotNil(t, pr.Issue)
2626
assert.Equal(t, pr.IssueID, pr.Issue.ID)
@@ -32,11 +32,11 @@ func TestPullRequestList_LoadAttributes(t *testing.T) {
3232
func TestPullRequestList_LoadReviewCommentsCounts(t *testing.T) {
3333
assert.NoError(t, unittest.PrepareTestDatabase())
3434

35-
prs := []*issues_model.PullRequest{
35+
prs := issues_model.PullRequestList{
3636
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}),
3737
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}),
3838
}
39-
reviewComments, err := issues_model.PullRequestList(prs).LoadReviewCommentsCounts(db.DefaultContext)
39+
reviewComments, err := prs.LoadReviewCommentsCounts(db.DefaultContext)
4040
assert.NoError(t, err)
4141
assert.Len(t, reviewComments, 2)
4242
for _, pr := range prs {
@@ -47,11 +47,11 @@ func TestPullRequestList_LoadReviewCommentsCounts(t *testing.T) {
4747
func TestPullRequestList_LoadReviews(t *testing.T) {
4848
assert.NoError(t, unittest.PrepareTestDatabase())
4949

50-
prs := []*issues_model.PullRequest{
50+
prs := issues_model.PullRequestList{
5151
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}),
5252
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}),
5353
}
54-
reviewList, err := issues_model.PullRequestList(prs).LoadReviews(db.DefaultContext)
54+
reviewList, err := prs.LoadReviews(db.DefaultContext)
5555
assert.NoError(t, err)
5656
// 1, 7, 8, 9, 10, 22
5757
assert.Len(t, reviewList, 6)

modules/markup/sanitizer_default_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ func TestSanitizer(t *testing.T) {
6262
`<a href="javascript:alert('xss')">bad</a>`, `bad`,
6363
`<a href="vbscript:no">bad</a>`, `bad`,
6464
`<a href="data:1234">bad</a>`, `bad`,
65+
66+
// Some classes and attributes are used by the frontend framework and will execute JS code, so make sure they are removed
67+
`<div class="link-action" data-attr-class="foo" data-url="xxx">txt</div>`, `<div data-attr-class="foo">txt</div>`,
68+
`<div class="form-fetch-action" data-markdown-generated-content="bar" data-global-init="a" data-global-click="b">txt</div>`, `<div data-markdown-generated-content="bar">txt</div>`,
6569
}
6670

6771
for i := 0; i < len(testCases); i += 2 {

services/pull/pull.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,10 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string,
407407
}
408408

409409
if isSync {
410-
requests := issues_model.PullRequestList(prs)
411-
if err = requests.LoadAttributes(ctx); err != nil {
410+
if err = prs.LoadAttributes(ctx); err != nil {
412411
log.Error("PullRequestList.LoadAttributes: %v", err)
413412
}
414-
if invalidationErr := checkForInvalidation(ctx, requests, repoID, doer, branch); invalidationErr != nil {
413+
if invalidationErr := checkForInvalidation(ctx, prs, repoID, doer, branch); invalidationErr != nil {
415414
log.Error("checkForInvalidation: %v", invalidationErr)
416415
}
417416
if err == nil {
@@ -645,7 +644,7 @@ func retargetBranchPulls(ctx context.Context, doer *user_model.User, repoID int6
645644
return err
646645
}
647646

648-
if err := issues_model.PullRequestList(prs).LoadAttributes(ctx); err != nil {
647+
if err := prs.LoadAttributes(ctx); err != nil {
649648
return err
650649
}
651650

@@ -672,11 +671,11 @@ func AdjustPullsCausedByBranchDeleted(ctx context.Context, doer *user_model.User
672671
return err
673672
}
674673

675-
if err := issues_model.PullRequestList(prs).LoadAttributes(ctx); err != nil {
674+
if err := prs.LoadAttributes(ctx); err != nil {
676675
return err
677676
}
678-
issues_model.PullRequestList(prs).SetHeadRepo(repo)
679-
if err := issues_model.PullRequestList(prs).LoadRepositories(ctx); err != nil {
677+
prs.SetHeadRepo(repo)
678+
if err := prs.LoadRepositories(ctx); err != nil {
680679
return err
681680
}
682681

@@ -707,11 +706,11 @@ func AdjustPullsCausedByBranchDeleted(ctx context.Context, doer *user_model.User
707706
return err
708707
}
709708

710-
if err := issues_model.PullRequestList(prs).LoadAttributes(ctx); err != nil {
709+
if err := prs.LoadAttributes(ctx); err != nil {
711710
return err
712711
}
713-
issues_model.PullRequestList(prs).SetBaseRepo(repo)
714-
if err := issues_model.PullRequestList(prs).LoadRepositories(ctx); err != nil {
712+
prs.SetBaseRepo(repo)
713+
if err := prs.LoadRepositories(ctx); err != nil {
715714
return err
716715
}
717716

@@ -744,7 +743,7 @@ func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *re
744743
return err
745744
}
746745

747-
if err = issues_model.PullRequestList(prs).LoadAttributes(ctx); err != nil {
746+
if err = prs.LoadAttributes(ctx); err != nil {
748747
return err
749748
}
750749

templates/base/alert.tmpl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
{{if .Flash.ErrorMsg}}
1+
{{- if .Flash.ErrorMsg -}}
22
<div class="ui negative message flash-message flash-error">
33
<p>{{.Flash.ErrorMsg | SanitizeHTML}}</p>
44
</div>
5-
{{end}}
6-
{{if .Flash.SuccessMsg}}
5+
{{- end -}}
6+
{{- if .Flash.SuccessMsg -}}
77
<div class="ui positive message flash-message flash-success">
88
<p>{{.Flash.SuccessMsg | SanitizeHTML}}</p>
99
</div>
10-
{{end}}
11-
{{if .Flash.InfoMsg}}
10+
{{- end -}}
11+
{{- if .Flash.InfoMsg -}}
1212
<div class="ui info message flash-message flash-info">
1313
<p>{{.Flash.InfoMsg | SanitizeHTML}}</p>
1414
</div>
15-
{{end}}
16-
{{if .Flash.WarningMsg}}
15+
{{- end -}}
16+
{{- if .Flash.WarningMsg -}}
1717
<div class="ui warning message flash-message flash-warning">
1818
<p>{{.Flash.WarningMsg | SanitizeHTML}}</p>
1919
</div>
20-
{{end}}
20+
{{- end -}}

templates/repo/issue/new_form.tmpl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
{{if .Flash}}
21
{{template "base/alert" .}}
3-
{{end}}
42
<form class="issue-content ui comment form form-fetch-action" id="new-issue" action="{{.Link}}" method="post">
53
{{.CsrfTokenHtml}}
64
<div class="issue-content-left">
@@ -9,7 +7,10 @@
97
{{ctx.AvatarUtils.Avatar .SignedUser 40}}
108
<div class="ui segment content tw-my-0">
119
<div class="field">
12-
<input name="title" class="js-autofocus-end" id="issue_title" placeholder="{{ctx.Locale.Tr "repo.milestones.title"}}" value="{{if .TitleQuery}}{{.TitleQuery}}{{else if .IssueTemplateTitle}}{{.IssueTemplateTitle}}{{else}}{{.title}}{{end}}" required maxlength="255" autocomplete="off">
10+
<input name="title" data-global-init="initInputAutoFocusEnd" id="issue_title" required maxlength="255" autocomplete="off"
11+
placeholder="{{ctx.Locale.Tr "repo.milestones.title"}}"
12+
value="{{if .TitleQuery}}{{.TitleQuery}}{{else if .IssueTemplateTitle}}{{.IssueTemplateTitle}}{{else}}{{.title}}{{end}}"
13+
>
1314
{{if .PageIsComparePull}}
1415
<div class="title_wip_desc" data-wip-prefixes="{{JsonUtils.EncodeToString .PullRequestWorkInProgressPrefixes}}">{{ctx.Locale.Tr "repo.pulls.title_wip_desc" (index .PullRequestWorkInProgressPrefixes 0)}}</div>
1516
{{end}}

web_src/js/features/autofocus-end.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

web_src/js/features/common-page.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {GET} from '../modules/fetch.ts';
22
import {showGlobalErrorMessage} from '../bootstrap.ts';
33
import {fomanticQuery} from '../modules/fomantic/base.ts';
44
import {queryElems} from '../utils/dom.ts';
5-
import {observeAddedElement} from '../modules/observer.ts';
5+
import {registerGlobalInitFunc, registerGlobalSelectorFunc} from '../modules/observer.ts';
66

77
const {appUrl} = window.config;
88

@@ -30,7 +30,7 @@ export function initFootLanguageMenu() {
3030

3131
export function initGlobalDropdown() {
3232
// do not init "custom" dropdowns, "custom" dropdowns are managed by their own code.
33-
observeAddedElement('.ui.dropdown:not(.custom)', (el) => {
33+
registerGlobalSelectorFunc('.ui.dropdown:not(.custom)', (el) => {
3434
const $dropdown = fomanticQuery(el);
3535
if ($dropdown.data('module-dropdown')) return; // do not re-init if other code has already initialized it.
3636

@@ -80,6 +80,25 @@ export function initGlobalTabularMenu() {
8080
fomanticQuery('.ui.menu.tabular:not(.custom) .item').tab({autoTabActivation: false});
8181
}
8282

83+
// for performance considerations, it only uses performant syntax
84+
function attachInputDirAuto(el: Partial<HTMLInputElement | HTMLTextAreaElement>) {
85+
if (el.type !== 'hidden' &&
86+
el.type !== 'checkbox' &&
87+
el.type !== 'radio' &&
88+
el.type !== 'range' &&
89+
el.type !== 'color') {
90+
el.dir = 'auto';
91+
}
92+
}
93+
94+
export function initGlobalInput() {
95+
registerGlobalSelectorFunc('input, textarea', attachInputDirAuto);
96+
registerGlobalInitFunc('initInputAutoFocusEnd', (el: HTMLInputElement) => {
97+
el.focus(); // expects only one such element on one page. If there are many, then the last one gets the focus.
98+
el.setSelectionRange(el.value.length, el.value.length);
99+
});
100+
}
101+
83102
/**
84103
* Too many users set their ROOT_URL to wrong value, and it causes a lot of problems:
85104
* * Cross-origin API request without correct cookie

web_src/js/features/repo-diff.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {POST, GET} from '../modules/fetch.ts';
1010
import {createTippy} from '../modules/tippy.ts';
1111
import {invertFileFolding} from './file-fold.ts';
1212
import {parseDom} from '../utils.ts';
13-
import {observeAddedElement} from '../modules/observer.ts';
13+
import {registerGlobalSelectorFunc} from '../modules/observer.ts';
1414

1515
const {i18n} = window.config;
1616

@@ -254,7 +254,7 @@ export function initRepoDiffView() {
254254
initExpandAndCollapseFilesButton();
255255
initRepoDiffHashChangeListener();
256256

257-
observeAddedElement('#diff-file-boxes .diff-file-box', initRepoDiffFileBox);
257+
registerGlobalSelectorFunc('#diff-file-boxes .diff-file-box', initRepoDiffFileBox);
258258
addDelegatedEventListener(document, 'click', '.fold-file', (el) => {
259259
invertFileFolding(el.closest('.file-content'), el);
260260
});

web_src/js/index.ts

Lines changed: 17 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {initImageDiff} from './features/imagediff.ts';
1111
import {initRepoMigration} from './features/repo-migration.ts';
1212
import {initRepoProject} from './features/repo-projects.ts';
1313
import {initTableSort} from './features/tablesort.ts';
14-
import {initAutoFocusEnd} from './features/autofocus-end.ts';
1514
import {initAdminUserListSearchForm} from './features/admin/users.ts';
1615
import {initAdminConfigs} from './features/admin/config.ts';
1716
import {initMarkupAnchors} from './markup/anchors.ts';
@@ -62,62 +61,23 @@ import {initRepoContributors} from './features/contributors.ts';
6261
import {initRepoCodeFrequency} from './features/code-frequency.ts';
6362
import {initRepoRecentCommits} from './features/recent-commits.ts';
6463
import {initRepoDiffCommitBranchesAndTags} from './features/repo-diff-commit.ts';
65-
import {initAddedElementObserver} from './modules/observer.ts';
64+
import {initGlobalSelectorObserver} from './modules/observer.ts';
6665
import {initRepositorySearch} from './features/repo-search.ts';
6766
import {initColorPickers} from './features/colorpicker.ts';
6867
import {initAdminSelfCheck} from './features/admin/selfcheck.ts';
6968
import {initOAuth2SettingsDisableCheckbox} from './features/oauth2-settings.ts';
7069
import {initGlobalFetchAction} from './features/common-fetch-action.ts';
71-
import {
72-
initFootLanguageMenu,
73-
initGlobalDropdown,
74-
initGlobalTabularMenu,
75-
initHeadNavbarContentToggle,
76-
} from './features/common-page.ts';
77-
import {
78-
initGlobalButtonClickOnEnter,
79-
initGlobalButtons,
80-
initGlobalDeleteButton,
81-
} from './features/common-button.ts';
82-
import {
83-
initGlobalComboMarkdownEditor,
84-
initGlobalEnterQuickSubmit,
85-
initGlobalFormDirtyLeaveConfirm,
86-
} from './features/common-form.ts';
70+
import {initFootLanguageMenu, initGlobalDropdown, initGlobalInput, initGlobalTabularMenu, initHeadNavbarContentToggle} from './features/common-page.ts';
71+
import {initGlobalButtonClickOnEnter, initGlobalButtons, initGlobalDeleteButton} from './features/common-button.ts';
72+
import {initGlobalComboMarkdownEditor, initGlobalEnterQuickSubmit, initGlobalFormDirtyLeaveConfirm} from './features/common-form.ts';
73+
import {callInitFunctions} from './modules/init.ts';
8774

8875
initGiteaFomantic();
89-
initAddedElementObserver();
9076
initSubmitEventPolyfill();
9177

92-
function callInitFunctions(functions: (() => any)[]) {
93-
// Start performance trace by accessing a URL by "https://localhost/?_ui_performance_trace=1" or "https://localhost/?key=value&_ui_performance_trace=1"
94-
// It is a quick check, no side effect so no need to do slow URL parsing.
95-
const initStart = performance.now();
96-
if (window.location.search.includes('_ui_performance_trace=1')) {
97-
let results: {name: string, dur: number}[] = [];
98-
for (const func of functions) {
99-
const start = performance.now();
100-
func();
101-
results.push({name: func.name, dur: performance.now() - start});
102-
}
103-
results = results.sort((a, b) => b.dur - a.dur);
104-
for (let i = 0; i < 20 && i < results.length; i++) {
105-
// eslint-disable-next-line no-console
106-
console.log(`performance trace: ${results[i].name} ${results[i].dur.toFixed(3)}`);
107-
}
108-
} else {
109-
for (const func of functions) {
110-
func();
111-
}
112-
}
113-
const initDur = performance.now() - initStart;
114-
if (initDur > 500) {
115-
console.error(`slow init functions took ${initDur.toFixed(3)}ms`);
116-
}
117-
}
118-
11978
onDomReady(() => {
120-
callInitFunctions([
79+
const initStartTime = performance.now();
80+
const initPerformanceTracer = callInitFunctions([
12181
initGlobalDropdown,
12282
initGlobalTabularMenu,
12383
initGlobalFetchAction,
@@ -129,6 +89,7 @@ onDomReady(() => {
12989
initGlobalFormDirtyLeaveConfirm,
13090
initGlobalComboMarkdownEditor,
13191
initGlobalDeleteButton,
92+
initGlobalInput,
13293

13394
initCommonOrganization,
13495
initCommonIssueListQuickGoto,
@@ -150,7 +111,6 @@ onDomReady(() => {
150111
initSshKeyFormParser,
151112
initStopwatch,
152113
initTableSort,
153-
initAutoFocusEnd,
154114
initFindFileInRepo,
155115
initCopyContent,
156116

@@ -212,4 +172,13 @@ onDomReady(() => {
212172

213173
initOAuth2SettingsDisableCheckbox,
214174
]);
175+
176+
// it must be the last one, then the "querySelectorAll" only needs to be executed once for global init functions.
177+
initGlobalSelectorObserver(initPerformanceTracer);
178+
if (initPerformanceTracer) initPerformanceTracer.printResults();
179+
180+
const initDur = performance.now() - initStartTime;
181+
if (initDur > 500) {
182+
console.error(`slow init functions took ${initDur.toFixed(3)}ms`);
183+
}
215184
});

0 commit comments

Comments
 (0)