This commit is contained in:
Konrad 2017-12-03 17:45:55 +01:00
commit 9af3aae2f3
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
37 changed files with 1617 additions and 1487 deletions

2
docker/Makefile vendored
View File

@ -8,4 +8,4 @@ DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
.PHONY: docker
docker:
docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" webhippie/golang:edge make clean generate build
docker build -t $(DOCKER_REF) .
docker build --disable-content-trust=false -t $(DOCKER_REF) .

View File

@ -49,6 +49,8 @@ When you find the correct .tmpl file, you need to copy it in the `custom/templat
You can now customize the template you copied in `custom/templates`, being carefully to not break the Gitea syntax.
Any statement contained inside `{{` and `}}` are Gitea templete's syntax and shouldn't be touch, unless you know what are you doing.
To add in custom HTML to the header or the footer of the page, in the `templates/custom` directory there are `header.tmpl` and `footer.tmpl` that can be modified. This is useful if you want to add in custom CSS files, or additional Javascript.
## Customizing gitignores, labels, licenses, locales, and readmes.
Place your own files in corresponding sub-folder under `custom/options`.

View File

@ -14,15 +14,14 @@ import (
"time"
"unicode"
"github.com/Unknwon/com"
"github.com/go-xorm/builder"
"code.gitea.io/git"
api "code.gitea.io/sdk/gitea"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/sdk/gitea"
"github.com/Unknwon/com"
"github.com/go-xorm/builder"
)
// ActionType represents the type of an action.
@ -59,14 +58,16 @@ var (
issueReferenceKeywordsPat *regexp.Regexp
)
const issueRefRegexpStr = `(?:\S+/\S=)?#\d+`
func assembleKeywordsPattern(words []string) string {
return fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(words, "|"))
return fmt.Sprintf(`(?i)(?:%s) %s`, strings.Join(words, "|"), issueRefRegexpStr)
}
func init() {
issueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueCloseKeywords))
issueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueReopenKeywords))
issueReferenceKeywordsPat = regexp.MustCompile(`(?i)(?:)(^| )\S+`)
issueReferenceKeywordsPat = regexp.MustCompile(issueRefRegexpStr)
}
// Action represents user operation type and other information to
@ -390,6 +391,49 @@ func (pc *PushCommits) AvatarLink(email string) string {
return pc.avatars[email]
}
// getIssueFromRef returns the issue referenced by a ref. Returns a nil *Issue
// if the provided ref is misformatted or references a non-existent issue.
func getIssueFromRef(repo *Repository, ref string) (*Issue, error) {
ref = ref[strings.IndexByte(ref, ' ')+1:]
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
var refRepo *Repository
poundIndex := strings.IndexByte(ref, '#')
if poundIndex < 0 {
return nil, nil
} else if poundIndex == 0 {
refRepo = repo
} else {
slashIndex := strings.IndexByte(ref, '/')
if slashIndex < 0 || slashIndex >= poundIndex {
return nil, nil
}
ownerName := ref[:slashIndex]
repoName := ref[slashIndex+1 : poundIndex]
var err error
refRepo, err = GetRepositoryByOwnerAndName(ownerName, repoName)
if err != nil {
if IsErrRepoNotExist(err) {
return nil, nil
}
return nil, err
}
}
issueIndex, err := strconv.ParseInt(ref[poundIndex+1:], 10, 64)
if err != nil {
return nil, nil
}
issue, err := GetIssueByIndex(refRepo.ID, int64(issueIndex))
if err != nil {
if IsErrIssueNotExist(err) {
return nil, nil
}
return nil, err
}
return issue, nil
}
// UpdateIssuesCommit checks if issues are manipulated by commit message.
func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) error {
// Commits are appended in the reverse order.
@ -398,31 +442,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
refMarked := make(map[int64]bool)
for _, ref := range issueReferenceKeywordsPat.FindAllString(c.Message, -1) {
ref = ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s%s", repo.FullName(), ref)
} else if !strings.Contains(ref, "/") {
// FIXME: We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
issue, err := getIssueFromRef(repo, ref)
if err != nil {
if IsErrIssueNotExist(err) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
continue
}
return err
}
if refMarked[issue.ID] {
if issue == nil || refMarked[issue.ID] {
continue
}
refMarked[issue.ID] = true
@ -436,31 +461,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
refMarked = make(map[int64]bool)
// FIXME: can merge this one and next one to a common function.
for _, ref := range issueCloseKeywordsPat.FindAllString(c.Message, -1) {
ref = ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s%s", repo.FullName(), ref)
} else if !strings.Contains(ref, "/") {
// We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
issue, err := getIssueFromRef(repo, ref)
if err != nil {
if IsErrIssueNotExist(err) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
continue
}
return err
}
if refMarked[issue.ID] {
if issue == nil || refMarked[issue.ID] {
continue
}
refMarked[issue.ID] = true
@ -484,31 +490,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
// It is conflict to have close and reopen at same time, so refsMarked doesn't need to reinit here.
for _, ref := range issueReopenKeywordsPat.FindAllString(c.Message, -1) {
ref = ref[strings.IndexByte(ref, byte(' '))+1:]
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s%s", repo.FullName(), ref)
} else if !strings.Contains(ref, "/") {
// We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
issue, err := getIssueFromRef(repo, ref)
if err != nil {
if IsErrIssueNotExist(err) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
continue
}
return err
}
if refMarked[issue.ID] {
if issue == nil || refMarked[issue.ID] {
continue
}
refMarked[issue.ID] = true

View File

@ -1,6 +1,7 @@
package models
import (
"fmt"
"path"
"strings"
"testing"
@ -154,6 +155,35 @@ func TestPushCommits_AvatarLink(t *testing.T) {
pushCommits.AvatarLink("nonexistent@example.com"))
}
func Test_getIssueFromRef(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
for _, test := range []struct {
Ref string
ExpectedIssueID int64
}{
{"#2", 2},
{"reopen #2", 2},
{"user2/repo2#1", 4},
{"fixes user2/repo2#1", 4},
} {
issue, err := getIssueFromRef(repo, test.Ref)
assert.NoError(t, err)
if assert.NotNil(t, issue) {
assert.EqualValues(t, test.ExpectedIssueID, issue.ID)
}
}
for _, badRef := range []string{
"doesnotexist/doesnotexist#1",
fmt.Sprintf("#%d", NonexistentID),
} {
issue, err := getIssueFromRef(repo, badRef)
assert.NoError(t, err)
assert.Nil(t, issue)
}
}
func TestUpdateIssuesCommit(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
pushCommits := []*PushCommit{

View File

@ -5,7 +5,6 @@
package models
import (
"errors"
"fmt"
"path"
"sort"
@ -22,11 +21,6 @@ import (
"code.gitea.io/gitea/modules/util"
)
var (
errMissingIssueNumber = errors.New("No issue number specified")
errInvalidIssueNumber = errors.New("Invalid issue number")
)
// Issue represents an issue or pull request of repository.
type Issue struct {
ID int64 `xorm:"pk autoincr"`
@ -961,32 +955,6 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
return nil
}
// GetIssueByRef returns an Issue specified by a GFM reference.
// See https://help.github.com/articles/writing-on-github#references for more information on the syntax.
func GetIssueByRef(ref string) (*Issue, error) {
n := strings.IndexByte(ref, '#')
if n == -1 {
return nil, errMissingIssueNumber
}
index, err := com.StrTo(ref[n+1:]).Int64()
if err != nil {
return nil, errInvalidIssueNumber
}
i := strings.IndexByte(ref[:n], '/')
if i < 2 {
return nil, ErrInvalidReference
}
repo, err := GetRepositoryByOwnerAndName(ref[:i], ref[i+1:n])
if err != nil {
return nil, err
}
return GetIssueByIndex(repo.ID, index)
}
// GetRawIssueByIndex returns raw issue without loading attributes by index in a repository.
func GetRawIssueByIndex(repoID, index int64) (*Issue, error) {
issue := &Issue{

View File

@ -605,9 +605,14 @@ func (repo *Repository) RepoPath() string {
return repo.repoPath(x)
}
// GitConfigPath returns the path to a repository's git config/ directory
func GitConfigPath(repoPath string) string {
return filepath.Join(repoPath, "config")
}
// GitConfigPath returns the repository git config path
func (repo *Repository) GitConfigPath() string {
return filepath.Join(repo.RepoPath(), "config")
return GitConfigPath(repo.RepoPath())
}
// RelLink returns the repository relative link

View File

@ -76,17 +76,23 @@ func (m *Mirror) ScheduleNextUpdate() {
m.NextUpdate = time.Now().Add(m.Interval)
}
func remoteAddress(repoPath string) (string, error) {
cfg, err := ini.Load(GitConfigPath(repoPath))
if err != nil {
return "", err
}
return cfg.Section("remote \"origin\"").Key("url").Value(), nil
}
func (m *Mirror) readAddress() {
if len(m.address) > 0 {
return
}
cfg, err := ini.Load(m.Repo.GitConfigPath())
var err error
m.address, err = remoteAddress(m.Repo.RepoPath())
if err != nil {
log.Error(4, "Load: %v", err)
return
log.Error(4, "remoteAddress: %v", err)
}
m.address = cfg.Section("remote \"origin\"").Key("url").Value()
}
// HandleCloneUserCredentials replaces user credentials from HTTP/HTTPS URL
@ -107,6 +113,19 @@ func HandleCloneUserCredentials(url string, mosaics bool) string {
return url[:start+3] + url[i+1:]
}
// sanitizeOutput sanitizes output of a command, replacing occurrences of the
// repository's remote address with a sanitized version.
func sanitizeOutput(output, repoPath string) (string, error) {
remoteAddr, err := remoteAddress(repoPath)
if err != nil {
// if we're unable to load the remote address, then we're unable to
// sanitize.
return "", err
}
sanitized := HandleCloneUserCredentials(remoteAddr, true)
return strings.Replace(output, remoteAddr, sanitized, -1), nil
}
// Address returns mirror address from Git repository config without credentials.
func (m *Mirror) Address() string {
m.readAddress()
@ -145,7 +164,14 @@ func (m *Mirror) runSync() bool {
if _, stderr, err := process.GetManager().ExecDir(
timeout, repoPath, fmt.Sprintf("Mirror.runSync: %s", repoPath),
"git", gitArgs...); err != nil {
desc := fmt.Sprintf("Failed to update mirror repository '%s': %s", repoPath, stderr)
// sanitize the output, since it may contain the remote address, which may
// contain a password
message, err := sanitizeOutput(stderr, repoPath)
if err != nil {
log.Error(4, "sanitizeOutput: %v", err)
return false
}
desc := fmt.Sprintf("Failed to update mirror repository '%s': %s", repoPath, message)
log.Error(4, desc)
if err = CreateRepositoryNotice(desc); err != nil {
log.Error(4, "CreateRepositoryNotice: %v", err)
@ -170,7 +196,14 @@ func (m *Mirror) runSync() bool {
if _, stderr, err := process.GetManager().ExecDir(
timeout, wikiPath, fmt.Sprintf("Mirror.runSync: %s", wikiPath),
"git", "remote", "update", "--prune"); err != nil {
desc := fmt.Sprintf("Failed to update mirror wiki repository '%s': %s", wikiPath, stderr)
// sanitize the output, since it may contain the remote address, which may
// contain a password
message, err := sanitizeOutput(stderr, wikiPath)
if err != nil {
log.Error(4, "sanitizeOutput: %v", err)
return false
}
desc := fmt.Sprintf("Failed to update mirror wiki repository '%s': %s", wikiPath, message)
log.Error(4, desc)
if err = CreateRepositoryNotice(desc); err != nil {
log.Error(4, "CreateRepositoryNotice: %v", err)

View File

@ -315,10 +315,9 @@ func (u *User) generateRandomAvatar(e Engine) error {
return nil
}
// RelAvatarLink returns relative avatar link to the site domain,
// which includes app sub-url as prefix. However, it is possible
// to return full URL if user enables Gravatar-like service.
func (u *User) RelAvatarLink() string {
// SizedRelAvatarLink returns a relative link to the user's avatar. When
// applicable, the link is for an avatar of the indicated size (in pixels).
func (u *User) SizedRelAvatarLink(size int) string {
if u.ID == -1 {
return base.DefaultAvatarLink()
}
@ -338,7 +337,14 @@ func (u *User) RelAvatarLink() string {
return setting.AppSubURL + "/avatars/" + u.Avatar
}
return base.AvatarLink(u.AvatarEmail)
return base.SizedAvatarLink(u.AvatarEmail, size)
}
// RelAvatarLink returns a relative link to the user's avatar. The link
// may either be a sub-URL to this site, or a full URL to an external avatar
// service.
func (u *User) RelAvatarLink() string {
return u.SizedRelAvatarLink(base.DefaultAvatarSize)
}
// AvatarLink returns user avatar absolute link.

View File

@ -16,6 +16,8 @@ import (
"math"
"math/big"
"net/http"
"net/url"
"path"
"strconv"
"strings"
"time"
@ -197,24 +199,59 @@ func DefaultAvatarLink() string {
return setting.AppSubURL + "/img/avatar_default.png"
}
// DefaultAvatarSize is a sentinel value for the default avatar size, as
// determined by the avatar-hosting service.
const DefaultAvatarSize = -1
// libravatarURL returns the URL for the given email. This function should only
// be called if a federated avatar service is enabled.
func libravatarURL(email string) (*url.URL, error) {
urlStr, err := setting.LibravatarService.FromEmail(email)
if err != nil {
log.Error(4, "LibravatarService.FromEmail(email=%s): error %v", email, err)
return nil, err
}
u, err := url.Parse(urlStr)
if err != nil {
log.Error(4, "Failed to parse libravatar url(%s): error %v", urlStr, err)
return nil, err
}
return u, nil
}
// SizedAvatarLink returns a sized link to the avatar for the given email
// address.
func SizedAvatarLink(email string, size int) string {
var avatarURL *url.URL
if setting.EnableFederatedAvatar && setting.LibravatarService != nil {
var err error
avatarURL, err = libravatarURL(email)
if err != nil {
return DefaultAvatarLink()
}
} else if !setting.DisableGravatar {
// copy GravatarSourceURL, because we will modify its Path.
copyOfGravatarSourceURL := *setting.GravatarSourceURL
avatarURL = &copyOfGravatarSourceURL
avatarURL.Path = path.Join(avatarURL.Path, HashEmail(email))
} else {
return DefaultAvatarLink()
}
vals := avatarURL.Query()
vals.Set("d", "identicon")
if size != DefaultAvatarSize {
vals.Set("s", strconv.Itoa(size))
}
avatarURL.RawQuery = vals.Encode()
return avatarURL.String()
}
// AvatarLink returns relative avatar link to the site domain by given email,
// which includes app sub-url as prefix. However, it is possible
// to return full URL if user enables Gravatar-like service.
func AvatarLink(email string) string {
if setting.EnableFederatedAvatar && setting.LibravatarService != nil {
url, err := setting.LibravatarService.FromEmail(email)
if err != nil {
log.Error(4, "LibravatarService.FromEmail(email=%s): error %v", email, err)
return DefaultAvatarLink()
}
return url
}
if !setting.DisableGravatar {
return setting.GravatarSource + HashEmail(email) + "?d=identicon"
}
return DefaultAvatarLink()
return SizedAvatarLink(email, DefaultAvatarSize)
}
// Seconds-based time units

View File

@ -1,11 +1,13 @@
package base
import (
"net/url"
"os"
"testing"
"time"
"code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/i18n"
macaroni18n "github.com/go-macaron/i18n"
"github.com/stretchr/testify/assert"
@ -126,16 +128,40 @@ func TestHashEmail(t *testing.T) {
)
}
func TestAvatarLink(t *testing.T) {
const gravatarSource = "https://secure.gravatar.com/avatar/"
func disableGravatar() {
setting.EnableFederatedAvatar = false
setting.LibravatarService = nil
setting.DisableGravatar = true
}
assert.Equal(t, "/img/avatar_default.png", AvatarLink(""))
func enableGravatar(t *testing.T) {
setting.DisableGravatar = false
var err error
setting.GravatarSourceURL, err = url.Parse(gravatarSource)
assert.NoError(t, err)
}
func TestSizedAvatarLink(t *testing.T) {
disableGravatar()
assert.Equal(t, "/img/avatar_default.png",
SizedAvatarLink("gitea@example.com", 100))
enableGravatar(t)
assert.Equal(t,
"353cbad9b58e69c96154ad99f92bedc7?d=identicon",
"https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100",
SizedAvatarLink("gitea@example.com", 100),
)
}
func TestAvatarLink(t *testing.T) {
disableGravatar()
assert.Equal(t, "/img/avatar_default.png", AvatarLink("gitea@example.com"))
enableGravatar(t)
assert.Equal(t,
"https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon",
AvatarLink("gitea@example.com"),
)
}

View File

@ -326,6 +326,7 @@ var (
// Picture settings
AvatarUploadPath string
GravatarSource string
GravatarSourceURL *url.URL
DisableGravatar bool
EnableFederatedAvatar bool
LibravatarService *libravatar.Libravatar
@ -1027,18 +1028,22 @@ func NewContext() {
if DisableGravatar {
EnableFederatedAvatar = false
}
if EnableFederatedAvatar || !DisableGravatar {
GravatarSourceURL, err = url.Parse(GravatarSource)
if err != nil {
log.Fatal(4, "Failed to parse Gravatar URL(%s): %v",
GravatarSource, err)
}
}
if EnableFederatedAvatar {
LibravatarService = libravatar.New()
parts := strings.Split(GravatarSource, "/")
if len(parts) >= 3 {
if parts[0] == "https:" {
LibravatarService.SetUseHTTPS(true)
LibravatarService.SetSecureFallbackHost(parts[2])
} else {
LibravatarService.SetUseHTTPS(false)
LibravatarService.SetFallbackHost(parts[2])
}
if GravatarSourceURL.Scheme == "https" {
LibravatarService.SetUseHTTPS(true)
LibravatarService.SetSecureFallbackHost(GravatarSourceURL.Host)
} else {
LibravatarService.SetUseHTTPS(false)
LibravatarService.SetFallbackHost(GravatarSourceURL.Host)
}
}

View File

@ -404,6 +404,7 @@ key_state_desc=該金鑰在 7 天內被使用過
token_state_desc=此 token 在過去七天內曾經被使用過
show_openid=在設定檔顯示
hide_openid=從設定檔隱藏
ssh_disabled=已停用 SSH
manage_social=管理關聯社交帳戶
social_desc=這是相關聯的社交帳戶清單。出於安全考量,請確保您識別所有項目,因為它們可用於登入到您的帳戶。
@ -616,6 +617,7 @@ issues.new.closed_milestone=已關閉的里程碑
issues.new.assignee=指派成員
issues.new.clear_assignee=取消指派成員
issues.new.no_assignee=未指派成員
issues.no_ref=未指定分支或標籤
issues.create=建立問題
issues.new_label=建立標籤
issues.new_label_placeholder=標籤名稱...
@ -705,6 +707,9 @@ issues.attachment.open_tab=`在新的標籤頁中查看 '%s'`
issues.attachment.download=`點擊下載 '%s'`
issues.subscribe=訂閱
issues.unsubscribe=取消訂閱
issues.add_time_hours=小時
issues.add_time_minutes=分鐘
issues.cancel_tracking=取消
pulls.desc=Pulls 管理你的程式碼審核及程式碼合併要求。
pulls.new=建立合併請求
@ -785,6 +790,11 @@ wiki.page_already_exists=相同名稱的 Wiki 頁面已經存在。
wiki.pages=所有頁面
wiki.last_updated=最後更新於 %s
activity.period.daily=1 天
activity.period.halfweekly=3 天
activity.period.weekly=1 星期
activity.period.monthly=1 個月
activity.overview=概覽
activity.closed_issue_label=已關閉
activity.title.releases_published_by=%s 由 %s 發佈
activity.published_release_label=已發佈
@ -989,12 +999,18 @@ release.tag_name_invalid=標記名稱不是有效的。
release.downloads=下載附件
branch.delete=刪除分支 %s
branch.delete_html=刪除分支
branch.delete_desc=刪除分支將是永久的。沒有其它方法能復原。
branch.delete_notices_1=- 此操作<strong>不可以</strong>被還原。
branch.delete_notices_2=- 此操作將永久刪除在 %s 分支內的所有內容。
branch.deletion_success=%s 已被刪除。
branch.deletion_failed=刪除分支 %s 失敗。
branch.delete_branch_has_new_commits=不能刪除 %s因為合併後已新增了新的提交。
branch.create_branch=建立分支 <strong>%s</strong>
branch.create_success=成功建立 '%s' 分支!
branch.branch_already_exists=分支 '%s' 已存在此儲存庫
branch.restore_failed=還原分支 %s 失敗
branch.protected_deletion_failed=不可能刪除已受保護的分支 %s。
[org]
org_name_holder=組織名稱
@ -1326,7 +1342,9 @@ config.mailer_disable_helo=禁用 HELO 操作
config.mailer_name=發送者名稱
config.mailer_host=郵件主機地址
config.mailer_user=發送者帳號
config.mailer_use_sendmail=使用 Sendmail
config.mailer_sendmail_path=Sendmail 路徑
config.mailer_sendmail_args=Sendmail 的額外參數
config.send_test_mail=發送測試郵件
config.test_mail_failed=發送測試郵件至 '%s' 時失敗:%v
config.test_mail_sent=測試電子郵件已發送到 '%s'。

File diff suppressed because one or more lines are too long

View File

@ -1,66 +1,66 @@
.admin {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
padding-top: 15px;
padding-bottom: @footer-margin * 2;
.table.segment {
padding: 0;
font-size: 13px;
.table.segment {
padding: 0;
font-size: 13px;
&:not(.striped) {
padding-top: 5px;
&:not(.striped) {
padding-top: 5px;
thead {
th:last-child {
padding-right: 5px !important;
}
}
}
thead {
th:last-child {
padding-right: 5px !important;
}
}
}
th {
padding-top: 5px;
padding-bottom: 5px;
}
th {
padding-top: 5px;
padding-bottom: 5px;
}
&:not(.select) {
th, td {
&:first-of-type {
padding-left: 15px !important;
}
}
}
}
.ui.header,
.ui.segment {
box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
}
&:not(.select) {
th, td {
&:first-of-type {
padding-left: 15px !important;
}
}
}
}
.ui.header,
.ui.segment {
box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
}
&.user {
.email {
max-width: 200px;
}
}
&.user {
.email {
max-width: 200px;
}
}
dl.admin-dl-horizontal {
padding: 20px;
margin: 0;
dl.admin-dl-horizontal {
padding: 20px;
margin: 0;
dd {
margin-left: 275px;
}
dt {
font-weight: bolder;
float: left;
width: 285px;
clear: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
dd {
margin-left: 275px;
}
dt {
font-weight: bolder;
float: left;
width: 285px;
clear: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
&.config {
#test-mail-btn {
margin-left: 5px;
}
}
&.config {
#test-mail-btn {
margin-left: 5px;
}
}
}

View File

@ -146,6 +146,12 @@ pre, code {
}
}
&.menu,
&.vertical.menu,
&.segment {
box-shadow: none;
}
.text {
&.red {
color: #d95c5c !important;

View File

@ -1,158 +1,163 @@
.dashboard {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
padding-top: 15px;
padding-bottom: @footer-margin * 2;
&.feeds,
&.issues {
.context.user.menu {
z-index: 101;
min-width: 200px;
.ui.header {
font-size: 1rem;
text-transform: none;
}
}
.filter.menu {
.item {
text-align: left;
.text {
height: 16px;
vertical-align: middle;
&.truncate {
width: 85%;
}
}
.floating.label {
top: 7px;
left: 90%;
width: 15%;
}
}
&.feeds,
&.issues {
.context.user.menu {
z-index: 101;
min-width: 200px;
.ui.header {
font-size: 1rem;
text-transform: none;
}
}
.filter.menu {
.item {
text-align: left;
.text {
height: 16px;
vertical-align: middle;
&.truncate {
width: 85%;
}
}
.floating.label {
top: 7px;
left: 90%;
width: 15%;
}
}
// Sort
.jump.item {
margin: 1px;
padding-right: 0;
}
.menu {
max-height: 300px;
overflow-x: auto;
right: 0!important;
left: auto!important;
}
}
.ui.right .head.menu {
margin-top: -5px;
.item.active {
color: #d9453d;
}
}
}
// Sort
.jump.item {
margin: 1px;
padding-right: 0;
}
.menu {
max-height: 300px;
overflow-x: auto;
right: 0!important;
left: auto!important;
}
}
.ui.right .head.menu {
margin-top: -5px;
.item.active {
color: #d9453d;
}
}
}
/* Accomodate for Semantic's 1px hacks on .attached elements */
.dashboard-repos {
margin: 0 1px;
}
}
&.feeds {
.news {
> .ui.grid {
margin-left: auto;
margin-right: auto;
}
.ui.avatar {
margin-top: 13px;
}
p {
line-height: 1em;
}
.time-since {
font-size: 13px;
}
.issue.title {
width: 80%;
}
.push.news .content ul {
font-size: 13px;
list-style: none;
padding-left: 10px;
.news {
> .ui.grid {
margin-left: auto;
margin-right: auto;
}
.ui.avatar {
margin-top: 13px;
}
p {
line-height: 1em;
}
.time-since {
font-size: 13px;
}
.issue.title {
width: 80%;
}
.push.news .content ul {
font-size: 13px;
list-style: none;
padding-left: 10px;
img {
margin-bottom: -2px;
}
.text.truncate {
width: 80%;
margin-bottom: -5px;
}
}
.commit-id {
font-family: Consolas, monospace;
}
code {
padding: 1px;
font-size: 85%;
background-color: rgba(0, 0, 0, 0.04);
border-radius: 3px;
word-break: break-all;
}
}
img {
margin-bottom: -2px;
}
.text.truncate {
width: 80%;
margin-bottom: -5px;
}
}
.commit-id {
font-family: Consolas, monospace;
}
code {
padding: 1px;
font-size: 85%;
background-color: rgba(0, 0, 0, 0.04);
border-radius: 3px;
word-break: break-all;
}
}
.list {
.header {
.ui.label {
margin-top: -4px;
padding: 4px 5px;
font-weight: normal;
}
.list {
.header {
.ui.label {
margin-top: -4px;
padding: 4px 5px;
font-weight: normal;
}
.plus.icon {
margin-top: 5px;
}
}
ul {
list-style: none;
margin: 0;
padding-left: 0;
.plus.icon {
margin-top: 5px;
}
}
ul {
list-style: none;
margin: 0;
padding-left: 0;
li {
&:not(:last-child) {
border-bottom: 1px solid #EAEAEA;
}
li {
&:not(:last-child) {
border-bottom: 1px solid #EAEAEA;
}
&.private {
background-color: #fcf8e9;
}
&.private {
background-color: #fcf8e9;
}
a {
padding: 6px 1.2em;
display: block;
a {
padding: 6px 1.2em;
display: block;
.octicon {
color: #888;
.octicon {
color: #888;
&.rear {
font-size: 15px;
}
}
.star-num {
font-size: 12px;
}
}
}
}
&.rear {
font-size: 15px;
}
}
.star-num {
font-size: 12px;
}
}
}
}
.repo-owner-name-list {
.item-name {
max-width: 70%;
margin-bottom: -4px;
}
}
.repo-owner-name-list {
.item-name {
max-width: 70%;
margin-bottom: -4px;
}
}
#collaborative-repo-list {
.owner-and-repo {
max-width: 80%;
margin-bottom: -5px;
}
.owner-name {
max-width: 120px;
margin-bottom: -5px;
}
}
}
#collaborative-repo-list {
.owner-and-repo {
max-width: 80%;
margin-bottom: -5px;
}
.owner-name {
max-width: 120px;
margin-bottom: -5px;
}
}
}
}

View File

@ -1,12 +1,12 @@
.CodeMirror {
font: 14px Consolas, "Liberation Mono", Menlo, Courier, monospace;
&.cm-s-default {
border-radius: 3px;
padding: 0 !important;
}
.cm-comment {
background: inherit !important;
}
font: 14px Consolas, "Liberation Mono", Menlo, Courier, monospace;
&.cm-s-default {
border-radius: 3px;
padding: 0 !important;
}
.cm-comment {
background: inherit !important;
}
}
.repository.file.editor .tab[data-tab="write"] {
padding: 0 !important;

View File

@ -1,6 +1,6 @@
.emoji {
width: 1.5em;
height: 1.5em;
display: inline-block;
background-size: contain;
width: 1.5em;
height: 1.5em;
display: inline-block;
background-size: contain;
}

View File

@ -1,8 +1,8 @@
.explore {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
padding-top: 15px;
padding-bottom: @footer-margin * 2;
.navbar {
.navbar {
justify-content: center;
padding-top: 15px !important;
margin-top: -15px !important;
@ -10,80 +10,80 @@
background-color: #FAFAFA !important;
border-width: 1px !important;
.octicon {
width: 16px;
text-align: center;
}
}
.octicon {
width: 16px;
text-align: center;
}
}
}
.ui.repository.list {
.item {
padding-bottom: 25px;
.item {
padding-bottom: 25px;
&:not(:first-child) {
border-top: 1px solid #eee;
padding-top: 25px;
}
&:not(:first-child) {
border-top: 1px solid #eee;
padding-top: 25px;
}
.ui.header {
font-size: 1.5rem;
padding-bottom: 10px;
.ui.header {
font-size: 1.5rem;
padding-bottom: 10px;
.name {
word-break: break-all;
}
.name {
word-break: break-all;
}
.metas {
color: #888;
font-size: 14px;
font-weight: normal;
span:not(:last-child) {
margin-right: 5px;
}
}
}
.time {
font-size: 12px;
color: #808080;
}
}
.metas {
color: #888;
font-size: 14px;
font-weight: normal;
span:not(:last-child) {
margin-right: 5px;
}
}
}
.time {
font-size: 12px;
color: #808080;
}
}
}
.ui.repository.branches {
.time{
font-size: 12px;
color: #808080;
}
.time{
font-size: 12px;
color: #808080;
}
}
.ui.user.list {
.item {
padding-bottom: 25px;
.item {
padding-bottom: 25px;
&:not(:first-child) {
border-top: 1px solid #eee;
padding-top: 25px;
}
&:not(:first-child) {
border-top: 1px solid #eee;
padding-top: 25px;
}
.ui.avatar.image {
width: 40px;
height: 40px;
}
.ui.avatar.image {
width: 40px;
height: 40px;
}
.description {
margin-top: 5px;
.description {
margin-top: 5px;
.octicon:not(:first-child) {
margin-left: 5px;
}
.octicon:not(:first-child) {
margin-left: 5px;
}
a {
color: #333;
&:hover {
text-decoration: underline;
}
}
}
}
a {
color: #333;
&:hover {
text-decoration: underline;
}
}
}
}
}

View File

@ -1,144 +1,144 @@
.form {
.help {
color: #999999;
padding-top: .6em;
padding-bottom: .6em;
display: inline-block;
}
.help {
color: #999999;
padding-top: .6em;
padding-bottom: .6em;
display: inline-block;
}
}
.ui.attached.header {
background: #f0f0f0;
.right {
margin-top: -5px;
.button {
padding: 8px 10px;
font-weight: normal;
}
}
background: #f0f0f0;
.right {
margin-top: -5px;
.button {
padding: 8px 10px;
font-weight: normal;
}
}
}
@create-page-form-input-padding: 250px !important;
#create-page-form {
form {
margin: auto;
width: 800px!important;
.ui.message {
text-align: center;
}
.header {
padding-left: @create-page-form-input-padding+30px;
}
.inline.field > label {
text-align: right;
width: @create-page-form-input-padding;
word-wrap: break-word;
}
.help {
margin-left: @create-page-form-input-padding+15px;
}
.optional .title {
margin-left: @create-page-form-input-padding;
}
input,
textarea {
width: 50%!important;
}
}
form {
margin: auto;
width: 800px!important;
.ui.message {
text-align: center;
}
.header {
padding-left: @create-page-form-input-padding+30px;
}
.inline.field > label {
text-align: right;
width: @create-page-form-input-padding;
word-wrap: break-word;
}
.help {
margin-left: @create-page-form-input-padding+15px;
}
.optional .title {
margin-left: @create-page-form-input-padding;
}
input,
textarea {
width: 50%!important;
}
}
}
.signin {
.oauth2{
div {
display: inline-block;
p {
margin: 10px 5px 0 0;
float: left;
}
}
a {
margin-right: 3px;
&:last-child {
margin-right: 0px;
}
}
img {
width: 32px;
height: 32px;
&.openidConnect {
width: auto;
}
}
}
.oauth2{
div {
display: inline-block;
p {
margin: 10px 5px 0 0;
float: left;
}
}
a {
margin-right: 3px;
&:last-child {
margin-right: 0px;
}
}
img {
width: 32px;
height: 32px;
&.openidConnect {
width: auto;
}
}
}
}
.user.activate,
.user.forgot.password,
.user.reset.password,
.user.signin,
.user.signup {
@input-padding: 200px!important;
#create-page-form;
form {
width: 700px!important;
.header {
padding-left: 0 !important;
text-align: center;
}
.inline.field > label {
width: @input-padding;
}
}
@input-padding: 200px!important;
#create-page-form;
form {
width: 700px!important;
.header {
padding-left: 0 !important;
text-align: center;
}
.inline.field > label {
width: @input-padding;
}
}
}
.repository {
&.new.repo,
&.new.migrate,
&.new.fork {
#create-page-form;
form {
.dropdown {
.dropdown.icon {
margin-top: -7px!important;
}
.text {
margin-right: 0!important;
i {
margin-right: 0!important;
}
}
}
.header {
padding-left: 0 !important;
text-align: center;
}
}
}
&.new.repo,
&.new.migrate,
&.new.fork {
#create-page-form;
form {
.dropdown {
.dropdown.icon {
margin-top: -7px!important;
}
.text {
margin-right: 0!important;
i {
margin-right: 0!important;
}
}
}
.header {
padding-left: 0 !important;
text-align: center;
}
}
}
&.new.repo {
.ui.form {
.selection.dropdown:not(.owner) {
width: 50%!important;
}
#auto-init {
margin-left: @create-page-form-input-padding+15px;
}
}
}
&.new.repo {
.ui.form {
.selection.dropdown:not(.owner) {
width: 50%!important;
}
#auto-init {
margin-left: @create-page-form-input-padding+15px;
}
}
}
}
.new.webhook {
form {
.help {
margin-left: 25px;
}
}
form {
.help {
margin-left: 25px;
}
}
}
.new.webhook {
.events.fields {
.column {
padding-left: 40px;
}
}
.events.fields {
.column {
padding-left: 40px;
}
}
}
.githook {

View File

@ -1,39 +1,39 @@
.home {
padding-bottom: @footer-margin * 2;
.logo {
max-width: 220px;
}
.hero {
h1, h2 {
font-family: 'PT Sans Narrow', sans-serif, 'Microsoft YaHei';
}
h1 {
font-size: 5.5em;
}
h2 {
font-size: 3em;
}
.octicon {
color: #5aa509;
font-size: 40px;
width: 50px;
}
&.header {
font-size: 20px;
}
}
p.large {
font-size: 16px
}
.stackable {
padding-top: 30px;
}
a {
color: #5aa509;
}
padding-bottom: @footer-margin * 2;
.logo {
max-width: 220px;
}
.hero {
h1, h2 {
font-family: 'PT Sans Narrow', sans-serif, 'Microsoft YaHei';
}
h1 {
font-size: 5.5em;
}
h2 {
font-size: 3em;
}
.octicon {
color: #5aa509;
font-size: 40px;
width: 50px;
}
&.header {
font-size: 20px;
}
}
p.large {
font-size: 16px
}
.stackable {
padding-top: 30px;
}
a {
color: #5aa509;
}
}
.signup {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
padding-top: 15px;
padding-bottom: @footer-margin * 2;
}

View File

@ -1,31 +1,31 @@
.install {
padding-top: 45px;
padding-bottom: @footer-margin * 2;
form {
@input-padding: 320px !important;
label {
text-align: right;
width: @input-padding;
}
input {
width: 35% !important;
}
.field {
text-align: left;
.help {
margin-left: @input-padding+15px;
}
&.optional .title {
margin-left: 38%;
}
}
}
.ui {
.checkbox {
margin-left: 40% !important;
label {
width: auto !important;
}
}
}
padding-top: 45px;
padding-bottom: @footer-margin * 2;
form {
@input-padding: 320px !important;
label {
text-align: right;
width: @input-padding;
}
input {
width: 35% !important;
}
.field {
text-align: left;
.help {
margin-left: @input-padding+15px;
}
&.optional .title {
margin-left: 38%;
}
}
}
.ui {
.checkbox {
margin-left: 40% !important;
label {
width: auto !important;
}
}
}
}

View File

@ -1,492 +1,492 @@
.markdown:not(code) {
overflow: hidden;
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
font-size: 16px;
line-height: 1.6 !important;
word-wrap: break-word;
&.file-view {
padding: 2em 2em 2em !important;
}
>*:first-child {
margin-top: 0 !important;
}
>*:last-child {
margin-bottom: 0 !important;
}
a:not([href]) {
color: inherit;
text-decoration: none;
}
.absent {
color: #c00;
}
.anchor {
position: absolute;
top: 0;
left: 0;
display: block;
padding-right: 6px;
padding-left: 30px;
margin-left: -30px;
}
.anchor:focus {
outline: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
position: relative;
margin-top: 1em;
margin-bottom: 16px;
font-weight: bold;
line-height: 1.4;
&:first-of-type {
margin-top: 0 !important;
}
}
h1 .octicon-link,
h2 .octicon-link,
h3 .octicon-link,
h4 .octicon-link,
h5 .octicon-link,
h6 .octicon-link {
display:none;
color:#000;
vertical-align:middle;
}
h1:hover .anchor,
h2:hover .anchor,
h3:hover .anchor,
h4:hover .anchor,
h5:hover .anchor,
h6:hover .anchor {
padding-left:8px;
margin-left:-30px;
text-decoration:none;
}
h1:hover .anchor .octicon-link,
h2:hover .anchor .octicon-link,
h3:hover .anchor .octicon-link,
h4:hover .anchor .octicon-link,
h5:hover .anchor .octicon-link,
h6:hover .anchor .octicon-link {
display:inline-block;
}
h1 tt,
h1 code,
h2 tt,
h2 code,
h3 tt,
h3 code,
h4 tt,
h4 code,
h5 tt,
h5 code,
h6 tt,
h6 code {
font-size:inherit;
}
h1 {
padding-bottom:0.3em;
font-size:2.25em;
line-height:1.2;
border-bottom:1px solid #eee;
}
h1 .anchor {
line-height:1;
}
h2 {
padding-bottom:0.3em;
font-size:1.75em;
line-height:1.225;
border-bottom:1px solid #eee;
}
h2 .anchor {
line-height:1;
}
h3 {
font-size:1.5em;
line-height:1.43;
}
h3 .anchor {
line-height:1.2;
}
h4 {
font-size:1.25em;
}
h4 .anchor {
line-height:1.2;
}
h5 {
font-size:1em;
}
h5 .anchor {
line-height:1.1;
}
h6 {
font-size:1em;color:#777;
}
h6 .anchor {
line-height:1.1;
}
p,
blockquote,
ul,
ol,
dl,
table,
pre {
margin-top: 0;
margin-bottom: 16px;
}
blockquote {
margin-left: 0;
}
hr {
height:4px;
padding:0;
margin:16px 0;
background-color:#e7e7e7;
border:0 none;
}
ul,
ol {
padding-left:2em;
}
ul.no-list,
ol.no-list {
padding:0;
list-style-type:none;
}
ul ul,
ul ol,
ol ol,
ol ul {
margin-top:0;
margin-bottom:0;
}
ol ol,
ul ol {
list-style-type: lower-roman;
}
li>p {
margin-top:0;
}
dl {
padding:0;
}
dl dt {
padding:0;
margin-top:16px;
font-size:1em;
font-style:italic;
font-weight:bold;
}
dl dd {
padding:0 16px;
margin-bottom:16px;
}
blockquote {
padding:0 15px;
color:#777;
border-left:4px solid #ddd;
}
blockquote>:first-child {
margin-top:0;
}
blockquote>:last-child {
margin-bottom:0;
}
table {
width:auto;
overflow:auto;
word-break:normal;
word-break:keep-all;
}
table th {
font-weight:bold;
}
table th,
table td {
padding: 6px 13px !important;
border: 1px solid #ddd !important;
}
table tr {
background-color:#fff;
border-top:1px solid #ccc;
}
table tr:nth-child(2n) {
background-color:#f8f8f8;
}
img {
max-width:100%;
box-sizing:border-box;
}
.emoji {
max-width:none;
}
span.frame {
display:block;
overflow:hidden;
}
span.frame>span {
display:block;
float:left;
width:auto;
padding:7px;
margin:13px 0 0;
overflow:hidden;
border:1px solid #ddd;
}
span.frame span img {
display:block;
float:left;
}
span.frame span span {
display:block;
padding:5px 0 0;
clear:both;
color:#333;
}
span.align-center {
display:block;
overflow:hidden;
clear:both;
}
span.align-center>span {
display:block;
margin:13px auto 0;
overflow:hidden;
text-align:center;
}
span.align-center span img {
margin:0 auto;
text-align:center;
}
span.align-right {
display:block;
overflow:hidden;
clear:both;
}
span.align-right>span {
display:block;
margin:13px 0 0;
overflow:hidden;
text-align:right;
}
span.align-right span img {
margin:0;
text-align:right;
}
span.float-left {
display:block;
float:left;
margin-right:13px;
overflow:hidden;
}
span.float-left span {
margin:13px 0 0;
}
span.float-right {
display:block;
float:right;
margin-left:13px;
overflow:hidden;
}
span.float-right>span {
display:block;
margin:13px auto 0;
overflow:hidden;
text-align:right;
}
code,
tt {
padding:0;
padding-top:0.2em;
padding-bottom:0.2em;
margin:0;
font-size:85%;
background-color:rgba(0,0,0,0.04);
border-radius:3px;
}
code:before,
code:after,
tt:before,
tt:after {
letter-spacing:-0.2em;
content:"\00a0";
}
code br,
tt br {
display:none;
}
del code {
text-decoration:inherit;
}
pre>code {
padding:0;
margin:0;
font-size:100%;
word-break:normal;
white-space:pre;
background:transparent;
border:0;
}
.highlight {
margin-bottom:16px;
}
.highlight pre,
pre {
padding:16px;
overflow:auto;
font-size:85%;
line-height:1.45;
background-color:#f7f7f7;
border-radius:3px;
}
.highlight pre {
margin-bottom:0;
word-break:normal;
}
pre {
word-wrap:normal;
}
pre code,
pre tt {
display:inline;
max-width:initial;
padding:0;
margin:0;
overflow:initial;
line-height:inherit;
word-wrap:normal;
background-color:transparent;
border:0;
}
pre code:before,
pre code:after,
pre tt:before,
pre tt:after {
content:normal;
}
kbd {
display:inline-block;
padding:3px 5px;
font-size:11px;
line-height:10px;
color:#555;
vertical-align:middle;
background-color:#fcfcfc;
border:solid 1px #ccc;
border-bottom-color:#bbb;
border-radius:3px;
box-shadow:inset 0 -1px 0 #bbb;
}
input[type="checkbox"] {
vertical-align: middle !important;
}
.csv-data td,
.csv-data th {
padding:5px;
overflow:hidden;
font-size:12px;
line-height:1;
text-align:left;
white-space:nowrap;
}
.csv-data .blob-num {
padding:10px 8px 9px;
text-align:right;
background:#fff;border:0;
}
.csv-data tr {
border-top:0;
}
.csv-data th {
font-weight:bold;
background:#f8f8f8;border-top:0;
}
.ui.list .list, ol.ui.list ol, ul.ui.list ul {
padding-left: 2em;
}
overflow: hidden;
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
font-size: 16px;
line-height: 1.6 !important;
word-wrap: break-word;
&.file-view {
padding: 2em 2em 2em !important;
}
>*:first-child {
margin-top: 0 !important;
}
>*:last-child {
margin-bottom: 0 !important;
}
a:not([href]) {
color: inherit;
text-decoration: none;
}
.absent {
color: #c00;
}
.anchor {
position: absolute;
top: 0;
left: 0;
display: block;
padding-right: 6px;
padding-left: 30px;
margin-left: -30px;
}
.anchor:focus {
outline: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
position: relative;
margin-top: 1em;
margin-bottom: 16px;
font-weight: bold;
line-height: 1.4;
&:first-of-type {
margin-top: 0 !important;
}
}
h1 .octicon-link,
h2 .octicon-link,
h3 .octicon-link,
h4 .octicon-link,
h5 .octicon-link,
h6 .octicon-link {
display:none;
color:#000;
vertical-align:middle;
}
h1:hover .anchor,
h2:hover .anchor,
h3:hover .anchor,
h4:hover .anchor,
h5:hover .anchor,
h6:hover .anchor {
padding-left:8px;
margin-left:-30px;
text-decoration:none;
}
h1:hover .anchor .octicon-link,
h2:hover .anchor .octicon-link,
h3:hover .anchor .octicon-link,
h4:hover .anchor .octicon-link,
h5:hover .anchor .octicon-link,
h6:hover .anchor .octicon-link {
display:inline-block;
}
h1 tt,
h1 code,
h2 tt,
h2 code,
h3 tt,
h3 code,
h4 tt,
h4 code,
h5 tt,
h5 code,
h6 tt,
h6 code {
font-size:inherit;
}
h1 {
padding-bottom:0.3em;
font-size:2.25em;
line-height:1.2;
border-bottom:1px solid #eee;
}
h1 .anchor {
line-height:1;
}
h2 {
padding-bottom:0.3em;
font-size:1.75em;
line-height:1.225;
border-bottom:1px solid #eee;
}
h2 .anchor {
line-height:1;
}
h3 {
font-size:1.5em;
line-height:1.43;
}
h3 .anchor {
line-height:1.2;
}
h4 {
font-size:1.25em;
}
h4 .anchor {
line-height:1.2;
}
h5 {
font-size:1em;
}
h5 .anchor {
line-height:1.1;
}
h6 {
font-size:1em;color:#777;
}
h6 .anchor {
line-height:1.1;
}
p,
blockquote,
ul,
ol,
dl,
table,
pre {
margin-top: 0;
margin-bottom: 16px;
}
blockquote {
margin-left: 0;
}
hr {
height:4px;
padding:0;
margin:16px 0;
background-color:#e7e7e7;
border:0 none;
}
ul,
ol {
padding-left:2em;
}
ul.no-list,
ol.no-list {
padding:0;
list-style-type:none;
}
ul ul,
ul ol,
ol ol,
ol ul {
margin-top:0;
margin-bottom:0;
}
ol ol,
ul ol {
list-style-type: lower-roman;
}
li>p {
margin-top:0;
}
dl {
padding:0;
}
dl dt {
padding:0;
margin-top:16px;
font-size:1em;
font-style:italic;
font-weight:bold;
}
dl dd {
padding:0 16px;
margin-bottom:16px;
}
blockquote {
padding:0 15px;
color:#777;
border-left:4px solid #ddd;
}
blockquote>:first-child {
margin-top:0;
}
blockquote>:last-child {
margin-bottom:0;
}
table {
width:auto;
overflow:auto;
word-break:normal;
word-break:keep-all;
}
table th {
font-weight:bold;
}
table th,
table td {
padding: 6px 13px !important;
border: 1px solid #ddd !important;
}
table tr {
background-color:#fff;
border-top:1px solid #ccc;
}
table tr:nth-child(2n) {
background-color:#f8f8f8;
}
img {
max-width:100%;
box-sizing:border-box;
}
.emoji {
max-width:none;
}
span.frame {
display:block;
overflow:hidden;
}
span.frame>span {
display:block;
float:left;
width:auto;
padding:7px;
margin:13px 0 0;
overflow:hidden;
border:1px solid #ddd;
}
span.frame span img {
display:block;
float:left;
}
span.frame span span {
display:block;
padding:5px 0 0;
clear:both;
color:#333;
}
span.align-center {
display:block;
overflow:hidden;
clear:both;
}
span.align-center>span {
display:block;
margin:13px auto 0;
overflow:hidden;
text-align:center;
}
span.align-center span img {
margin:0 auto;
text-align:center;
}
span.align-right {
display:block;
overflow:hidden;
clear:both;
}
span.align-right>span {
display:block;
margin:13px 0 0;
overflow:hidden;
text-align:right;
}
span.align-right span img {
margin:0;
text-align:right;
}
span.float-left {
display:block;
float:left;
margin-right:13px;
overflow:hidden;
}
span.float-left span {
margin:13px 0 0;
}
span.float-right {
display:block;
float:right;
margin-left:13px;
overflow:hidden;
}
span.float-right>span {
display:block;
margin:13px auto 0;
overflow:hidden;
text-align:right;
}
code,
tt {
padding:0;
padding-top:0.2em;
padding-bottom:0.2em;
margin:0;
font-size:85%;
background-color:rgba(0,0,0,0.04);
border-radius:3px;
}
code:before,
code:after,
tt:before,
tt:after {
letter-spacing:-0.2em;
content:"\00a0";
}
code br,
tt br {
display:none;
}
del code {
text-decoration:inherit;
}
pre>code {
padding:0;
margin:0;
font-size:100%;
word-break:normal;
white-space:pre;
background:transparent;
border:0;
}
.highlight {
margin-bottom:16px;
}
.highlight pre,
pre {
padding:16px;
overflow:auto;
font-size:85%;
line-height:1.45;
background-color:#f7f7f7;
border-radius:3px;
}
.highlight pre {
margin-bottom:0;
word-break:normal;
}
pre {
word-wrap:normal;
}
pre code,
pre tt {
display:inline;
max-width:initial;
padding:0;
margin:0;
overflow:initial;
line-height:inherit;
word-wrap:normal;
background-color:transparent;
border:0;
}
pre code:before,
pre code:after,
pre tt:before,
pre tt:after {
content:normal;
}
kbd {
display:inline-block;
padding:3px 5px;
font-size:11px;
line-height:10px;
color:#555;
vertical-align:middle;
background-color:#fcfcfc;
border:solid 1px #ccc;
border-bottom-color:#bbb;
border-radius:3px;
box-shadow:inset 0 -1px 0 #bbb;
}
input[type="checkbox"] {
vertical-align: middle !important;
}
.csv-data td,
.csv-data th {
padding:5px;
overflow:hidden;
font-size:12px;
line-height:1;
text-align:left;
white-space:nowrap;
}
.csv-data .blob-num {
padding:10px 8px 9px;
text-align:right;
background:#fff;border:0;
}
.csv-data tr {
border-top:0;
}
.csv-data th {
font-weight:bold;
background:#f8f8f8;border-top:0;
}
.ui.list .list, ol.ui.list ol, ul.ui.list ul {
padding-left: 2em;
}
}

View File

@ -1,162 +1,162 @@
.organization {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
padding-top: 15px;
padding-bottom: @footer-margin * 2;
.head {
.ui.header {
.text {
vertical-align: middle;
font-size: 1.6rem;
margin-left: 15px;
}
.ui.right {
margin-top: 5px;
}
}
}
.head {
.ui.header {
.text {
vertical-align: middle;
font-size: 1.6rem;
margin-left: 15px;
}
.ui.right {
margin-top: 5px;
}
}
}
&.new.org {
#create-page-form;
form {
.header {
padding-left: 0 !important;
text-align: center;
}
}
}
&.new.org {
#create-page-form;
form {
.header {
padding-left: 0 !important;
text-align: center;
}
}
}
&.options {
input {
min-width: 300px;
}
}
&.options {
input {
min-width: 300px;
}
}
&.profile {
#org-avatar {
width: 100px;
height: 100px;
margin-right: 15px;
}
&.profile {
#org-avatar {
width: 100px;
height: 100px;
margin-right: 15px;
}
#org-info {
.ui.header {
font-size: 36px;
margin-bottom: 0;
}
.desc {
font-size: 16px;
margin-bottom: 10px;
}
.meta {
.item {
display: inline-block;
margin-right: 10px;
#org-info {
.ui.header {
font-size: 36px;
margin-bottom: 0;
}
.desc {
font-size: 16px;
margin-bottom: 10px;
}
.meta {
.item {
display: inline-block;
margin-right: 10px;
.icon {
margin-right: 5px;
}
}
}
}
.icon {
margin-right: 5px;
}
}
}
}
.ui.top.header {
.ui.right {
margin-top: 0;
}
}
.ui.top.header {
.ui.right {
margin-top: 0;
}
}
.teams {
.item {
padding: 10px 15px;
}
}
}
.teams {
.item {
padding: 10px 15px;
}
}
}
&.teams,
&.profile {
.members {
.ui.avatar {
width: 48px;
height: 48px;
margin-right: 5px;
}
}
}
&.teams,
&.profile {
.members {
.ui.avatar {
width: 48px;
height: 48px;
margin-right: 5px;
}
}
}
&.invite {
#invite-box {
margin: auto;
margin-top: 50px;
width: 500px !important;
&.invite {
#invite-box {
margin: auto;
margin-top: 50px;
width: 500px !important;
#search-user-box {
input {
margin-left: 0;
width: 300px;
}
}
.ui.button {
margin-left: 5px;
margin-top: -3px;
}
}
}
#search-user-box {
input {
margin-left: 0;
width: 300px;
}
}
.ui.button {
margin-left: 5px;
margin-top: -3px;
}
}
}
&.members {
.list {
.item {
margin-left: 0;
margin-right: 0;
border-bottom: 1px solid #eee;
&.members {
.list {
.item {
margin-left: 0;
margin-right: 0;
border-bottom: 1px solid #eee;
.ui.avatar {
width: 48px;
height: 48px;
}
.meta {
line-height: 24px;
}
}
}
}
.ui.avatar {
width: 48px;
height: 48px;
}
.meta {
line-height: 24px;
}
}
}
}
&.teams {
.detail {
.item {
padding: 10px 15px;
&.teams {
.detail {
.item {
padding: 10px 15px;
&:not(:last-child) {
border-bottom: 1px solid #eee;
}
}
}
&:not(:last-child) {
border-bottom: 1px solid #eee;
}
}
}
.repositories,
.members {
.item {
padding: 10px 20px;
line-height: 32px;
.repositories,
.members {
.item {
padding: 10px 20px;
line-height: 32px;
&:not(:last-child) {
border-bottom: 1px solid #DDD;
}
&:not(:last-child) {
border-bottom: 1px solid #DDD;
}
.button {
padding: 9px 10px;
}
}
}
.button {
padding: 9px 10px;
}
}
}
#add-repo-form,
#add-member-form {
input {
margin-left: 0;
}
#add-repo-form,
#add-member-form {
input {
margin-left: 0;
}
.ui.button {
margin-left: 5px;
margin-top: -3px;
}
}
}
.ui.button {
margin-left: 5px;
margin-top: -3px;
}
}
}
}

View File

@ -1354,257 +1354,257 @@
// End of .repository
&.user-cards {
.list {
padding: 0;
.list {
padding: 0;
.item {
list-style: none;
width: 32%;
margin: 10px 10px 10px 0;
padding-bottom: 14px;
float: left;
.item {
list-style: none;
width: 32%;
margin: 10px 10px 10px 0;
padding-bottom: 14px;
float: left;
.avatar {
width: 48px;
height: 48px;
float: left;
display: block;
margin-right: 10px;
}
.name {
margin-top: 0;
margin-bottom: 0;
font-weight: normal;
}
.meta {
margin-top: 5px;
}
}
}
.avatar {
width: 48px;
height: 48px;
float: left;
display: block;
margin-right: 10px;
}
.name {
margin-top: 0;
margin-bottom: 0;
font-weight: normal;
}
.meta {
margin-top: 5px;
}
}
}
}
#search-repo-box,
#search-user-box {
.results {
.result {
.image {
float: left;
margin-right: 8px;
width: 2em;
height: 2em;
}
.content {
margin: 6px 0;
}
}
}
.results {
.result {
.image {
float: left;
margin-right: 8px;
width: 2em;
height: 2em;
}
.content {
margin: 6px 0;
}
}
}
}
.issue-actions {
display: none;
display: none;
}
.issue.list {
list-style: none;
padding-top: 15px;
>.item {
padding-top: 15px;
padding-bottom: 10px;
border-bottom: 1px dashed #AAA;
.title {
color: #444;
font-size: 15px;
font-weight: bold;
margin: 0 6px;
&:hover {
color: #000;
}
}
.comment {
padding-right: 10px;
color: #666;
}
.desc {
padding-top: 5px;
color: #999;
a.milestone {
padding-left: 5px;
color: #999!important;
&:hover {
color: #000!important;
}
}
.assignee {
margin-top: -5px;
margin-right: 5px;
}
}
}
list-style: none;
padding-top: 15px;
>.item {
padding-top: 15px;
padding-bottom: 10px;
border-bottom: 1px dashed #AAA;
.title {
color: #444;
font-size: 15px;
font-weight: bold;
margin: 0 6px;
&:hover {
color: #000;
}
}
.comment {
padding-right: 10px;
color: #666;
}
.desc {
padding-top: 5px;
color: #999;
a.milestone {
padding-left: 5px;
color: #999!important;
&:hover {
color: #000!important;
}
}
.assignee {
margin-top: -5px;
margin-right: 5px;
}
}
}
}
.page.buttons {
padding-top: 15px;
padding-top: 15px;
}
.ui.form {
.dropzone {
width: 100%;
margin-bottom: 10px;
border: 2px dashed #0087F7;
box-shadow: none!important;
.dz-error-message {
top: 140px;
}
}
.dropzone {
width: 100%;
margin-bottom: 10px;
border: 2px dashed #0087F7;
box-shadow: none!important;
.dz-error-message {
top: 140px;
}
}
}
.settings {
.content {
margin-top: 2px;
>.header,
.segment {
box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
}
}
.list {
> .item {
.green {
color: #21BA45 !important;
}
&:not(:first-child) {
border-top: 1px solid #eaeaea;
padding:1rem;
margin: 15px -1rem -1rem -1rem;
}
> .mega-octicon {
display: table-cell;
}
> .mega-octicon + .content {
display: table-cell;
padding: 0 0 0 .5em;
vertical-align: top;
}
.info {
margin-top: 10px;
.tab.segment {
border: none;
padding: 10px 0 0;
}
}
}
&.key{
.meta {
padding-top: 5px;
color: #666;
}
}
&.email {
> .item:not(:first-child) {
min-height: 60px;
}
}
&.collaborator {
> .item {
padding: 0;
}
}
}
.content {
margin-top: 2px;
>.header,
.segment {
box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
}
}
.list {
> .item {
.green {
color: #21BA45 !important;
}
&:not(:first-child) {
border-top: 1px solid #eaeaea;
padding:1rem;
margin: 15px -1rem -1rem -1rem;
}
> .mega-octicon {
display: table-cell;
}
> .mega-octicon + .content {
display: table-cell;
padding: 0 0 0 .5em;
vertical-align: top;
}
.info {
margin-top: 10px;
.tab.segment {
border: none;
padding: 10px 0 0;
}
}
}
&.key{
.meta {
padding-top: 5px;
color: #666;
}
}
&.email {
> .item:not(:first-child) {
min-height: 60px;
}
}
&.collaborator {
> .item {
padding: 0;
}
}
}
}
.ui.vertical.menu {
.header.item {
font-size: 1.1em;
background: #f0f0f0;
}
.header.item {
font-size: 1.1em;
background: #f0f0f0;
}
}
.edit-label.modal,
.new-label.segment {
.form {
.column {
padding-right: 0;
}
.buttons {
margin-left: auto;
padding-top: 15px;
}
.color.picker.column {
width: auto;
.color-picker {
height: 35px;
width: auto;
padding-left: 30px;
}
}
.minicolors-swatch.minicolors-sprite {
top: 10px;
left: 10px;
width: 15px;
height: 15px;
}
.precolors {
padding-left: 0;
padding-right: 0;
margin: 3px 10px auto 10px;
width: 120px;
.color {
float: left;
width: 15px;
height: 15px;
}
}
}
.form {
.column {
padding-right: 0;
}
.buttons {
margin-left: auto;
padding-top: 15px;
}
.color.picker.column {
width: auto;
.color-picker {
height: 35px;
width: auto;
padding-left: 30px;
}
}
.minicolors-swatch.minicolors-sprite {
top: 10px;
left: 10px;
width: 15px;
height: 15px;
}
.precolors {
padding-left: 0;
padding-right: 0;
margin: 3px 10px auto 10px;
width: 120px;
.color {
float: left;
width: 15px;
height: 15px;
}
}
}
}
#avatar-arrow {
&:before, &:after {
right: 100%;
top: 20px;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
&:before {
border-right-color: #D4D4D5;
border-width: 9px;
margin-top: -9px;
}
&:after {
border-right-color: #f7f7f7;
border-width: 8px;
margin-top: -8px;
}
&:before, &:after {
right: 100%;
top: 20px;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
&:before {
border-right-color: #D4D4D5;
border-width: 9px;
margin-top: -9px;
}
&:after {
border-right-color: #f7f7f7;
border-width: 8px;
margin-top: -8px;
}
}
#transfer-repo-modal,
#delete-repo-modal {
.ui.message {
width: 100%!important;
}
.ui.message {
width: 100%!important;
}
}
// generate .tab-size-{i} from 1 to 16
.generate-tab-size(16);
.generate-tab-size(@n, @i: 1) when (@i =< @n) {
.tab-size-@{i} {
tab-size: @i !important;
-moz-tab-size: @i !important;
}
.generate-tab-size(@n, (@i + 1));
.tab-size-@{i} {
tab-size: @i !important;
-moz-tab-size: @i !important;
}
.generate-tab-size(@n, (@i + 1));
}
.stats-table {
display: table;
width: 100%;
.table-cell {
display: table-cell;
&.tiny {
height: .5em;
}
}
display: table;
width: 100%;
.table-cell {
display: table-cell;
&.tiny {
height: .5em;
}
}
}
tbody.commit-list {
@ -1612,5 +1612,5 @@ tbody.commit-list {
}
.commit-body {
white-space: pre-wrap;
white-space: pre-wrap;
}

View File

@ -1,62 +1,62 @@
.user {
&:not(.icon) {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
}
&:not(.icon) {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
}
&.profile {
.ui.card {
.username {
display: block;
}
.extra.content {
padding: 0;
&.profile {
.ui.card {
.username {
display: block;
}
.extra.content {
padding: 0;
ul {
margin: 0;
padding: 0;
ul {
margin: 0;
padding: 0;
li {
padding: 10px;
list-style: none;
li {
padding: 10px;
list-style: none;
&:not(:last-child) {
border-bottom: 1px solid #eaeaea;
}
&:not(:last-child) {
border-bottom: 1px solid #eaeaea;
}
.octicon {
margin-left: 1px;
margin-right: 5px;
}
.octicon {
margin-left: 1px;
margin-right: 5px;
}
&.follow {
.ui.button {
width: 100%;
}
}
}
}
}
}
&.follow {
.ui.button {
width: 100%;
}
}
}
}
}
}
.ui.repository.list {
margin-top: 25px;
}
}
.ui.repository.list {
margin-top: 25px;
}
}
&.followers {
.header.name {
font-size: 20px;
line-height: 24px;
vertical-align: middle;
}
&.followers {
.header.name {
font-size: 20px;
line-height: 24px;
vertical-align: middle;
}
.follow {
.ui.button {
padding: 8px 15px;
}
}
}
.follow {
.ui.button {
padding: 8px 15px;
}
}
}
&.notification {
.octicon {

View File

@ -66,5 +66,6 @@
<!-- JavaScript -->
<script src="{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.js"></script>
<script src="{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}"></script>
{{template "custom/footer" .}}
</body>
</html>

View File

@ -122,6 +122,7 @@
<meta property="og:url" content="{{AppUrl}}" />
<meta property="og:description" content="{{MetaDescription}}">
{{end}}
{{template "custom/header" .}}
</head>
<body>
<div class="full height">

View File

View File

View File

@ -3,7 +3,7 @@
<div class="ui vertically grid head">
<div class="column">
<div class="ui header">
<img class="ui image" src="{{.RelAvatarLink}}?s=100">
<img class="ui image" src="{{.SizedRelAvatarLink 100}}">
<span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
<div class="ui right">

View File

@ -3,7 +3,7 @@
<div class="ui container">
<div class="ui grid">
<div class="ui sixteen wide column">
<img class="ui left" id="org-avatar" src="{{.Org.RelAvatarLink}}?s=140"/>
<img class="ui left" id="org-avatar" src="{{.Org.SizedRelAvatarLink 140}}"/>
<div id="org-info">
<div class="ui header">
{{.Org.DisplayName}}

View File

@ -8,7 +8,7 @@
{{range .Members}}
<div class="item ui grid">
<div class="ui one wide column">
<img class="ui avatar" src="{{.RelAvatarLink}}?s=48">
<img class="ui avatar" src="{{.SizedRelAvatarLink 48}}">
</div>
<div class="ui three wide column">
<div class="meta"><a href="{{.HomeLink}}">{{.Name}}</a></div>

View File

@ -1,6 +1,6 @@
<div class="fitted item choose reference">
<div class="ui floating filter dropdown custom" data-can-create-branch="{{.CanCreateBranch}}" data-no-results="{{.i18n.Tr "repo.pulls.no_results"}}">
<div class="ui basic small button" @click="menuVisible = !menuVisible" @keyup.enter="menuVisible = !menuVisible">
<div class="ui basic small compact button" @click="menuVisible = !menuVisible" @keyup.enter="menuVisible = !menuVisible">
<span class="text">
<i class="octicon octicon-git-branch"></i>
{{if .IsViewBranch}}{{.i18n.Tr "repo.branch"}}{{else}}{{.i18n.Tr "repo.tree"}}{{end}}:

View File

@ -172,7 +172,7 @@
<a class="title has-emoji" href="{{$.Link}}/{{.Index}}">{{.Title}}</a>
{{if .Ref}}
<a class="ui label" href="{{$.RepoLink}}/src/commit/{{.Ref}}">{{.Ref}}</a>
<a class="ui label" href="{{$.RepoLink}}/src/branch/{{.Ref}}">{{.Ref}}</a>
{{end}}
{{range .Labels}}
<a class="ui label" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}">{{.Name}}</a>

View File

@ -31,7 +31,7 @@
<a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.i18n.Tr "repository"}}</a>
<a :class="{item: true, active: tab === 'organizations'}" @click="changeTab('organizations')">{{.i18n.Tr "organization"}}</a>
</div>
<div v-show="tab === 'repos'" class="ui tab active list">
<div v-show="tab === 'repos'" class="ui tab active list dashboard-repos">
<h4 class="ui top attached header">
{{.i18n.Tr "home.my_repos"}} <span class="ui grey label">${reposTotalCount}</span>
<div class="ui right">

View File

@ -6,11 +6,11 @@
<div class="ui card">
{{if eq .SignedUserName .Owner.Name}}
<a class="image poping up" href="{{AppSubUrl}}/user/settings/avatar" id="profile-avatar" data-content="{{.i18n.Tr "user.change_avatar"}}" data-variation="inverted tiny" data-position="bottom center">
<img src="{{.Owner.RelAvatarLink}}?s=290" title="{{.Owner.Name}}"/>
<img src="{{.Owner.SizedRelAvatarLink 290}}" title="{{.Owner.Name}}"/>
</a>
{{else}}
<span class="image">
<img src="{{.Owner.RelAvatarLink}}?s=290" title="{{.Owner.Name}}"/>
<img src="{{.Owner.SizedRelAvatarLink 290}}" title="{{.Owner.Name}}"/>
</span>
{{end}}
<div class="content">