Implements ignore-whitespace and hilight-syntax on diff.

Improvement experience speed
 * lazy diff rendering ( it is effective if tha diff has a lot of files ).
 * some feature implemented by javascript, to implement by css.
 * some javascript event handlers on each elements move to on parent elements.
This commit is contained in:
nazoking
2015-03-06 03:31:49 +09:00
parent 14becd0bd6
commit aa35498bdd
4 changed files with 400 additions and 156 deletions

View File

@@ -42,15 +42,16 @@
}
@diffs.zipWithIndex.map { case (diff, i) =>
<a name="diff-@i"></a>
<table class="table table-bordered" commitId="@newCommitId" fileName="@diff.newPath">
<table class="table table-bordered diff-outside" commitId="@newCommitId" fileName="@diff.newPath" data-diff-id="@i">
<tr>
<th style="font-weight: normal; line-height: 27px;" class="box-header">
@if(diff.changeType == ChangeType.COPY || diff.changeType == ChangeType.RENAME){
<img src="@assets/common/images/diff_move.png"/> @diff.oldPath -> @diff.newPath
@if(newCommitId.isDefined){
<div class="pull-right align-right">
<label class="checkbox" style="display: inline-block;"><input type="checkbox" class="ignore-whitespace" value="1"/>Ignore Space</label>
<label class="checkbox" style="display: inline-block;"><input type="checkbox" class="toggle-notes" checked><span>Show notes</span></label>
<a href="@url(repository)/blob/@newCommitId.get/@diff.newPath" class="btn btn-small">View file @@ @newCommitId.get.substring(0, 10)</a>
<a href="@url(repository)/blob/@newCommitId.get/@diff.newPath" class="btn btn-small" title="View the whole file at version @newCommitId.get.substring(0, 10)" data-toggle="tooltip">View</a>
</div>
}
}
@@ -62,8 +63,9 @@
} @diff.newPath
@if(newCommitId.isDefined){
<div class="pull-right align-right">
<label class="checkbox" style="display: inline-block;"><input type="checkbox" class="ignore-whitespace" value="1"/>Ignore Space</label>
<label class="checkbox" style="display: inline-block;"><input type="checkbox" class="toggle-notes" checked><span>Show notes</span></label>
<a href="@url(repository)/blob/@newCommitId.get/@diff.newPath" class="btn btn-small">View file @@ @newCommitId.get.substring(0, 10)</a>
<a href="@url(repository)/blob/@newCommitId.get/@diff.newPath" class="btn btn-small" title="View the whole file at version @newCommitId.get.substring(0, 10)" data-toggle="tooltip">View</a>
</div>
}
}
@@ -72,7 +74,7 @@
@if(oldCommitId.isDefined){
<div class="pull-right align-right">
<label class="checkbox" style="display: inline-block;"><input type="checkbox" class="toggle-notes" checked><span>Show notes</span></label>
<a href="@url(repository)/blob/@oldCommitId.get/@diff.oldPath" class="btn btn-small">View file @@ @oldCommitId.get.substring(0, 10)</a>
<a href="@url(repository)/blob/@oldCommitId.get/@diff.oldPath" class="btn btn-small" title="View the whole file at version @oldCommitId.get.substring(0, 10)" data-toggle="tooltip">View</a>
</div>
}
}
@@ -81,7 +83,7 @@
<tr>
<td style="padding: 0;">
@if(diff.newContent != None || diff.oldContent != None){
<div id="diffText-@i"></div>
<div id="diffText-@i" class="diffText"></div>
<textarea id="newText-@i" style="display: none;">@diff.newContent.getOrElse("")</textarea>
<textarea id="oldText-@i" style="display: none;">@diff.oldContent.getOrElse("")</textarea>
} else {
@@ -92,7 +94,6 @@
</table>
}
<script type="text/javascript" src="@assets/vendors/jsdifflib/difflib.js"></script>
<script type="text/javascript" src="@assets/vendors/jsdifflib/diffview.js"></script>
<link href="@assets/vendors/jsdifflib/diffview.css" type="text/css" rel="stylesheet" />
<script>
$(function(){
@@ -108,16 +109,26 @@ $(function(){
}
// Render diffs as unified mode initially
renderDiffs(1);
if(("&"+location.search.substring(1)).indexOf("&w=1")!=-1){
$('.ignore-whitespace').prop('checked',true);
}
window.viewType=1;
if(("&"+location.search.substring(1)).indexOf("&diff=split")!=-1){
$('.container').removeClass('container').addClass('container-wide');
window.viewType=0;
}
renderDiffs();
$('#btn-unified').click(function(){
window.viewType=1;
$('.container-wide').removeClass('container-wide').addClass('container');
renderDiffs(1);
renderDiffs();
});
$('#btn-split').click(function(){
window.viewType=0;
$('.container').removeClass('container').addClass('container-wide');
renderDiffs(0);
renderDiffs();
});
$('.toggle-notes').change(function() {
@@ -126,126 +137,124 @@ $(function(){
}
$(this).closest('table').find('.not-diff').toggle();
});
$('.ignore-whitespace').change(function() {
renderOneDiff($(this).closest("table").find(".diffText"), viewType);
});
function renderDiffs(viewType){
window.viewType = viewType;
@diffs.zipWithIndex.map { case (diff, i) =>
@if(diff.newContent != None || diff.oldContent != None){
if($('#oldText-@i').length > 0){
diffUsingJS('oldText-@i', 'newText-@i', 'diffText-@i', viewType);
}
function getInlineContainer(where) {
if (viewType == 0) {
if (where === 'new') {
return $('<tr class="not-diff"><td colspan="2"></td><td colspan="2" class="comment-box-container"></td></tr>');
} else if (where === 'old') {
return $('<tr class="not-diff"><td colspan="2" class="comment-box-container"></td><td colspan="2"></td></tr>');
}
}
return $('<tr class="not-diff"><td colspan="3" class="comment-box-container"></td></tr>');
}
if (typeof $('#show-notes')[0] !== 'undefined' && !$('#show-notes')[0].checked) {
$('.inline-comment').hide();
}
$('.diff-outside').on('click','table.diff .add-comment',function() {
var $this = $(this),
$tr = $this.closest('tr'),
$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,
url = '@url(repository)/commit/' + commitId + '/comment/_form?fileName=' + fileName@issueId.map { id => + '&issueId=@id' };
if (viewType == 0) {
oldLineNumber = $this.parent().prev('.oldline').attr('line-number');
newLineNumber = $this.parent().prev('.newline').attr('line-number');
} else {
oldLineNumber = $this.parent().prevAll('.oldline').attr('line-number');
newLineNumber = $this.parent().prevAll('.newline').attr('line-number');
}
if (!isNaN(oldLineNumber) && oldLineNumber) {
url += ('&oldLineNumber=' + oldLineNumber)
}
if (!isNaN(newLineNumber) && newLineNumber) {
url += ('&newLineNumber=' + newLineNumber)
}
$.get(
url,
{
dataType : 'html'
},
function(responseContent) {
$this.hide();
var tmp;
if (!isNaN(oldLineNumber) && oldLineNumber) {
if (!isNaN(newLineNumber) && newLineNumber) {
tmp = getInlineContainer();
} else {
tmp = getInlineContainer('old');
}
} else {
tmp = getInlineContainer('new');
}
tmp.addClass('inline-comment-form').children('.comment-box-container').html(responseContent);
$tr.nextAll(':not(.not-diff):first').before(tmp);
}
);
}
}).on('click', 'table.diff .btn-default', function() {
$(this).closest('.inline-comment-form').remove();
});
function renderOneCommitCommentIntoDiff($v, diff){
var filename = $v.attr('filename'),
oldline = $v.attr('oldline'), newline = $v.attr('newline');
var tmp;
var diff;
if (typeof oldline !== 'undefined') {
if (typeof newline !== 'undefined') {
tmp = getInlineContainer();
} else {
tmp = getInlineContainer('old');
}
tmp.children('td:first').html($v.clone().show());
diff.find('table.diff').find('.oldline[line-number=' + oldline + ']')
.parent().nextAll(':not(.not-diff):first').before(tmp);
} else {
tmp = getInlineContainer('new');
tmp.children('td:last').html($v.clone().show());
diff.find('table.diff').find('.newline[line-number=' + newline + ']')
.parent().nextAll(':not(.not-diff):first').before(tmp);
}
if (!diff.find('.toggle-notes').prop('checked')) {
tmp.hide();
}
}
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);
@if(hasWritePermission) {
diffText.find('.body').each(function(){ $('<b class="add-comment">+</b>').prependTo(this); });
}
@if(showLineNotes){
function getInlineContainer(where) {
if (viewType == 0) {
if (where === 'new') {
return $('<tr class="not-diff"><td colspan="2"></td><td colspan="2" class="comment-box-container"></td></tr>');
} else if (where === 'old') {
return $('<tr class="not-diff"><td colspan="2" class="comment-box-container"></td><td colspan="2"></td></tr>');
}
}
return $('<tr class="not-diff"><td colspan="3" class="comment-box-container"></td></tr>');
}
var fileName = table.attr('filename');
$('.inline-comment').each(function(i, v) {
var $v = $(v), filename = $v.attr('filename'),
oldline = $v.attr('oldline'), newline = $v.attr('newline');
if (typeof $('#show-notes')[0] !== 'undefined' && !$('#show-notes')[0].checked) {
$(this).hide();
}
var tmp;
var diff;
if (typeof oldline !== 'undefined') {
if (typeof newline !== 'undefined') {
tmp = getInlineContainer();
} else {
tmp = getInlineContainer('old');
}
tmp.children('td:first').html($(this).clone().show());
diff = $('table[filename="' + filename + '"]');
diff.find('table.diff').find('.oldline[line-number=' + oldline + ']')
.parent().nextAll(':not(.not-diff):first').before(tmp);
} else {
tmp = getInlineContainer('new');
tmp.children('td:last').html($(this).clone().show());
diff = $('table[filename="' + filename + '"]');
diff.find('table.diff').find('.newline[line-number=' + newline + ']')
.parent().nextAll(':not(.not-diff):first').before(tmp);
}
if (!diff.find('.toggle-notes').prop('checked')) {
tmp.hide();
if($(this).attr('filename')==fileName){
renderOneCommitCommentIntoDiff($(this), table);
}
});
@if(hasWritePermission) {
$('table.diff td').hover(
function() {
$(this).find('b').css('display', 'inline-block');
},
function() {
$(this).find('b').css('display', 'none');
}
);
$('table.diff th').hover(
function() {
$(this).nextAll().find('b').first().css('display', 'inline-block');
},
function() {
$(this).nextAll().find('b').first().css('display', 'none');
}
);
$('.add-comment').click(function() {
var $this = $(this),
$tr = $this.closest('tr'),
$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,
url = '@url(repository)/commit/' + commitId + '/comment/_form?fileName=' + fileName@issueId.map { id => + '&issueId=@id' };
if (viewType == 0) {
oldLineNumber = $this.parent().prev('.oldline').attr('line-number');
newLineNumber = $this.parent().prev('.newline').attr('line-number');
} else {
oldLineNumber = $this.parent().prevAll('.oldline').attr('line-number');
newLineNumber = $this.parent().prevAll('.newline').attr('line-number');
}
if (!isNaN(oldLineNumber) && oldLineNumber) {
url += ('&oldLineNumber=' + oldLineNumber)
}
if (!isNaN(newLineNumber) && newLineNumber) {
url += ('&newLineNumber=' + newLineNumber)
}
$.get(
url,
{
dataType : 'html'
},
function(responseContent) {
$this.hide();
var tmp;
if (!isNaN(oldLineNumber) && oldLineNumber) {
if (!isNaN(newLineNumber) && newLineNumber) {
tmp = getInlineContainer();
} else {
tmp = getInlineContainer('old');
}
} else {
tmp = getInlineContainer('new');
}
tmp.addClass('inline-comment-form').children('.comment-box-container').html(responseContent);
$tr.nextAll(':not(.not-diff):first').before(tmp);
}
);
}
});
$('table.diff').on('click', '.btn-default', function() {
$(this).closest('.inline-comment-form').remove();
});
}
}
function renderDiffs(){
var i=0, diffs = $('.diffText');
function render(){
if(diffs[i]){
renderOneDiff($(diffs[i]), viewType);
i++;
setTimeout(render);
}
}
render();
}
});
</script>