Merge pull request #2296 from bkcsoft/feature/split-diff

Implement Split Diff-View
This commit is contained in:
Unknwon 2016-01-06 13:31:36 +08:00
commit 2481fe2f56
7 changed files with 820 additions and 928 deletions

View file

@ -296,8 +296,8 @@ add_key = Add Key
ssh_desc = This is a list of SSH keys associated with your account. As these keys allow anyone using them to gain access to your repositories, it is highly important that you make sure you recognize them. ssh_desc = This is a list of SSH keys associated with your account. As these keys allow anyone using them to gain access to your repositories, it is highly important that you make sure you recognize them.
ssh_helper = <strong>Don't know how?</strong> Check out GitHub's guide to <a href="%s">create your own SSH keys</a> or solve <a href="%s">common problems</a> you might encounter using SSH. ssh_helper = <strong>Don't know how?</strong> Check out GitHub's guide to <a href="%s">create your own SSH keys</a> or solve <a href="%s">common problems</a> you might encounter using SSH.
add_new_key = Add SSH Key add_new_key = Add SSH Key
ssh_key_been_used = Public key content has been used. ssh_key_been_used = Public key content has been used.
ssh_key_name_used = Public key with same name has already existed. ssh_key_name_used = Public key with same name has already existed.
key_name = Key Name key_name = Key Name
key_content = Content key_content = Content
add_key_success = New SSH key '%s' has been added successfully! add_key_success = New SSH key '%s' has been added successfully!
@ -525,7 +525,7 @@ milestones.new = New Milestone
milestones.open_tab = %d Open milestones.open_tab = %d Open
milestones.close_tab = %d Closed milestones.close_tab = %d Closed
milestones.closed = Closed %s milestones.closed = Closed %s
milestones.no_due_date = No due date milestones.no_due_date = No due date
milestones.open = Open milestones.open = Open
milestones.close = Close milestones.close = Close
milestones.new_subheader = Create milestones to organize your issues. milestones.new_subheader = Create milestones to organize your issues.
@ -575,7 +575,7 @@ settings.wiki_desc = Enable wiki to allow people write documents
settings.use_external_wiki = Use external wiki settings.use_external_wiki = Use external wiki
settings.external_wiki_url = External Wiki URL settings.external_wiki_url = External Wiki URL
settings.external_wiki_url_desc = Visitors will be redirected to URL when they click on the tab. settings.external_wiki_url_desc = Visitors will be redirected to URL when they click on the tab.
settings.issues_desc = Enable builtin lightweight issue tracker settings.issues_desc = Enable builtin lightweight issue tracker
settings.use_external_issue_tracker = Use external issue tracker settings.use_external_issue_tracker = Use external issue tracker
settings.tracker_url_format = External Issue Tracker URL Format settings.tracker_url_format = External Issue Tracker URL Format
settings.tracker_url_format_desc = You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index. settings.tracker_url_format_desc = You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
@ -588,7 +588,7 @@ settings.delete = Delete This Repository
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain. settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
settings.transfer_notices_1 = - You will lose access if new owner is a individual user. settings.transfer_notices_1 = - You will lose access if new owner is a individual user.
settings.transfer_notices_2 = - You will conserve access if new owner is an organization and if you're one of the owners. settings.transfer_notices_2 = - You will conserve access if new owner is an organization and if you're one of the owners.
settings.transfer_form_title = Please enter following information to confirm your operation: settings.transfer_form_title = Please enter following information to confirm your operation:
settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone. settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone.
settings.delete_notices_2 = - This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators. settings.delete_notices_2 = - This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
settings.delete_notices_fork_1 = - If this repository is public, all forks will be became independent after deletion. settings.delete_notices_fork_1 = - If this repository is public, all forks will be became independent after deletion.
@ -668,6 +668,8 @@ diff.parent = parent
diff.commit = commit diff.commit = commit
diff.data_not_available = Diff Data Not Available. diff.data_not_available = Diff Data Not Available.
diff.show_diff_stats = Show Diff Stats diff.show_diff_stats = Show Diff Stats
diff.show_split_view = Split View
diff.show_unified_view = Unified View
diff.stats_desc = <strong> %d changed files</strong> with <strong>%d additions</strong> and <strong>%d deletions</strong> diff.stats_desc = <strong> %d changed files</strong> with <strong>%d additions</strong> and <strong>%d deletions</strong>
diff.bin = BIN diff.bin = BIN
diff.view_file = View File diff.view_file = View File

