Merge pull request #145 from rtfpessoa/fix-stuck
Fix generation of diff with long lines
This commit is contained in:
commit
b88c775ebe
6 changed files with 121 additions and 55 deletions
|
|
@ -97,6 +97,7 @@ The HTML output accepts a Javascript object with configuration. Possible options
|
||||||
- `matching`: matching level: `'lines'` for matching lines, `'words'` for matching lines and words or `'none'`, default is `none`
|
- `matching`: matching level: `'lines'` for matching lines, `'words'` for matching lines and words or `'none'`, default is `none`
|
||||||
- `matchWordsThreshold`: similarity threshold for word matching, default is 0.25
|
- `matchWordsThreshold`: similarity threshold for word matching, default is 0.25
|
||||||
- `matchingMaxComparisons`: perform at most this much comparisons for line matching a block of changes, default is `2500`
|
- `matchingMaxComparisons`: perform at most this much comparisons for line matching a block of changes, default is `2500`
|
||||||
|
- `maxLineLengthHighlight`: only perform diff changes highlight if lines are smaller than this, default is `10000`
|
||||||
- `templates`: object with previously compiled templates to replace parts of the html
|
- `templates`: object with previously compiled templates to replace parts of the html
|
||||||
- `rawTemplates`: object with raw not compiled templates to replace parts of the html
|
- `rawTemplates`: object with raw not compiled templates to replace parts of the html
|
||||||
> For more information regarding the possible templates look into [src/templates](https://github.com/rtfpessoa/diff2html/tree/master/src/templates)
|
> For more information regarding the possible templates look into [src/templates](https://github.com/rtfpessoa/diff2html/tree/master/src/templates)
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"diff": "^3.3.1",
|
"diff": "^3.3.1",
|
||||||
"hogan.js": "^3.0.2",
|
"hogan.js": "^3.0.2",
|
||||||
|
"lodash": "^4.17.4",
|
||||||
"whatwg-fetch": "^2.0.3"
|
"whatwg-fetch": "^2.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -8,48 +8,49 @@
|
||||||
(function() {
|
(function() {
|
||||||
var diffParser = require('./diff-parser.js').DiffParser;
|
var diffParser = require('./diff-parser.js').DiffParser;
|
||||||
var htmlPrinter = require('./html-printer.js').HtmlPrinter;
|
var htmlPrinter = require('./html-printer.js').HtmlPrinter;
|
||||||
|
var utils = require('./utils.js').Utils;
|
||||||
|
|
||||||
function Diff2Html() {
|
function Diff2Html() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
var defaultConfig = {
|
||||||
* Line diff type configuration
|
wordByWord: true,
|
||||||
var config = {
|
outputFormat: 'line-by-line',
|
||||||
'wordByWord': true, // (default)
|
matching: 'none',
|
||||||
// OR
|
matchWordsThreshold: 0.25,
|
||||||
'charByChar': true
|
matchingMaxComparisons: 2500,
|
||||||
|
maxLineLengthHighlight: 10000
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates json object from string diff input
|
* Generates json object from string diff input
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getJsonFromDiff = function(diffInput, config) {
|
Diff2Html.prototype.getJsonFromDiff = function(diffInput, config) {
|
||||||
var configOrEmpty = config || {};
|
var cfg = utils.safeConfig(config, defaultConfig);
|
||||||
return diffParser.generateDiffJson(diffInput, configOrEmpty);
|
return diffParser.generateDiffJson(diffInput, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates the html diff. The config parameter configures the output/input formats and other options
|
* Generates the html diff. The config parameter configures the output/input formats and other options
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettyHtml = function(diffInput, config) {
|
Diff2Html.prototype.getPrettyHtml = function(diffInput, config) {
|
||||||
var configOrEmpty = config || {};
|
var cfg = utils.safeConfig(config, defaultConfig);
|
||||||
|
|
||||||
var diffJson = diffInput;
|
var diffJson = diffInput;
|
||||||
if (!configOrEmpty.inputFormat || configOrEmpty.inputFormat === 'diff') {
|
if (!cfg.inputFormat || cfg.inputFormat === 'diff') {
|
||||||
diffJson = diffParser.generateDiffJson(diffInput, configOrEmpty);
|
diffJson = diffParser.generateDiffJson(diffInput, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileList = '';
|
var fileList = '';
|
||||||
if (configOrEmpty.showFiles === true) {
|
if (cfg.showFiles === true) {
|
||||||
fileList = htmlPrinter.generateFileListSummary(diffJson, configOrEmpty);
|
fileList = htmlPrinter.generateFileListSummary(diffJson, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
var diffOutput = '';
|
var diffOutput = '';
|
||||||
if (configOrEmpty.outputFormat === 'side-by-side') {
|
if (cfg.outputFormat === 'side-by-side') {
|
||||||
diffOutput = htmlPrinter.generateSideBySideJsonHtml(diffJson, configOrEmpty);
|
diffOutput = htmlPrinter.generateSideBySideJsonHtml(diffJson, cfg);
|
||||||
} else {
|
} else {
|
||||||
diffOutput = htmlPrinter.generateLineByLineJsonHtml(diffJson, configOrEmpty);
|
diffOutput = htmlPrinter.generateLineByLineJsonHtml(diffJson, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileList + diffOutput;
|
return fileList + diffOutput;
|
||||||
|
|
@ -63,40 +64,40 @@
|
||||||
* Generates pretty html from string diff input
|
* Generates pretty html from string diff input
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettyHtmlFromDiff = function(diffInput, config) {
|
Diff2Html.prototype.getPrettyHtmlFromDiff = function(diffInput, config) {
|
||||||
var configOrEmpty = config || {};
|
var cfg = utils.safeConfig(config, defaultConfig);
|
||||||
configOrEmpty.inputFormat = 'diff';
|
cfg.inputFormat = 'diff';
|
||||||
configOrEmpty.outputFormat = 'line-by-line';
|
cfg.outputFormat = 'line-by-line';
|
||||||
return this.getPrettyHtml(diffInput, configOrEmpty);
|
return this.getPrettyHtml(diffInput, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates pretty html from a json object
|
* Generates pretty html from a json object
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettyHtmlFromJson = function(diffJson, config) {
|
Diff2Html.prototype.getPrettyHtmlFromJson = function(diffJson, config) {
|
||||||
var configOrEmpty = config || {};
|
var cfg = utils.safeConfig(config, defaultConfig);
|
||||||
configOrEmpty.inputFormat = 'json';
|
cfg.inputFormat = 'json';
|
||||||
configOrEmpty.outputFormat = 'line-by-line';
|
cfg.outputFormat = 'line-by-line';
|
||||||
return this.getPrettyHtml(diffJson, configOrEmpty);
|
return this.getPrettyHtml(diffJson, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates pretty side by side html from string diff input
|
* Generates pretty side by side html from string diff input
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettySideBySideHtmlFromDiff = function(diffInput, config) {
|
Diff2Html.prototype.getPrettySideBySideHtmlFromDiff = function(diffInput, config) {
|
||||||
var configOrEmpty = config || {};
|
var cfg = utils.safeConfig(config, defaultConfig);
|
||||||
configOrEmpty.inputFormat = 'diff';
|
cfg.inputFormat = 'diff';
|
||||||
configOrEmpty.outputFormat = 'side-by-side';
|
cfg.outputFormat = 'side-by-side';
|
||||||
return this.getPrettyHtml(diffInput, configOrEmpty);
|
return this.getPrettyHtml(diffInput, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates pretty side by side html from a json object
|
* Generates pretty side by side html from a json object
|
||||||
*/
|
*/
|
||||||
Diff2Html.prototype.getPrettySideBySideHtmlFromJson = function(diffJson, config) {
|
Diff2Html.prototype.getPrettySideBySideHtmlFromJson = function(diffJson, config) {
|
||||||
var configOrEmpty = config || {};
|
var cfg = utils.safeConfig(config, defaultConfig);
|
||||||
configOrEmpty.inputFormat = 'json';
|
cfg.inputFormat = 'json';
|
||||||
configOrEmpty.outputFormat = 'side-by-side';
|
cfg.outputFormat = 'side-by-side';
|
||||||
return this.getPrettyHtml(diffJson, configOrEmpty);
|
return this.getPrettyHtml(diffJson, cfg);
|
||||||
};
|
};
|
||||||
|
|
||||||
var diffObject = new Diff2Html();
|
var diffObject = new Diff2Html();
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,20 @@
|
||||||
unprefixedLine1 = diffLine1.substr(prefixSize);
|
unprefixedLine1 = diffLine1.substr(prefixSize);
|
||||||
unprefixedLine2 = diffLine2.substr(prefixSize);
|
unprefixedLine2 = diffLine2.substr(prefixSize);
|
||||||
|
|
||||||
|
if (unprefixedLine1.length > config.maxLineLengthHighlight ||
|
||||||
|
unprefixedLine2.length > config.maxLineLengthHighlight) {
|
||||||
|
return {
|
||||||
|
first: {
|
||||||
|
prefix: linePrefix1,
|
||||||
|
line: utils.escape(unprefixedLine1)
|
||||||
|
},
|
||||||
|
second: {
|
||||||
|
prefix: linePrefix2,
|
||||||
|
line: utils.escape(unprefixedLine2)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var diff;
|
var diff;
|
||||||
if (config.charByChar) {
|
if (config.charByChar) {
|
||||||
diff = jsDiff.diffChars(unprefixedLine1, unprefixedLine2);
|
diff = jsDiff.diffChars(unprefixedLine1, unprefixedLine2);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
var lodash = require('lodash');
|
||||||
|
|
||||||
function Utils() {
|
function Utils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,5 +41,11 @@
|
||||||
return value || '';
|
return value || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Utils.prototype.safeConfig = function(cfg, defaultConfig) {
|
||||||
|
var newCfg = {};
|
||||||
|
lodash.merge(newCfg, defaultConfig, cfg);
|
||||||
|
return newCfg;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports.Utils = new Utils();
|
module.exports.Utils = new Utils();
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ $(document).ready(function() {
|
||||||
var $outputFormat = $('#diff-url-options-output-format');
|
var $outputFormat = $('#diff-url-options-output-format');
|
||||||
var $showFiles = $('#diff-url-options-show-files');
|
var $showFiles = $('#diff-url-options-show-files');
|
||||||
var $matching = $('#diff-url-options-matching');
|
var $matching = $('#diff-url-options-matching');
|
||||||
var $wordThreshold = $('#diff-url-options-match-words-threshold');
|
var $wordsThreshold = $('#diff-url-options-match-words-threshold');
|
||||||
var $matchingMaxComparisons = $('#diff-url-options-matching-max-comparisons');
|
var $matchingMaxComparisons = $('#diff-url-options-matching-max-comparisons');
|
||||||
|
|
||||||
if (window.location.search) {
|
if (window.location.search) {
|
||||||
|
|
@ -38,10 +38,13 @@ $(document).ready(function() {
|
||||||
$outputFormat
|
$outputFormat
|
||||||
.add($showFiles)
|
.add($showFiles)
|
||||||
.add($matching)
|
.add($matching)
|
||||||
.add($wordThreshold)
|
.add($wordsThreshold)
|
||||||
.add($matchingMaxComparisons)
|
.add($matchingMaxComparisons)
|
||||||
.change(function() {
|
.change(function(e) {
|
||||||
smartDraw();
|
console.log('');
|
||||||
|
console.log(e);
|
||||||
|
console.log('');
|
||||||
|
smartDraw(null, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
function getUrlFromSearch(search) {
|
function getUrlFromSearch(search) {
|
||||||
|
|
@ -56,6 +59,22 @@ $(document).ready(function() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getParamsFromSearch(search) {
|
||||||
|
var map = {};
|
||||||
|
try {
|
||||||
|
search
|
||||||
|
.split('?')[1]
|
||||||
|
.split('&')
|
||||||
|
.map(function(e) {
|
||||||
|
var values = e.split('=');
|
||||||
|
map[values[0]] = values[1];
|
||||||
|
});
|
||||||
|
} catch (_ignore) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
function bind() {
|
function bind() {
|
||||||
$('#url-btn').click(function(e) {
|
$('#url-btn').click(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -124,13 +143,13 @@ $(document).ready(function() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function smartDraw(urlOpt) {
|
function smartDraw(urlOpt, forced) {
|
||||||
var url = urlOpt || $url.val();
|
var url = urlOpt || $url.val();
|
||||||
var req = prepareUrl(url);
|
var req = prepareUrl(url);
|
||||||
draw(req);
|
draw(req, forced);
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw(req) {
|
function draw(req, forced) {
|
||||||
if (!validateUrl(req.url)) {
|
if (!validateUrl(req.url)) {
|
||||||
console.error('Invalid url provided!');
|
console.error('Invalid url provided!');
|
||||||
return;
|
return;
|
||||||
|
|
@ -141,7 +160,7 @@ $(document).ready(function() {
|
||||||
var outputFormat = $outputFormat.val();
|
var outputFormat = $outputFormat.val();
|
||||||
var showFiles = $showFiles.is(':checked');
|
var showFiles = $showFiles.is(':checked');
|
||||||
var matching = $matching.val();
|
var matching = $matching.val();
|
||||||
var wordThreshold = $wordThreshold.val();
|
var wordsThreshold = $wordsThreshold.val();
|
||||||
var matchingMaxComparisons = $matchingMaxComparisons.val();
|
var matchingMaxComparisons = $matchingMaxComparisons.val();
|
||||||
|
|
||||||
fetch(req.url, {
|
fetch(req.url, {
|
||||||
|
|
@ -163,16 +182,34 @@ $(document).ready(function() {
|
||||||
$container.css({'width': ''});
|
$container.css({'width': ''});
|
||||||
}
|
}
|
||||||
|
|
||||||
diff2htmlUi.draw(container, {
|
var params = getParamsFromSearch(window.location.search);
|
||||||
outputFormat: outputFormat,
|
delete params[searchParam];
|
||||||
showFiles: showFiles,
|
|
||||||
matching: matching,
|
if (forced) {
|
||||||
matchWordsThreshold: wordThreshold,
|
params['outputFormat'] = outputFormat;
|
||||||
matchingMaxComparisons: matchingMaxComparisons,
|
params['showFiles'] = showFiles;
|
||||||
synchronisedScroll: true
|
params['matching'] = matching;
|
||||||
});
|
params['wordsThreshold'] = wordsThreshold;
|
||||||
diff2htmlUi.fileListCloseable(container, false);
|
params['matchingMaxComparisons'] = matchingMaxComparisons;
|
||||||
diff2htmlUi.highlightCode(container);
|
} else {
|
||||||
|
params['outputFormat'] = params['outputFormat'] || outputFormat;
|
||||||
|
params['showFiles'] = String(params['showFiles']) !== 'false' || (params['showFiles'] === null && showFiles);
|
||||||
|
params['matching'] = params['matching'] || matching;
|
||||||
|
params['wordsThreshold'] = params['wordsThreshold'] || wordsThreshold;
|
||||||
|
params['matchingMaxComparisons'] = params['matchingMaxComparisons'] || matchingMaxComparisons;
|
||||||
|
|
||||||
|
$outputFormat.val(params['outputFormat']);
|
||||||
|
$showFiles.prop('checked', params['showFiles']);
|
||||||
|
$matching.val(params['matching']);
|
||||||
|
$wordsThreshold.val(params['wordsThreshold']);
|
||||||
|
$matchingMaxComparisons.val(params['matchingMaxComparisons']);
|
||||||
|
}
|
||||||
|
|
||||||
|
params['synchronisedScroll'] = params['synchronisedScroll'] || true;
|
||||||
|
|
||||||
|
diff2htmlUi.draw(container, params);
|
||||||
|
diff2htmlUi.fileListCloseable(container, params['fileListCloseable'] || false);
|
||||||
|
params['highlight'] && diff2htmlUi.highlightCode(container);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,10 +218,14 @@ $(document).ready(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateUrl(url) {
|
function updateUrl(url) {
|
||||||
var currentUrl = getUrlFromSearch(window.location.search);
|
var params = getParamsFromSearch(window.location.search);
|
||||||
|
|
||||||
if (currentUrl === url) return;
|
if (params[searchParam] === url) return;
|
||||||
|
|
||||||
window.location = 'demo.html?' + searchParam + '=' + url;
|
params[searchParam] = url;
|
||||||
|
|
||||||
|
var paramString = Object.keys(params).map(function(k) { return k + '=' + params[k]; }).join('&');
|
||||||
|
|
||||||
|
window.location = 'demo.html?' + paramString;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue