diff --git a/src/main/scala/gitbucket/core/view/helpers.scala b/src/main/scala/gitbucket/core/view/helpers.scala
index 730b827..9828128 100644
--- a/src/main/scala/gitbucket/core/view/helpers.scala
+++ b/src/main/scala/gitbucket/core/view/helpers.scala
@@ -10,6 +10,7 @@
import gitbucket.core.service.RepositoryService.RepositoryInfo
import gitbucket.core.service.{RepositoryService, RequestCache}
import gitbucket.core.util.{FileUtil, JGitUtil, StringUtil}
+import org.apache.commons.codec.digest.DigestUtils
import play.twirl.api.{Html, HtmlFormat}
/**
@@ -506,4 +507,6 @@
s"$baseUrl${if (baseUrl.contains("?")) "&" else "?"}$queryString"
}
+ def md5(value: String): String = DigestUtils.md5Hex(value)
+
}
diff --git a/src/main/twirl/gitbucket/core/helper/diff.scala.html b/src/main/twirl/gitbucket/core/helper/diff.scala.html
index 37b53a6..3869d63 100644
--- a/src/main/twirl/gitbucket/core/helper/diff.scala.html
+++ b/src/main/twirl/gitbucket/core/helper/diff.scala.html
@@ -8,6 +8,11 @@
showLineNotes: Boolean)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers
@import org.eclipse.jgit.diff.DiffEntry.ChangeType
+
@if(showIndex){
@if(oldCommitId.isEmpty && newCommitId.isDefined) {
@@ -59,7 +64,7 @@
}
- @diff.oldPath → @diff.newPath
+ @diff.oldPath → @diff.newPath
}
@if(diff.changeType == ChangeType.ADD || diff.changeType == ChangeType.MODIFY){
@if(newCommitId.isDefined){
@@ -76,7 +81,7 @@
}
- @diff.newPath
+ @diff.newPath
}
@if(diff.changeType == ChangeType.DELETE){
@if(oldCommitId.isDefined){
@@ -86,7 +91,7 @@
}
- @diff.oldPath
+ @diff.oldPath
}
@if(diff.oldMode != diff.newMode){
@diff.oldMode → @diff.newMode
@@ -180,6 +185,10 @@
}
renderDiffs();
+ window.onhashchange = function(){
+ updateHighlighting();
+ }
+
$('.toggle-notes').change(function() {
if (!$(this).prop('checked')) {
$(this).closest('table').find('.not-diff.inline-comment-form').remove();
@@ -188,7 +197,7 @@
});
$('.ignore-whitespace').change(function() {
- renderOneDiff($(this).closest("table").find(".diffText"), window.viewType);
+ renderOneDiff($(this).closest("table").find(".diffText"), window.viewType, $(this).closest("table").find(".file-hash")[0].id);
});
function getInlineContainer(where) {
@@ -208,7 +217,7 @@
function showCommentForm(commitId, fileName, oldLineNumber, newLineNumber, $tr){
// assemble Ajax url
- var url = '@helpers.url(repository)/commit/' + commitId + '/comment/_form?fileName=' + fileName@issueId.map { id => + '&issueId=@id' };
+ let url = '@helpers.url(repository)/commit/' + commitId + '/comment/_form?fileName=' + fileName@issueId.map { id => + '&issueId=@id' };
if (!isNaN(oldLineNumber) && oldLineNumber) {
url += ('&oldLineNumber=' + oldLineNumber)
}
@@ -218,7 +227,7 @@
// send Ajax request
$.get(url, { dataType : 'html' }, function(responseContent) {
// create container
- var tmp;
+ let tmp;
if (!isNaN(oldLineNumber) && oldLineNumber) {
if (!isNaN(newLineNumber) && newLineNumber) {
tmp = getInlineContainer();
@@ -240,16 +249,16 @@
// Add comment button
$('.diff-outside').on('click','table.diff .add-comment',function() {
- var $this = $(this);
- var $tr = $this.closest('tr');
- var $check = $this.closest('table:not(.diff)').find('.toggle-notes');
+ const $this = $(this);
+ const $tr = $this.closest('tr');
+ const $check = $this.closest('table:not(.diff)').find('.toggle-notes');
if (!$check.prop('checked')) {
$check.prop('checked', true).trigger('change');
}
if (!$tr.nextAll(':not(.not-diff):first').prev().hasClass('inline-comment-form')) {
- var commitId = $this.closest('.table-bordered').attr('commitId'),
- fileName = $this.closest('.table-bordered').attr('fileName'),
- oldLineNumber, newLineNumber;
+ const commitId = $this.closest('.table-bordered').attr('commitId'),
+ fileName = $this.closest('.table-bordered').attr('fileName');
+ let oldLineNumber, newLineNumber;
if (window.viewType == 0) {
oldLineNumber = $this.parent().prev('.oldline').attr('line-number');
newLineNumber = $this.parent().prev('.newline').attr('line-number');
@@ -268,21 +277,37 @@
// Reply comment
$('.diff-outside').on('click', '.reply-comment',function(){
- var $this = $(this);
- var $tr = $this.closest('tr');
- var commitId = $this.closest('.table-bordered').attr('commitId');
- var fileName = $this.data('filename');
- var oldLineNumber = $this.data('oldline');
- var newLineNumber = $this.data('newline');
+ const $this = $(this);
+ const $tr = $this.closest('tr');
+ const commitId = $this.closest('.table-bordered').attr('commitId');
+ const fileName = $this.data('filename');
+ const oldLineNumber = $this.data('oldline');
+ const newLineNumber = $this.data('newline');
showCommentForm(commitId, fileName, oldLineNumber, newLineNumber, $tr);
});
+ // Line selection
+ $('.diff-outside').on('click','table.diff th.line-num',function(e) {
+ const $this = $(this);
+ const hash = location.hash;
+ const baseUrl = location.toString().split("#")[0];
+
+ if (e.shiftKey == true && hash.match(/#diff-\w+-L\d+(-L\d+)?/)) {
+ const fragments = hash.split('-');
+ window.history.pushState('', '', baseUrl + '#diff-' + fragments[1] + '-' + fragments[2] + '-' + $this[0].id.split('-')[2]);
+ } else {
+ window.history.pushState('', '', baseUrl + '#' + $this[0].id);
+ }
+ getSelection().empty();
+ updateHighlighting();
+ });
+
function renderOneCommitCommentIntoDiff($v, diff){
//var filename = $v.attr('filename');
- var oldline = $v.attr('oldline');
- var newline = $v.attr('newline');
- var tmp;
+ const oldline = $v.attr('oldline');
+ const newline = $v.attr('newline');
+ let tmp;
if (typeof oldline !== 'undefined') {
if (typeof newline !== 'undefined') {
tmp = getInlineContainer();
@@ -312,8 +337,8 @@
}
del = 5 - add;
}
- var ret = $('');
- for(var i = 0; i < 5; i++){
+ const ret = $('
');
+ for(let i = 0; i < 5; i++){
if(add){
ret.append('■');
add--;
@@ -327,13 +352,13 @@
return ret;
}
- function renderOneDiff(diffText, viewType){
- var table = diffText.closest("table[data-diff-id]");
- var i = table.data("diff-id");
- var ignoreWhiteSpace = table.find('.ignore-whitespace').prop('checked');
- diffUsingJS('oldText-' + i, 'newText-' + i, diffText.attr('id'), viewType, ignoreWhiteSpace);
- var add = diffText.find("table").attr("add") * 1;
- var del = diffText.find("table").attr("del") * 1;
+ function renderOneDiff(diffText, viewType, fileHash){
+ const table = diffText.closest("table[data-diff-id]");
+ const i = table.data("diff-id");
+ const ignoreWhiteSpace = table.find('.ignore-whitespace').prop('checked');
+ diffUsingJS('oldText-' + i, 'newText-' + i, diffText.attr('id'), viewType, ignoreWhiteSpace, fileHash);
+ const add = diffText.find("table").attr("add") * 1;
+ const del = diffText.find("table").attr("del") * 1;
table.find(".diffstat").text(add + del + " ").append(renderStatBar(add, del)).attr("title", add + " additions & " + del + " deletions").tooltip();
$('span.diffstat[data-diff-id="' + i + '"]')
.html('+' + add + '-' + del + '')
@@ -347,7 +372,7 @@
});
}
@if(showLineNotes){
- var fileName = table.attr('filename');
+ const fileName = table.attr('filename');
$('.inline-comment').each(function(i, v) {
if($(this).attr('filename') == fileName){
renderOneCommitCommentIntoDiff($(this), table);
@@ -358,13 +383,13 @@
}
function renderReplyComment($table){
- var elements = {};
- var filename, newline, oldline;
+ const elements = {};
+ let filename, newline, oldline;
$table.find('.comment-box-container .inline-comment').each(function(i, e){
filename = $(e).attr('filename');
newline = $(e).attr('newline');
oldline = $(e).attr('oldline');
- var key = filename + '-' + newline + '-' + oldline;
+ const key = filename + '-' + newline + '-' + oldline;
elements[key] = {
element: $(e),
filename: filename,
@@ -372,18 +397,18 @@
oldline: oldline
};
});
- for(var key in elements){
+ for(const key in elements){
filename = elements[key]['filename'];
oldline = elements[key]['oldline']; //? elements[key]['oldline'] : '';
newline = elements[key]['newline']; //? elements[key]['newline'] : '';
- var $v = $('
').append(bc.slice(o[1], o[2]))); + } + if(o[4] != o[3]){ + ret.head.push($('').append(nc.slice(o[3], o[4]))); + } + break; } } return ret; } }, flatten: function(opcodes, headTextLines, baseTextLines, isIgnoreLine){ - var ret = [], add=0, del=0; - for (var idx = 0; idx < opcodes.length; idx++) { - var code = opcodes[idx]; - var change = code[0]; - var b = code[1]; - var n = code[3]; - var rowcnt = Math.max(code[2] - b, code[4] - n); - for (var i = 0; i < rowcnt; i++) { + let ret = [], add = 0, del = 0; + for (let idx = 0; idx < opcodes.length; idx++) { + const code = opcodes[idx]; + const change = code[0]; + let b = code[1]; + let n = code[3]; + const rowcnt = Math.max(code[2] - b, code[4] - n); + for (let i = 0; i < rowcnt; i++) { switch(change){ - case 'insert': - add++; - ret.push({ - change:(isIgnoreLine(headTextLines[n]) ? 'equal' : change), - head: ++n - }); - break; - case 'delete': - del++; - ret.push({ - change: (isIgnoreLine(baseTextLines[b]) ? 'equal' : change), - base: ++b - }); - break; - case 'replace': - add++; - del++; - var r = {change: change}; - if(ncontextSize){ + } else { + if (skips.length > contextSize) { ret.push({ - change:'skip', - start:skips[0], - end:skips[skips.length-contextSize] + change: 'skip', + start: skips[0], + end: skips[skips.length-contextSize] }); } ret = ret.concat(skips.splice(- contextSize)); @@ -326,7 +331,7 @@ bskip = 0; } } - if(skips.length > contextSize){ + if (skips.length > contextSize) { ret.push({ change:'skip', start:skips[0], @@ -344,12 +349,12 @@ */ function scrollIntoView(target){ target = $(target); - var $window = $(window); - var docViewTop = $window.scrollTop(); - var docViewBottom = docViewTop + $window.height(); + const $window = $(window); + const docViewTop = $window.scrollTop(); + const docViewBottom = docViewTop + $window.height(); - var elemTop = target.offset().top; - var elemBottom = elemTop + target.height(); + const elemTop = target.offset().top; + const elemBottom = elemTop + target.height(); if(elemBottom > docViewBottom){ $('html, body').scrollTop(elemBottom - $window.height());