github.com/msteinert/pam = commit:02ccfbf | github.com/msteinert/pam = commit:02ccfbf | ||||
github.com/nfnt/resize = commit:dc93e1b98c | github.com/nfnt/resize = commit:dc93e1b98c | ||||
github.com/russross/blackfriday = commit:d18b67a | github.com/russross/blackfriday = commit:d18b67a | ||||
github.com/sergi/go-diff = | |||||
github.com/shurcooL/sanitized_anchor_name = commit:10ef21a | github.com/shurcooL/sanitized_anchor_name = commit:10ef21a | ||||
github.com/Unknwon/cae = commit:7f5e046 | github.com/Unknwon/cae = commit:7f5e046 | ||||
github.com/Unknwon/com = commit:28b053d | github.com/Unknwon/com = commit:28b053d |
![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true) | ![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true) | ||||
##### Current version: 0.8.17 | |||||
##### Current version: 0.8.18 | |||||
| Web | UI | Preview | | | Web | UI | Preview | | ||||
|:-------------:|:-------:|:-------:| | |:-------------:|:-------:|:-------:| |
"github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
) | ) | ||||
const APP_VER = "0.8.17.0109" | |||||
const APP_VER = "0.8.18.0109" | |||||
func init() { | func init() { | ||||
runtime.GOMAXPROCS(runtime.NumCPU()) | runtime.GOMAXPROCS(runtime.NumCPU()) |
"bufio" | "bufio" | ||||
"bytes" | "bytes" | ||||
"fmt" | "fmt" | ||||
"html" | |||||
"html/template" | |||||
"io" | "io" | ||||
"io/ioutil" | "io/ioutil" | ||||
"os" | "os" | ||||
"os/exec" | "os/exec" | ||||
"strings" | "strings" | ||||
"html/template" | |||||
"html" | |||||
"github.com/Unknwon/com" | "github.com/Unknwon/com" | ||||
"github.com/sergi/go-diff/diffmatchpatch" | |||||
"golang.org/x/net/html/charset" | "golang.org/x/net/html/charset" | ||||
"golang.org/x/text/transform" | "golang.org/x/text/transform" | ||||
"github.com/sergi/go-diff/diffmatchpatch" | |||||
"github.com/gogits/git-module" | "github.com/gogits/git-module" | ||||
) | ) | ||||
type DiffLine struct { | type DiffLine struct { | ||||
LeftIdx int | |||||
RightIdx int | |||||
Type DiffLineType | |||||
Content string | |||||
LeftIdx int | |||||
RightIdx int | |||||
Type DiffLineType | |||||
Content string | |||||
ParsedContent template.HTML | ParsedContent template.HTML | ||||
} | } | ||||
Lines []*DiffLine | Lines []*DiffLine | ||||
} | } | ||||
func diffToHtml(diffRecord []diffmatchpatch.Diff, lineType DiffLineType) template.HTML { | |||||
result := "" | |||||
for _, s := range diffRecord { | |||||
if s.Type == diffmatchpatch.DiffInsert && lineType == DIFF_LINE_ADD { | |||||
result = result + "<span class=\"added-code\">"+html.EscapeString(s.Text)+"</span>" | |||||
} else if s.Type == diffmatchpatch.DiffDelete && lineType == DIFF_LINE_DEL { | |||||
result = result + "<span class=\"removed-code\">"+html.EscapeString(s.Text)+"</span>" | |||||
} else if s.Type == diffmatchpatch.DiffEqual { | |||||
result = result + html.EscapeString(s.Text) | |||||
var ( | |||||
addedCodePrefix = []byte("<span class=\"added-code\">") | |||||
removedCodePrefix = []byte("<span class=\"removed-code\">") | |||||
codeTagSuffix = []byte("</span>") | |||||
) | |||||
func diffToHTML(diffs []diffmatchpatch.Diff, lineType DiffLineType) template.HTML { | |||||
var buf bytes.Buffer | |||||
for i := range diffs { | |||||
if diffs[i].Type == diffmatchpatch.DiffInsert && lineType == DIFF_LINE_ADD { | |||||
buf.Write(addedCodePrefix) | |||||
buf.WriteString(html.EscapeString(diffs[i].Text)) | |||||
buf.Write(codeTagSuffix) | |||||
} else if diffs[i].Type == diffmatchpatch.DiffDelete && lineType == DIFF_LINE_DEL { | |||||
buf.Write(removedCodePrefix) | |||||
buf.WriteString(html.EscapeString(diffs[i].Text)) | |||||
buf.Write(codeTagSuffix) | |||||
} else if diffs[i].Type == diffmatchpatch.DiffEqual { | |||||
buf.WriteString(html.EscapeString(diffs[i].Text)) | |||||
} | } | ||||
} | } | ||||
return template.HTML(result) | |||||
return template.HTML(buf.Bytes()) | |||||
} | } | ||||
// get an specific line by type (add or del) and file line number | // get an specific line by type (add or del) and file line number | ||||
} | } | ||||
if lineType == DIFF_LINE_DEL { | if lineType == DIFF_LINE_DEL { | ||||
if diffLine.RightIdx == 0 && diffLine.LeftIdx == idx - difference { | |||||
if diffLine.RightIdx == 0 && diffLine.LeftIdx == idx-difference { | |||||
return diffLine | return diffLine | ||||
} | } | ||||
} else if lineType == DIFF_LINE_ADD { | } else if lineType == DIFF_LINE_ADD { | ||||
if diffLine.LeftIdx == 0 && diffLine.RightIdx == idx + difference { | |||||
if diffLine.LeftIdx == 0 && diffLine.RightIdx == idx+difference { | |||||
return diffLine | return diffLine | ||||
} | } | ||||
} | } | ||||
var compareDiffLine *DiffLine | var compareDiffLine *DiffLine | ||||
var diff1, diff2 string | var diff1, diff2 string | ||||
// default content: as is | |||||
diffLine.ParsedContent = template.HTML(html.EscapeString(diffLine.Content[1:])) | |||||
// just compute diff for adds and removes | // just compute diff for adds and removes | ||||
if diffLine.Type != DIFF_LINE_ADD && diffLine.Type != DIFF_LINE_DEL { | if diffLine.Type != DIFF_LINE_ADD && diffLine.Type != DIFF_LINE_DEL { | ||||
diffLine.ParsedContent = template.HTML(html.EscapeString(diffLine.Content[1:])) | |||||
continue | continue | ||||
} | } | ||||
diffRecord := dmp.DiffMain(diff1[1:], diff2[1:], true) | diffRecord := dmp.DiffMain(diff1[1:], diff2[1:], true) | ||||
diffRecord = dmp.DiffCleanupSemantic(diffRecord) | diffRecord = dmp.DiffCleanupSemantic(diffRecord) | ||||
diffLine.ParsedContent = diffToHtml(diffRecord, diffLine.Type) | |||||
diffLine.ParsedContent = diffToHTML(diffRecord, diffLine.Type) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
.repository .diff-box .count { | .repository .diff-box .count { | ||||
margin-right: 12px; | margin-right: 12px; | ||||
font-size: 13px; | |||||
} | } | ||||
.repository .diff-box .count .bar { | .repository .diff-box .count .bar { | ||||
background-color: #e75316; | |||||
background-color: #bd2c00 ; | |||||
height: 12px; | height: 12px; | ||||
width: 40px; | width: 40px; | ||||
display: inline-block; | display: inline-block; | ||||
vertical-align: text-top; | vertical-align: text-top; | ||||
} | } | ||||
.repository .diff-box .count .bar .add { | .repository .diff-box .count .bar .add { | ||||
background-color: #77c64a; | |||||
background-color: #55a532; | |||||
height: 12px; | height: 12px; | ||||
} | } | ||||
.repository .diff-box .file { | .repository .diff-box .file { | ||||
.repository .diff-file-box .code-diff tbody tr.add-code td.halfwidth { | .repository .diff-file-box .code-diff tbody tr.add-code td.halfwidth { | ||||
width: 50%; | width: 50%; | ||||
} | } | ||||
.repository .diff-file-box .code-diff tbody tr .removed-code { | |||||
background-color: #ff9999; | |||||
} | |||||
.repository .diff-file-box .code-diff tbody tr .added-code { | |||||
background-color: #99ff99; | |||||
} | |||||
.repository .diff-file-box.file-content img { | .repository .diff-file-box.file-content img { | ||||
max-width: 100%; | max-width: 100%; | ||||
padding: 5px 5px 0 5px; | padding: 5px 5px 0 5px; | ||||
#delete-repo-modal .ui.message { | #delete-repo-modal .ui.message { | ||||
width: 100%!important; | width: 100%!important; | ||||
} | } | ||||
.removed-code { | |||||
background-color: #ff9999; | |||||
} | |||||
.added-code { | |||||
background-color: #99ff99; | |||||
} | |||||
.organization { | .organization { | ||||
padding-top: 15px; | padding-top: 15px; | ||||
padding-bottom: 80px; | padding-bottom: 80px; |
.diff-box { | .diff-box { | ||||
.count { | .count { | ||||
margin-right: 12px; | margin-right: 12px; | ||||
font-size: 13px; | |||||
.bar { | .bar { | ||||
background-color: #e75316; | |||||
background-color: #bd2c00 ; | |||||
height: 12px; | height: 12px; | ||||
width: 40px; | width: 40px; | ||||
display: inline-block; | display: inline-block; | ||||
margin: 2px 4px 0 4px; | margin: 2px 4px 0 4px; | ||||
vertical-align: text-top; | vertical-align: text-top; | ||||
.add { | .add { | ||||
background-color: #77c64a; | |||||
background-color: #55a532; | |||||
height: 12px; | height: 12px; | ||||
} | } | ||||
} | } | ||||
// } | // } | ||||
// } | // } | ||||
&.del-code { | &.del-code { | ||||
// Duplicate here to enforce add code color. | |||||
td.add-code { | td.add-code { | ||||
background-color: #eaffea !important; | background-color: #eaffea !important; | ||||
border-color: #c1e9c1 !important; | border-color: #c1e9c1 !important; | ||||
// background-color: #ffffdd !important; | // background-color: #ffffdd !important; | ||||
// } | // } | ||||
} | } | ||||
.removed-code { | |||||
background-color: #ff9999; | |||||
} | |||||
.added-code { | |||||
background-color: #99ff99; | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
.removed-code { | |||||
background-color: #ff9999; | |||||
} | |||||
.added-code { | |||||
background-color: #99ff99; | |||||
} |
0.8.17.0109 | |||||
0.8.18.0109 |