From c28a976112a74ed83896561eecfb9504ea9901f1 Mon Sep 17 00:00:00 2001
From: Andrew Thornton <art27@cantab.net>
Date: Sat, 22 Jun 2019 21:00:23 +0100
Subject: [PATCH 1/7] Make diff line-marker non-selectable

---
 models/git_diff.go                       | 20 ++++++--------------
 public/css/index.css                     |  1 +
 public/less/_repository.less             |  4 ++++
 templates/repo/diff/box.tmpl             |  4 ++--
 templates/repo/diff/section_unified.tmpl |  2 +-
 5 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/models/git_diff.go b/models/git_diff.go
index a6ea7306d491f..734f9f06886f7 100644
--- a/models/git_diff.go
+++ b/models/git_diff.go
@@ -87,22 +87,14 @@ type DiffSection struct {
 }
 
 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 {
 	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 {
 		switch {
 		case diffs[i].Type == diffmatchpatch.DiffInsert && lineType == DiffLineAdd:
@@ -186,19 +178,19 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) tem
 	case DiffLineAdd:
 		compareDiffLine = diffSection.GetLine(DiffLineDel, diffLine.RightIdx)
 		if compareDiffLine == nil {
-			return template.HTML(html.EscapeString(diffLine.Content))
+			return template.HTML(html.EscapeString(diffLine.Content[1:]))
 		}
 		diff1 = compareDiffLine.Content
 		diff2 = diffLine.Content
 	case DiffLineDel:
 		compareDiffLine = diffSection.GetLine(DiffLineAdd, diffLine.LeftIdx)
 		if compareDiffLine == nil {
-			return template.HTML(html.EscapeString(diffLine.Content))
+			return template.HTML(html.EscapeString(diffLine.Content[1:]))
 		}
 		diff1 = diffLine.Content
 		diff2 = compareDiffLine.Content
 	default:
-		return template.HTML(html.EscapeString(diffLine.Content))
+		return template.HTML(html.EscapeString(diffLine.Content[1:]))
 	}
 
 	diffRecord := diffMatchPatch.DiffMain(diff1[1:], diff2[1:], true)
diff --git a/public/css/index.css b/public/css/index.css
index 24a5d7865cff4..b695bd12c2aff 100644
--- a/public/css/index.css
+++ b/public/css/index.css
@@ -644,6 +644,7 @@ 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 .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 .line-type-marker{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
 .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-split table,.repository .diff-file-box .code-diff-split tbody{width:100%}
diff --git a/public/less/_repository.less b/public/less/_repository.less
index acf8d7b870b74..8579bfbc1ee51 100644
--- a/public/less/_repository.less
+++ b/public/less/_repository.less
@@ -1403,6 +1403,10 @@
                     .added-code {
                         background-color: #99ff99;
                     }
+
+                    .line-type-marker {
+                        user-select: none;
+                    }
                 }
             }
         }
diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl
index 2bdf9e58810d7..21335ce991d48 100644
--- a/templates/repo/diff/box.tmpl
+++ b/templates/repo/diff/box.tmpl
@@ -127,7 +127,7 @@
 															{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}}
 																<a class="ui green button add-code-comment add-code-comment-left" data-path="{{$file.Name}}" data-side="left" data-idx="{{$line.LeftIdx}}">+</a>
 															{{end}}
-															<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}}<span class="line-type-marker">{{index $line.Content 0 | printf "%c"}}</span>{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
 														</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>
@@ -137,7 +137,7 @@
 															{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}}
 																<a class="ui green button add-code-comment add-code-comment-right" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}">+</a>
 															{{end}}
