mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-14 01:35:55 +09:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f29011723 | ||
|
|
ee43d20d3b | ||
|
|
99ffd826e5 | ||
|
|
93bac4e10d | ||
|
|
9fbb898058 | ||
|
|
0a9794a6bc | ||
|
|
d4044b9c98 | ||
|
|
1e6d2e47e9 | ||
|
|
d827b0bfb7 | ||
|
|
d789170e31 | ||
|
|
9bbe3eb0b4 | ||
|
|
650fdceb5a | ||
|
|
4c69e158e5 | ||
|
|
b7e41f7b8f | ||
|
|
5a3d9861ba | ||
|
|
adb43358bc | ||
|
|
d6a980501b | ||
|
|
103a66ae83 | ||
|
|
426fd2a816 | ||
|
|
337f2625ac | ||
|
|
5ebf4990a5 | ||
|
|
3fd07a0be6 | ||
|
|
d372539f79 | ||
|
|
91e24a3a10 | ||
|
|
a29e667eff | ||
|
|
92b993c91f | ||
|
|
33b1027c76 | ||
|
|
b45f9260bf | ||
|
|
ee1a8d7b41 | ||
|
|
ba19a35b6b | ||
|
|
cc8e7dd355 | ||
|
|
f52840623c | ||
|
|
97d4a38e01 | ||
|
|
60ccd87d6e | ||
|
|
2477737fff | ||
|
|
a360daeff9 | ||
|
|
82d4d725ae | ||
|
|
1e585d7991 | ||
|
|
f849766998 | ||
|
|
f4818671e4 |
No files matched your search
+29
-38
@@ -114,6 +114,17 @@ steps:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: tag-pre-condition
|
||||
pull: always
|
||||
image: alpine/git
|
||||
commands:
|
||||
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
|
||||
depends_on:
|
||||
- build
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
|
||||
- name: tag-test
|
||||
pull: always
|
||||
image: golang:1.12
|
||||
@@ -122,7 +133,7 @@ steps:
|
||||
environment:
|
||||
TAGS: bindata
|
||||
depends_on:
|
||||
- build
|
||||
- tag-pre-condition
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
@@ -442,7 +453,6 @@ trigger:
|
||||
|
||||
depends_on:
|
||||
- testing
|
||||
- translations
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
@@ -558,6 +568,15 @@ workspace:
|
||||
base: /go
|
||||
path: src/code.gitea.io/gitea
|
||||
|
||||
depends_on:
|
||||
- testing
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/master
|
||||
- "refs/tags/**"
|
||||
- "refs/pull/**"
|
||||
|
||||
steps:
|
||||
- name: fetch-tags
|
||||
pull: default
|
||||
@@ -571,56 +590,28 @@ steps:
|
||||
|
||||
- name: dryrun
|
||||
pull: always
|
||||
image: plugins/docker:18.09
|
||||
image: plugins/docker:linux-amd64
|
||||
settings:
|
||||
cache_from: gitea/gitea
|
||||
dry_run: true
|
||||
repo: gitea/gitea
|
||||
when:
|
||||
event:
|
||||
- pull_request
|
||||
|
||||
- name: release
|
||||
- name: publish
|
||||
pull: always
|
||||
image: plugins/docker:18.09
|
||||
image: plugins/docker:linux-amd64
|
||||
settings:
|
||||
cache_from: gitea/gitea
|
||||
auto_tag: true
|
||||
repo: gitea/gitea
|
||||
tags:
|
||||
- "${DRONE_BRANCH##release/v}"
|
||||
environment:
|
||||
DOCKER_PASSWORD:
|
||||
password:
|
||||
from_secret: docker_password
|
||||
DOCKER_USERNAME:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
depends_on:
|
||||
- dryrun
|
||||
when:
|
||||
branch:
|
||||
- "release/*"
|
||||
event:
|
||||
- push
|
||||
|
||||
- name: latest
|
||||
pull: always
|
||||
image: plugins/docker:18.09
|
||||
settings:
|
||||
cache_from: gitea/gitea
|
||||
default_tags: true
|
||||
repo: gitea/gitea
|
||||
environment:
|
||||
DOCKER_PASSWORD:
|
||||
from_secret: docker_password
|
||||
DOCKER_USERNAME:
|
||||
from_secret: docker_username
|
||||
depends_on:
|
||||
- dryrun
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
exclude:
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
|
||||
+41
-3
@@ -4,9 +4,15 @@ This changelog goes through all the changes that have been made in each release
|
||||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.9.0-RC1](https://github.com/go-gitea/gitea/releases/tag/v1.9.0-rc1) - 2019-07-06
|
||||
## [1.9.0](https://github.com/go-gitea/gitea/releases/tag/v1.9.0) - 2019-07-30
|
||||
* BREAKING
|
||||
* Better logging (#6038) (#6095)
|
||||
* SECURITY
|
||||
* Shadow the password on cache and session config on admin panel (#7300)
|
||||
* Fix markdown invoke sequence (#7513) (#7560)
|
||||
* Reserve .well-known username (#7638)
|
||||
* Do not leak secrets via timing side channel (#7364)
|
||||
* Ensure that decryption of cookie actually suceeds (#7363)
|
||||
* FEATURE
|
||||
* Content API for Creating, Updating, Deleting Files (#6314)
|
||||
* Enable tls-alpn-01: Use certmanager provided TLSConfig for LetsEncrypt (#7229)
|
||||
@@ -29,6 +35,39 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Implement Default Webhooks (#4299)
|
||||
* Telegram webhook (#4227)
|
||||
* BUGFIXES
|
||||
* Send webhook after commit when creating issue with assignees (#7681) (#7684)
|
||||
* Upgrade macaron/captcha to fix random error problem (#7407) (#7683)
|
||||
* Move add to hook queue for created repo to outside xorm session. (#7682) (#7675)
|
||||
* Show protection symbol if needed on default branch (#7660) (#7668)
|
||||
* Hide delete/restore button on archived repos (#7660)
|
||||
* Fix bug on migrating milestone from github (#7665) (#7666)
|
||||
* Use flex to fix floating paginate (#7656) (#7662)
|
||||
* Change length of some repository's columns (#7652) (#7655)
|
||||
* Fix wrong email when use gitea as OAuth2 provider (#7640) (#7647)
|
||||
* Fix syntax highlight initialization (#7617) (#7626)
|
||||
* Fix bug create/edit wiki pages when code master branch protected (#7580) (#7623)
|
||||
* Fix panic on push at #7611 (#7615) (#7618)
|
||||
* Handle ErrUserProhibitLogin in http git (#7586, #7591) (#7590)
|
||||
* Fix color of split-diff view in dark theme (#7587) (#7589)
|
||||
* Fix file header overflow in file and blame views (#7562) (#7579)
|
||||
* Malformed URLs in API git/commits response (#7565) (#7567)
|
||||
* Fix empty commits now showing in repo overview (#7521) (#7563)
|
||||
* Fix repository's pull request count error (#7518) (#7524)
|
||||
* Remove duplicated webhook trigger (#7511) (#7516)
|
||||
* Handles all redirects for Web UI File CRUD (#7478) (#7507)
|
||||
* Fix regex for issues in commit messages (#7444) (#7466)
|
||||
* cmd/serv: actually exit after fatal errors (#7458) (#7460)
|
||||
* Fix an issue with some pages throwing 'not defined' js exceptions #7450 (#7453)
|
||||
* Fix Dropzone.js integration (#7445) (#7448)
|
||||
* Create class for inline positioned lists (#7439) (#7393)
|
||||
* Diff: Fix indentation on unhighlighted code (#7435) (#7443)
|
||||
* jQuery 3 (#7442) (#7425)
|
||||
* Only show "New Pull Request" button if repo allows pulls (#7426) (#7432)
|
||||
* Fix vendor references (#7394) (#7396)
|
||||
* Only return head: null if source branch was deleted (#6705) (#7376)
|
||||
* Add missing template variable on organisation settings (#7386) (#7385)
|
||||
* Fix post parameter on issue list which had unset assignee (#7380) (#7383)
|
||||
* Fix migration tests due to issue 7 being resolved (#7375) (#7381)
|
||||
* Correctly adjust mirror url (#6593)
|
||||
* Handle early git version's lack of get-url (#7065)
|
||||
* Fix icon position in issue view (#7354)
|
||||
@@ -166,6 +205,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Disable benchmarking during tag events on DroneIO (#6365)
|
||||
* Comments list performance optimization (#5305)
|
||||
* ENHANCEMENT
|
||||
* Update Drone docker generation to standard format (#7480) (#7496) (#7504)
|
||||
* Add API Endpoint for Repo Edit (#7006)
|
||||
* Add state param to milestone listing API (#7131)
|
||||
* Make captcha and password optional for external accounts (#6606)
|
||||
@@ -285,8 +325,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Refactor: append, build variable and type switch (#4940)
|
||||
* Git statistics in Activity tab (#4724)
|
||||
* Drop the bits argument when generating an ed25519 key (#6504)
|
||||
* SECURITY
|
||||
* Shadow the password on cache and session config on admin panel (#7300)
|
||||
* TESTING
|
||||
* Exclude pull_request from fetch-tags step, fixes #7108 (#7120)
|
||||
* Refactor and improve git test (#7086)
|
||||
|
||||
@@ -73,7 +73,6 @@ func fail(userMessage, logMessage string, args ...interface{}) {
|
||||
if !setting.ProdMode {
|
||||
fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
os.Exit(1)
|
||||
|
||||
@@ -45,7 +45,7 @@ require (
|
||||
github.com/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e // indirect
|
||||
github.com/go-macaron/binding v0.0.0-20160711225916-9440f336b443
|
||||
github.com/go-macaron/cache v0.0.0-20151013081102-561735312776
|
||||
github.com/go-macaron/captcha v0.0.0-20151123225153-8aa5919789ab
|
||||
github.com/go-macaron/captcha v0.0.0-20190710000913-8dc5911259df
|
||||
github.com/go-macaron/cors v0.0.0-20190309005821-6fd6a9bfe14e9
|
||||
github.com/go-macaron/csrf v0.0.0-20180426211211-503617c6b372
|
||||
github.com/go-macaron/i18n v0.0.0-20160612092837-ef57533c3b0f
|
||||
@@ -135,4 +135,4 @@ require (
|
||||
xorm.io/core v0.6.3
|
||||
)
|
||||
|
||||
replace github.com/denisenkom/go-mssqldb => github.com/denisenkom/go-mssqldb v0.0.0-20180314172330-6a30f4e59a44
|
||||
replace github.com/denisenkom/go-mssqldb => github.com/denisenkom/go-mssqldb v0.0.0-20180315180555-6a30f4e59a44
|
||||
@@ -66,8 +66,8 @@ github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20180314172330-6a30f4e59a44 h1:x0uHqLQTSEL9LKic8sWDt3ASkq07ve5ojIIUl5uF64M=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20180314172330-6a30f4e59a44/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20180315180555-6a30f4e59a44 h1:DWxZh2sImfCFn/79OUBhzFkPTKnsdDzXH/JTxpw5n6w=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20180315180555-6a30f4e59a44/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
@@ -113,8 +113,8 @@ github.com/go-macaron/binding v0.0.0-20160711225916-9440f336b443 h1:i801KPR7j76u
|
||||
github.com/go-macaron/binding v0.0.0-20160711225916-9440f336b443/go.mod h1:u+H6rwW+HQwUL+w5uaEJSpIlVZDye1o9MB4Su0JfRfM=
|
||||
github.com/go-macaron/cache v0.0.0-20151013081102-561735312776 h1:UYIHS1r0WotqB5cIa0PAiV0m6GzD9rDBcn4alp5JgCw=
|
||||
github.com/go-macaron/cache v0.0.0-20151013081102-561735312776/go.mod h1:hHAsZm/oBZVcY+S7qdQL6Vbg5VrXF6RuKGuqsszt3Ok=
|
||||
github.com/go-macaron/captcha v0.0.0-20151123225153-8aa5919789ab h1:4VFhsA3GE5Wwq1Ymr8KWCmrOWi1wRLEgdj48LPfQjxI=
|
||||
github.com/go-macaron/captcha v0.0.0-20151123225153-8aa5919789ab/go.mod h1:j9TJ+0nwUOWBvNnm0bheHIPFf3cC62EQo7n7O6PbjZA=
|
||||
github.com/go-macaron/captcha v0.0.0-20190710000913-8dc5911259df h1:MdgvtI3Y1u/DHNj7xUGOqAv+KGoTikjy8xQtCm12L78=
|
||||
github.com/go-macaron/captcha v0.0.0-20190710000913-8dc5911259df/go.mod h1:j9TJ+0nwUOWBvNnm0bheHIPFf3cC62EQo7n7O6PbjZA=
|
||||
github.com/go-macaron/cors v0.0.0-20190309005821-6fd6a9bfe14e9 h1:A0QGzY6UHHEil0I2e7C21JenNNG0mmrj5d9SFWTlgr8=
|
||||
github.com/go-macaron/cors v0.0.0-20190309005821-6fd6a9bfe14e9/go.mod h1:utmMRnVIrXPSfA9MFcpIYKEpKawjKxf62vv62k4707E=
|
||||
github.com/go-macaron/csrf v0.0.0-20180426211211-503617c6b372 h1:acrx8CnDmlKl+BPoOOLEK9Ko+SrWFB5pxRuGkKj4iqo=
|
||||
|
||||
+2
-1
@@ -65,6 +65,7 @@ var (
|
||||
)
|
||||
|
||||
const issueRefRegexpStr = `(?:([0-9a-zA-Z-_\.]+)/([0-9a-zA-Z-_\.]+))?(#[0-9]+)+`
|
||||
const issueRefRegexpStrNoKeyword = `(?:\s|^|\(|\[)(?:([0-9a-zA-Z-_\.]+)/([0-9a-zA-Z-_\.]+))?(#[0-9]+)(?:\s|$|\)|\]|\.(\s|$))`
|
||||
|
||||
func assembleKeywordsPattern(words []string) string {
|
||||
return fmt.Sprintf(`(?i)(?:%s)(?::?) %s`, strings.Join(words, "|"), issueRefRegexpStr)
|
||||
@@ -73,7 +74,7 @@ func assembleKeywordsPattern(words []string) string {
|
||||
func init() {
|
||||
issueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueCloseKeywords))
|
||||
issueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueReopenKeywords))
|
||||
issueReferenceKeywordsPat = regexp.MustCompile(issueRefRegexpStr)
|
||||
issueReferenceKeywordsPat = regexp.MustCompile(issueRefRegexpStrNoKeyword)
|
||||
}
|
||||
|
||||
// Action represents user operation type and other information to
|
||||
|
||||
@@ -155,6 +155,25 @@ func TestPushCommits_AvatarLink(t *testing.T) {
|
||||
pushCommits.AvatarLink("nonexistent@example.com"))
|
||||
}
|
||||
|
||||
func TestRegExp_issueReferenceKeywordsPat(t *testing.T) {
|
||||
trueTestCases := []string{
|
||||
"#2",
|
||||
"[#2]",
|
||||
"please see go-gitea/gitea#5",
|
||||
}
|
||||
falseTestCases := []string{
|
||||
"kb#2",
|
||||
"#2xy",
|
||||
}
|
||||
|
||||
for _, testCase := range trueTestCases {
|
||||
assert.True(t, issueReferenceKeywordsPat.MatchString(testCase))
|
||||
}
|
||||
for _, testCase := range falseTestCases {
|
||||
assert.False(t, issueReferenceKeywordsPat.MatchString(testCase))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getIssueFromRef(t *testing.T) {
|
||||
assert.NoError(t, PrepareTestDatabase())
|
||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ func (protectBranch *ProtectedBranch) HasEnoughApprovals(pr *PullRequest) bool {
|
||||
|
||||
// GetGrantedApprovalsCount returns the number of granted approvals for pr. A granted approval must be authored by a user in an approval whitelist.
|
||||
func (protectBranch *ProtectedBranch) GetGrantedApprovalsCount(pr *PullRequest) int64 {
|
||||
reviews, err := GetReviewersByPullID(pr.Issue.ID)
|
||||
reviews, err := GetReviewersByPullID(pr.IssueID)
|
||||
if err != nil {
|
||||
log.Error("GetReviewersByPullID: %v", err)
|
||||
return 0
|
||||
|
||||
@@ -12,13 +12,13 @@ import (
|
||||
|
||||
// PushingEnvironment returns an os environment to allow hooks to work on push
|
||||
func PushingEnvironment(doer *User, repo *Repository) []string {
|
||||
return FullPushingEnvironment(doer, doer, repo, 0)
|
||||
return FullPushingEnvironment(doer, doer, repo, repo.Name, 0)
|
||||
}
|
||||
|
||||
// FullPushingEnvironment returns an os environment to allow hooks to work on push
|
||||
func FullPushingEnvironment(author, committer *User, repo *Repository, prID int64) []string {
|
||||
func FullPushingEnvironment(author, committer *User, repo *Repository, repoName string, prID int64) []string {
|
||||
isWiki := "false"
|
||||
if strings.HasSuffix(repo.Name, ".wiki") {
|
||||
if strings.HasSuffix(repoName, ".wiki") {
|
||||
isWiki = "true"
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ func FullPushingEnvironment(author, committer *User, repo *Repository, prID int6
|
||||
"GIT_AUTHOR_EMAIL="+authorSig.Email,
|
||||
"GIT_COMMITTER_NAME="+committerSig.Name,
|
||||
"GIT_COMMITTER_EMAIL="+committerSig.Email,
|
||||
EnvRepoName+"="+repo.Name,
|
||||
EnvRepoName+"="+repoName,
|
||||
EnvRepoUsername+"="+repo.MustOwnerName(),
|
||||
EnvRepoIsWiki+"="+isWiki,
|
||||
EnvPusherName+"="+committer.Name,
|
||||
|
||||
@@ -1835,3 +1835,22 @@ func (issue *Issue) BlockedByDependencies() ([]*Issue, error) {
|
||||
func (issue *Issue) BlockingDependencies() ([]*Issue, error) {
|
||||
return issue.getBlockingDependencies(x)
|
||||
}
|
||||
|
||||
func (issue *Issue) updateClosedNum(e Engine) (err error) {
|
||||
if issue.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=(SELECT count(*) FROM issue WHERE repo_id=? AND is_pull=? AND is_closed=?) WHERE id=?",
|
||||
issue.RepoID,
|
||||
true,
|
||||
true,
|
||||
issue.RepoID,
|
||||
)
|
||||
} else {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=(SELECT count(*) FROM issue WHERE repo_id=? AND is_pull=? AND is_closed=?) WHERE id=?",
|
||||
issue.RepoID,
|
||||
false,
|
||||
true,
|
||||
issue.RepoID,
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -142,11 +142,15 @@ func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
if err := sess.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go HookQueue.Add(issue.RepoID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID int64, isCreate bool) (err error) {
|
||||
|
||||
// Update the assignee
|
||||
removed, err := updateIssueAssignee(sess, issue, assigneeID)
|
||||
if err != nil {
|
||||
@@ -209,7 +213,6 @@ func (issue *Issue) changeAssignee(sess *xorm.Session, doer *User, assigneeID in
|
||||
return nil
|
||||
}
|
||||
}
|
||||
go HookQueue.Add(issue.RepoID)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+2
-12
@@ -632,12 +632,7 @@ func sendCreateCommentAction(e *xorm.Session, opts *CreateCommentOptions, commen
|
||||
act.OpType = ActionReopenPullRequest
|
||||
}
|
||||
|
||||
if opts.Issue.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls-1 WHERE id=?", opts.Repo.ID)
|
||||
} else {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues-1 WHERE id=?", opts.Repo.ID)
|
||||
}
|
||||
if err != nil {
|
||||
if err = opts.Issue.updateClosedNum(e); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -647,12 +642,7 @@ func sendCreateCommentAction(e *xorm.Session, opts *CreateCommentOptions, commen
|
||||
act.OpType = ActionClosePullRequest
|
||||
}
|
||||
|
||||
if opts.Issue.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_pulls=num_closed_pulls+1 WHERE id=?", opts.Repo.ID)
|
||||
} else {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_closed_issues=num_closed_issues+1 WHERE id=?", opts.Repo.ID)
|
||||
}
|
||||
if err != nil {
|
||||
if err = opts.Issue.updateClosedNum(e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
+58
-32
@@ -189,36 +189,6 @@ func (pr *PullRequest) apiFormat(e Engine) *api.PullRequest {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if baseBranch, err = pr.BaseRepo.GetBranch(pr.BaseBranch); err != nil {
|
||||
log.Error("pr.BaseRepo.GetBranch[%d]: %v", pr.BaseBranch, err)
|
||||
return nil
|
||||
}
|
||||
if baseCommit, err = baseBranch.GetCommit(); err != nil {
|
||||
log.Error("baseBranch.GetCommit[%d]: %v", pr.ID, err)
|
||||
return nil
|
||||
}
|
||||
if headBranch, err = pr.HeadRepo.GetBranch(pr.HeadBranch); err != nil {
|
||||
log.Error("pr.HeadRepo.GetBranch[%d]: %v", pr.HeadBranch, err)
|
||||
return nil
|
||||
}
|
||||
if headCommit, err = headBranch.GetCommit(); err != nil {
|
||||
log.Error("headBranch.GetCommit[%d]: %v", pr.ID, err)
|
||||
return nil
|
||||
}
|
||||
apiBaseBranchInfo := &api.PRBranchInfo{
|
||||
Name: pr.BaseBranch,
|
||||
Ref: pr.BaseBranch,
|
||||
Sha: baseCommit.ID.String(),
|
||||
RepoID: pr.BaseRepoID,
|
||||
Repository: pr.BaseRepo.innerAPIFormat(e, AccessModeNone, false),
|
||||
}
|
||||
apiHeadBranchInfo := &api.PRBranchInfo{
|
||||
Name: pr.HeadBranch,
|
||||
Ref: pr.HeadBranch,
|
||||
Sha: headCommit.ID.String(),
|
||||
RepoID: pr.HeadRepoID,
|
||||
Repository: pr.HeadRepo.innerAPIFormat(e, AccessModeNone, false),
|
||||
}
|
||||
|
||||
if err = pr.Issue.loadRepo(e); err != nil {
|
||||
log.Error("pr.Issue.loadRepo[%d]: %v", pr.ID, err)
|
||||
@@ -227,6 +197,7 @@ func (pr *PullRequest) apiFormat(e Engine) *api.PullRequest {
|
||||
|
||||
apiPullRequest := &api.PullRequest{
|
||||
ID: pr.ID,
|
||||
URL: pr.Issue.HTMLURL(),
|
||||
Index: pr.Index,
|
||||
Poster: apiIssue.Poster,
|
||||
Title: apiIssue.Title,
|
||||
@@ -241,13 +212,68 @@ func (pr *PullRequest) apiFormat(e Engine) *api.PullRequest {
|
||||
DiffURL: pr.Issue.DiffURL(),
|
||||
PatchURL: pr.Issue.PatchURL(),
|
||||
HasMerged: pr.HasMerged,
|
||||
Base: apiBaseBranchInfo,
|
||||
Head: apiHeadBranchInfo,
|
||||
MergeBase: pr.MergeBase,
|
||||
Deadline: apiIssue.Deadline,
|
||||
Created: pr.Issue.CreatedUnix.AsTimePtr(),
|
||||
Updated: pr.Issue.UpdatedUnix.AsTimePtr(),
|
||||
}
|
||||
baseBranch, err = pr.BaseRepo.GetBranch(pr.BaseBranch)
|
||||
if err != nil {
|
||||
if git.IsErrBranchNotExist(err) {
|
||||
apiPullRequest.Base = nil
|
||||
} else {
|
||||
log.Error("GetBranch[%s]: %v", pr.BaseBranch, err)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
apiBaseBranchInfo := &api.PRBranchInfo{
|
||||
Name: pr.BaseBranch,
|
||||
Ref: pr.BaseBranch,
|
||||
RepoID: pr.BaseRepoID,
|
||||
Repository: pr.BaseRepo.innerAPIFormat(e, AccessModeNone, false),
|
||||
}
|
||||
baseCommit, err = baseBranch.GetCommit()
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
apiBaseBranchInfo.Sha = ""
|
||||
} else {
|
||||
log.Error("GetCommit[%s]: %v", baseBranch.Name, err)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
apiBaseBranchInfo.Sha = baseCommit.ID.String()
|
||||
}
|
||||
apiPullRequest.Base = apiBaseBranchInfo
|
||||
}
|
||||
|
||||
headBranch, err = pr.HeadRepo.GetBranch(pr.HeadBranch)
|
||||
if err != nil {
|
||||
if git.IsErrBranchNotExist(err) {
|
||||
apiPullRequest.Head = nil
|
||||
} else {
|
||||
log.Error("GetBranch[%s]: %v", pr.HeadBranch, err)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
apiHeadBranchInfo := &api.PRBranchInfo{
|
||||
Name: pr.HeadBranch,
|
||||
Ref: pr.HeadBranch,
|
||||
RepoID: pr.HeadRepoID,
|
||||
Repository: pr.HeadRepo.innerAPIFormat(e, AccessModeNone, false),
|
||||
}
|
||||
headCommit, err = headBranch.GetCommit()
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
apiHeadBranchInfo.Sha = ""
|
||||
} else {
|
||||
log.Error("GetCommit[%s]: %v", headBranch.Name, err)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
apiHeadBranchInfo.Sha = headCommit.ID.String()
|
||||
}
|
||||
apiPullRequest.Head = apiHeadBranchInfo
|
||||
}
|
||||
|
||||
if pr.Status != PullRequestStatusChecking {
|
||||
mergeable := pr.Status != PullRequestStatusConflict && !pr.IsWorkInProgress()
|
||||
|
||||
+9
-1
@@ -31,7 +31,15 @@ func TestPullRequest_LoadIssue(t *testing.T) {
|
||||
assert.Equal(t, int64(2), pr.Issue.ID)
|
||||
}
|
||||
|
||||
// TODO TestPullRequest_APIFormat
|
||||
func TestPullRequest_APIFormat(t *testing.T) {
|
||||
assert.NoError(t, PrepareTestDatabase())
|
||||
pr := AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest)
|
||||
assert.NoError(t, pr.LoadAttributes())
|
||||
assert.NoError(t, pr.LoadIssue())
|
||||
apiPullRequest := pr.APIFormat()
|
||||
assert.NotNil(t, apiPullRequest)
|
||||
assert.Nil(t, apiPullRequest.Head)
|
||||
}
|
||||
|
||||
func TestPullRequest_GetBaseRepo(t *testing.T) {
|
||||
assert.NoError(t, PrepareTestDatabase())
|
||||
|
||||
+34
-4
@@ -134,8 +134,8 @@ type Repository struct {
|
||||
Owner *User `xorm:"-"`
|
||||
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
|
||||
Name string `xorm:"INDEX NOT NULL"`
|
||||
Description string
|
||||
Website string
|
||||
Description string `xorm:"TEXT"`
|
||||
Website string `xorm:"VARCHAR(2048)"`
|
||||
DefaultBranch string
|
||||
|
||||
NumWatches int
|
||||
@@ -1324,7 +1324,6 @@ func createRepository(e *xorm.Session, doer, u *User, repo *Repository) (err err
|
||||
}); err != nil {
|
||||
return fmt.Errorf("prepareWebhooks: %v", err)
|
||||
}
|
||||
go HookQueue.Add(repo.ID)
|
||||
} else if err = repo.recalculateAccesses(e); err != nil {
|
||||
// Organization automatically called this in addRepository method.
|
||||
return fmt.Errorf("recalculateAccesses: %v", err)
|
||||
@@ -1393,7 +1392,16 @@ func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err
|
||||
}
|
||||
}
|
||||
|
||||
return repo, sess.Commit()
|
||||
if err = sess.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Add to hook queue for created repo after session commit.
|
||||
if u.IsOrganization() {
|
||||
go HookQueue.Add(repo.ID)
|
||||
}
|
||||
|
||||
return repo, err
|
||||
}
|
||||
|
||||
func countRepositories(userID int64, private bool) int64 {
|
||||
@@ -2327,6 +2335,23 @@ func CheckRepoStats() {
|
||||
}
|
||||
// ***** END: Repository.NumClosedIssues *****
|
||||
|
||||
// ***** START: Repository.NumClosedPulls *****
|
||||
desc = "repository count 'num_closed_pulls'"
|
||||
results, err = x.Query("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, true)
|
||||
if err != nil {
|
||||
log.Error("Select %s: %v", desc, err)
|
||||
} else {
|
||||
for _, result := range results {
|
||||
id := com.StrTo(result["id"]).MustInt64()
|
||||
log.Trace("Updating %s: %d", desc, id)
|
||||
_, err = x.Exec("UPDATE `repository` SET num_closed_pulls=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_closed=? AND is_pull=?) WHERE id=?", id, true, true, id)
|
||||
if err != nil {
|
||||
log.Error("Update %s[%d]: %v", desc, id, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// ***** END: Repository.NumClosedPulls *****
|
||||
|
||||
// FIXME: use checker when stop supporting old fork repo format.
|
||||
// ***** START: Repository.NumForks *****
|
||||
results, err = x.Query("SELECT repo.id FROM `repository` repo WHERE repo.num_forks!=(SELECT COUNT(*) FROM `repository` WHERE fork_id=repo.id)")
|
||||
@@ -2461,6 +2486,11 @@ func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *R
|
||||
go HookQueue.Add(oldRepo.ID)
|
||||
}
|
||||
|
||||
// Add to hook queue for created repo after session commit.
|
||||
if u.IsOrganization() {
|
||||
go HookQueue.Add(repo.ID)
|
||||
}
|
||||
|
||||
if err = repo.UpdateSize(); err != nil {
|
||||
log.Error("Failed to update size for repository: %v", err)
|
||||
}
|
||||
|
||||
+5
-4
@@ -195,9 +195,9 @@ func (u *User) UpdateTheme(themeName string) error {
|
||||
return UpdateUserCols(u, "theme")
|
||||
}
|
||||
|
||||
// getEmail returns an noreply email, if the user has set to keep his
|
||||
// GetEmail returns an noreply email, if the user has set to keep his
|
||||
// email address private, otherwise the primary email address.
|
||||
func (u *User) getEmail() string {
|
||||
func (u *User) GetEmail() string {
|
||||
if u.KeepEmailPrivate {
|
||||
return fmt.Sprintf("%s@%s", u.LowerName, setting.Service.NoReplyAddress)
|
||||
}
|
||||
@@ -210,7 +210,7 @@ func (u *User) APIFormat() *api.User {
|
||||
ID: u.ID,
|
||||
UserName: u.Name,
|
||||
FullName: u.FullName,
|
||||
Email: u.getEmail(),
|
||||
Email: u.GetEmail(),
|
||||
AvatarURL: u.AvatarLink(),
|
||||
Language: u.Language,
|
||||
IsAdmin: u.IsAdmin,
|
||||
@@ -425,7 +425,7 @@ func (u *User) GetFollowing(page int) ([]*User, error) {
|
||||
func (u *User) NewGitSig() *git.Signature {
|
||||
return &git.Signature{
|
||||
Name: u.GitName(),
|
||||
Email: u.getEmail(),
|
||||
Email: u.GetEmail(),
|
||||
When: time.Now(),
|
||||
}
|
||||
}
|
||||
@@ -751,6 +751,7 @@ var (
|
||||
"robots.txt",
|
||||
".",
|
||||
"..",
|
||||
".well-known",
|
||||
}
|
||||
reservedUserPatterns = []string{"*.keys", "*.gpg"}
|
||||
)
|
||||
|
||||
+7
-1
@@ -217,7 +217,13 @@ func (repo *Repository) updateWikiPage(doer *User, oldWikiName, newWikiName, con
|
||||
if err := git.Push(basePath, git.PushOptions{
|
||||
Remote: "origin",
|
||||
Branch: fmt.Sprintf("%s:%s%s", commitHash.String(), git.BranchPrefix, "master"),
|
||||
Env: PushingEnvironment(doer, repo),
|
||||
Env: FullPushingEnvironment(
|
||||
doer,
|
||||
doer,
|
||||
repo,
|
||||
repo.Name+".wiki",
|
||||
0,
|
||||
),
|
||||
}); err != nil {
|
||||
log.Error("%v", err)
|
||||
return fmt.Errorf("Push: %v", err)
|
||||
|
||||
@@ -68,7 +68,9 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache LastCom
|
||||
// get it for free during the tree traversal and it's used for listing
|
||||
// pages to display information about newest commit for a given path.
|
||||
var treeCommit *Commit
|
||||
if rev, ok := revs[""]; ok {
|
||||
if treePath == "" {
|
||||
treeCommit = commit
|
||||
} else if rev, ok := revs[""]; ok {
|
||||
treeCommit = convertCommit(rev)
|
||||
}
|
||||
return commitsInfo, treeCommit, nil
|
||||
|
||||
@@ -28,21 +28,27 @@ func cloneRepo(url, dir, name string) (string, error) {
|
||||
func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
|
||||
// these test case are specific to the repo1 test repo
|
||||
testCases := []struct {
|
||||
CommitID string
|
||||
Path string
|
||||
ExpectedIDs map[string]string
|
||||
CommitID string
|
||||
Path string
|
||||
ExpectedIDs map[string]string
|
||||
ExpectedTreeCommit string
|
||||
}{
|
||||
{"8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", "", map[string]string{
|
||||
"file1.txt": "95bb4d39648ee7e325106df01a621c530863a653",
|
||||
"file2.txt": "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2",
|
||||
}},
|
||||
}, "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2"},
|
||||
{"2839944139e0de9737a044f78b0e4b40d989a9e3", "", map[string]string{
|
||||
"file1.txt": "2839944139e0de9737a044f78b0e4b40d989a9e3",
|
||||
"branch1.txt": "9c9aef8dd84e02bc7ec12641deb4c930a7c30185",
|
||||
}},
|
||||
}, "2839944139e0de9737a044f78b0e4b40d989a9e3"},
|
||||
{"5c80b0245c1c6f8343fa418ec374b13b5d4ee658", "branch2", map[string]string{
|
||||
"branch2.txt": "5c80b0245c1c6f8343fa418ec374b13b5d4ee658",
|
||||
}},
|
||||
}, "5c80b0245c1c6f8343fa418ec374b13b5d4ee658"},
|
||||
{"feaf4ba6bc635fec442f46ddd4512416ec43c2c2", "", map[string]string{
|
||||
"file1.txt": "95bb4d39648ee7e325106df01a621c530863a653",
|
||||
"file2.txt": "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2",
|
||||
"foo": "37991dec2c8e592043f47155ce4808d4580f9123",
|
||||
}, "feaf4ba6bc635fec442f46ddd4512416ec43c2c2"},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
commit, err := repo1.GetCommit(testCase.CommitID)
|
||||
@@ -51,7 +57,8 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
|
||||
assert.NoError(t, err)
|
||||
entries, err := tree.ListEntries()
|
||||
assert.NoError(t, err)
|
||||
commitsInfo, _, err := entries.GetCommitsInfo(commit, testCase.Path, nil)
|
||||
commitsInfo, treeCommit, err := entries.GetCommitsInfo(commit, testCase.Path, nil)
|
||||
assert.Equal(t, testCase.ExpectedTreeCommit, treeCommit.ID.String())
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, commitsInfo, len(testCase.ExpectedIDs))
|
||||
for _, commitInfo := range commitsInfo {
|
||||
|
||||
@@ -23,12 +23,12 @@ func TestRepository_GetCodeActivityStats(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, code)
|
||||
|
||||
assert.EqualValues(t, 8, code.CommitCount)
|
||||
assert.EqualValues(t, 2, code.AuthorCount)
|
||||
assert.EqualValues(t, 8, code.CommitCountInAllBranches)
|
||||
assert.EqualValues(t, 9, code.CommitCount)
|
||||
assert.EqualValues(t, 3, code.AuthorCount)
|
||||
assert.EqualValues(t, 9, code.CommitCountInAllBranches)
|
||||
assert.EqualValues(t, 10, code.Additions)
|
||||
assert.EqualValues(t, 1, code.Deletions)
|
||||
assert.Len(t, code.Authors, 2)
|
||||
assert.Len(t, code.Authors, 3)
|
||||
assert.Contains(t, code.Authors, "tris.git@shoddynet.org")
|
||||
assert.EqualValues(t, 3, code.Authors["tris.git@shoddynet.org"])
|
||||
assert.EqualValues(t, 5, code.Authors[""])
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
37991dec2c8e592043f47155ce4808d4580f9123 feaf4ba6bc635fec442f46ddd4512416ec43c2c2 silverwind <me@silverwind.io> 1563741799 +0200 push
|
||||
@@ -0,0 +1 @@
|
||||
37991dec2c8e592043f47155ce4808d4580f9123 feaf4ba6bc635fec442f46ddd4512416ec43c2c2 silverwind <me@silverwind.io> 1563741799 +0200 push
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
37991dec2c8e592043f47155ce4808d4580f9123
|
||||
feaf4ba6bc635fec442f46ddd4512416ec43c2c2
|
||||
@@ -153,7 +153,7 @@ func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
|
||||
}
|
||||
|
||||
body = blackfriday.Markdown(body, renderer, exts)
|
||||
return body
|
||||
return markup.SanitizeBytes(body)
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -111,7 +111,7 @@ func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) err
|
||||
RepoID: g.repo.ID,
|
||||
Name: milestone.Title,
|
||||
Content: milestone.Description,
|
||||
IsClosed: milestone.State == "close",
|
||||
IsClosed: milestone.State == "closed",
|
||||
DeadlineUnix: deadline,
|
||||
}
|
||||
if ms.IsClosed && milestone.Closed != nil {
|
||||
|
||||
@@ -173,6 +173,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
|
||||
|
||||
var (
|
||||
closed1 = time.Date(2018, 10, 23, 02, 57, 43, 0, time.UTC)
|
||||
closed7 = time.Date(2019, 7, 8, 8, 20, 23, 0, time.UTC)
|
||||
)
|
||||
assert.EqualValues(t, []*base.Issue{
|
||||
{
|
||||
@@ -208,9 +209,9 @@ func TestGitHubDownloadRepo(t *testing.T) {
|
||||
Number: 7,
|
||||
Title: "display page revisions on wiki",
|
||||
Content: "Hi guys,\r\n\r\nWiki on Gogs is very fine, I liked a lot, but I think that is good idea to be possible see other revisions from page as a page history.\r\n\r\nWhat you think?\r\n\r\nReference: https://github.com/gogits/gogs/issues/2991",
|
||||
Milestone: "1.x.x",
|
||||
Milestone: "1.10.0",
|
||||
PosterName: "joubertredrat",
|
||||
State: "open",
|
||||
State: "closed",
|
||||
Created: time.Date(2016, 11, 02, 18, 57, 32, 0, time.UTC),
|
||||
Labels: []*base.Label{
|
||||
{
|
||||
@@ -232,6 +233,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
|
||||
Heart: 0,
|
||||
Hooray: 0,
|
||||
},
|
||||
Closed: &closed7,
|
||||
},
|
||||
{
|
||||
Number: 8,
|
||||
|
||||
@@ -49,7 +49,6 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
||||
}
|
||||
|
||||
defer func() {
|
||||
go models.HookQueue.Add(pr.BaseRepo.ID)
|
||||
go models.AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false)
|
||||
}()
|
||||
|
||||
@@ -102,7 +101,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
||||
}
|
||||
|
||||
// Fetch head branch
|
||||
if err := git.NewCommand("fetch", remoteRepoName).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||
if err := git.NewCommand("fetch", remoteRepoName, pr.HeadBranch).RunInDirPipeline(tmpBasePath, nil, &errbuf); err != nil {
|
||||
return fmt.Errorf("git fetch [%s -> %s]: %s", headRepoPath, tmpBasePath, errbuf.String())
|
||||
}
|
||||
|
||||
@@ -241,7 +240,13 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
||||
headUser = doer
|
||||
}
|
||||
|
||||
env := models.FullPushingEnvironment(headUser, doer, pr.BaseRepo, pr.ID)
|
||||
env := models.FullPushingEnvironment(
|
||||
headUser,
|
||||
doer,
|
||||
pr.BaseRepo,
|
||||
pr.BaseRepo.Name,
|
||||
pr.ID,
|
||||
)
|
||||
|
||||
// Push back to upstream.
|
||||
if err := git.NewCommand("push", "origin", pr.BaseBranch).RunInDirTimeoutEnvPipeline(env, -1, tmpBasePath, nil, &errbuf); err != nil {
|
||||
|
||||
@@ -694,6 +694,7 @@ editor.delete = Delete '%s'
|
||||
editor.commit_message_desc = Add an optional extended description…
|
||||
editor.commit_directly_to_this_branch = Commit directly to the <strong class="branch-name">%s</strong> branch.
|
||||
editor.create_new_branch = Create a <strong>new branch</strong> for this commit and start a pull request.
|
||||
editor.propose_file_change = Propose file change
|
||||
editor.new_branch_name_desc = New branch name…
|
||||
editor.cancel = Cancel
|
||||
editor.filename_cannot_be_empty = The filename cannot be empty.
|
||||
|
||||
@@ -208,6 +208,9 @@ footer .ui.left,footer .ui.right{line-height:40px}
|
||||
.ui.tabular.menu .item{color:rgba(0,0,0,.5)}
|
||||
.ui.tabular.menu .item:hover{color:rgba(0,0,0,.8)}
|
||||
.ui.tabular.menu .item.active{color:rgba(0,0,0,.9)}
|
||||
.inline-grouped-list{display:inline-block;vertical-align:top}
|
||||
.inline-grouped-list>.ui{display:block;margin-top:5px;margin-bottom:10px}
|
||||
.inline-grouped-list>.ui:first-child{margin-top:1px}
|
||||
.markdown:not(code){overflow:hidden;font-size:16px;line-height:1.6!important;word-wrap:break-word}
|
||||
.markdown:not(code).ui.segment{padding:3em}
|
||||
.markdown:not(code).file-view{padding:2em 2em 2em!important}
|
||||
@@ -744,7 +747,7 @@ footer .ui.left,footer .ui.right{line-height:40px}
|
||||
.repository .segment.reactions .select-reaction{float:none}
|
||||
.repository .segment.reactions .select-reaction:not(.active) a{display:none}
|
||||
.repository .segment.reactions:hover .select-reaction a{display:block}
|
||||
.user-cards .list{padding:0}
|
||||
.user-cards .list{padding:0;display:flex;flex-wrap:wrap}
|
||||
.user-cards .list .item{list-style:none;width:32%;margin:10px 10px 10px 0;padding-bottom:14px;float:left}
|
||||
.user-cards .list .item .avatar{width:48px;height:48px;float:left;display:block;margin-right:10px}
|
||||
.user-cards .list .item .name{margin-top:0;margin-bottom:0;font-weight:400}
|
||||
|
||||
@@ -209,7 +209,7 @@ a.ui.label:hover,a.ui.labels .label:hover{background-color:#505667;color:#dbdbdb
|
||||
.repository .label.list .item{border-bottom:1px dashed #4c505c}
|
||||
.ui.basic.blue.button,.ui.basic.blue.buttons .button{box-shadow:0 0 0 1px #87ab63 inset!important;color:#87ab63!important}
|
||||
.repository.file.list #file-content .code-view .hljs,.repository.file.list #file-content .code-view .lines-code ol,.repository.file.list #file-content .code-view .lines-code pre,.repository.file.list #file-content .code-view .lines-num .hljs,.repository.file.list #file-content .code-view .lines-num ol,.repository.file.list #file-content .code-view .lines-num pre{background-color:#2a2e3a}
|
||||
.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(1),.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(2),.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(3),.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(4),.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(5),.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(6){background-color:#2a2e3a}
|
||||
.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(1),.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(2),.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(3),.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(4),.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(5),.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(6){background-color:#2a2e3a}
|
||||
.repository .diff-file-box .code-diff-split tbody tr td.add-code,.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(4),.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(5),.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(6){background-color:#283e2d!important;border-color:#314a37!important}
|
||||
.repository .diff-file-box .code-diff-split tbody tr td.del-code,.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(1),.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(2),.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(3){background-color:#3c2626!important;border-color:#634343!important}
|
||||
.ui.blue.button:active,.ui.blue.buttons .button:active{background-color:#a27558}
|
||||
|
||||
+22
-11
@@ -10,6 +10,11 @@ function htmlEncode(text) {
|
||||
var csrf;
|
||||
var suburl;
|
||||
|
||||
// Disable Dropzone auto-discover because it's manually initialized
|
||||
if (typeof(Dropzone) !== "undefined") {
|
||||
Dropzone.autoDiscover = false;
|
||||
}
|
||||
|
||||
// Polyfill for IE9+ support (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from)
|
||||
if (!Array.from) {
|
||||
Array.from = (function () {
|
||||
@@ -1270,6 +1275,7 @@ function initEditor() {
|
||||
$('.quick-pull-branch-name').hide();
|
||||
$('.quick-pull-branch-name input').prop('required',false);
|
||||
}
|
||||
$('#commit-button').text($(this).attr('button_text'));
|
||||
});
|
||||
|
||||
var $editFilename = $("#file-name");
|
||||
@@ -1968,17 +1974,18 @@ $(document).ready(function () {
|
||||
|
||||
// Highlight JS
|
||||
if (typeof hljs != 'undefined') {
|
||||
hljs.initHighlightingOnLoad();
|
||||
const nodes = [].slice.call(document.querySelectorAll('pre code') || []);
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
hljs.highlightBlock(nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Dropzone
|
||||
var $dropzone = $('#dropzone');
|
||||
const $dropzone = $('#dropzone');
|
||||
if ($dropzone.length > 0) {
|
||||
// Disable auto discover for all elements:
|
||||
Dropzone.autoDiscover = false;
|
||||
const filenameDict = {};
|
||||
|
||||
var filenameDict = {};
|
||||
$dropzone.dropzone({
|
||||
new Dropzone("#dropzone", {
|
||||
url: $dropzone.data('upload-url'),
|
||||
headers: {"X-Csrf-Token": csrf},
|
||||
maxFiles: $dropzone.data('max-file'),
|
||||
@@ -2006,7 +2013,7 @@ $(document).ready(function () {
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2104,12 +2111,16 @@ $(document).ready(function () {
|
||||
});
|
||||
|
||||
$('.issue-action').click(function () {
|
||||
var action = this.dataset.action
|
||||
var elementId = this.dataset.elementId
|
||||
var issueIDs = $('.issue-checkbox').children('input:checked').map(function() {
|
||||
let action = this.dataset.action;
|
||||
let elementId = this.dataset.elementId;
|
||||
let issueIDs = $('.issue-checkbox').children('input:checked').map(function() {
|
||||
return this.dataset.issueId;
|
||||
}).get().join();
|
||||
var url = this.dataset.url
|
||||
let url = this.dataset.url;
|
||||
if (elementId === '0' && url.substr(-9) === '/assignee'){
|
||||
elementId = '';
|
||||
action = 'clear';
|
||||
}
|
||||
updateIssuesMeta(url, action, issueIDs, elementId).then(reload);
|
||||
});
|
||||
|
||||
|
||||
+16
-1
@@ -605,7 +605,6 @@ code,
|
||||
.file-comment {
|
||||
font: 12px @monospaced-fonts, monospace;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
|
||||
}
|
||||
|
||||
.ui.floating.dropdown {
|
||||
@@ -877,3 +876,19 @@ footer {
|
||||
.ui.tabular.menu .item.active {
|
||||
color: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
|
||||
/* multiple radio or checkboxes as inline element */
|
||||
.inline-grouped-list {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
||||
> .ui {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1971,6 +1971,8 @@
|
||||
&.user-cards {
|
||||
.list {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
list-style: none;
|
||||
|
||||
@@ -1082,7 +1082,7 @@ a.ui.labels .label:hover {
|
||||
|
||||
.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(1),
|
||||
.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(2),
|
||||
.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(3),
|
||||
.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(3),
|
||||
.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(4),
|
||||
.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(5),
|
||||
.repository .diff-file-box .code-diff-split tbody tr.del-code td:nth-child(6) {
|
||||
|
||||
Vendored
+4
-1
@@ -6,7 +6,10 @@ File(s): /vendor/plugins/jquery.areyousure/jquery.are-you-sure.js
|
||||
Version: 1.9.0
|
||||
|
||||
File(s): /vendor/plugins/jquery/jquery.min.js
|
||||
Version: 1.12.4
|
||||
Version: 3.4.1
|
||||
|
||||
File(s): /vendor/plugins/jquery-migrate/jquery-migrate.min.js
|
||||
Version: 3.0.1
|
||||
|
||||
File(s): /vendor/plugins/semantic/semantic.min.js
|
||||
Version: 2.3.1
|
||||
|
||||
Vendored
+7
-2
@@ -17,8 +17,13 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="./plugins/jquery/jquery.min.js">jquery.min.js</a></td>
|
||||
<td><a href="http://www.freebsd.org/copyright/freebsd-license.html">Expat</a></td>
|
||||
<td><a href="https://code.jquery.com/jquery-1.12.4.min.js">jquery-1.12.4.min.js</a></td>
|
||||
<td><a href="https://jquery.org/license/">MIT</a></td>
|
||||
<td><a href="https://code.jquery.com/jquery-3.4.1.min.js">jquery-3.4.1.min.js</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="./plugins/jquery-migrate/jquery-migrate.min.js">jquery-migrate.min.js</a></td>
|
||||
<td><a href="https://jquery.org/license/">MIT</a></td>
|
||||
<td><a href="https://code.jquery.com/jquery-migrate-3.0.1.min.js">jquery-migrate-3.0.1.min.js</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="./plugins/semantic/semantic.min.js">semantic.min.js</a></td>
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*! jQuery Migrate v3.0.1 | (c) jQuery Foundation and other contributors | jquery.org/license */
|
||||
|
||||
void 0 === jQuery.migrateMute && (jQuery.migrateMute = !0), function(e) {
|
||||
"function" == typeof define && define.amd ? define([ "jquery" ], window, e) : "object" == typeof module && module.exports ? module.exports = e(require("jquery"), window) : e(jQuery, window);
|
||||
}(function(e, t) {
|
||||
"use strict";
|
||||
function r(r) {
|
||||
var n = t.console;
|
||||
o[r] || (o[r] = !0, e.migrateWarnings.push(r), n && n.warn && !e.migrateMute && (n.warn("JQMIGRATE: " + r),
|
||||
e.migrateTrace && n.trace && n.trace()));
|
||||
}
|
||||
function n(e, t, n, a) {
|
||||
Object.defineProperty(e, t, {
|
||||
configurable: !0,
|
||||
enumerable: !0,
|
||||
get: function() {
|
||||
return r(a), n;
|
||||
},
|
||||
set: function(e) {
|
||||
r(a), n = e;
|
||||
}
|
||||
});
|
||||
}
|
||||
function a(e, t, n, a) {
|
||||
e[t] = function() {
|
||||
return r(a), n.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
e.migrateVersion = "3.0.1", function() {
|
||||
var r = /^[12]\./;
|
||||
t.console && t.console.log && (e && !r.test(e.fn.jquery) || t.console.log("JQMIGRATE: jQuery 3.0.0+ REQUIRED"),
|
||||
e.migrateWarnings && t.console.log("JQMIGRATE: Migrate plugin loaded multiple times"),
|
||||
t.console.log("JQMIGRATE: Migrate is installed" + (e.migrateMute ? "" : " with logging active") + ", version " + e.migrateVersion));
|
||||
}();
|
||||
var o = {};
|
||||
e.migrateWarnings = [], void 0 === e.migrateTrace && (e.migrateTrace = !0), e.migrateReset = function() {
|
||||
o = {}, e.migrateWarnings.length = 0;
|
||||
}, "BackCompat" === t.document.compatMode && r("jQuery is not compatible with Quirks Mode");
|
||||
var i = e.fn.init, s = e.isNumeric, u = e.find, c = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, l = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g;
|
||||
e.fn.init = function(e) {
|
||||
var t = Array.prototype.slice.call(arguments);
|
||||
return "string" == typeof e && "#" === e && (r("jQuery( '#' ) is not a valid selector"),
|
||||
t[0] = []), i.apply(this, t);
|
||||
}, e.fn.init.prototype = e.fn, e.find = function(e) {
|
||||
var n = Array.prototype.slice.call(arguments);
|
||||
if ("string" == typeof e && c.test(e)) try {
|
||||
t.document.querySelector(e);
|
||||
} catch (a) {
|
||||
e = e.replace(l, function(e, t, r, n) {
|
||||
return "[" + t + r + '"' + n + '"]';
|
||||
});
|
||||
try {
|
||||
t.document.querySelector(e), r("Attribute selector with '#' must be quoted: " + n[0]),
|
||||
n[0] = e;
|
||||
} catch (e) {
|
||||
r("Attribute selector with '#' was not fixed: " + n[0]);
|
||||
}
|
||||
}
|
||||
return u.apply(this, n);
|
||||
};
|
||||
var d;
|
||||
for (d in u) Object.prototype.hasOwnProperty.call(u, d) && (e.find[d] = u[d]);
|
||||
e.fn.size = function() {
|
||||
return r("jQuery.fn.size() is deprecated and removed; use the .length property"),
|
||||
this.length;
|
||||
}, e.parseJSON = function() {
|
||||
return r("jQuery.parseJSON is deprecated; use JSON.parse"), JSON.parse.apply(null, arguments);
|
||||
}, e.isNumeric = function(t) {
|
||||
var n = s(t), a = function(t) {
|
||||
var r = t && t.toString();
|
||||
return !e.isArray(t) && r - parseFloat(r) + 1 >= 0;
|
||||
}(t);
|
||||
return n !== a && r("jQuery.isNumeric() should not be called on constructed objects"),
|
||||
a;
|
||||
}, a(e, "holdReady", e.holdReady, "jQuery.holdReady is deprecated"), a(e, "unique", e.uniqueSort, "jQuery.unique is deprecated; use jQuery.uniqueSort"),
|
||||
n(e.expr, "filters", e.expr.pseudos, "jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"),
|
||||
n(e.expr, ":", e.expr.pseudos, "jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos");
|
||||
var p = e.ajax;
|
||||
e.ajax = function() {
|
||||
var e = p.apply(this, arguments);
|
||||
return e.promise && (a(e, "success", e.done, "jQXHR.success is deprecated and removed"),
|
||||
a(e, "error", e.fail, "jQXHR.error is deprecated and removed"), a(e, "complete", e.always, "jQXHR.complete is deprecated and removed")),
|
||||
e;
|
||||
};
|
||||
var f = e.fn.removeAttr, y = e.fn.toggleClass, m = /\S+/g;
|
||||
e.fn.removeAttr = function(t) {
|
||||
var n = this;
|
||||
return e.each(t.match(m), function(t, a) {
|
||||
e.expr.match.bool.test(a) && (r("jQuery.fn.removeAttr no longer sets boolean properties: " + a),
|
||||
n.prop(a, !1));
|
||||
}), f.apply(this, arguments);
|
||||
}, e.fn.toggleClass = function(t) {
|
||||
return void 0 !== t && "boolean" != typeof t ? y.apply(this, arguments) : (r("jQuery.fn.toggleClass( boolean ) is deprecated"),
|
||||
this.each(function() {
|
||||
var r = this.getAttribute && this.getAttribute("class") || "";
|
||||
r && e.data(this, "__className__", r), this.setAttribute && this.setAttribute("class", r || !1 === t ? "" : e.data(this, "__className__") || "");
|
||||
}));
|
||||
};
|
||||
var h = !1;
|
||||
e.swap && e.each([ "height", "width", "reliableMarginRight" ], function(t, r) {
|
||||
var n = e.cssHooks[r] && e.cssHooks[r].get;
|
||||
n && (e.cssHooks[r].get = function() {
|
||||
var e;
|
||||
return h = !0, e = n.apply(this, arguments), h = !1, e;
|
||||
});
|
||||
}), e.swap = function(e, t, n, a) {
|
||||
var o, i, s = {};
|
||||
h || r("jQuery.swap() is undocumented and deprecated");
|
||||
for (i in t) s[i] = e.style[i], e.style[i] = t[i];
|
||||
o = n.apply(e, a || []);
|
||||
for (i in t) e.style[i] = s[i];
|
||||
return o;
|
||||
};
|
||||
var g = e.data;
|
||||
e.data = function(t, n, a) {
|
||||
var o;
|
||||
if (n && "object" == typeof n && 2 === arguments.length) {
|
||||
o = e.hasData(t) && g.call(this, t);
|
||||
var i = {};
|
||||
for (var s in n) s !== e.camelCase(s) ? (r("jQuery.data() always sets/gets camelCased names: " + s),
|
||||
o[s] = n[s]) : i[s] = n[s];
|
||||
return g.call(this, t, i), n;
|
||||
}
|
||||
return n && "string" == typeof n && n !== e.camelCase(n) && (o = e.hasData(t) && g.call(this, t)) && n in o ? (r("jQuery.data() always sets/gets camelCased names: " + n),
|
||||
arguments.length > 2 && (o[n] = a), o[n]) : g.apply(this, arguments);
|
||||
};
|
||||
var v = e.Tween.prototype.run, j = function(e) {
|
||||
return e;
|
||||
};
|
||||
e.Tween.prototype.run = function() {
|
||||
e.easing[this.easing].length > 1 && (r("'jQuery.easing." + this.easing.toString() + "' should use only one argument"),
|
||||
e.easing[this.easing] = j), v.apply(this, arguments);
|
||||
}, e.fx.interval = e.fx.interval || 13, t.requestAnimationFrame && n(e.fx, "interval", e.fx.interval, "jQuery.fx.interval is deprecated");
|
||||
var Q = e.fn.load, b = e.event.add, w = e.event.fix;
|
||||
e.event.props = [], e.event.fixHooks = {}, n(e.event.props, "concat", e.event.props.concat, "jQuery.event.props.concat() is deprecated and removed"),
|
||||
e.event.fix = function(t) {
|
||||
var n, a = t.type, o = this.fixHooks[a], i = e.event.props;
|
||||
if (i.length) for (r("jQuery.event.props are deprecated and removed: " + i.join()); i.length; ) e.event.addProp(i.pop());
|
||||
if (o && !o._migrated_ && (o._migrated_ = !0, r("jQuery.event.fixHooks are deprecated and removed: " + a),
|
||||
(i = o.props) && i.length)) for (;i.length; ) e.event.addProp(i.pop());
|
||||
return n = w.call(this, t), o && o.filter ? o.filter(n, t) : n;
|
||||
}, e.event.add = function(e, n) {
|
||||
return e === t && "load" === n && "complete" === t.document.readyState && r("jQuery(window).on('load'...) called after load event occurred"),
|
||||
b.apply(this, arguments);
|
||||
}, e.each([ "load", "unload", "error" ], function(t, n) {
|
||||
e.fn[n] = function() {
|
||||
var e = Array.prototype.slice.call(arguments, 0);
|
||||
return "load" === n && "string" == typeof e[0] ? Q.apply(this, e) : (r("jQuery.fn." + n + "() is deprecated"),
|
||||
e.splice(0, 0, n), arguments.length ? this.on.apply(this, e) : (this.triggerHandler.apply(this, e),
|
||||
this));
|
||||
};
|
||||
}), e.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "), function(t, n) {
|
||||
e.fn[n] = function(e, t) {
|
||||
return r("jQuery.fn." + n + "() event shorthand is deprecated"), arguments.length > 0 ? this.on(n, null, e, t) : this.trigger(n);
|
||||
};
|
||||
}), e(function() {
|
||||
e(t.document).triggerHandler("ready");
|
||||
}), e.event.special.ready = {
|
||||
setup: function() {
|
||||
this === t.document && r("'ready' event is deprecated");
|
||||
}
|
||||
}, e.fn.extend({
|
||||
bind: function(e, t, n) {
|
||||
return r("jQuery.fn.bind() is deprecated"), this.on(e, null, t, n);
|
||||
},
|
||||
unbind: function(e, t) {
|
||||
return r("jQuery.fn.unbind() is deprecated"), this.off(e, null, t);
|
||||
},
|
||||
delegate: function(e, t, n, a) {
|
||||
return r("jQuery.fn.delegate() is deprecated"), this.on(t, e, n, a);
|
||||
},
|
||||
undelegate: function(e, t, n) {
|
||||
return r("jQuery.fn.undelegate() is deprecated"), 1 === arguments.length ? this.off(e, "**") : this.off(t, e || "**", n);
|
||||
},
|
||||
hover: function(e, t) {
|
||||
return r("jQuery.fn.hover() is deprecated"), this.on("mouseenter", e).on("mouseleave", t || e);
|
||||
}
|
||||
});
|
||||
var x = e.fn.offset;
|
||||
e.fn.offset = function() {
|
||||
var n, a = this[0], o = {
|
||||
top: 0,
|
||||
left: 0
|
||||
};
|
||||
return a && a.nodeType ? (n = (a.ownerDocument || t.document).documentElement, e.contains(n, a) ? x.apply(this, arguments) : (r("jQuery.fn.offset() requires an element connected to a document"),
|
||||
o)) : (r("jQuery.fn.offset() requires a valid DOM element"), o);
|
||||
};
|
||||
var k = e.param;
|
||||
e.param = function(t, n) {
|
||||
var a = e.ajaxSettings && e.ajaxSettings.traditional;
|
||||
return void 0 === n && a && (r("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),
|
||||
n = a), k.call(this, t, n);
|
||||
};
|
||||
var A = e.fn.andSelf || e.fn.addBack;
|
||||
e.fn.andSelf = function() {
|
||||
return r("jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),
|
||||
A.apply(this, arguments);
|
||||
};
|
||||
var S = e.Deferred, q = [ [ "resolve", "done", e.Callbacks("once memory"), e.Callbacks("once memory"), "resolved" ], [ "reject", "fail", e.Callbacks("once memory"), e.Callbacks("once memory"), "rejected" ], [ "notify", "progress", e.Callbacks("memory"), e.Callbacks("memory") ] ];
|
||||
return e.Deferred = function(t) {
|
||||
var n = S(), a = n.promise();
|
||||
return n.pipe = a.pipe = function() {
|
||||
var t = arguments;
|
||||
return r("deferred.pipe() is deprecated"), e.Deferred(function(r) {
|
||||
e.each(q, function(o, i) {
|
||||
var s = e.isFunction(t[o]) && t[o];
|
||||
n[i[1]](function() {
|
||||
var t = s && s.apply(this, arguments);
|
||||
t && e.isFunction(t.promise) ? t.promise().done(r.resolve).fail(r.reject).progress(r.notify) : r[i[0] + "With"](this === a ? r.promise() : this, s ? [ t ] : arguments);
|
||||
});
|
||||
}), t = null;
|
||||
}).promise();
|
||||
}, t && t.call(n, n), n;
|
||||
}, e.Deferred.exceptionHook = S.exceptionHook, e;
|
||||
});
|
||||
+2
-5
@@ -1,5 +1,2 @@
|
||||
/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|Line truncated
|
||||
}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFraLine truncated
|
||||
marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]Line truncated
|
||||
padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});
|
||||
/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */
|
||||
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}k.fn=k.prototype={jquery:f,constructor:k,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(n){return this.pushStack(k.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},k.extend=k.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(k.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||k.isPlainObject(n)?n:{},i=!1,a[t]=k.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},k.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t){b(e,{nonce:t&&t.nonce})},each:function(e,t){var n,r=0;if(d(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(p,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?k.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g.apply([],a)},guid:1,support:y}),"function"==typeof Symbol&&(k.fn[Symbol.iterator]=t[Symbol.iterator]),k.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var h=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,k="sizzle"+1*new Date,m=n.document,S=0,r=0,p=ue(),x=ue(),N=ue(),A=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",$=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",F=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+Line truncated
|
||||
@@ -91,8 +91,7 @@ func CreateUser(ctx *context.APIContext, form api.CreateUserOption) {
|
||||
if form.SendNotify && setting.MailService != nil {
|
||||
models.SendRegisterNotifyMail(ctx.Context.Context, u)
|
||||
}
|
||||
|
||||
ctx.JSON(201, u.APIFormat())
|
||||
ctx.JSON(201, convert.ToUser(u, ctx.IsSigned, ctx.User.IsAdmin))
|
||||
}
|
||||
|
||||
// EditUser api for modifying a user's information
|
||||
@@ -181,7 +180,7 @@ func EditUser(ctx *context.APIContext, form api.EditUserOption) {
|
||||
}
|
||||
log.Trace("Account profile updated by admin (%s): %s", ctx.User.Name, u.Name)
|
||||
|
||||
ctx.JSON(200, u.APIFormat())
|
||||
ctx.JSON(200, convert.ToUser(u, ctx.IsSigned, ctx.User.IsAdmin))
|
||||
}
|
||||
|
||||
// DeleteUser api for deleting a user
|
||||
@@ -326,7 +325,7 @@ func GetAllUsers(ctx *context.APIContext) {
|
||||
|
||||
results := make([]*api.User, len(users))
|
||||
for i := range users {
|
||||
results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
|
||||
results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User.IsAdmin)
|
||||
}
|
||||
|
||||
ctx.JSON(200, &results)
|
||||
|
||||
@@ -229,7 +229,7 @@ func ToTeam(team *models.Team) *api.Team {
|
||||
}
|
||||
|
||||
// ToUser convert models.User to api.User
|
||||
func ToUser(user *models.User, signed, admin bool) *api.User {
|
||||
func ToUser(user *models.User, signed, authed bool) *api.User {
|
||||
result := &api.User{
|
||||
ID: user.ID,
|
||||
UserName: user.Name,
|
||||
@@ -239,7 +239,12 @@ func ToUser(user *models.User, signed, admin bool) *api.User {
|
||||
LastLogin: user.LastLoginUnix.AsTime(),
|
||||
Created: user.CreatedUnix.AsTime(),
|
||||
}
|
||||
if signed && (!user.KeepEmailPrivate || admin) {
|
||||
// hide primary email if API caller isn't user itself or an admin
|
||||
if !signed {
|
||||
result.Email = ""
|
||||
} else if user.KeepEmailPrivate && !authed {
|
||||
result.Email = user.GetEmail()
|
||||
} else {
|
||||
result.Email = user.Email
|
||||
}
|
||||
return result
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
"code.gitea.io/gitea/routers/api/v1/user"
|
||||
)
|
||||
|
||||
@@ -46,7 +47,7 @@ func listMembers(ctx *context.APIContext, publicOnly bool) {
|
||||
|
||||
apiMembers := make([]*api.User, len(members))
|
||||
for i, member := range members {
|
||||
apiMembers[i] = member.APIFormat()
|
||||
apiMembers[i] = convert.ToUser(member, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
|
||||
}
|
||||
ctx.JSON(200, apiMembers)
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ func GetTeamMembers(ctx *context.APIContext) {
|
||||
}
|
||||
members := make([]*api.User, len(team.Members))
|
||||
for i, member := range team.Members {
|
||||
members[i] = member.APIFormat()
|
||||
members[i] = convert.ToUser(member, ctx.IsSigned, ctx.User.IsAdmin)
|
||||
}
|
||||
ctx.JSON(200, members)
|
||||
}
|
||||
@@ -288,7 +288,7 @@ func GetTeamMember(ctx *context.APIContext) {
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
ctx.JSON(200, u.APIFormat())
|
||||
ctx.JSON(200, convert.ToUser(u, ctx.IsSigned, ctx.User.IsAdmin))
|
||||
}
|
||||
|
||||
// AddTeamMember api for add a member to a team
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
)
|
||||
|
||||
// ListCollaborators list a repository's collaborators
|
||||
@@ -42,7 +43,7 @@ func ListCollaborators(ctx *context.APIContext) {
|
||||
}
|
||||
users := make([]*api.User, len(collaborators))
|
||||
for i, collaborator := range collaborators {
|
||||
users[i] = collaborator.APIFormat()
|
||||
users[i] = convert.ToUser(collaborator.User, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
|
||||
}
|
||||
ctx.JSON(200, users)
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ func GetSingleCommit(ctx *context.APIContext) {
|
||||
URL: setting.AppURL + ctx.Link[1:],
|
||||
SHA: commit.ID.String(),
|
||||
},
|
||||
HTMLURL: ctx.Repo.Repository.HTMLURL() + "/commits/" + commit.ID.String(),
|
||||
HTMLURL: ctx.Repo.Repository.HTMLURL() + "/commit/" + commit.ID.String(),
|
||||
RepoCommit: &api.RepoCommit{
|
||||
URL: setting.AppURL + ctx.Link[1:],
|
||||
Author: &api.CommitUser{
|
||||
@@ -111,7 +111,7 @@ func GetSingleCommit(ctx *context.APIContext) {
|
||||
},
|
||||
Message: commit.Message(),
|
||||
Tree: &api.CommitMeta{
|
||||
URL: ctx.Repo.Repository.APIURL() + "/trees/" + commit.ID.String(),
|
||||
URL: ctx.Repo.Repository.APIURL() + "/git/trees/" + commit.ID.String(),
|
||||
SHA: commit.ID.String(),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -130,8 +130,8 @@ func TestHook(ctx *context.APIContext) {
|
||||
convert.ToCommit(ctx.Repo.Repository, ctx.Repo.Commit),
|
||||
},
|
||||
Repo: ctx.Repo.Repository.APIFormat(models.AccessModeNone),
|
||||
Pusher: ctx.User.APIFormat(),
|
||||
Sender: ctx.User.APIFormat(),
|
||||
Pusher: convert.ToUser(ctx.User, ctx.IsSigned, false),
|
||||
Sender: convert.ToUser(ctx.User, ctx.IsSigned, false),
|
||||
}); err != nil {
|
||||
ctx.Error(500, "PrepareWebhook: ", err)
|
||||
return
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
)
|
||||
|
||||
// ListStargazers list a repository's stargazers
|
||||
@@ -38,7 +39,7 @@ func ListStargazers(ctx *context.APIContext) {
|
||||
}
|
||||
users := make([]*api.User, len(stargazers))
|
||||
for i, stargazer := range stargazers {
|
||||
users[i] = stargazer.APIFormat()
|
||||
users[i] = convert.ToUser(stargazer, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
|
||||
}
|
||||
ctx.JSON(200, users)
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
)
|
||||
|
||||
// ListSubscribers list a repo's subscribers (i.e. watchers)
|
||||
@@ -38,7 +39,7 @@ func ListSubscribers(ctx *context.APIContext) {
|
||||
}
|
||||
users := make([]*api.User, len(subscribers))
|
||||
for i, subscriber := range subscribers {
|
||||
users[i] = subscriber.APIFormat()
|
||||
users[i] = convert.ToUser(subscriber, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
|
||||
}
|
||||
ctx.JSON(200, users)
|
||||
}
|
||||
@@ -9,12 +9,13 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
)
|
||||
|
||||
func responseAPIUsers(ctx *context.APIContext, users []*models.User) {
|
||||
apiUsers := make([]*api.User, len(users))
|
||||
for i := range users {
|
||||
apiUsers[i] = users[i].APIFormat()
|
||||
apiUsers[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
|
||||
}
|
||||
ctx.JSON(200, &apiUsers)
|
||||
}
|
||||
|
||||
@@ -22,13 +22,13 @@ func appendPrivateInformation(apiKey *api.PublicKey, key *models.PublicKey, defa
|
||||
apiKey.KeyType = "user"
|
||||
|
||||
if defaultUser.ID == key.OwnerID {
|
||||
apiKey.Owner = defaultUser.APIFormat()
|
||||
apiKey.Owner = convert.ToUser(defaultUser, true, true)
|
||||
} else {
|
||||
user, err := models.GetUserByID(key.OwnerID)
|
||||
if err != nil {
|
||||
return apiKey, err
|
||||
}
|
||||
apiKey.Owner = user.APIFormat()
|
||||
apiKey.Owner = convert.ToUser(user, true, true)
|
||||
}
|
||||
} else {
|
||||
apiKey.KeyType = "unknown"
|
||||
|
||||
@@ -104,11 +104,7 @@ func GetInfo(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
// Hide user e-mail when API caller isn't signed in.
|
||||
if !ctx.IsSigned {
|
||||
u.Email = ""
|
||||
}
|
||||
ctx.JSON(200, u.APIFormat())
|
||||
ctx.JSON(200, convert.ToUser(u, ctx.IsSigned, ctx.User.ID == u.ID || ctx.User.IsAdmin))
|
||||
}
|
||||
|
||||
// GetAuthenticatedUser get current user's information
|
||||
@@ -121,7 +117,7 @@ func GetAuthenticatedUser(ctx *context.APIContext) {
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/User"
|
||||
ctx.JSON(200, ctx.User.APIFormat())
|
||||
ctx.JSON(200, convert.ToUser(ctx.User, ctx.IsSigned, ctx.User != nil))
|
||||
}
|
||||
|
||||
// GetUserHeatmapData is the handler to get a users heatmap
|
||||
|
||||
@@ -39,6 +39,7 @@ func Settings(ctx *context.Context) {
|
||||
func SettingsPost(ctx *context.Context, form auth.UpdateOrgSettingForm) {
|
||||
ctx.Data["Title"] = ctx.Tr("org.settings")
|
||||
ctx.Data["PageIsSettingsOptions"] = true
|
||||
ctx.Data["CurrentVisibility"] = structs.VisibleType(ctx.Org.Organization.Visibility)
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(200, tplSettingsOptions)
|
||||
|
||||
@@ -39,6 +39,7 @@ func Branches(ctx *context.Context) {
|
||||
ctx.Data["Title"] = "Branches"
|
||||
ctx.Data["IsRepoToolbarBranches"] = true
|
||||
ctx.Data["DefaultBranch"] = ctx.Repo.Repository.DefaultBranch
|
||||
ctx.Data["AllowsPulls"] = ctx.Repo.Repository.AllowsPulls()
|
||||
ctx.Data["IsWriter"] = ctx.Repo.CanWrite(models.UnitTypeCode)
|
||||
ctx.Data["IsMirror"] = ctx.Repo.Repository.IsMirror
|
||||
ctx.Data["PageIsViewCode"] = true
|
||||
|
||||
+80
-15
@@ -9,6 +9,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
@@ -137,7 +138,7 @@ func editFile(ctx *context.Context, isNewFile bool) {
|
||||
} else {
|
||||
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
|
||||
}
|
||||
ctx.Data["new_branch_name"] = ""
|
||||
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
|
||||
ctx.Data["last_commit"] = ctx.Repo.CommitID
|
||||
ctx.Data["MarkdownFileExts"] = strings.Join(setting.Markdown.FileExtensions, ",")
|
||||
ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",")
|
||||
@@ -266,6 +267,10 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo
|
||||
} else {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.fail_to_update_file", form.TreePath, err), tplEditFile, &form)
|
||||
}
|
||||
}
|
||||
|
||||
if form.CommitChoice == frmCommitChoiceNewBranch {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName)
|
||||
} else {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath))
|
||||
}
|
||||
@@ -335,7 +340,7 @@ func DeleteFile(ctx *context.Context) {
|
||||
} else {
|
||||
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
|
||||
}
|
||||
ctx.Data["new_branch_name"] = ""
|
||||
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
|
||||
|
||||
ctx.HTML(200, tplDeleteFile)
|
||||
}
|
||||
@@ -362,7 +367,7 @@ func DeleteFilePost(ctx *context.Context, form auth.DeleteRepoFileForm) {
|
||||
return
|
||||
}
|
||||
|
||||
if branchName != ctx.Repo.BranchName && !canCommit {
|
||||
if branchName == ctx.Repo.BranchName && !canCommit {
|
||||
ctx.Data["Err_NewBranchName"] = true
|
||||
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.cannot_commit_to_protected_branch", branchName), tplDeleteFile, &form)
|
||||
@@ -387,20 +392,20 @@ func DeleteFilePost(ctx *context.Context, form auth.DeleteRepoFileForm) {
|
||||
}); err != nil {
|
||||
// This is where we handle all the errors thrown by repofiles.DeleteRepoFile
|
||||
if git.IsErrNotExist(err) || models.IsErrRepoFileDoesNotExist(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_deleting_no_longer_exists", ctx.Repo.TreePath), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_deleting_no_longer_exists", ctx.Repo.TreePath), tplDeleteFile, &form)
|
||||
} else if models.IsErrFilenameInvalid(err) {
|
||||
ctx.Data["Err_TreePath"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.filename_is_invalid", ctx.Repo.TreePath), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.filename_is_invalid", ctx.Repo.TreePath), tplDeleteFile, &form)
|
||||
} else if models.IsErrFilePathInvalid(err) {
|
||||
ctx.Data["Err_TreePath"] = true
|
||||
if fileErr, ok := err.(models.ErrFilePathInvalid); ok {
|
||||
switch fileErr.Type {
|
||||
case git.EntryModeSymlink:
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_is_a_symlink", fileErr.Path), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_is_a_symlink", fileErr.Path), tplDeleteFile, &form)
|
||||
case git.EntryModeTree:
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.filename_is_a_directory", fileErr.Path), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.filename_is_a_directory", fileErr.Path), tplDeleteFile, &form)
|
||||
case git.EntryModeBlob:
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.directory_is_a_file", fileErr.Path), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.directory_is_a_file", fileErr.Path), tplDeleteFile, &form)
|
||||
default:
|
||||
ctx.ServerError("DeleteRepoFile", err)
|
||||
}
|
||||
@@ -410,25 +415,44 @@ func DeleteFilePost(ctx *context.Context, form auth.DeleteRepoFileForm) {
|
||||
} else if git.IsErrBranchNotExist(err) {
|
||||
// For when a user deletes a file to a branch that no longer exists
|
||||
if branchErr, ok := err.(git.ErrBranchNotExist); ok {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_does_not_exist", branchErr.Name), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_does_not_exist", branchErr.Name), tplDeleteFile, &form)
|
||||
} else {
|
||||
ctx.Error(500, err.Error())
|
||||
}
|
||||
} else if models.IsErrBranchAlreadyExists(err) {
|
||||
// For when a user specifies a new branch that already exists
|
||||
if branchErr, ok := err.(models.ErrBranchAlreadyExists); ok {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplDeleteFile, &form)
|
||||
} else {
|
||||
ctx.Error(500, err.Error())
|
||||
}
|
||||
} else if models.IsErrCommitIDDoesNotMatch(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+ctx.Repo.CommitID), tplEditFile, &form)
|
||||
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_deleting", ctx.Repo.RepoLink+"/compare/"+form.LastCommit+"..."+ctx.Repo.CommitID), tplDeleteFile, &form)
|
||||
} else {
|
||||
ctx.ServerError("DeleteRepoFile", err)
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("repo.editor.file_delete_success", ctx.Repo.TreePath))
|
||||
if form.CommitChoice == frmCommitChoiceNewBranch {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName)
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("repo.editor.file_delete_success", ctx.Repo.TreePath))
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName))
|
||||
treePath := filepath.Dir(ctx.Repo.TreePath)
|
||||
if treePath == "." {
|
||||
treePath = "" // the file deleted was in the root, so we return the user to the root directory
|
||||
}
|
||||
if len(treePath) > 0 {
|
||||
// Need to get the latest commit since it changed
|
||||
commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.BranchName)
|
||||
if err == nil && commit != nil {
|
||||
// We have the comment, now find what directory we can return the user to
|
||||
// (must have entries)
|
||||
treePath = GetClosestParentWithFiles(treePath, commit)
|
||||
} else {
|
||||
treePath = "" // otherwise return them to the root of the repo
|
||||
}
|
||||
}
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(treePath))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +491,7 @@ func UploadFile(ctx *context.Context) {
|
||||
} else {
|
||||
ctx.Data["commit_choice"] = frmCommitChoiceNewBranch
|
||||
}
|
||||
ctx.Data["new_branch_name"] = ""
|
||||
ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx)
|
||||
|
||||
ctx.HTML(200, tplUploadFile)
|
||||
}
|
||||
@@ -565,7 +589,11 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath))
|
||||
if form.CommitChoice == frmCommitChoiceNewBranch {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName)
|
||||
} else {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath))
|
||||
}
|
||||
}
|
||||
|
||||
func cleanUploadFileName(name string) string {
|
||||
@@ -645,3 +673,40 @@ func RemoveUploadFileFromServer(ctx *context.Context, form auth.RemoveUploadFile
|
||||
log.Trace("Upload file removed: %s", form.File)
|
||||
ctx.Status(204)
|
||||
}
|
||||
|
||||
// GetUniquePatchBranchName Gets a unique branch name for a new patch branch
|
||||
// It will be in the form of <username>-patch-<num> where <num> is the first branch of this format
|
||||
// that doesn't already exist. If we exceed 1000 tries or an error is thrown, we just return "" so the user has to
|
||||
// type in the branch name themselves (will be an empty field)
|
||||
func GetUniquePatchBranchName(ctx *context.Context) string {
|
||||
prefix := ctx.User.LowerName + "-patch-"
|
||||
for i := 1; i <= 1000; i++ {
|
||||
branchName := fmt.Sprintf("%s%d", prefix, i)
|
||||
if _, err := ctx.Repo.Repository.GetBranch(branchName); err != nil {
|
||||
if git.IsErrBranchNotExist(err) {
|
||||
return branchName
|
||||
}
|
||||
log.Error("GetUniquePatchBranchName: %v", err)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetClosestParentWithFiles Recursively gets the path of parent in a tree that has files (used when file in a tree is
|
||||
// deleted). Returns "" for the root if no parents other than the root have files. If the given treePath isn't a
|
||||
// SubTree or it has no entries, we go up one dir and see if we can return the user to that listing.
|
||||
func GetClosestParentWithFiles(treePath string, commit *git.Commit) string {
|
||||
if len(treePath) == 0 || treePath == "." {
|
||||
return ""
|
||||
}
|
||||
// see if the tree has entries
|
||||
if tree, err := commit.SubTree(treePath); err != nil {
|
||||
// failed to get tree, going up a dir
|
||||
return GetClosestParentWithFiles(filepath.Dir(treePath), commit)
|
||||
} else if entries, err := tree.ListEntries(); err != nil || len(entries) == 0 {
|
||||
// no files in this dir, going up a dir
|
||||
return GetClosestParentWithFiles(filepath.Dir(treePath), commit)
|
||||
}
|
||||
return treePath
|
||||
}
|
||||
@@ -5,6 +5,8 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
@@ -37,3 +39,40 @@ func TestCleanUploadName(t *testing.T) {
|
||||
assert.EqualValues(t, cleanUploadFileName(k), v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUniquePatchBranchName(t *testing.T) {
|
||||
models.PrepareTestEnv(t)
|
||||
ctx := test.MockContext(t, "user2/repo1")
|
||||
ctx.SetParams(":id", "1")
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
test.LoadRepoCommit(t, ctx)
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadGitRepo(t, ctx)
|
||||
expectedBranchName := "user2-patch-1"
|
||||
branchName := GetUniquePatchBranchName(ctx)
|
||||
assert.Equal(t, expectedBranchName, branchName)
|
||||
}
|
||||
|
||||
func TestGetClosestParentWithFiles(t *testing.T) {
|
||||
models.PrepareTestEnv(t)
|
||||
ctx := test.MockContext(t, "user2/repo1")
|
||||
ctx.SetParams(":id", "1")
|
||||
test.LoadRepo(t, ctx, 1)
|
||||
test.LoadRepoCommit(t, ctx)
|
||||
test.LoadUser(t, ctx, 2)
|
||||
test.LoadGitRepo(t, ctx)
|
||||
repo := ctx.Repo.Repository
|
||||
branch := repo.DefaultBranch
|
||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||
commit, _ := gitRepo.GetBranchCommit(branch)
|
||||
expectedTreePath := ""
|
||||
|
||||
expectedTreePath = "" // Should return the root dir, empty string, since there are no subdirs in this repo
|
||||
for _, deletedFile := range []string{
|
||||
"dir1/dir2/dir3/file.txt",
|
||||
"file.txt",
|
||||
} {
|
||||
treePath := GetClosestParentWithFiles(deletedFile, commit)
|
||||
assert.Equal(t, expectedTreePath, treePath)
|
||||
}
|
||||
}
|
||||
@@ -215,7 +215,10 @@ func HTTP(ctx *context.Context) {
|
||||
// Check username and password
|
||||
authUser, err = models.UserSignIn(authUsername, authPasswd)
|
||||
if err != nil {
|
||||
if !models.IsErrUserNotExist(err) {
|
||||
if models.IsErrUserProhibitLogin(err) {
|
||||
ctx.HandleText(http.StatusForbidden, "User is not permitted to login")
|
||||
return
|
||||
} else if !models.IsErrUserNotExist(err) {
|
||||
ctx.ServerError("UserSignIn error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -665,7 +665,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
||||
}, func(ctx *context.Context) {
|
||||
ctx.Data["PageIsSettings"] = true
|
||||
})
|
||||
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.UnitTypes(), context.RepoRef())
|
||||
}, reqSignIn, context.RepoAssignment(), context.UnitTypes(), reqRepoAdmin, context.RepoRef())
|
||||
|
||||
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action)
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
|
||||
{{template "base/footer_content" .}}
|
||||
|
||||
<script src="{{AppSubUrl}}/vendor/plugins/jquery/jquery.min.js"></script>
|
||||
<script src="{{AppSubUrl}}/vendor/plugins/jquery/jquery.min.js?v=3.4.1"></script>
|
||||
<script src="{{AppSubUrl}}/vendor/plugins/jquery-migrate/jquery-migrate.min.js?v=3.0.1"></script>
|
||||
<script src="{{AppSubUrl}}/vendor/plugins/jquery.areyousure/jquery.are-you-sure.js"></script>
|
||||
{{if .RequireSimpleMDE}}
|
||||
<script src="{{AppSubUrl}}/vendor/plugins/simplemde/simplemde.min.js"></script>
|
||||
|
||||
+13
-17
@@ -17,23 +17,19 @@
|
||||
|
||||
<div class="inline field {{if .Err_OrgVisibility}}error{{end}}">
|
||||
<span class="inline required field"><label for="visibility">{{.i18n.Tr "org.settings.visibility"}}</label></span>
|
||||
<div class="ui radio checkbox">
|
||||
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="0" {{if .DefaultOrgVisibilityMode.IsPublic}}checked{{end}}/>
|
||||
<label>{{.i18n.Tr "org.settings.visibility.public"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline field {{if .Err_OrgVisibility}}error{{end}}">
|
||||
<label> </label>
|
||||
<div class="ui radio checkbox">
|
||||
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="1" {{if .DefaultOrgVisibilityMode.IsLimited}}checked{{end}}/>
|
||||
<label>{{.i18n.Tr "org.settings.visibility.limited"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline field {{if .Err_OrgVisibility}}error{{end}}">
|
||||
<label> </label>
|
||||
<div class="ui radio checkbox">
|
||||
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="2" {{if .DefaultOrgVisibilityMode.IsPrivate}}checked{{end}}/>
|
||||
<label>{{.i18n.Tr "org.settings.visibility.private"}}</label>
|
||||
<div class="inline-grouped-list">
|
||||
<div class="ui radio checkbox">
|
||||
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="0" {{if .DefaultOrgVisibilityMode.IsPublic}}checked{{end}}/>
|
||||
<label>{{.i18n.Tr "org.settings.visibility.public"}}</label>
|
||||
</div>
|
||||
<div class="ui radio checkbox">
|
||||
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="1" {{if .DefaultOrgVisibilityMode.IsLimited}}checked{{end}}/>
|
||||
<label>{{.i18n.Tr "org.settings.visibility.limited"}}</label>
|
||||
</div>
|
||||
<div class="ui radio checkbox">
|
||||
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="2" {{if .DefaultOrgVisibilityMode.IsPrivate}}checked{{end}}/>
|
||||
<label>{{.i18n.Tr "org.settings.visibility.private"}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
|
||||
@@ -2,7 +2,8 @@ var STATIC_CACHE = 'static-cache-v1';
|
||||
var urlsToCache = [
|
||||
// js
|
||||
'{{AppSubUrl}}/vendor/plugins/jquery.areyousure/jquery.are-you-sure.js',
|
||||
'{{AppSubUrl}}/vendor/plugins/jquery/jquery.min.js',
|
||||
'{{AppSubUrl}}/vendor/plugins/jquery/jquery.min.js?v=3.4.1',
|
||||
'{{AppSubUrl}}/vendor/plugins/jquery-migrate/jquery-migrate.min.js?v=3.0.1',
|
||||
'{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.js',
|
||||
'{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}',
|
||||
'{{AppSubUrl}}/js/draw.js',
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
<h4 class="ui top attached header" id="repo-read-file">
|
||||
<div class="ui stackable grid">
|
||||
<div class="ten wide column">
|
||||
<div class="eight wide column">
|
||||
<i class="file text outline icon ui left"></i>
|
||||
<strong>{{.FileName}}</strong> <span class="text grey normal">{{FileSize .FileSize}}{{if .IsLFSFile}} ({{.i18n.Tr "repo.stored_lfs"}}){{end}}</span>
|
||||
</div>
|
||||
<div class="six wide right aligned column">
|
||||
<div class="eight wide right aligned column">
|
||||
<div class="ui right file-actions">
|
||||
<div class="ui buttons">
|
||||
{{if not .IsViewCommit}}
|
||||
@@ -48,4 +48,4 @@
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -12,7 +12,16 @@
|
||||
<table class="ui very basic striped fixed table single line">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{.DefaultBranch}}</td>
|
||||
<td>
|
||||
{{range .Branches}}
|
||||
{{if eq .Name $.DefaultBranch}}
|
||||
{{if .IsProtected}}
|
||||
<i class="octicon octicon-shield"></i>
|
||||
{{end}}
|
||||
{{.Name}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -27,15 +36,15 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="six wide">{{.i18n.Tr "repo.branch.name"}}</th>
|
||||
<th class="three wide"></th>
|
||||
<th class="two wide"></th>
|
||||
<th class="two wide"></th>
|
||||
{{if and $.IsWriter (not $.IsMirror)}}
|
||||
{{if and $.IsWriter (not $.IsMirror) (not $.Repository.IsArchived)}}
|
||||
<th class="one wide right aligned">{{.i18n.Tr "repo.branch.delete_head"}}</th>
|
||||
{{end}}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range $branch := .Branches}}
|
||||
{{range .Branches}}
|
||||
{{if ne .Name $.DefaultBranch}}
|
||||
<tr>
|
||||
<td>
|
||||
@@ -43,6 +52,9 @@
|
||||
<s><a href="{{$.RepoLink}}/src/branch/{{.Name | EscapePound}}">{{.Name}}</a></s>
|
||||
<p class="time">{{$.i18n.Tr "repo.branch.deleted_by" .DeletedBranch.DeletedBy.Name}} {{TimeSinceUnix .DeletedBranch.DeletedUnix $.i18n.Lang}}</p>
|
||||
{{else}}
|
||||
{{if .IsProtected}}
|
||||
<i class="octicon octicon-shield"></i>
|
||||
{{end}}
|
||||
<a href="{{$.RepoLink}}/src/branch/{{.Name | EscapePound}}">{{.Name}}</a>
|
||||
<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Commit.Committer.When $.i18n.Lang}}</p>
|
||||
{{end}}
|
||||
@@ -63,7 +75,7 @@
|
||||
</td>
|
||||
<td class="right aligned">
|
||||
{{if not .LatestPullRequest}}
|
||||
{{if not .IsDeleted}}
|
||||
{{if and (not .IsDeleted) $.AllowsPulls}}
|
||||
<a href="{{$.RepoLink}}/compare/{{$.DefaultBranch | EscapePound}}...{{if ne $.Repository.Owner.Name $.Owner.Name}}{{$.Owner.Name}}:{{end}}{{.Name | EscapePound}}">
|
||||
<button id="new-pull-request" class="ui compact basic button">{{$.i18n.Tr "repo.pulls.compare_changes"}}</button>
|
||||
</a>
|
||||
@@ -79,13 +91,11 @@
|
||||
{{end}}
|
||||
{{end}}
|
||||
</td>
|
||||
{{if and $.IsWriter (not $.IsMirror)}}
|
||||
{{if and $.IsWriter (not $.IsMirror) (not $.Repository.IsArchived)}}
|
||||
<td class="right aligned">
|
||||
{{if .IsProtected}}
|
||||
<i class="octicon octicon-shield"></i>
|
||||
{{else if .IsDeleted}}
|
||||
{{if and .IsDeleted (not .IsProtected)}}
|
||||
<a class="undo-button" href data-url="{{$.Link}}/restore?branch_id={{.DeletedBranch.ID | urlquery}}&name={{.DeletedBranch.Name | urlquery}}"><i class="octicon octicon-reply"></i></a>
|
||||
{{else}}
|
||||
{{else if (not .IsProtected)}}
|
||||
<a class="delete-branch-button" href data-url="{{$.Link}}/delete?name={{.Name | urlquery}}" data-name="{{.Name}}"><i class="trash icon text red"></i></a>
|
||||
{{end}}
|
||||
</td>
|
||||
|
||||
@@ -122,10 +122,10 @@
|
||||
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}">
|
||||
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
||||
<td class="lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td>
|
||||
<td class="lines-code lines-code-old halfwidth">{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}}<a class="ui green button add-code-comment add-code-comment-left" data-path="{{$file.Name}}" data-side="left" data-idx="{{$line.LeftIdx}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.LeftIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
||||
<td class="lines-code lines-code-old halfwidth">{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}}<a class="ui green button add-code-comment add-code-comment-left" data-path="{{$file.Name}}" data-side="left" data-idx="{{$line.LeftIdx}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}} nohighlight{{end}}">{{if $line.LeftIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
||||
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||
<td class="lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td>
|
||||
<td class="lines-code lines-code-new halfwidth">{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}}<a class="ui green button add-code-comment add-code-comment-right" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
||||
<td class="lines-code lines-code-new halfwidth">{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}}<a class="ui green button add-code-comment add-code-comment-right" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}} nohighlight{{end}}">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
||||
</tr>
|
||||
{{if gt (len $line.Comments) 0}}
|
||||
<tr class="add-code-comment">
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||
{{end}}
|
||||
<td class="lines-type-marker"><span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
|
||||
<td class="lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}">{{if and $.root.SignedUserID $line.CanComment $.root.PageIsPullFiles}}<a class="ui green button add-code-comment add-code-comment-{{if $line.RightIdx}}right{{else}}left{{end}}" data-path="{{$file.Name}}" data-side="{{if $line.RightIdx}}right{{else}}left{{end}}" data-idx="{{if $line.RightIdx}}{{$line.RightIdx}}{{else}}{{$line.LeftIdx}}{{end}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{$section.GetComputedInlineDiffFor $line}}</span></td>
|
||||
<td class="lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}">{{if and $.root.SignedUserID $line.CanComment $.root.PageIsPullFiles}}<a class="ui green button add-code-comment add-code-comment-{{if $line.RightIdx}}right{{else}}left{{end}}" data-path="{{$file.Name}}" data-side="{{if $line.RightIdx}}right{{else}}left{{end}}" data-idx="{{if $line.RightIdx}}{{$line.RightIdx}}{{else}}{{$line.LeftIdx}}{{end}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}} nohighlight{{end}}">{{$section.GetComputedInlineDiffFor $line}}</span></td>
|
||||
</tr>
|
||||
{{if gt (len $line.Comments) 0}}
|
||||
<tr>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="quick-pull-choice js-quick-pull-choice">
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox {{if not .CanCommitToBranch}}disabled{{end}}">
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="direct" {{if eq .commit_choice "direct"}}checked{{end}}>
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="direct" button_text="{{.i18n.Tr "repo.editor.commit_changes"}}" {{if eq .commit_choice "direct"}}checked{{end}}>
|
||||
<label>
|
||||
<i class="octicon octicon-git-commit" height="16" width="14"></i>
|
||||
{{.i18n.Tr "repo.editor.commit_directly_to_this_branch" (.BranchName|Escape) | Safe}}
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
|
||||
<input type="radio" class="js-quick-pull-choice-option" name="commit_choice" value="commit-to-new-branch" button_text="{{.i18n.Tr "repo.editor.propose_file_change"}}" {{if eq .commit_choice "commit-to-new-branch"}}checked{{end}}>
|
||||
<label>
|
||||
<i class="octicon octicon-git-pull-request" height="16" width="12"></i>
|
||||
{{.i18n.Tr "repo.editor.create_new_branch" | Safe}}
|
||||
@@ -36,8 +36,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="ui green button">
|
||||
{{.i18n.Tr "repo.editor.commit_changes"}}
|
||||
<button id="commit-button" type="submit" class="ui green button">
|
||||
{{if eq .commit_choice "commit-to-new-branch"}}{{.i18n.Tr "repo.editor.propose_file_change"}}{{else}}{{.i18n.Tr "repo.editor.commit_changes"}}{{end}}
|
||||
</button>
|
||||
<a class="ui button red" href="{{EscapePound $.BranchLink}}/{{EscapePound .TreePath}}">{{.i18n.Tr "repo.editor.cancel"}}</a>
|
||||
</div>
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="{{TabSizeClass .Editorconfig .FileName}} non-diff-file-content">
|
||||
<h4 class="ui top attached header" id="{{if .ReadmeExist}}repo-readme{{else}}repo-read-file{{end}}">
|
||||
<div class="ui stackable grid">
|
||||
<div class="ten wide column">
|
||||
<div class="eight wide column">
|
||||
{{if .ReadmeExist}}
|
||||
<i class="book icon ui left"></i>
|
||||
{{if .ReadmeInList}}
|
||||
@@ -14,7 +14,7 @@
|
||||
<strong>{{.FileName}}</strong> <span class="text grey normal">{{FileSize .FileSize}}{{if .IsLFSFile}} ({{.i18n.Tr "repo.stored_lfs"}}){{end}}</span>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="six wide right aligned column">
|
||||
<div class="eight wide right aligned column">
|
||||
{{if not .ReadmeInList}}
|
||||
<div class="ui right file-actions">
|
||||
<div class="ui buttons">
|
||||
|
||||
+5
-9
@@ -1,14 +1,10 @@
|
||||
sudo: false
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- tip
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
|
||||
script: go test -v -cover -race
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- u@gogs.io
|
||||
+19
-7
@@ -19,6 +19,7 @@ package captcha
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"image/color"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
@@ -49,6 +50,7 @@ type Captcha struct {
|
||||
ChallengeNums int
|
||||
Expiration int64
|
||||
CachePrefix string
|
||||
ColorPalette color.Palette
|
||||
}
|
||||
|
||||
// generate key string
|
||||
@@ -61,16 +63,21 @@ func (c *Captcha) genRandChars() string {
|
||||
return string(com.RandomCreateBytes(c.ChallengeNums, defaultChars...))
|
||||
}
|
||||
|
||||
// tempalte func for output html
|
||||
func (c *Captcha) CreateHtml() template.HTML {
|
||||
// CreateHTML outputs HTML for display and fetch new captcha images.
|
||||
func (c *Captcha) CreateHTML() template.HTML {
|
||||
value, err := c.CreateCaptcha()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("fail to create captcha: %v", err))
|
||||
}
|
||||
return template.HTML(fmt.Sprintf(`<input type="hidden" name="%s" value="%s">
|
||||
<a class="captcha" href="javascript:">
|
||||
<img onclick="this.src=('%s%s%s.png?reload='+(new Date()).getTime())" class="captcha-img" src="%s%s%s.png">
|
||||
</a>`, c.FieldIdName, value, c.SubURL, c.URLPrefix, value, c.SubURL, c.URLPrefix, value))
|
||||
return template.HTML(fmt.Sprintf(`<input type="hidden" name="%[1]s" value="%[2]s">
|
||||
<a class="captcha" href="javascript:" tabindex="-1">
|
||||
<img onclick="this.src=('%[3]s%[4]s%[2]s.png?reload='+(new Date()).getTime())" class="captcha-img" src="%[3]s%[4]s%[2]s.png">
|
||||
</a>`, c.FieldIdName, value, c.SubURL, c.URLPrefix))
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
func (c *Captcha) CreateHtml() template.HTML {
|
||||
return c.CreateHTML()
|
||||
}
|
||||
|
||||
// create a new captcha id
|
||||
@@ -139,6 +146,9 @@ type Options struct {
|
||||
Expiration int64
|
||||
// Cache key prefix captcha characters. Default is "captcha_".
|
||||
CachePrefix string
|
||||
// ColorPalette holds a collection of primary colors used for
|
||||
// the captcha's text. If not defined, a random color will be generated.
|
||||
ColorPalette color.Palette
|
||||
}
|
||||
|
||||
func prepareOptions(options []Options) Options {
|
||||
@@ -192,6 +202,7 @@ func NewCaptcha(opt Options) *Captcha {
|
||||
ChallengeNums: opt.ChallengeNums,
|
||||
Expiration: opt.Expiration,
|
||||
CachePrefix: opt.CachePrefix,
|
||||
ColorPalette: opt.ColorPalette,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,9 +240,10 @@ func Captchaer(options ...Options) macaron.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := NewImage([]byte(chars), cpt.StdWidth, cpt.StdHeight).WriteTo(ctx.Resp); err != nil {
|
||||
if _, err := NewImage([]byte(chars), cpt.StdWidth, cpt.StdHeight, cpt.ColorPalette).WriteTo(ctx.Resp); err != nil {
|
||||
panic(fmt.Errorf("write captcha: %v", err))
|
||||
}
|
||||
ctx.Status(200)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+16
-9
@@ -265,16 +265,22 @@ func randFloat(from, to float64) float64 {
|
||||
return (to-from)*prng.Float64() + from
|
||||
}
|
||||
|
||||
func randomPalette() color.Palette {
|
||||
func randomPalette(primary color.Palette) color.Palette {
|
||||
p := make([]color.Color, circleCount+1)
|
||||
// Transparent color.
|
||||
p[0] = color.RGBA{0xFF, 0xFF, 0xFF, 0x00}
|
||||
// Primary color.
|
||||
prim := color.RGBA{
|
||||
uint8(randIntn(129)),
|
||||
uint8(randIntn(129)),
|
||||
uint8(randIntn(129)),
|
||||
0xFF,
|
||||
var prim color.RGBA
|
||||
if len(primary) == 0 {
|
||||
prim = color.RGBA{
|
||||
uint8(randIntn(129)),
|
||||
uint8(randIntn(129)),
|
||||
uint8(randIntn(129)),
|
||||
0xFF,
|
||||
}
|
||||
} else {
|
||||
r, g, b, a := primary[randIntn(len(primary)-1)].RGBA()
|
||||
prim = color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)}
|
||||
}
|
||||
p[1] = prim
|
||||
// Circle colors.
|
||||
@@ -285,10 +291,11 @@ func randomPalette() color.Palette {
|
||||
}
|
||||
|
||||
// NewImage returns a new captcha image of the given width and height with the
|
||||
// given digits, where each digit must be in range 0-9.
|
||||
func NewImage(digits []byte, width, height int) *Image {
|
||||
// given digits, where each digit must be in range 0-9. The digit's color is
|
||||
// chosen by random from the colorPalette.
|
||||
func NewImage(digits []byte, width, height int, colorPalette color.Palette) *Image {
|
||||
m := new(Image)
|
||||
m.Paletted = image.NewPaletted(image.Rect(0, 0, width, height), randomPalette())
|
||||
m.Paletted = image.NewPaletted(image.Rect(0, 0, width, height), randomPalette(colorPalette))
|
||||
m.calculateSizes(width, height, len(digits))
|
||||
// Randomly position captcha inside the image.
|
||||
maxx := width - (m.numWidth+m.dotSize)*len(digits) - m.dotSize
|
||||
|
||||
Vendored
+2
-2
@@ -85,7 +85,7 @@ github.com/couchbase/vellum/utf8
|
||||
github.com/couchbaselabs/go-couchbase
|
||||
# github.com/davecgh/go-spew v1.1.1
|
||||
github.com/davecgh/go-spew/spew
|
||||
# github.com/denisenkom/go-mssqldb v0.0.0-20190121005146-b04fd42d9952 => github.com/denisenkom/go-mssqldb v0.0.0-20180314172330-6a30f4e59a44
|
||||
# github.com/denisenkom/go-mssqldb v0.0.0-20190121005146-b04fd42d9952 => github.com/denisenkom/go-mssqldb v0.0.0-20180315180555-6a30f4e59a44
|
||||
github.com/denisenkom/go-mssqldb
|
||||
github.com/denisenkom/go-mssqldb/internal/cp
|
||||
# github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
@@ -120,7 +120,7 @@ github.com/go-macaron/binding
|
||||
github.com/go-macaron/cache
|
||||
github.com/go-macaron/cache/memcache
|
||||
github.com/go-macaron/cache/redis
|
||||
# github.com/go-macaron/captcha v0.0.0-20151123225153-8aa5919789ab
|
||||
# github.com/go-macaron/captcha v0.0.0-20190710000913-8dc5911259df
|
||||
github.com/go-macaron/captcha
|
||||
# github.com/go-macaron/cors v0.0.0-20190309005821-6fd6a9bfe14e9
|
||||
github.com/go-macaron/cors
|
||||
|
||||
Reference in new issue
Block a user