diff2html/src/ui/js/diff2html-ui.js

220 lines
6.1 KiB
JavaScript
Raw Normal View History

/*
*
* Diff to HTML (diff2html-ui.js)
* Author: rtfpessoa
*
* Depends on: [ jQuery ]
* Optional dependencies on: [ highlight.js ]
*
*/
/*global $, hljs, Diff2Html*/
(function() {
var highlightJS = require('./highlight.js-internals.js').HighlightJS;
var diffJson = null;
2016-07-12 12:47:29 +00:00
var defaultTarget = 'body';
var currentSelectionColumnId = -1;
function Diff2HtmlUI(config) {
var cfg = config || {};
if (cfg.diff) {
diffJson = Diff2Html.getJsonFromDiff(cfg.diff);
} else if (cfg.json) {
diffJson = cfg.json;
}
this._initSelection();
}
Diff2HtmlUI.prototype.draw = function(targetId, config) {
var cfg = config || {};
cfg.inputFormat = 'json';
var $target = this._getTarget(targetId);
$target.html(Diff2Html.getPrettyHtml(diffJson, cfg));
2016-05-21 22:16:43 +00:00
if (cfg.synchronisedScroll) {
this.synchronisedScroll($target, cfg);
}
};
Diff2HtmlUI.prototype.synchronisedScroll = function(targetId) {
var $target = this._getTarget(targetId);
$target.find('.d2h-file-side-diff').scroll(function() {
var $this = $(this);
$this.closest('.d2h-file-wrapper').find('.d2h-file-side-diff')
.scrollLeft($this.scrollLeft());
});
};
2016-05-21 22:16:43 +00:00
Diff2HtmlUI.prototype.fileListCloseable = function(targetId, startVisible) {
var $target = this._getTarget(targetId);
var hashTag = this._getHashTag();
2016-07-12 12:47:29 +00:00
var $showBtn = $target.find('.d2h-show');
var $hideBtn = $target.find('.d2h-hide');
var $fileList = $target.find('.d2h-file-list');
if (hashTag === 'files-summary-show') show();
else if (hashTag === 'files-summary-hide') hide();
else if (startVisible) show();
else hide();
$showBtn.click(show);
$hideBtn.click(hide);
function show() {
$showBtn.hide();
$hideBtn.show();
$fileList.show();
}
function hide() {
$hideBtn.hide();
$showBtn.show();
$fileList.hide();
}
};
Diff2HtmlUI.prototype.highlightCode = function(targetId) {
var that = this;
2016-02-09 21:26:22 +00:00
var $target = that._getTarget(targetId);
// collect all the diff files and execute the highlight on their lines
2016-07-12 12:47:29 +00:00
var $files = $target.find('.d2h-file-wrapper');
$files.map(function(_i, file) {
var oldLinesState;
var newLinesState;
var $file = $(file);
2016-07-12 12:47:29 +00:00
var language = $file.data('lang');
// collect all the code lines and execute the highlight on them
2016-07-12 12:47:29 +00:00
var $codeLines = $file.find('.d2h-code-line-ctn');
$codeLines.map(function(_j, line) {
var $line = $(line);
var text = line.textContent;
var lineParent = line.parentNode;
var lineState;
2016-07-12 12:47:29 +00:00
if (lineParent.className.indexOf('d2h-del') !== -1) {
lineState = oldLinesState;
} else {
lineState = newLinesState;
}
var result = hljs.getLanguage(language) ? hljs.highlight(language, text, true, lineState) : hljs.highlightAuto(text);
2016-07-12 12:47:29 +00:00
if (lineParent.className.indexOf('d2h-del') !== -1) {
oldLinesState = result.top;
2016-07-12 12:47:29 +00:00
} else if (lineParent.className.indexOf('d2h-ins') !== -1) {
newLinesState = result.top;
} else {
oldLinesState = result.top;
newLinesState = result.top;
}
var originalStream = highlightJS.nodeStream(line);
if (originalStream.length) {
var resultNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
resultNode.innerHTML = result.value;
result.value = highlightJS.mergeStreams(originalStream, highlightJS.nodeStream(resultNode), text);
}
2016-07-12 12:47:29 +00:00
$line.addClass('hljs');
2016-05-09 17:21:50 +00:00
$line.addClass(result.language);
$line.html(result.value);
});
});
};
Diff2HtmlUI.prototype._getTarget = function(targetId) {
var $target;
2016-04-25 17:20:00 +00:00
if (typeof targetId === 'object' && targetId instanceof jQuery) {
$target = targetId;
2016-04-25 17:20:00 +00:00
} else if (typeof targetId === 'string') {
$target = $(targetId);
} else {
console.error("Wrong target provided! Falling back to default value 'body'.");
2016-07-12 12:47:29 +00:00
console.log('Please provide a jQuery object or a valid DOM query string.');
$target = $(defaultTarget);
}
return $target;
};
Diff2HtmlUI.prototype._getHashTag = function() {
var docUrl = document.URL;
var hashTagIndex = docUrl.indexOf('#');
var hashTag = null;
2016-02-21 16:40:22 +00:00
if (hashTagIndex !== -1) {
hashTag = docUrl.substr(hashTagIndex + 1);
}
return hashTag;
};
2016-02-21 14:45:50 +00:00
Diff2HtmlUI.prototype._distinct = function(collection) {
return collection.filter(function(v, i) {
return collection.indexOf(v) === i;
});
};
2016-05-01 19:26:10 +00:00
Diff2HtmlUI.prototype._initSelection = function() {
var body = $('body');
var that = this;
2016-05-01 19:26:10 +00:00
body.on('mousedown', '.d2h-diff-table', function(event) {
var target = $(event.target);
var table = target.closest('.d2h-diff-table');
if (target.closest('.d2h-code-line,.d2h-code-side-line').length) {
table.removeClass('selecting-left');
table.addClass('selecting-right');
currentSelectionColumnId = 1;
} else if (target.closest('.d2h-code-linenumber,.d2h-code-side-linenumber').length) {
table.removeClass('selecting-right');
table.addClass('selecting-left');
currentSelectionColumnId = 0;
}
});
2016-05-01 19:26:10 +00:00
body.on('copy', '.d2h-diff-table', function(event) {
var clipboardData = event.originalEvent.clipboardData;
var text = that._getSelectedText();
clipboardData.setData('text', text);
event.preventDefault();
});
};
2016-05-01 19:26:10 +00:00
Diff2HtmlUI.prototype._getSelectedText = function() {
var sel = window.getSelection();
var range = sel.getRangeAt(0);
var doc = range.cloneContents();
var nodes = doc.querySelectorAll('tr');
var text = '';
var idx = currentSelectionColumnId;
if (nodes.length === 0) {
text = doc.textContent;
} else {
2016-05-01 19:26:10 +00:00
[].forEach.call(nodes, function(tr, i) {
2016-05-01 19:33:55 +00:00
var td = tr.cells[tr.cells.length === 1 ? 0 : idx];
text += (i ? '\n' : '') + td.textContent.replace(/(?:\r\n|\r|\n)/g, '');
});
}
return text;
};
module.exports.Diff2HtmlUI = Diff2HtmlUI;
// Expose diff2html in the browser
global.Diff2HtmlUI = Diff2HtmlUI;
})();