Browse Source

Implement Split Diff-View

- Unified/Inline Diff-View Selectable
Kim "BKC" Carlbäcker 9 năm trước cách đây
mục cha
commit
0df39b33eb

+ 33 - 0
public/css/gogs.css

@@ -735,6 +735,18 @@ pre.raw {
   line-height: 1.5;
   overflow: auto;
 }
+pre.wrap {
+  white-space: pre-wrap;
+  /* CSS 3 */
+  white-space: -moz-pre-wrap;
+  /* Mozilla, since 1999 */
+  white-space: -pre-wrap;
+  /* Opera 4-6 */
+  white-space: -o-pre-wrap;
+  /* Opera 7 */
+  word-wrap: break-word;
+  /* Internet Explorer 5.5+ */
+}
 .full.height {
   padding: 0;
   margin: 0 0 -80px 0;
@@ -2325,6 +2337,10 @@ footer .container .links > *:first-child {
   background: #fafafa;
   width: 1%;
 }
+.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;
 }
@@ -2350,16 +2366,33 @@ footer .container .links > *:first-child {
   padding-top: 4px;
   padding-bottom: 4px;
 }
+.repository .diff-file-box .code-diff tbody tr.tag-code td.halfwidth {
+  width: 50%;
+}
+.repository .diff-file-box .code-diff tbody tr.del-code td.add-code {
+  background-color: #eaffea !important;
+  border-color: #c1e9c1 !important;
+}
+.repository .diff-file-box .code-diff tbody tr.del-code td.add-code pre {
+  background-color: #eaffea !important;
+  border-color: #c1e9c1 !important;
+}
 .repository .diff-file-box .code-diff tbody tr.del-code td,
 .repository .diff-file-box .code-diff tbody tr.del-code pre {
   background-color: #ffecec !important;
   border-color: #f1c0c0 !important;
 }
+.repository .diff-file-box .code-diff tbody tr.del-code td.halfwidth {
+  width: 50%;
+}
 .repository .diff-file-box .code-diff tbody tr.add-code td,
 .repository .diff-file-box .code-diff tbody tr.add-code pre {
   background-color: #eaffea !important;
   border-color: #c1e9c1 !important;
 }
+.repository .diff-file-box .code-diff tbody tr.add-code td.halfwidth {
+  width: 50%;
+}
 .repository .diff-file-box.file-content img {
   max-width: 100%;
   padding: 5px 5px 0 5px;

+ 7 - 0
public/less/_base.less

@@ -19,6 +19,13 @@ pre {
 		line-height: 1.5;
 		overflow: auto;
 	}
+	&.wrap {
+		white-space: pre-wrap;       /* CSS 3 */
+		white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
+		white-space: -pre-wrap;      /* Opera 4-6 */
+		white-space: -o-pre-wrap;    /* Opera 7 */
+		word-wrap: break-word;       /* Internet Explorer 5.5+ */
+	}
 }
 .full.height {
 	padding: 0;

+ 24 - 0
public/less/_repository.less

@@ -668,6 +668,11 @@
 				color: #A7A7A7;
 				background: #fafafa;
 				width: 1%;
+
+				span.fold {
+					display: block;
+					text-align: center;
+				}
 			}
 			.lines-num-old {
 				border-right: 1px solid #DDD;
@@ -698,6 +703,9 @@
 							padding-top: 4px;
 							padding-bottom: 4px;
 						}
+						td.halfwidth {
+							width: 50%;
+						}
 						// td.selected-line, td.selected-line pre {
 						// 	background-color: #ffffdd !important;
 						// }
@@ -708,10 +716,23 @@
 					// 	}
 					// }
 					&.del-code {
+						td.add-code {
+							background-color: #eaffea !important;
+							border-color: #c1e9c1 !important;
+							pre {
+								background-color: #eaffea !important;
+								border-color: #c1e9c1 !important;
+
+							}
+						}
 						td, pre {
 							background-color: #ffecec !important;
 					    border-color: #f1c0c0 !important;
 						}
+
+						td.halfwidth {
+							width: 50%;
+						}
 						// td.selected-line, td.selected-line pre {
 						// 	background-color: #ffffdd !important;
 						// }
@@ -721,6 +742,9 @@
 							background-color: #eaffea !important;
 							border-color: #c1e9c1 !important;
 						}
+						td.halfwidth {
+							width: 50%;
+						}
 						// td.selected-line, td.selected-line pre {
 						// 	background-color: #ffffdd !important;
 						// }

+ 2 - 0
routers/repo/commit.go

@@ -168,6 +168,7 @@ func Diff(ctx *middleware.Context) {
 		}
 	}
 