File diff suppressed because one or more lines are too long

View file

@ -736,6 +736,11 @@ pre.raw {
line-height: 1.5; line-height: 1.5;
overflow: auto; overflow: auto;
} }
pre.wrap {
white-space: pre-wrap;
/* CSS 3 */
word-break: break-word;
}
.full.height { .full.height {
padding: 0; padding: 0;
margin: 0 0 -80px 0; margin: 0 0 -80px 0;
@ -2326,6 +2331,10 @@ footer .container .links > *:first-child {
background: #fafafa; background: #fafafa;
width: 1%; 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 { .repository .diff-file-box .file-body.file-code .lines-num-old {
border-right: 1px solid #DDD; border-right: 1px solid #DDD;
} }
@ -2351,16 +2360,33 @@ footer .container .links > *:first-child {
padding-top: 4px; padding-top: 4px;
padding-bottom: 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 td,
.repository .diff-file-box .code-diff tbody tr.del-code pre { .repository .diff-file-box .code-diff tbody tr.del-code pre {
background-color: #ffecec !important; background-color: #ffecec !important;
border-color: #f1c0c0 !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 td,
.repository .diff-file-box .code-diff tbody tr.add-code pre { .repository .diff-file-box .code-diff tbody tr.add-code pre {
background-color: #eaffea !important; background-color: #eaffea !important;
border-color: #c1e9c1 !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 { .repository .diff-file-box.file-content img {
max-width: 100%; max-width: 100%;
padding: 5px 5px 0 5px; padding: 5px 5px 0 5px;

View file

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

View file

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

View file

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

View file

@ -6,6 +6,7 @@
<i class="fa fa-retweet"></i> <i class="fa fa-retweet"></i>
{{.i18n.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}} {{.i18n.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}}
<div class="ui right"> <div class="ui right">
<a class="ui tiny basic toggle button" href="?style={{if .IsSplitStyle}}unified{{else}}split{{end}}">{{ if .IsSplitStyle }}{{.i18n.Tr "repo.diff.show_unified_view"}}{{else}}{{.i18n.Tr "repo.diff.show_split_view"}}{{end}}</a>
<a class="ui tiny basic toggle button" data-target="#diff-files">{{.i18n.Tr "repo.diff.show_diff_stats"}}</a> <a class="ui tiny basic toggle button" data-target="#diff-files">{{.i18n.Tr "repo.diff.show_diff_stats"}}</a>
</div> </div>
</div> </div>
@ -67,19 +68,46 @@
<div class="file-body file-code code-view code-diff"> <div class="file-body file-code code-view code-diff">
<table> <table>
<tbody> <tbody>
{{range .Sections}} {{if $.IsSplitStyle}}
{{range $k, $line := .Lines}} {{range $j, $section := .Sections}}
<tr class="{{DiffLineTypeToStr .Type}}-code nl-{{$k}} ol-{{$k}}"> {{range $k, $line := .Lines}}
<td class="lines-num lines-num-old"> <tr class="{{DiffLineTypeToStr .Type}}-code nl-{{$k}} ol-{{$k}}">
<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">
</td> <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-new"> </td>
<span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span> <td class="lines-code halfwidth">
</td> <pre class="wrap">{{if $line.LeftIdx}}{{$line.Content}}{{end}}</pre>
<td class="lines-code"> </td>
<pre>{{$line.Content}}</pre> <td class="lines-num lines-num-new">
</td> <span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span>
</tr> </td>
<td class="lines-code halfwidth">
<pre class="wrap">{{if $line.RightIdx}}{{$line.Content}}{{end}}</pre>
</td>
</tr>
{{end}}
{{end}}
{{else}}
{{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}} {{end}}
{{end}} {{end}}
</tbody> </tbody>
@ -89,6 +117,25 @@
{{end}} {{end}}
</div> </div>
</div> </div>
<br> <br>
{{end}}
{{if .IsSplitStyle}}
<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');
$(this).remove();
}
});
}());
</script>
{{end}} {{end}}
{{end}} {{end}}