-															<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
+															<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.RightIdx}}<span class="line-type-marker">{{index $line.Content 0 | printf "%c"}}</span>{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
 														</td>
 													</tr>
 													{{if gt (len $line.Comments) 0}}
diff --git a/templates/repo/diff/section_unified.tmpl b/templates/repo/diff/section_unified.tmpl
index 53ccaedbc242a..1b6e8324b8bac 100644
--- a/templates/repo/diff/section_unified.tmpl
+++ b/templates/repo/diff/section_unified.tmpl
@@ -19,7 +19,7 @@
 				{{if and $.root.SignedUserID $line.CanComment $.root.PageIsPullFiles}}
 					<a class="ui green button add-code-comment add-code-comment-{{if $line.RightIdx}}right{{else}}left{{end}}" data-path="{{$file.Name}}" data-side="{{if $line.RightIdx}}right{{else}}left{{end}}" data-idx="{{if $line.RightIdx}}{{$line.RightIdx}}{{else}}{{$line.LeftIdx}}{{end}}">+</a>
 				{{end}}
-				<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{$section.GetComputedInlineDiffFor $line}}</code></pre>
+				<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}"><span class="line-type-marker">{{index $line.Content 0 | printf "%c"}}</span>{{$section.GetComputedInlineDiffFor $line}}</code></pre>
 			</td>
 		</tr>
 		{{if gt (len $line.Comments) 0}}

From c80b316964bfe1fe24375cbc31e1236e97088b05 Mon Sep 17 00:00:00 2001
From: Andrew Thornton <art27@cantab.net>
Date: Sat, 22 Jun 2019 21:13:24 +0100
Subject: [PATCH 2/7] Fix tests

---
 models/git_diff_test.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/models/git_diff_test.go b/models/git_diff_test.go
index deca7c8d4affa..bf52095acf184 100644
--- a/models/git_diff_test.go
+++ b/models/git_diff_test.go
@@ -18,14 +18,14 @@ func assertEqual(t *testing.T, s1 string, s2 template.HTML) {
 }
 
 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.DiffInsert, Text: "bar"},
 		{Type: dmp.DiffDelete, Text: " baz"},
 		{Type: dmp.DiffEqual, Text: " biz"},
 	}, 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.DiffDelete, Text: "bar"},
 		{Type: dmp.DiffInsert, Text: " baz"},

From 207b8ee954695458f758a493d6274582bd505403 Mon Sep 17 00:00:00 2001
From: Andrew Thornton <art27@cantab.net>
Date: Sun, 23 Jun 2019 08:02:37 +0100
Subject: [PATCH 3/7] Move to use data-* as per @mrsdizzie

---
 public/css/index.css                     |  3 ++-
 public/less/_repository.less             | 13 +++++++++----
 templates/repo/diff/box.tmpl             | 12 ++++++------
 templates/repo/diff/section_unified.tmpl | 10 +++++-----
 4 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/public/css/index.css b/public/css/index.css
index b695bd12c2aff..842b285775e95 100644
--- a/public/css/index.css
+++ b/public/css/index.css
@@ -465,6 +465,7 @@ footer .ui.left,footer .ui.right{line-height:40px}
 .repository.file.list .non-diff-file-content .code-view table{width:100%}
 .repository.file.list .non-diff-file-content .code-view .lines-num{vertical-align:top;text-align:right;color:#999;background:#f5f5f5;width:1%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
 .repository.file.list .non-diff-file-content .code-view .lines-num span{line-height:20px;padding:0 10px;cursor:pointer;display:block}
+.repository.file.list .non-diff-file-content .code-view .lines-num[data-line-num]::before{content:attr(data-line-num);display:inline-block}
 .repository.file.list .non-diff-file-content .code-view .lines-code,.repository.file.list .non-diff-file-content .code-view .lines-num{padding:0}
 .repository.file.list .non-diff-file-content .code-view .lines-code .hljs,.repository.file.list .non-diff-file-content .code-view .lines-code ol,.repository.file.list .non-diff-file-content .code-view .lines-code pre,.repository.file.list .non-diff-file-content .code-view .lines-num .hljs,.repository.file.list .non-diff-file-content .code-view .lines-num ol,.repository.file.list .non-diff-file-content .code-view .lines-num pre{background-color:#fff;margin:0;padding:0!important}
 .repository.file.list .non-diff-file-content .code-view .lines-code .hljs li,.repository.file.list .non-diff-file-content .code-view .lines-code ol li,.repository.file.list .non-diff-file-content .code-view .lines-code pre li,.repository.file.list .non-diff-file-content .code-view .lines-num .hljs li,.repository.file.list .non-diff-file-content .code-view .lines-num ol li,.repository.file.list .non-diff-file-content .code-view .lines-num pre li{display:block;width:100%}
@@ -644,7 +645,7 @@ 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 .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 .line-type-marker{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
+.repository .diff-file-box .code-diff tbody tr .line-type-marker[data-type-marker]::before{content:attr(data-type-marker);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.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%}
diff --git a/public/less/_repository.less b/public/less/_repository.less
index 8579bfbc1ee51..ea79184593f17 100644
--- a/public/less/_repository.less
+++ b/public/less/_repository.less
@@ -431,6 +431,11 @@
                     }
                 }
 
+                .lines-num[data-line-num]::before {
+                    content: attr(data-line-num);
+                    display: inline-block;
+                  }
+
                 .lines-num,
                 .lines-code {
                     padding: 0;
@@ -1404,10 +1409,10 @@
                         background-color: #99ff99;
                     }
 
-                    .line-type-marker {
-                        user-select: none;
-                    }
-                }
+                    .line-type-marker[data-type-marker]::before {
+                        content: attr(data-type-marker);
+                        display: inline-block;
+                      }                }
             }
         }
 
diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl
index 21335ce991d48..6e372bf43cd9e 100644
--- a/templates/repo/diff/box.tmpl
+++ b/templates/repo/diff/box.tmpl
@@ -120,24 +120,24 @@
 											{{range $j, $section := $file.Sections}}
 												{{range $k, $line := $section.Lines}}
 													<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-code lines-code-old halfwidth">
 															{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}}
 																<a class="ui green button add-code-comment add-code-comment-left" data-path="{{$file.Name}}" data-side="left" data-idx="{{$line.LeftIdx}}">+</a>
 															{{end}}
-															<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.LeftIdx}}<span class="line-type-marker">{{index $line.Content 0 | printf "%c"}}</span>{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
+															<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.LeftIdx}}<span class="line-type-marker" data-type-marker="{{index $line.Content 0 | printf "%c"}}"></span>{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
 														</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-code lines-code-new halfwidth">
 															{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}}
 																<a class="ui green button add-code-comment add-code-comment-right" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}">+</a>
 															{{end}}
-															<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.RightIdx}}<span class="line-type-marker">{{index $line.Content 0 | printf "%c"}}</span>{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
+															<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.RightIdx}}<span class="line-type-marker" data-type-marker="{{index $line.Content 0 | printf "%c"}}"></span>{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
 														</td>
 													</tr>
 													{{if gt (len $line.Comments) 0}}
diff --git a/templates/repo/diff/section_unified.tmpl b/templates/repo/diff/section_unified.tmpl
index 1b6e8324b8bac..64b87c8f9a428 100644
--- a/templates/repo/diff/section_unified.tmpl
+++ b/templates/repo/diff/section_unified.tmpl
@@ -8,18 +8,18 @@
 				{{/* {{if gt $j 0}}<span class="fold octicon octicon-fold"></span>{{end}} */}}
 			</td>
 			{{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 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>
 			{{end}}
 			<td class="lines-code {{if (not $line.RightIdx)}}lines-code-old{{end}}">
 				{{if and $.root.SignedUserID $line.CanComment $.root.PageIsPullFiles}}
 					<a class="ui green button add-code-comment add-code-comment-{{if $line.RightIdx}}right{{else}}left{{end}}" data-path="{{$file.Name}}" data-side="{{if $line.RightIdx}}right{{else}}left{{end}}" data-idx="{{if $line.RightIdx}}{{$line.RightIdx}}{{else}}{{$line.LeftIdx}}{{end}}">+</a>
 				{{end}}
-				<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}"><span class="line-type-marker">{{index $line.Content 0 | printf "%c"}}</span>{{$section.GetComputedInlineDiffFor $line}}</code></pre>
+				<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}"><span class="line-type-marker" data-type-marker="{{index $line.Content 0 | printf "%c"}}"></span>{{$section.GetComputedInlineDiffFor $line}}</code></pre>
 			</td>
 		</tr>
 		{{if gt (len $line.Comments) 0}}

From b898f4391fcf29011aa2159d10182ff6a2d4fea0 Mon Sep 17 00:00:00 2001
From: Andrew Thornton <art27@cantab.net>
Date: Sun, 23 Jun 2019 08:06:17 +0100
Subject: [PATCH 4/7] fix formatting in _repository.less

---
 public/less/_repository.less | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/public/less/_repository.less b/public/less/_repository.less
index ea79184593f17..856e2b34d2ad7 100644
--- a/public/less/_repository.less
+++ b/public/less/_repository.less
@@ -1412,7 +1412,8 @@
                     .line-type-marker[data-type-marker]::before {
                         content: attr(data-type-marker);
                         display: inline-block;
-                      }                }
+                    }
+                }
             }
         }
 