+	ctx.Data["Style"] = ctx.Query("style") == "split"
 	ctx.Data["Username"] = userName
 	ctx.Data["Reponame"] = repoName
 	ctx.Data["IsImageFile"] = commit.IsImageFile
@@ -213,6 +214,7 @@ func CompareDiff(ctx *middleware.Context) {
 	}
 	commits = models.ValidateCommitsWithEmails(commits)
 
+	ctx.Data["Style"] = ctx.Query("style") == "split"
 	ctx.Data["CommitRepoLink"] = ctx.Repo.RepoLink
 	ctx.Data["Commits"] = commits
 	ctx.Data["CommitCount"] = commits.Len()

+ 5 - 58
templates/repo/diff_box.tmpl

@@ -6,6 +6,7 @@
 			<i class="fa fa-retweet"></i>
 			{{.i18n.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}}
 			<div class="ui right">
+				<a class="ui tiny basic toggle button" href="?style={{if .Style}}inline{{else}}split{{end}}">{{ if .Style }}Inline{{else}}Split{{end}}</a>
 				<a class="ui tiny basic toggle button" data-target="#diff-files">{{.i18n.Tr "repo.diff.show_diff_stats"}}</a>
 			</div>
 		</div>
@@ -32,63 +33,9 @@
 		</ol>
 	</div>
 
-	{{range $i, $file := .Diff.Files}}
-		<div class="diff-file-box diff-box file-content" id="diff-{{.Index}}">
-			<h4 class="ui top attached normal header">
-				<div class="diff-counter count ui left">
-					{{if $file.IsBin}}
-						{{$.i18n.Tr "repo.diff.bin"}}
-					{{else if not $file.IsRenamed}}
-						<span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span>
-						<span class="bar">
-							<span class="pull-left add"></span>
-							<span class="pull-left del"></span>
-						</span>
-						<span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span>
-					{{end}}
-				</div>
-				<span class="file">{{if $file.IsRenamed}}{{$file.OldName}} &rarr; {{end}}{{$file.Name}}</span>
-				<div class="ui right">
-					{{if $file.IsDeleted}}
-						<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
-					{{else}}
-						<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.SourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
-					{{end}}
-				</div>
-			</h4>
-			<div class="ui attached table segment">
-				{{if not $file.IsRenamed}}
-					{{$isImage := (call $.IsImageFile $file.Name)}}
-					{{if and $isImage}}
-						<div class="center">
-							<img src="{{$.RawPath}}/{{EscapePound .Name}}">
-						</div>
-					{{else}}
-						<div class="file-body file-code code-view code-diff">
-							<table>
-								<tbody>
-									{{range .Sections}}
-										{{range $k, $line := .Lines}}
-											<tr class="{{DiffLineTypeToStr .Type}}-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>
-												<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>
-												<td class="lines-code">
-													<pre>{{$line.Content}}</pre>
-												</td>
-											</tr>
-										{{end}}
-									{{end}}
-								</tbody>
-							</table>
-						</div>
-					{{end}}
-				{{end}}
-			</div>
-		</div>
-		<br>
+	{{if .Style}}
+		{{ template "repo/diff_box_split" . }}
+	{{else}}
+		{{ template "repo/diff_box_inline" . }}
 	{{end}}
 {{end}}

+ 74 - 0
templates/repo/diff_box_inline.tmpl

