* Make diff line-marker non-selectable * Move to use data-* as per @mrsdizzie * fix missing line nums * Add a minimum-width to force right-align of the line num * Move line-type-marker into separate columntags/v1.21.12.1
| @@ -80,6 +80,14 @@ func (d *DiffLine) GetCommentSide() string { | |||||
| return d.Comments[0].DiffSide() | return d.Comments[0].DiffSide() | ||||
| } | } | ||||
| // GetLineTypeMarker returns the line type marker | |||||
| func (d *DiffLine) GetLineTypeMarker() string { | |||||
| if strings.IndexByte(" +-", d.Content[0]) > -1 { | |||||
| return d.Content[0:1] | |||||
| } | |||||
| return "" | |||||
| } | |||||
| // DiffSection represents a section of a DiffFile. | // DiffSection represents a section of a DiffFile. | ||||
| type DiffSection struct { | type DiffSection struct { | ||||
| Name string | Name string | ||||
| @@ -87,22 +95,14 @@ type DiffSection struct { | |||||
| } | } | ||||
| var ( | var ( | ||||
| addedCodePrefix = []byte("<span class=\"added-code\">") | |||||
| removedCodePrefix = []byte("<span class=\"removed-code\">") | |||||
| codeTagSuffix = []byte("</span>") | |||||
| addedCodePrefix = []byte(`<span class="added-code">`) | |||||
| removedCodePrefix = []byte(`<span class="removed-code">`) | |||||
| codeTagSuffix = []byte(`</span>`) | |||||
| ) | ) | ||||
| func diffToHTML(diffs []diffmatchpatch.Diff, lineType DiffLineType) template.HTML { | func diffToHTML(diffs []diffmatchpatch.Diff, lineType DiffLineType) template.HTML { | ||||
| buf := bytes.NewBuffer(nil) | buf := bytes.NewBuffer(nil) | ||||
| // Reproduce signs which are cut for inline diff before. | |||||
| switch lineType { | |||||
| case DiffLineAdd: | |||||
| buf.WriteByte('+') | |||||
| case DiffLineDel: | |||||
| buf.WriteByte('-') | |||||
| } | |||||
| for i := range diffs { | for i := range diffs { | ||||
| switch { | switch { | ||||
| case diffs[i].Type == diffmatchpatch.DiffInsert && lineType == DiffLineAdd: | case diffs[i].Type == diffmatchpatch.DiffInsert && lineType == DiffLineAdd: | ||||
| @@ -186,18 +186,21 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) tem | |||||
| case DiffLineAdd: | case DiffLineAdd: | ||||
| compareDiffLine = diffSection.GetLine(DiffLineDel, diffLine.RightIdx) | compareDiffLine = diffSection.GetLine(DiffLineDel, diffLine.RightIdx) | ||||
| if compareDiffLine == nil { | if compareDiffLine == nil { | ||||
| return template.HTML(html.EscapeString(diffLine.Content)) | |||||
| return template.HTML(html.EscapeString(diffLine.Content[1:])) | |||||
| } | } | ||||
| diff1 = compareDiffLine.Content | diff1 = compareDiffLine.Content | ||||
| diff2 = diffLine.Content | diff2 = diffLine.Content | ||||
| case DiffLineDel: | case DiffLineDel: | ||||
| compareDiffLine = diffSection.GetLine(DiffLineAdd, diffLine.LeftIdx) | compareDiffLine = diffSection.GetLine(DiffLineAdd, diffLine.LeftIdx) | ||||
| if compareDiffLine == nil { | if compareDiffLine == nil { | ||||
| return template.HTML(html.EscapeString(diffLine.Content)) | |||||
| return template.HTML(html.EscapeString(diffLine.Content[1:])) | |||||
| } | } | ||||
| diff1 = diffLine.Content | diff1 = diffLine.Content | ||||
| diff2 = compareDiffLine.Content | diff2 = compareDiffLine.Content | ||||
| default: | default: | ||||
| if strings.IndexByte(" +-", diffLine.Content[0]) > -1 { | |||||
| return template.HTML(html.EscapeString(diffLine.Content[1:])) | |||||
| } | |||||
| return template.HTML(html.EscapeString(diffLine.Content)) | return template.HTML(html.EscapeString(diffLine.Content)) | ||||
| } | } | ||||
| @@ -18,14 +18,14 @@ func assertEqual(t *testing.T, s1 string, s2 template.HTML) { | |||||
| } | } | ||||
| func TestDiffToHTML(t *testing.T) { | func TestDiffToHTML(t *testing.T) { | ||||
| assertEqual(t, "+foo <span class=\"added-code\">bar</span> biz", diffToHTML([]dmp.Diff{ | |||||
| assertEqual(t, "foo <span class=\"added-code\">bar</span> biz", diffToHTML([]dmp.Diff{ | |||||
| {Type: dmp.DiffEqual, Text: "foo "}, | {Type: dmp.DiffEqual, Text: "foo "}, | ||||
| {Type: dmp.DiffInsert, Text: "bar"}, | {Type: dmp.DiffInsert, Text: "bar"}, | ||||
| {Type: dmp.DiffDelete, Text: " baz"}, | {Type: dmp.DiffDelete, Text: " baz"}, | ||||
| {Type: dmp.DiffEqual, Text: " biz"}, | {Type: dmp.DiffEqual, Text: " biz"}, | ||||
| }, DiffLineAdd)) | }, DiffLineAdd)) | ||||
| assertEqual(t, "-foo <span class=\"removed-code\">bar</span> biz", diffToHTML([]dmp.Diff{ | |||||
| assertEqual(t, "foo <span class=\"removed-code\">bar</span> biz", diffToHTML([]dmp.Diff{ | |||||
| {Type: dmp.DiffEqual, Text: "foo "}, | {Type: dmp.DiffEqual, Text: "foo "}, | ||||
| {Type: dmp.DiffDelete, Text: "bar"}, | {Type: dmp.DiffDelete, Text: "bar"}, | ||||
| {Type: dmp.DiffInsert, Text: " baz"}, | {Type: dmp.DiffInsert, Text: " baz"}, | ||||
| @@ -633,7 +633,7 @@ footer .ui.left,footer .ui.right{line-height:40px} | |||||
| .repository .diff-box .header .file{flex:1;color:#888;word-break:break-all} | .repository .diff-box .header .file{flex:1;color:#888;word-break:break-all} | ||||
| .repository .diff-box .header .button{margin:-5px 0 -5px 12px;padding:8px 10px;flex:0 0 auto} | .repository .diff-box .header .button{margin:-5px 0 -5px 12px;padding:8px 10px;flex:0 0 auto} | ||||
| .repository .diff-file-box .header{background-color:#f7f7f7} | .repository .diff-file-box .header{background-color:#f7f7f7} | ||||
| .repository .diff-file-box .file-body.file-code .lines-num{text-align:right;color:#a6a6a6;background:#fafafa;width:1%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top} | |||||
| .repository .diff-file-box .file-body.file-code .lines-num{text-align:right;color:#a6a6a6;background:#fafafa;width:1%;min-width:50px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top} | |||||
| .repository .diff-file-box .file-body.file-code .lines-num span.fold{display:block;text-align:center} | .repository .diff-file-box .file-body.file-code .lines-num span.fold{display:block;text-align:center} | ||||
| .repository .diff-file-box .file-body.file-code .lines-num-old{border-right:1px solid #ddd} | .repository .diff-file-box .file-body.file-code .lines-num-old{border-right:1px solid #ddd} | ||||
| .repository .diff-file-box .code-diff{font-size:12px} | .repository .diff-file-box .code-diff{font-size:12px} | ||||
| @@ -644,13 +644,16 @@ footer .ui.left,footer .ui.right{line-height:40px} | |||||
| .repository .diff-file-box .code-diff tbody tr td.tag-code,.repository .diff-file-box .code-diff tbody tr.tag-code td{background-color:#f0f0f0!important;border-color:#d3cfcf!important;padding-top:8px;padding-bottom:8px} | .repository .diff-file-box .code-diff tbody tr td.tag-code,.repository .diff-file-box .code-diff tbody tr.tag-code td{background-color:#f0f0f0!important;border-color:#d3cfcf!important;padding-top:8px;padding-bottom:8px} | ||||
| .repository .diff-file-box .code-diff tbody tr .removed-code{background-color:#f99} | .repository .diff-file-box .code-diff tbody tr .removed-code{background-color:#f99} | ||||
| .repository .diff-file-box .code-diff tbody tr .added-code{background-color:#9f9} | .repository .diff-file-box .code-diff tbody tr .added-code{background-color:#9f9} | ||||
| .repository .diff-file-box .code-diff tbody tr .lines-num[data-line-num]::before{content:attr(data-line-num);text-align:right} | |||||
| .repository .diff-file-box .code-diff tbody tr .lines-type-marker{width:10px;min-width:10px} | |||||
| .repository .diff-file-box .code-diff tbody tr .line-type-marker[data-type-marker]::before{content:attr(data-type-marker);text-align:right;display:inline-block} | |||||
| .repository .diff-file-box .code-diff-unified tbody tr.del-code td{background-color:#ffe0e0!important;border-color:#f1c0c0!important} | .repository .diff-file-box .code-diff-unified tbody tr.del-code td{background-color:#ffe0e0!important;border-color:#f1c0c0!important} | ||||
| .repository .diff-file-box .code-diff-unified tbody tr.add-code td{background-color:#d6fcd6!important;border-color:#c1e9c1!important} | .repository .diff-file-box .code-diff-unified tbody tr.add-code td{background-color:#d6fcd6!important;border-color:#c1e9c1!important} | ||||
| .repository .diff-file-box .code-diff-split table,.repository .diff-file-box .code-diff-split tbody{width:100%} | .repository .diff-file-box .code-diff-split table,.repository .diff-file-box .code-diff-split tbody{width:100%} | ||||
| .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){background-color:#fafafa} | |||||
| .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){background-color:#ffe0e0!important;border-color:#f1c0c0!important} | |||||
| .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(3),.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(4){background-color:#d6fcd6!important;border-color:#c1e9c1!important} | |||||
| .repository .diff-file-box .code-diff-split tbody tr td:nth-child(3){border-left-width:1px;border-left-style:solid} | |||||
| .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:#fafafa} | |||||
| .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:#ffe0e0!important;border-color:#f1c0c0!important} | |||||
| .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:#d6fcd6!important;border-color:#c1e9c1!important} | |||||
| .repository .diff-file-box .code-diff-split tbody tr td:nth-child(4){border-left-width:1px;border-left-style:solid} | |||||
| .repository .diff-file-box.file-content{clear:right} | .repository .diff-file-box.file-content{clear:right} | ||||
| .repository .diff-file-box.file-content img{max-width:100%;padding:5px 5px 0 5px} | .repository .diff-file-box.file-content img{max-width:100%;padding:5px 5px 0 5px} | ||||
| .repository .code-view{overflow:auto;overflow-x:auto;overflow-y:hidden} | .repository .code-view{overflow:auto;overflow-x:auto;overflow-y:hidden} | ||||
| @@ -1339,6 +1339,7 @@ | |||||
| color: #a6a6a6; | color: #a6a6a6; | ||||
| background: #fafafa; | background: #fafafa; | ||||
| width: 1%; | width: 1%; | ||||
| min-width: 50px; | |||||
| user-select: none; | user-select: none; | ||||
| vertical-align: top; | vertical-align: top; | ||||
| @@ -1403,6 +1404,22 @@ | |||||
| .added-code { | .added-code { | ||||
| background-color: #99ff99; | background-color: #99ff99; | ||||
| } | } | ||||
| .lines-num[data-line-num]::before { | |||||
| content: attr(data-line-num); | |||||
| text-align: right; | |||||
| } | |||||
| .lines-type-marker { | |||||
| width: 10px; | |||||
| min-width: 10px; | |||||
| } | |||||
| .line-type-marker[data-type-marker]::before { | |||||
| content: attr(data-type-marker); | |||||
| text-align: right; | |||||
| display: inline-block; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -1432,25 +1449,29 @@ | |||||
| &.add-code td:nth-child(1), | &.add-code td:nth-child(1), | ||||
| &.add-code td:nth-child(2), | &.add-code td:nth-child(2), | ||||
| &.del-code td:nth-child(3), | &.del-code td:nth-child(3), | ||||
| &.del-code td:nth-child(4) { | |||||
| &.del-code td:nth-child(4), | |||||
| &.del-code td:nth-child(5), | |||||
| &.del-code td:nth-child(6) { | |||||
| background-color: #fafafa; | background-color: #fafafa; | ||||
| } | } | ||||
| &.del-code td:nth-child(1), | &.del-code td:nth-child(1), | ||||
| &.del-code td:nth-child(2), | &.del-code td:nth-child(2), | ||||
| &.del-code td:nth-child(3), | |||||
| td.del-code { | td.del-code { | ||||
| background-color: #ffe0e0 !important; | background-color: #ffe0e0 !important; | ||||
| border-color: #f1c0c0 !important; | border-color: #f1c0c0 !important; | ||||
| } | } | ||||
| &.add-code td:nth-child(3), | |||||
| &.add-code td:nth-child(4), | &.add-code td:nth-child(4), | ||||
| &.add-code td:nth-child(5), | |||||
| &.add-code td:nth-child(6), | |||||
| td.add-code { | td.add-code { | ||||
| background-color: #d6fcd6 !important; | background-color: #d6fcd6 !important; | ||||
| border-color: #c1e9c1 !important; | border-color: #c1e9c1 !important; | ||||
| } | } | ||||
| td:nth-child(3) { | |||||
| td:nth-child(4) { | |||||
| border-left-width: 1px; | border-left-width: 1px; | ||||
| border-left-style: solid; | border-left-style: solid; | ||||
| } | } | ||||
| @@ -120,8 +120,11 @@ | |||||
| {{range $j, $section := $file.Sections}} | {{range $j, $section := $file.Sections}} | ||||
| {{range $k, $line := $section.Lines}} | {{range $k, $line := $section.Lines}} | ||||
| <tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}"> | <tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}"> | ||||
| <td class="lines-num lines-num-old"> | |||||
| <span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}">{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}</span> | |||||
| <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"> | |||||
| <pre>{{if $line.LeftIdx}}<span class="line-type-marker" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</pre> | |||||
| </td> | </td> | ||||
| <td class="lines-code lines-code-old halfwidth"> | <td class="lines-code lines-code-old halfwidth"> | ||||
| {{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}} | {{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}} | ||||
| @@ -129,10 +132,12 @@ | |||||
| {{end}} | {{end}} | ||||
| <pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.LeftIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre> | <pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.LeftIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre> | ||||
| </td> | </td> | ||||
| <td class="lines-num lines-num-new"> | |||||
| <span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span> | |||||
| <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"> | |||||
| <pre>{{if $line.RightIdx}}<span class="line-type-marker" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</pre> | |||||
| </td> | </td> | ||||
| <td class="lines-code lines-code-new halfwidth"> | <td class="lines-code lines-code-new halfwidth"> | ||||
| {{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}} | {{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> | <a class="ui green button add-code-comment add-code-comment-right" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}">+</a> | ||||
| @@ -143,6 +148,7 @@ | |||||
| {{if gt (len $line.Comments) 0}} | {{if gt (len $line.Comments) 0}} | ||||
| <tr class="add-code-comment"> | <tr class="add-code-comment"> | ||||
| <td class="lines-num"></td> | <td class="lines-num"></td> | ||||
| <td class="lines-type-marker"></td> | |||||
| <td class="add-comment-left"> | <td class="add-comment-left"> | ||||
| {{if eq $line.GetCommentSide "previous"}} | {{if eq $line.GetCommentSide "previous"}} | ||||
| <div class="field comment-code-cloud"> | <div class="field comment-code-cloud"> | ||||
| @@ -156,6 +162,7 @@ | |||||
| {{end}} | {{end}} | ||||
| </td> | </td> | ||||
| <td class="lines-num"></td> | <td class="lines-num"></td> | ||||
| <td class="lines-type-marker"></td> | |||||
| <td class="add-comment-right"> | <td class="add-comment-right"> | ||||
| {{if eq $line.GetCommentSide "proposed"}} | {{if eq $line.GetCommentSide "proposed"}} | ||||
| <div class="field comment-code-cloud"> | <div class="field comment-code-cloud"> | ||||
| @@ -8,13 +8,16 @@ | |||||
| {{/* {{if gt $j 0}}<span class="fold octicon octicon-fold"></span>{{end}} */}} | {{/* {{if gt $j 0}}<span class="fold octicon octicon-fold"></span>{{end}} */}} | ||||
| </td> | </td> | ||||
| {{else}} | {{else}} | ||||
| <td class="lines-num lines-num-old"> | |||||
| <span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}">{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}</span> | |||||
| <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> | ||||
| <td class="lines-num lines-num-new"> | |||||
| <span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span> | |||||
| <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> | ||||
| {{end}} | {{end}} | ||||
| <td class="lines-type-marker"> | |||||
| <pre><span class="line-type-marker" data-type-marker="{{$line.GetLineTypeMarker}}"></span></pre> | |||||
| </td> | |||||
| <td class="lines-code {{if (not $line.RightIdx)}}lines-code-old{{end}}"> | <td class="lines-code {{if (not $line.RightIdx)}}lines-code-old{{end}}"> | ||||
| {{if and $.root.SignedUserID $line.CanComment $.root.PageIsPullFiles}} | {{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> | <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> | ||||
| @@ -25,6 +28,7 @@ | |||||
| {{if gt (len $line.Comments) 0}} | {{if gt (len $line.Comments) 0}} | ||||
| <tr> | <tr> | ||||
| <td colspan="2" class="lines-num"></td> | <td colspan="2" class="lines-num"></td> | ||||
| <td class="lines-type-marker"></td> | |||||
| <td class="add-comment-left add-comment-right"> | <td class="add-comment-left add-comment-right"> | ||||
| <div class="field comment-code-cloud"> | <div class="field comment-code-cloud"> | ||||
| <div class="comment-list"> | <div class="comment-list"> | ||||