From 7933f76c6342e3b79519433c79ac31fff7f8d602 Mon Sep 17 00:00:00 2001
From: Andrew Thornton <art27@cantab.net>
Date: Mon, 24 Jun 2019 17:09:14 +0100
Subject: [PATCH 5/7] fix missing line nums

---
 public/css/index.css         |  2 +-
 public/less/_repository.less | 10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/public/css/index.css b/public/css/index.css
index 842b285775e95..6faca6a71105a 100644
--- a/public/css/index.css
+++ b/public/css/index.css
@@ -465,7 +465,6 @@ footer .ui.left,footer .ui.right{line-height:40px}
 .repository.file.list .non-diff-file-content .code-view table{width:100%}
 .repository.file.list .non-diff-file-content .code-view .lines-num{vertical-align:top;text-align:right;color:#999;background:#f5f5f5;width:1%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
 .repository.file.list .non-diff-file-content .code-view .lines-num span{line-height:20px;padding:0 10px;cursor:pointer;display:block}
-.repository.file.list .non-diff-file-content .code-view .lines-num[data-line-num]::before{content:attr(data-line-num);display:inline-block}
 .repository.file.list .non-diff-file-content .code-view .lines-code,.repository.file.list .non-diff-file-content .code-view .lines-num{padding:0}
 .repository.file.list .non-diff-file-content .code-view .lines-code .hljs,.repository.file.list .non-diff-file-content .code-view .lines-code ol,.repository.file.list .non-diff-file-content .code-view .lines-code pre,.repository.file.list .non-diff-file-content .code-view .lines-num .hljs,.repository.file.list .non-diff-file-content .code-view .lines-num ol,.repository.file.list .non-diff-file-content .code-view .lines-num pre{background-color:#fff;margin:0;padding:0!important}
 .repository.file.list .non-diff-file-content .code-view .lines-code .hljs li,.repository.file.list .non-diff-file-content .code-view .lines-code ol li,.repository.file.list .non-diff-file-content .code-view .lines-code pre li,.repository.file.list .non-diff-file-content .code-view .lines-num .hljs li,.repository.file.list .non-diff-file-content .code-view .lines-num ol li,.repository.file.list .non-diff-file-content .code-view .lines-num pre li{display:block;width:100%}
@@ -645,6 +644,7 @@ 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 .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 .lines-num[data-line-num]::before{content:attr(data-line-num);display:inline-block}
 .repository .diff-file-box .code-diff tbody tr .line-type-marker[data-type-marker]::before{content:attr(data-type-marker);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.add-code td{background-color:#d6fcd6!important;border-color:#c1e9c1!important}
diff --git a/public/less/_repository.less b/public/less/_repository.less
index 856e2b34d2ad7..4097c1d9238d3 100644
--- a/public/less/_repository.less
+++ b/public/less/_repository.less
@@ -431,11 +431,6 @@
                     }
                 }
 
-                .lines-num[data-line-num]::before {
-                    content: attr(data-line-num);
-                    display: inline-block;
-                  }
-
                 .lines-num,
                 .lines-code {
                     padding: 0;
@@ -1409,6 +1404,11 @@
                         background-color: #99ff99;
                     }
 
+                    .lines-num[data-line-num]::before {
+                        content: attr(data-line-num);
+                        display: inline-block;
+                    }
+
                     .line-type-marker[data-type-marker]::before {
                         content: attr(data-type-marker);
                         display: inline-block;

From c0188b58fe40e70ded2740edf5d3e7ef6d7f5687 Mon Sep 17 00:00:00 2001
From: Andrew Thornton <art27@cantab.net>
Date: Mon, 24 Jun 2019 17:24:11 +0100
Subject: [PATCH 6/7] Add a minimum-width to force right-align of the line num

---
 public/css/index.css         | 6 +++---
 public/less/_repository.less | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/public/css/index.css b/public/css/index.css
index 6faca6a71105a..0e71bb5629b30 100644
--- a/public/css/index.css
+++ b/public/css/index.css
@@ -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 .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 .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-old{border-right:1px solid #ddd}
 .repository .diff-file-box .code-diff{font-size:12px}
@@ -644,8 +644,8 @@ 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 .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 .lines-num[data-line-num]::before{content:attr(data-line-num);display:inline-block}
-.repository .diff-file-box .code-diff tbody tr .line-type-marker[data-type-marker]::before{content:attr(data-type-marker);display:inline-block}
+.repository .diff-file-box .code-diff tbody tr .lines-num[data-line-num]::before{content:attr(data-line-num)}
+.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.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%}
diff --git a/public/less/_repository.less b/public/less/_repository.less
index 4097c1d9238d3..8953d12c29f4d 100644
--- a/public/less/_repository.less
+++ b/public/less/_repository.less
@@ -1339,6 +1339,7 @@
                 color: #a6a6a6;
                 background: #fafafa;
                 width: 1%;
+                min-width: 50px;
                 user-select: none;
                 vertical-align: top;
 
@@ -1406,11 +1407,11 @@
 
                     .lines-num[data-line-num]::before {
                         content: attr(data-line-num);
-                        display: inline-block;
                     }
 
                     .line-type-marker[data-type-marker]::before {
                         content: attr(data-type-marker);
+                        text-align: right;
                         display: inline-block;
                     }
                 }

From c8d85390812fd2ff9ce593bc82cf7b0fb34c5b0f Mon Sep 17 00:00:00 2001
From: Andrew Thornton <art27@cantab.net>
Date: Mon, 24 Jun 2019 18:14:08 +0100
Subject: [PATCH 7/7] Move line-type-marker into separate column

---
 models/git_diff.go                       | 13 ++++++++++++-
 public/css/index.css                     | 11 ++++++-----
 public/less/_repository.less             | 16 +++++++++++++---
 templates/repo/diff/box.tmpl             | 13 ++++++++++---
 templates/repo/diff/section_unified.tmpl |  6 +++++-
 5 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/models/git_diff.go b/models/git_diff.go
index 734f9f06886f7..29c424c11c83a 100644
--- a/models/git_diff.go
+++ b/models/git_diff.go
@@ -80,6 +80,14 @@ func (d *DiffLine) GetCommentSide() string {
 	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.
 type DiffSection struct {
 	Name  string
@@ -190,7 +198,10 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) tem
 		diff1 = diffLine.Content
 		diff2 = compareDiffLine.Content
 	default:
-		return template.HTML(html.EscapeString(diffLine.Content[1:]))
+		if strings.IndexByte(" +-", diffLine.Content[0]) > -1 {
+			return template.HTML(html.EscapeString(diffLine.Content[1:]))
+		}
+		return template.HTML(html.EscapeString(diffLine.Content))
 	}
 
 	diffRecord := diffMatchPatch.DiffMain(diff1[1:], diff2[1:], true)
diff --git a/public/css/index.css b/public/css/index.css
index 0e71bb5629b30..475a54f75fe4c 100644
--- a/public/css/index.css
+++ b/public/css/index.css
@@ -644,15 +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 .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 .lines-num[data-line-num]::before{content:attr(data-line-num)}
+.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.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 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 img{max-width:100%;padding:5px 5px 0 5px}
 .repository .code-view{overflow:auto;overflow-x:auto;overflow-y:hidden}
diff --git a/public/less/_repository.less b/public/less/_repository.less
index 8953d12c29f4d..8d38faf50c383 100644
--- a/public/less/_repository.less
+++ b/public/less/_repository.less
@@ -1407,6 +1407,12 @@
 
                     .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 {
@@ -1443,25 +1449,29 @@
                 &.add-code td:nth-child(1),
                 &.add-code td:nth-child(2),
                 &.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;
                 }
 
                 &.del-code td:nth-child(1),
                 &.del-code td:nth-child(2),
+                &.del-code td:nth-child(3),
                 td.del-code {
                     background-color: #ffe0e0 !important;
                     border-color: #f1c0c0 !important;
                 }
 
-                &.add-code td:nth-child(3),
                 &.add-code td:nth-child(4),
+                &.add-code td:nth-child(5),
+                &.add-code td:nth-child(6),
                 td.add-code {
                     background-color: #d6fcd6 !important;
                     border-color: #c1e9c1 !important;
                 }
 
-                td:nth-child(3) {
+                td:nth-child(4) {
                     border-left-width: 1px;
                     border-left-style: solid;
                 }
diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl
index 6e372bf43cd9e..94ac094fa4e77 100644
--- a/templates/repo/diff/box.tmpl
+++ b/templates/repo/diff/box.tmpl
@@ -123,26 +123,32 @@
 														<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 class="lines-code lines-code-old halfwidth">
 															{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}}
 																<a class="ui green button add-code-comment add-code-comment-left" data-path="{{$file.Name}}" data-side="left" data-idx="{{$line.LeftIdx}}">+</a>
 															{{end}}
-															<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.LeftIdx}}<span class="line-type-marker" data-type-marker="{{index $line.Content 0 | printf "%c"}}"></span>{{$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 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 class="lines-code lines-code-new halfwidth">
 															{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}}
 																<a class="ui green button add-code-comment add-code-comment-right" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}">+</a>
 															{{end}}