@@ -0,0 +1,74 @@
+{{range $i, $file := .Diff.Files}}
+	<div class="diff-file-box diff-box file-content" id="diff-{{.Index}}">
+		<h4 class="ui top attached normal header">
+			<div class="diff-counter count ui left">
+				{{if $file.IsBin}}
+					{{$.i18n.Tr "repo.diff.bin"}}
+				{{else if not $file.IsRenamed}}
+					<span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span>
+					<span class="bar">
+						<span class="pull-left add"></span>
+						<span class="pull-left del"></span>
+					</span>
+					<span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span>
+				{{end}}
+			</div>
+			<span class="file">{{if $file.IsRenamed}}{{$file.OldName}} &rarr; {{end}}{{$file.Name}}</span>
+			<div class="ui right">
+				{{if $file.IsDeleted}}
+					<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
+				{{else}}
+					<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.SourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
+				{{end}}
+			</div>
+		</h4>
+		<div class="ui attached table segment">
+			{{if not $file.IsRenamed}}
+				{{$isImage := (call $.IsImageFile $file.Name)}}
+				{{if and $isImage}}
+					<div class="center">
+						<img src="{{$.RawPath}}/{{EscapePound .Name}}">
+					</div>
+				{{else}}
+					<div class="file-body file-code code-view code-diff">
+						<table>
+							<tbody>
+								{{range $j, $section := .Sections}}
+									{{range $k, $line := .Lines}}
+										<tr class="{{DiffLineTypeToStr .Type}}-code nl-{{$k}} ol-{{$k}}">
+											{{if eq .Type 4}}
+											<td colspan="2" class="lines-num">
+												{{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>
+											<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>
+											{{end}}
+											<td class="lines-code">
+												<pre>{{$line.Content}}</pre>
+											</td>
+										</tr>
+									{{end}}
+								{{end}}
+							</tbody>
+						</table>
+					</div>
+					<script>
+					(function() {
+						$('tr.del-code').each(function() {
+							if($(this).next().hasClass('add-code')) {
+							//	$($(this).children()[3]).replaceWith($(this).next().children()[3]);
+							}
+						});
+					}());
+					</script>
+				{{end}}
+			{{end}}
+		</div>
+	</div>
+	<br>
+{{end}}

+ 98 - 0
templates/repo/diff_box_split.tmpl

@@ -0,0 +1,98 @@
+{{range $i, $file := .Diff.Files}}
+	<div class="diff-file-box diff-box file-content" id="diff-{{.Index}}">
+		<h4 class="ui top attached normal header">
+			<div class="diff-counter count ui left">
+				{{if $file.IsBin}}
+					{{$.i18n.Tr "repo.diff.bin"}}
+				{{else if not $file.IsRenamed}}
+					<span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span>
+					<span class="bar">
+						<span class="pull-left add"></span>
+						<span class="pull-left del"></span>
+					</span>
+					<span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span>
+				{{end}}
+			</div>
+			<span class="file">{{if $file.IsRenamed}}{{$file.OldName}} &rarr; {{end}}{{$file.Name}}</span>
+			<div class="ui right">
+				{{if $file.IsDeleted}}
+					<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
+				{{else}}
+					<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.SourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
+				{{end}}
+			</div>
+		</h4>
+		<div class="ui attached table segment">
+			{{if not $file.IsRenamed}}
+				{{$isImage := (call $.IsImageFile $file.Name)}}
+				{{if and $isImage}}
+					<div class="center">
+						<img src="{{$.RawPath}}/{{EscapePound .Name}}">
+					</div>
+				{{else}}
+					<div class="file-body file-code code-view code-diff">
+						<table>
+							<tbody>
+								{{range $j, $section := .Sections}}
+									{{range $k, $line := .Lines}}
+										<tr class="{{DiffLineTypeToStr .Type}}-code nl-{{$k}} ol-{{$k}}">
+										{{if eq .Type 4}}
+											<td class="lines-num lines-num-old">
+												<span class="{{if gt $j 0}}fold octicon octicon-fold{{end}}"></span>
+											</td>
+											<td class="lines-code halfwidth">
+												<pre class="wrap">{{$line.Content}}</pre>
+											</td>
+											<td class="lines-num lines-num-old">
+												<span class="{{if gt $j 0}}fold octicon octicon-fold{{end}}"></span>
+											</td>
+											<td class="lines-code halfwidth">
+												<pre class="wrap">{{$line.Content}}</pre>
+											</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>
+											<td class="lines-code halfwidth">
+												<pre class="wrap">{{if $line.LeftIdx}}{{$line.Content}}{{end}}</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>
+											<td class="lines-code halfwidth">
+												<pre class="wrap">{{if $line.RightIdx}}{{$line.Content}}{{end}}</pre>
+											</td>
+										{{end}}
+										</tr>
+									{{end}}
+								{{end}}
+							</tbody>
+						</table>
+					</div>
+					<script>
+					(function() {
+						$('.add-code').each(function() {
+							var prev = $(this).prev();
+							if(prev.is('.del-code') && prev.children().eq(3).text().trim() === '') {
+								while(prev.prev().is('.del-code') && prev.prev().children().eq(3).text().trim() === '') {
+									prev = prev.prev();
+								}
+								prev.children().eq(3).html($(this).children().eq(3).html());
+								prev.children().eq(2).html($(this).children().eq(2).html());
+								prev.children().eq(3).addClass('add-code');
+								prev.children().eq(2).addClass('add-code');
+//								prev.children().eq(2).attr('style', 'background-color: #eaffea !important');
+//								prev.children().eq(2).children().eq(0).attr('style', 'background-color: #eaffea !important');
+//								prev.children().eq(3).attr('style', 'background-color: #eaffea !important');
+//								prev.children().eq(3).children().eq(0).attr('style', 'background-color: #eaffea !important');
+								$(this).remove();
+							}
+						});
+					}());
+					</script>
+				{{end}}
+			{{end}}
+		</div>
+	</div>
+<br>
+{{end}}