mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-01 05:36:19 +01:00
Merge pull request #2296 from bkcsoft/feature/split-diff
Implement Split Diff-View
This commit is contained in:
commit
2481fe2f56
7 changed files with 820 additions and 928 deletions
|
@ -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
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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}}
|
||||||
|
|
Loading…
Reference in a new issue