-															<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.RightIdx}}<span class="line-type-marker" data-type-marker="{{index $line.Content 0 | printf "%c"}}"></span>{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
+															<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</code></pre>
 														</td>
 													</tr>
 													{{if gt (len $line.Comments) 0}}
 														<tr class="add-code-comment">
 															<td class="lines-num"></td>
+															<td class="lines-type-marker"></td>
 															<td class="add-comment-left">
 																{{if eq $line.GetCommentSide "previous"}}
 																	<div class="field comment-code-cloud">
@@ -156,6 +162,7 @@
 																{{end}}
 															</td>
 															<td class="lines-num"></td>
+															<td class="lines-type-marker"></td>
 															<td class="add-comment-right">
 																{{if eq $line.GetCommentSide "proposed"}}
 																	<div class="field comment-code-cloud">
diff --git a/templates/repo/diff/section_unified.tmpl b/templates/repo/diff/section_unified.tmpl
index 64b87c8f9a428..5706e4cdeecf2 100644
--- a/templates/repo/diff/section_unified.tmpl
+++ b/templates/repo/diff/section_unified.tmpl
@@ -15,16 +15,20 @@
 				<span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}"></span>
 			</td>
 			{{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}}">
 				{{if and $.root.SignedUserID $line.CanComment $.root.PageIsPullFiles}}
 					<a class="ui green button add-code-comment add-code-comment-{{if $line.RightIdx}}right{{else}}left{{end}}" data-path="{{$file.Name}}" data-side="{{if $line.RightIdx}}right{{else}}left{{end}}" data-idx="{{if $line.RightIdx}}{{$line.RightIdx}}{{else}}{{$line.LeftIdx}}{{end}}">+</a>
 				{{end}}
-				<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}"><span class="line-type-marker" data-type-marker="{{index $line.Content 0 | printf "%c"}}"></span>{{$section.GetComputedInlineDiffFor $line}}</code></pre>
+				<pre><code class="wrap {{if $highlightClass}}language-{{$highlightClass}}{{else}}nohighlight{{end}}">{{$section.GetComputedInlineDiffFor $line}}</code></pre>
 			</td>
 		</tr>
 		{{if gt (len $line.Comments) 0}}
 		<tr>
 			<td colspan="2" class="lines-num"></td>
+			<td class="lines-type-marker"></td>
 			<td class="add-comment-left add-comment-right">
 				<div class="field comment-code-cloud">
 					<div class="comment-list">