Browse Source

Make diff line-marker non-selectable (#7279)

* 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 column
tags/v1.9.0-rc1
zeripath 4 years ago
parent
commit
5908bb1030
No account linked to committer's email address

+ 16
- 13
models/git_diff.go View File

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
} }


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:
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))
} }



+ 2
- 2
models/git_diff_test.go View File

} }


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"},

+ 8
- 5
public/css/index.css View File

.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}
.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}

+ 24
- 3
public/less/_repository.less View File

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;


.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;
}
} }
} }
} }
&.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;
} }

+ 12
- 5
templates/repo/diff/box.tmpl View File

{{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))}}
{{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>
{{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">
{{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
- 4
templates/repo/diff/section_unified.tmpl View File

{{/* {{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>
{{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">

Loading…
Cancel
Save