diff2html
Advanced tools
Comparing version 1.2.0 to 1.3.0
{ | ||
"name": "diff2html", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"homepage": "http://rtfpessoa.github.io/diff2html/", | ||
@@ -39,17 +39,26 @@ "description": "Fast Diff to colorized HTML", | ||
"scripts": { | ||
"release": "bash release.sh" | ||
"release": "bash release.sh", | ||
"test": "mocha", | ||
"style": "jscs src test", | ||
"codacy": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage" | ||
}, | ||
"main": "./src/diff2html.js", | ||
"dependencies": { | ||
"diff": "2.2.*" | ||
"diff": "^2.2.1" | ||
}, | ||
"devDependencies": { | ||
"webpack": "1.12.*", | ||
"uglifyjs": "2.4.*", | ||
"less": "2.5.*" | ||
"codacy-coverage": "^1.1.3", | ||
"clean-css": "^3.4.9", | ||
"fast-html-parser": "^1.0.1", | ||
"istanbul": "^0.4.1", | ||
"jscs": "^2.9.0", | ||
"mocha": "^2.4.5", | ||
"uglifyjs": "^2.4.10", | ||
"webpack": "^1.12.13" | ||
}, | ||
"license": "MIT", | ||
"files": [ | ||
"src" | ||
"src", | ||
"css" | ||
] | ||
} |
108
README.md
@@ -1,5 +0,20 @@ | ||
# Diff to Html by [rtfpessoa](https://github.com/rtfpessoa) | ||
# diff2html | ||
Diff to Html generates pretty HTML diffs from git diff output. | ||
[![Circle CI](https://circleci.com/gh/rtfpessoa/diff2html.svg?style=svg)](https://circleci.com/gh/rtfpessoa/diff2html) | ||
[![Codacy Code Badge](https://api.codacy.com/project/badge/grade/06412dc3f5a14f568778d0db8a1f7dc8)](https://www.codacy.com/app/Codacy/diff2html) | ||
[![Codacy Coverage Badge](https://api.codacy.com/project/badge/coverage/06412dc3f5a14f568778d0db8a1f7dc8)](https://www.codacy.com/app/Codacy/diff2html) | ||
[![npm](https://img.shields.io/npm/v/diff2html.svg)](https://www.npmjs.com/package/diff2html) | ||
[![David](https://img.shields.io/david/rtfpessoa/diff2html.svg)](https://david-dm.org/rtfpessoa/diff2html) | ||
[![David](https://img.shields.io/david/dev/rtfpessoa/diff2html.svg)](https://david-dm.org/rtfpessoa/diff2html) | ||
[![node](https://img.shields.io/node/v/diff2html.svg)]() | ||
[![npm](https://img.shields.io/npm/l/diff2html.svg)]() | ||
[![npm](https://img.shields.io/npm/dm/diff2html.svg)](https://www.npmjs.com/package/diff2html) | ||
[![Gitter](https://badges.gitter.im/rtfpessoa/diff2html.svg)](https://gitter.im/rtfpessoa/diff2html?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) | ||
diff2html generates pretty HTML diffs from git diff output. | ||
[![NPM](https://nodei.co/npm/diff2html.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/diff2html/) | ||
## Features | ||
@@ -21,3 +36,3 @@ | ||
> Go to [Diff2HTML](http://rtfpessoa.github.io/diff2html/) | ||
> Go to [diff2html](http://rtfpessoa.github.io/diff2html/) | ||
@@ -57,3 +72,34 @@ ## Distributions | ||
## Diff2HtmlUI Helper | ||
> Simple wrapper to ease simple tasks in the browser such as: code highlight and js effects | ||
### How to use | ||
> Init | ||
```js | ||
var diff2htmlUi = new Diff2HtmlUI({diff: diffString}); | ||
// or | ||
var diff2htmlUi = new Diff2HtmlUI({json: diffJson}); | ||
``` | ||
> Draw | ||
```js | ||
diff2htmlUi.draw('html-target-elem', {inputFormat: 'json', showFiles: true, matching: 'lines'}); | ||
``` | ||
> Highlight Code | ||
```js | ||
diff2htmlUi.highlightCode('html-target-elem'); | ||
``` | ||
> Collapse File Summary List | ||
```js | ||
diff2htmlUi.fileListCloseable('html-target-elem', false); | ||
``` | ||
## Syntax Highlight | ||
@@ -67,38 +113,38 @@ | ||
<!-- Stylesheet --> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.6/styles/github.min.css"> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/styles/github.min.css"> | ||
<!-- Javascripts --> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.6/highlight.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.6/languages/scala.min.js"></script> | ||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/languages/scala.min.js"></script> | ||
<script type="text/javascript" src="dist/diff2html-ui.js"></script> | ||
``` | ||
> Invoke the highlightjs plugin | ||
> Invoke the Diff2HtmlUI helper | ||
```js | ||
document.addEventListener("DOMContentLoaded", function () { | ||
// parse the diff to json | ||
var diffJson = Diff2Html.getJsonFromDiff(lineDiffExample); | ||
$(document).ready(function() { | ||
var diff2htmlUi = new Diff2HtmlUI({diff: lineDiffExample}); | ||
diff2htmlUi.draw('#line-by-line', {inputFormat: 'json', showFiles: true, matching: 'lines'}); | ||
diff2htmlUi.highlightCode('#line-by-line'); | ||
}); | ||
``` | ||
// collect all the file extensions in the json | ||
var allFileLanguages = diffJson.map(function (line) { | ||
return line.language; | ||
}); | ||
## Collapsable File Summary List | ||
// remove duplicated languages | ||
var distinctLanguages = allFileLanguages.filter(function (v, i) { | ||
return allFileLanguages.indexOf(v) == i; | ||
}); | ||
> Add the dependencies. | ||
// pass the languages to the highlightjs plugin | ||
hljs.configure({languages: distinctLanguages}); | ||
```html | ||
<!-- Javascripts --> | ||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> | ||
<script type="text/javascript" src="dist/diff2html-ui.js"></script> | ||
``` | ||
// generate and inject the diff HTML into the desired place | ||
document.getElementById("line-by-line").innerHTML = Diff2Html.getPrettyHtml(diffJson, { inputFormat: 'json' }); | ||
document.getElementById("side-by-side").innerHTML = Diff2Html.getPrettyHtml(diffJson, { inputFormat: 'json', outputFormat: 'side-by-side' }); | ||
> Invoke the Diff2HtmlUI helper | ||
// collect all the code lines and execute the highlight on them | ||
var codeLines = document.getElementsByClassName("d2h-code-line-ctn"); | ||
[].forEach.call(codeLines, function (line) { | ||
hljs.highlightBlock(line); | ||
}); | ||
```js | ||
$(document).ready(function() { | ||
var diff2htmlUi = new Diff2HtmlUI({diff: lineDiffExample}); | ||
diff2htmlUi.draw('#line-by-line', {inputFormat: 'json', showFiles: true, matching: 'lines'}); | ||
diff2htmlUi.fileListCloseable('#line-by-line', false); | ||
}); | ||
@@ -109,6 +155,6 @@ ``` | ||
All the contributions are welcome. | ||
This is a developer friendly project, all the contributions are welcome. | ||
To contribute just send a pull request with your changes following the guidelines described in `CONTRIBUTING.md`. | ||
I will try to review them as soon as possible. | ||
To contribute just send a pull request with your changes and I will review it asap. | ||
## License | ||
@@ -115,0 +161,0 @@ |
@@ -8,3 +8,3 @@ /* | ||
(function(ctx, undefined) { | ||
(function() { | ||
@@ -35,2 +35,3 @@ var utils = require('./utils.js').Utils; | ||
var saveBlock = function() { | ||
/* Add previous block(if exists) before start a new file */ | ||
@@ -44,2 +45,3 @@ if (currentBlock) { | ||
var saveFile = function() { | ||
/* | ||
@@ -126,3 +128,6 @@ * Add previous file(if exists) before start a new one | ||
var diffLines = diffInput.split('\n'); | ||
var diffLines = | ||
diffInput.replace(/\\ No newline at end of file/g, '') | ||
.replace(/\r\n?/g, '\n') | ||
.split('\n'); | ||
@@ -223,9 +228,9 @@ /* Diff */ | ||
return nameSplit[nameSplit.length - 1]; | ||
} else { | ||
return language; | ||
} | ||
return language; | ||
} | ||
module.exports['DiffParser'] = new DiffParser(); | ||
module.exports.DiffParser = new DiffParser(); | ||
})(this); | ||
})(); |
@@ -8,3 +8,3 @@ /* | ||
(function(ctx, undefined) { | ||
(function() { | ||
@@ -21,5 +21,5 @@ var diffParser = require('./diff-parser.js').DiffParser; | ||
var config = { | ||
"wordByWord": true, // (default) | ||
'wordByWord': true, // (default) | ||
// OR | ||
"charByChar": true | ||
'charByChar': true | ||
}; | ||
@@ -42,13 +42,13 @@ */ | ||
var diffJson = diffInput; | ||
if(!configOrEmpty.inputFormat || configOrEmpty.inputFormat === 'diff') { | ||
if (!configOrEmpty.inputFormat || configOrEmpty.inputFormat === 'diff') { | ||
diffJson = diffParser.generateDiffJson(diffInput); | ||
} | ||
var fileList = ""; | ||
if(configOrEmpty.showFiles === true) { | ||
var fileList = ''; | ||
if (configOrEmpty.showFiles === true) { | ||
fileList = fileLister.generateFileList(diffJson, configOrEmpty); | ||
} | ||
var diffOutput = ""; | ||
if(configOrEmpty.outputFormat === 'side-by-side') { | ||
var diffOutput = ''; | ||
if (configOrEmpty.outputFormat === 'side-by-side') { | ||
diffOutput = htmlPrinter.generateSideBySideJsonHtml(diffJson, configOrEmpty); | ||
@@ -59,3 +59,3 @@ } else { | ||
return fileList + diffOutput | ||
return fileList + diffOutput; | ||
}; | ||
@@ -73,5 +73,5 @@ | ||
var configOrEmpty = config || {}; | ||
configOrEmpty['inputFormat'] = 'diff'; | ||
configOrEmpty['outputFormat'] = 'line-by-line'; | ||
return this.getPrettyHtml(diffInput, configOrEmpty) | ||
configOrEmpty.inputFormat = 'diff'; | ||
configOrEmpty.outputFormat = 'line-by-line'; | ||
return this.getPrettyHtml(diffInput, configOrEmpty); | ||
}; | ||
@@ -84,5 +84,5 @@ | ||
var configOrEmpty = config || {}; | ||
configOrEmpty['inputFormat'] = 'json'; | ||
configOrEmpty['outputFormat'] = 'line-by-line'; | ||
return this.getPrettyHtml(diffJson, configOrEmpty) | ||
configOrEmpty.inputFormat = 'json'; | ||
configOrEmpty.outputFormat = 'line-by-line'; | ||
return this.getPrettyHtml(diffJson, configOrEmpty); | ||
}; | ||
@@ -95,5 +95,5 @@ | ||
var configOrEmpty = config || {}; | ||
configOrEmpty['inputFormat'] = 'diff'; | ||
configOrEmpty['outputFormat'] = 'side-by-side'; | ||
return this.getPrettyHtml(diffInput, configOrEmpty) | ||
configOrEmpty.inputFormat = 'diff'; | ||
configOrEmpty.outputFormat = 'side-by-side'; | ||
return this.getPrettyHtml(diffInput, configOrEmpty); | ||
}; | ||
@@ -106,13 +106,13 @@ | ||
var configOrEmpty = config || {}; | ||
configOrEmpty['inputFormat'] = 'json'; | ||
configOrEmpty['outputFormat'] = 'side-by-side'; | ||
return this.getPrettyHtml(diffJson, configOrEmpty) | ||
configOrEmpty.inputFormat = 'json'; | ||
configOrEmpty.outputFormat = 'side-by-side'; | ||
return this.getPrettyHtml(diffJson, configOrEmpty); | ||
}; | ||
var diffName = 'Diff2Html'; | ||
var diffObject = new Diff2Html(); | ||
module.exports[diffName] = diffObject; | ||
module.exports.Diff2Html = diffObject; | ||
// Expose diff2html in the browser | ||
global[diffName] = diffObject; | ||
global.Diff2Html = diffObject; | ||
})(this); | ||
})(); |
@@ -8,37 +8,35 @@ /* | ||
(function (ctx, undefined) { | ||
(function() { | ||
var printerUtils = require('./printer-utils.js').PrinterUtils; | ||
var utils = require('./utils.js').Utils; | ||
var printerUtils = require('./printer-utils.js').PrinterUtils; | ||
function FileListPrinter() { | ||
} | ||
function FileListPrinter() { | ||
} | ||
FileListPrinter.prototype.generateFileList = function (diffFiles) { | ||
var hideId = utils.getRandomId("d2h-hide"); //necessary if there are 2 elements like this in the same page | ||
var showId = utils.getRandomId("d2h-show"); | ||
return '<div class="d2h-file-list-wrapper">\n' + | ||
' <div class="d2h-file-list-header">Files changed (' + diffFiles.length + ')  </div>\n' + | ||
' <a id="' + hideId + '" class="d2h-hide" href="#' + hideId + '">+</a>\n' + | ||
' <a id="' + showId + 'd2h-show" class="d2h-show" href="#' + showId + '">-</a>\n' + | ||
' <div class="d2h-clear"></div>\n' + | ||
' <table class="d2h-file-list">\n' + | ||
FileListPrinter.prototype.generateFileList = function(diffFiles) { | ||
return '<div class="d2h-file-list-wrapper">\n' + | ||
' <div class="d2h-file-list-header">Files changed (' + diffFiles.length + ')  </div>\n' + | ||
' <a class="d2h-file-switch d2h-hide">hide</a>\n' + | ||
' <a class="d2h-file-switch d2h-show">show</a>\n' + | ||
' <div class="d2h-clear"></div>\n' + | ||
' <table class="d2h-file-list">\n' + | ||
diffFiles.map(function (file) { | ||
return ' <tr class="d2h-file-list-line">\n' + | ||
' <td class="d2h-lines-added">\n' + | ||
' <span>+' + file.addedLines + '</span>\n' + | ||
' </td>\n' + | ||
' <td class="d2h-lines-deleted">\n' + | ||
' <span>-' + file.deletedLines + '</span>\n' + | ||
' </td>\n' + | ||
' <td class="d2h-file-name"><a href="#' + printerUtils.getHtmlId(file) + '"> ' + printerUtils.getDiffName(file) + '</a></td>\n' + | ||
' </tr>\n' | ||
}).join('\n') + | ||
'</table></div>\n'; | ||
}; | ||
diffFiles.map(function(file) { | ||
return ' <tr class="d2h-file-list-line">\n' + | ||
' <td class="d2h-lines-added">\n' + | ||
' <span>+' + file.addedLines + '</span>\n' + | ||
' </td>\n' + | ||
' <td class="d2h-lines-deleted">\n' + | ||
' <span>-' + file.deletedLines + '</span>\n' + | ||
' </td>\n' + | ||
' <td class="d2h-file-name"><a href="#' + printerUtils.getHtmlId(file) + '">' + | ||
' ' + printerUtils.getDiffName(file) + '</a></td>\n' + | ||
' </tr>\n'; | ||
}).join('\n') + | ||
'</table></div>\n'; | ||
}; | ||
module.exports['FileListPrinter'] = new FileListPrinter(); | ||
module.exports.FileListPrinter = new FileListPrinter(); | ||
})(this); | ||
})(); |
@@ -8,6 +8,6 @@ /* | ||
(function(ctx, undefined) { | ||
(function() { | ||
var lineByLinePrinter = require('./line-by-line-printer.js').LineByLinePrinter; | ||
var sideBySidePrinter = require('./side-by-side-printer.js').SideBySidePrinter; | ||
var LineByLinePrinter = require('./line-by-line-printer.js').LineByLinePrinter; | ||
var SideBySidePrinter = require('./side-by-side-printer.js').SideBySidePrinter; | ||
@@ -17,8 +17,14 @@ function HtmlPrinter() { | ||
HtmlPrinter.prototype.generateLineByLineJsonHtml = lineByLinePrinter.generateLineByLineJsonHtml; | ||
HtmlPrinter.prototype.generateLineByLineJsonHtml = function(diffFiles, config) { | ||
var lineByLinePrinter = new LineByLinePrinter(config); | ||
return lineByLinePrinter.generateLineByLineJsonHtml(diffFiles); | ||
}; | ||
HtmlPrinter.prototype.generateSideBySideJsonHtml = sideBySidePrinter.generateSideBySideJsonHtml; | ||
HtmlPrinter.prototype.generateSideBySideJsonHtml = function(diffFiles, config) { | ||
var sideBySidePrinter = new SideBySidePrinter(config); | ||
return sideBySidePrinter.generateSideBySideJsonHtml(diffFiles); | ||
}; | ||
module.exports['HtmlPrinter'] = new HtmlPrinter(); | ||
module.exports.HtmlPrinter = new HtmlPrinter(); | ||
})(this); | ||
})(); |
@@ -8,3 +8,3 @@ /* | ||
(function(ctx, undefined) { | ||
(function() { | ||
@@ -16,52 +16,55 @@ var diffParser = require('./diff-parser.js').DiffParser; | ||
function LineByLinePrinter() { | ||
function LineByLinePrinter(config) { | ||
this.config = config; | ||
} | ||
LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles, config) { | ||
return '<div class="d2h-wrapper">\n' + | ||
diffFiles.map(function(file) { | ||
LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) { | ||
return '<div id="' + printerUtils.getHtmlId(file) + '" class="d2h-file-wrapper" data-lang="' + file.language + '">\n' + | ||
' <div class="d2h-file-header">\n' + | ||
' <div class="d2h-file-stats">\n' + | ||
' <span class="d2h-lines-added">' + | ||
' <span>+' + file.addedLines + '</span>\n' + | ||
' </span>\n' + | ||
' <span class="d2h-lines-deleted">' + | ||
' <span>-' + file.deletedLines + '</span>\n' + | ||
' </span>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-file-name">' + printerUtils.getDiffName(file) + '</div>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-file-diff">\n' + | ||
' <div class="d2h-code-wrapper">\n' + | ||
' <table class="d2h-diff-table">\n' + | ||
' <tbody class="d2h-diff-tbody">\n' + | ||
' ' + diffs + | ||
' </tbody>\n' + | ||
' </table>\n' + | ||
' </div>\n' + | ||
' </div>\n' + | ||
' </div>\n'; | ||
}; | ||
LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles) { | ||
var that = this; | ||
var htmlDiffs = diffFiles.map(function(file) { | ||
var diffs; | ||
if (file.blocks.length) { | ||
diffs = generateFileHtml(file, config); | ||
diffs = that._generateFileHtml(file); | ||
} else { | ||
diffs = generateEmptyDiff(); | ||
diffs = that._generateEmptyDiff(); | ||
} | ||
return that.makeFileDiffHtml(file, diffs); | ||
}); | ||
return '<div id="' + printerUtils.getHtmlId(file) + '" class="d2h-file-wrapper" data-lang="' + file.language + '">\n' + | ||
' <div class="d2h-file-header">\n' + | ||
' <div class="d2h-file-stats">\n' + | ||
' <span class="d2h-lines-added">' + | ||
' <span>+' + file.addedLines + '</span>\n' + | ||
' </span>\n' + | ||
' <span class="d2h-lines-deleted">' + | ||
' <span>-' + file.deletedLines + '</span>\n' + | ||
' </span>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-file-name">' + printerUtils.getDiffName(file) + '</div>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-file-diff">\n' + | ||
' <div class="d2h-code-wrapper">\n' + | ||
' <table class="d2h-diff-table">\n' + | ||
' <tbody class="d2h-diff-tbody">\n' + | ||
' ' + diffs + | ||
' </tbody>\n' + | ||
' </table>\n' + | ||
' </div>\n' + | ||
' </div>\n' + | ||
' </div>\n'; | ||
}).join('\n') + | ||
'</div>\n'; | ||
return '<div class="d2h-wrapper">\n' + htmlDiffs.join('\n') + '</div>\n'; | ||
}; | ||
var matcher=Rematch.rematch(function(a,b) { | ||
var amod = a.content.substr(1), | ||
bmod = b.content.substr(1); | ||
var matcher = Rematch.rematch(function(a, b) { | ||
var amod = a.content.substr(1); | ||
var bmod = b.content.substr(1); | ||
return Rematch.distance(amod, bmod); | ||
}); | ||
function generateFileHtml(file, config) { | ||
return file.blocks.map(function(block) { | ||
var lines = '<tr>\n' + | ||
LineByLinePrinter.prototype.makeColumnLineNumberHtml = function(block) { | ||
return '<tr>\n' + | ||
' <td class="d2h-code-linenumber ' + diffParser.LINE_TYPE.INFO + '"></td>\n' + | ||
@@ -72,5 +75,12 @@ ' <td class="' + diffParser.LINE_TYPE.INFO + '">' + | ||
'</tr>\n'; | ||
}; | ||
LineByLinePrinter.prototype._generateFileHtml = function(file) { | ||
var that = this; | ||
return file.blocks.map(function(block) { | ||
var lines = that.makeColumnLineNumberHtml(block); | ||
var oldLines = []; | ||
var newLines = []; | ||
function processChangeBlock() { | ||
@@ -80,3 +90,5 @@ var matches; | ||
var deleteType; | ||
var doMatching = config.matching === "lines" || config.matching === "words"; | ||
var doMatching = that.config.matching === 'lines' || that.config.matching === 'words'; | ||
if (doMatching) { | ||
@@ -87,36 +99,36 @@ matches = matcher(oldLines, newLines); | ||
} else { | ||
matches = [[oldLines,newLines]]; | ||
matches = [[oldLines, newLines]]; | ||
insertType = diffParser.LINE_TYPE.INSERTS; | ||
deleteType = diffParser.LINE_TYPE.DELETES; | ||
} | ||
matches.forEach(function(match){ | ||
var oldLines = match[0]; | ||
var newLines = match[1]; | ||
matches.forEach(function(match) { | ||
oldLines = match[0]; | ||
newLines = match[1]; | ||
var processedOldLines = []; | ||
var processedNewLines = []; | ||
var j = 0; | ||
var oldLine, newLine, | ||
common = Math.min(oldLines.length, newLines.length), | ||
max = Math.max(oldLines.length, newLines.length); | ||
for (j = 0; j < common; j++) { | ||
oldLine = oldLines[j]; | ||
newLine = newLines[j]; | ||
config.isCombined = file.isCombined; | ||
var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, config); | ||
var common = Math.min(oldLines.length, newLines.length); | ||
processedOldLines += | ||
generateLineHtml(deleteType, oldLine.oldNumber, oldLine.newNumber, | ||
diff.first.line, diff.first.prefix); | ||
processedNewLines += | ||
generateLineHtml(insertType, newLine.oldNumber, newLine.newNumber, | ||
diff.second.line, diff.second.prefix); | ||
} | ||
var oldLine, newLine; | ||
for (var j = 0; j < common; j++) { | ||
oldLine = oldLines[j]; | ||
newLine = newLines[j]; | ||
lines += processedOldLines + processedNewLines; | ||
lines += processLines(oldLines.slice(common), newLines.slice(common)); | ||
that.config.isCombined = file.isCombined; | ||
var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); | ||
processedOldLines = []; | ||
processedNewLines = []; | ||
processedOldLines += | ||
that._generateLineHtml(deleteType, oldLine.oldNumber, oldLine.newNumber, | ||
diff.first.line, diff.first.prefix); | ||
processedNewLines += | ||
that._generateLineHtml(insertType, newLine.oldNumber, newLine.newNumber, | ||
diff.second.line, diff.second.prefix); | ||
} | ||
lines += processedOldLines + processedNewLines; | ||
lines += that._processLines(oldLines.slice(common), newLines.slice(common)); | ||
}); | ||
oldLines = []; | ||
@@ -130,16 +142,17 @@ newLines = []; | ||
if ( line.type !== diffParser.LINE_TYPE.INSERTS && | ||
(newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) { | ||
if (line.type !== diffParser.LINE_TYPE.INSERTS && | ||
(newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) { | ||
processChangeBlock(); | ||
} | ||
if (line.type == diffParser.LINE_TYPE.CONTEXT) { | ||
lines += generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine); | ||
} else if (line.type == diffParser.LINE_TYPE.INSERTS && !oldLines.length) { | ||
lines += generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine); | ||
} else if (line.type == diffParser.LINE_TYPE.DELETES) { | ||
if (line.type === diffParser.LINE_TYPE.CONTEXT) { | ||
lines += that._generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine); | ||
} else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) { | ||
lines += that._generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine); | ||
} else if (line.type === diffParser.LINE_TYPE.DELETES) { | ||
oldLines.push(line); | ||
} else if (line.type == diffParser.LINE_TYPE.INSERTS && !!oldLines.length) { | ||
} else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) { | ||
newLines.push(line); | ||
} else { | ||
console.error('unknown state in html line-by-line generator'); | ||
console.error('Unknown state in html line-by-line generator'); | ||
processChangeBlock(); | ||
@@ -153,23 +166,35 @@ } | ||
}).join('\n'); | ||
} | ||
}; | ||
function processLines(oldLines, newLines) { | ||
LineByLinePrinter.prototype._processLines = function(oldLines, newLines) { | ||
var lines = ''; | ||
for (j = 0; j < oldLines.length; j++) { | ||
var oldLine = oldLines[j]; | ||
for (var i = 0; i < oldLines.length; i++) { | ||
var oldLine = oldLines[i]; | ||
var oldEscapedLine = utils.escape(oldLine.content); | ||
lines += generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine); | ||
lines += this._generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine); | ||
} | ||
for (j = 0; j < newLines.length; j++) { | ||
for (var j = 0; j < newLines.length; j++) { | ||
var newLine = newLines[j]; | ||
var newEscapedLine = utils.escape(newLine.content); | ||
lines += generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine); | ||
lines += this._generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine); | ||
} | ||
return lines; | ||
} | ||
}; | ||
function generateLineHtml(type, oldNumber, newNumber, content, prefix) { | ||
LineByLinePrinter.prototype.makeLineHtml = function(type, oldNumber, newNumber, htmlPrefix, htmlContent) { | ||
return '<tr>\n' + | ||
' <td class="d2h-code-linenumber ' + type + '">' + | ||
' <div class="line-num1">' + utils.valueOrEmpty(oldNumber) + '</div>' + | ||
' <div class="line-num2">' + utils.valueOrEmpty(newNumber) + '</div>' + | ||
' </td>\n' + | ||
' <td class="' + type + '">' + | ||
' <div class="d2h-code-line ' + type + '">' + htmlPrefix + htmlContent + '</div>' + | ||
' </td>\n' + | ||
'</tr>\n'; | ||
}; | ||
LineByLinePrinter.prototype._generateLineHtml = function(type, oldNumber, newNumber, content, prefix) { | ||
var htmlPrefix = ''; | ||
@@ -185,14 +210,6 @@ if (prefix) { | ||
return '<tr>\n' + | ||
' <td class="d2h-code-linenumber ' + type + '">' + | ||
' <div class="line-num1">' + utils.valueOrEmpty(oldNumber) + '</div>' + | ||
' <div class="line-num2">' + utils.valueOrEmpty(newNumber) + '</div>' + | ||
' </td>\n' + | ||
' <td class="' + type + '">' + | ||
' <div class="d2h-code-line ' + type + '">' + htmlPrefix + htmlContent + '</div>' + | ||
' </td>\n' + | ||
'</tr>\n'; | ||
} | ||
return this.makeLineHtml(type, oldNumber, newNumber, htmlPrefix, htmlContent); | ||
}; | ||
function generateEmptyDiff() { | ||
LineByLinePrinter.prototype._generateEmptyDiff = function() { | ||
return '<tr>\n' + | ||
@@ -205,6 +222,6 @@ ' <td class="' + diffParser.LINE_TYPE.INFO + '">' + | ||
'</tr>\n'; | ||
} | ||
}; | ||
module.exports['LineByLinePrinter'] = new LineByLinePrinter(); | ||
module.exports.LineByLinePrinter = LineByLinePrinter; | ||
})(this); | ||
})(); |
@@ -8,3 +8,3 @@ /* | ||
(function(ctx, undefined) { | ||
(function() { | ||
@@ -19,14 +19,20 @@ var jsDiff = require('diff'); | ||
PrinterUtils.prototype.getHtmlId = function(file) { | ||
var hashCode = function(text) { | ||
var hash = 0, i, chr, len; | ||
if (text.length == 0) return hash; | ||
var hashCode = function(text) { | ||
var i, chr, len; | ||
var hash = 0; | ||
if (text.length === 0) { | ||
return hash; | ||
} | ||
for (i = 0, len = text.length; i < len; i++) { | ||
chr = text.charCodeAt(i); | ||
hash = ((hash << 5) - hash) + chr; | ||
chr = text.charCodeAt(i); | ||
hash = ((hash << 5) - hash) + chr; | ||
hash |= 0; // Convert to 32bit integer | ||
} | ||
return hash; | ||
}; | ||
return "d2h-" + hashCode(this.getDiffName(file)).toString().slice(-6); | ||
return 'd2h-' + hashCode(this.getDiffName(file)).toString().slice(-6); | ||
}; | ||
@@ -38,5 +44,3 @@ | ||
if (oldFilename && newFilename | ||
&& oldFilename !== newFilename | ||
&& !isDeletedName(newFilename)) { | ||
if (oldFilename && newFilename && oldFilename !== newFilename && !isDeletedName(newFilename)) { | ||
return oldFilename + ' -> ' + newFilename; | ||
@@ -47,9 +51,9 @@ } else if (newFilename && !isDeletedName(newFilename)) { | ||
return oldFilename; | ||
} else { | ||
return 'Unknown filename'; | ||
} | ||
return 'Unknown filename'; | ||
}; | ||
PrinterUtils.prototype.diffHighlight = function(diffLine1, diffLine2, config) { | ||
var lineStart1, lineStart2; | ||
var linePrefix1, linePrefix2, unprefixedLine1, unprefixedLine2; | ||
@@ -62,13 +66,12 @@ var prefixSize = 1; | ||
lineStart1 = diffLine1.substr(0, prefixSize); | ||
lineStart2 = diffLine2.substr(0, prefixSize); | ||
linePrefix1 = diffLine1.substr(0, prefixSize); | ||
linePrefix2 = diffLine2.substr(0, prefixSize); | ||
unprefixedLine1 = diffLine1.substr(prefixSize); | ||
unprefixedLine2 = diffLine2.substr(prefixSize); | ||
diffLine1 = diffLine1.substr(prefixSize); | ||
diffLine2 = diffLine2.substr(prefixSize); | ||
var diff; | ||
if (config.charByChar) { | ||
diff = jsDiff.diffChars(diffLine1, diffLine2); | ||
diff = jsDiff.diffChars(unprefixedLine1, unprefixedLine2); | ||
} else { | ||
diff = jsDiff.diffWordsWithSpace(diffLine1, diffLine2); | ||
diff = jsDiff.diffWordsWithSpace(unprefixedLine1, unprefixedLine2); | ||
} | ||
@@ -81,21 +84,26 @@ | ||
var treshold = 0.25; | ||
if (typeof(config.matchWordsThreshold) !== "undefined") { | ||
if (typeof (config.matchWordsThreshold) !== 'undefined') { | ||
treshold = config.matchWordsThreshold; | ||
} | ||
var matcher = Rematch.rematch(function(a, b) { | ||
var amod = a.value, | ||
bmod = b.value, | ||
result = Rematch.distance(amod, bmod); | ||
return result; | ||
var amod = a.value; | ||
var bmod = b.value; | ||
return Rematch.distance(amod, bmod); | ||
}); | ||
var removed = diff.filter(function isRemoved(element){ | ||
var removed = diff.filter(function isRemoved(element) { | ||
return element.removed; | ||
}); | ||
var added = diff.filter(function isAdded(element){ | ||
var added = diff.filter(function isAdded(element) { | ||
return element.added; | ||
}); | ||
var chunks = matcher(added, removed); | ||
chunks = chunks.forEach(function(chunk){ | ||
if(chunk[0].length === 1 && chunk[1].length === 1) { | ||
var dist = Rematch.distance(chunk[0][0].value, chunk[1][0].value) | ||
chunks.forEach(function(chunk) { | ||
if (chunk[0].length === 1 && chunk[1].length === 1) { | ||
var dist = Rematch.distance(chunk[0][0].value, chunk[1][0].value); | ||
if (dist < treshold) { | ||
@@ -108,2 +116,3 @@ changedWords.push(chunk[0][0]); | ||
} | ||
diff.forEach(function(part) { | ||
@@ -123,10 +132,10 @@ var addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : ''; | ||
first: { | ||
prefix: lineStart1, | ||
prefix: linePrefix1, | ||
line: removeIns(highlightedLine) | ||
}, | ||
second: { | ||
prefix: lineStart2, | ||
prefix: linePrefix2, | ||
line: removeDel(highlightedLine) | ||
} | ||
} | ||
}; | ||
}; | ||
@@ -146,4 +155,4 @@ | ||
module.exports['PrinterUtils'] = new PrinterUtils(); | ||
module.exports.PrinterUtils = new PrinterUtils(); | ||
})(this); | ||
})(); |
@@ -9,6 +9,7 @@ /* | ||
(function(ctx, undefined) { | ||
(function() { | ||
var Rematch = {}; | ||
Rematch.arrayToString = function arrayToString(a) { | ||
if (Object.prototype.toString.apply(a,[]) === "[object Array]") { | ||
if (Object.prototype.toString.apply(a, []) === "[object Array]") { | ||
return "[" + a.map(arrayToString).join(", ") + "]"; | ||
@@ -18,25 +19,35 @@ } else { | ||
} | ||
} | ||
}; | ||
/* | ||
Copyright (c) 2011 Andrei Mackenzie | ||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
function levenshtein(a, b){ | ||
if(a.length == 0) return b.length; | ||
if(b.length == 0) return a.length; | ||
Copyright (c) 2011 Andrei Mackenzie | ||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated | ||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation | ||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO | ||
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
function levenshtein(a, b) { | ||
if (a.length == 0) { | ||
return b.length; | ||
} | ||
if (b.length == 0) { | ||
return a.length; | ||
} | ||
var matrix = []; | ||
// increment along the first column of each row | ||
// Increment along the first column of each row | ||
var i; | ||
for(i = 0; i <= b.length; i++){ | ||
for (i = 0; i <= b.length; i++) { | ||
matrix[i] = [i]; | ||
} | ||
// increment each column in the first row | ||
// Increment each column in the first row | ||
var j; | ||
for(j = 0; j <= a.length; j++){ | ||
for (j = 0; j <= a.length; j++) { | ||
matrix[0][j] = j; | ||
@@ -46,33 +57,36 @@ } | ||
// Fill in the rest of the matrix | ||
for(i = 1; i <= b.length; i++){ | ||
for(j = 1; j <= a.length; j++){ | ||
if(b.charAt(i-1) == a.charAt(j-1)){ | ||
matrix[i][j] = matrix[i-1][j-1]; | ||
for (i = 1; i <= b.length; i++) { | ||
for (j = 1; j <= a.length; j++) { | ||
if (b.charAt(i - 1) == a.charAt(j - 1)) { | ||
matrix[i][j] = matrix[i - 1][j - 1]; | ||
} else { | ||
matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution | ||
Math.min(matrix[i][j-1] + 1, // insertion | ||
matrix[i-1][j] + 1)); // deletion | ||
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // Substitution | ||
Math.min(matrix[i][j - 1] + 1, // Insertion | ||
matrix[i - 1][j] + 1)); // Deletion | ||
} | ||
} | ||
} | ||
return matrix[b.length][a.length]; | ||
} | ||
Rematch.levenshtein = levenshtein; | ||
Rematch.distance = function distance(x,y) { | ||
x=x.trim(); | ||
y=y.trim(); | ||
var lev = levenshtein(x,y), | ||
score = lev / (x.length + y.length); | ||
Rematch.distance = function distance(x, y) { | ||
x = x.trim(); | ||
y = y.trim(); | ||
var lev = levenshtein(x, y); | ||
var score = lev / (x.length + y.length); | ||
return score; | ||
} | ||
}; | ||
Rematch.rematch = function rematch(distanceFunction) { | ||
function findBestMatch(a, b, cache) { | ||
var cachecount = 0; | ||
for(var key in cache) { | ||
for (var key in cache) { | ||
cachecount++; | ||
} | ||
var bestMatchDist = Infinity; | ||
@@ -92,47 +106,55 @@ var bestMatch; | ||
bestMatchDist = md; | ||
bestMatch = { indexA: i, indexB: j, score: bestMatchDist }; | ||
bestMatch = {indexA: i, indexB: j, score: bestMatchDist}; | ||
} | ||
} | ||
} | ||
return bestMatch; | ||
} | ||
function group(a, b, level, cache) { | ||
if (typeof(cache)==="undefined") { | ||
if (typeof (cache) === "undefined") { | ||
cache = {}; | ||
} | ||
var minLength = Math.min(a.length, b.length); | ||
var bm = findBestMatch(a,b, cache); | ||
var bm = findBestMatch(a, b, cache); | ||
if (!level) { | ||
level = 0; | ||
} | ||
if (!bm || (a.length + b.length < 3)) { | ||
return [[a, b]]; | ||
} | ||
var a1 = a.slice(0, bm.indexA), | ||
b1 = b.slice(0, bm.indexB), | ||
aMatch = [a[bm.indexA]], | ||
bMatch = [b[bm.indexB]], | ||
tailA = bm.indexA + 1, | ||
tailB = bm.indexB + 1, | ||
a2 = a.slice(tailA), | ||
b2 = b.slice(tailB); | ||
var group1 = group(a1, b1, level+1, cache); | ||
var groupMatch = group(aMatch, bMatch, level+1, cache); | ||
var group2 = group(a2, b2, level+1, cache); | ||
var a1 = a.slice(0, bm.indexA); | ||
var b1 = b.slice(0, bm.indexB); | ||
var aMatch = [a[bm.indexA]]; | ||
var bMatch = [b[bm.indexB]]; | ||
var tailA = bm.indexA + 1; | ||
var tailB = bm.indexB + 1; | ||
var a2 = a.slice(tailA); | ||
var b2 = b.slice(tailB); | ||
var group1 = group(a1, b1, level + 1, cache); | ||
var groupMatch = group(aMatch, bMatch, level + 1, cache); | ||
var group2 = group(a2, b2, level + 1, cache); | ||
var result = groupMatch; | ||
if (bm.indexA > 0 || bm.indexB > 0) { | ||
result = group1.concat(result); | ||
} | ||
if (a.length > tailA || b.length > tailB ) { | ||
if (a.length > tailA || b.length > tailB) { | ||
result = result.concat(group2); | ||
} | ||
return result; | ||
} | ||
return group; | ||
} | ||
}; | ||
module.exports['Rematch'] = Rematch; | ||
module.exports.Rematch = Rematch; | ||
})(this); | ||
})(); |
@@ -8,3 +8,3 @@ /* | ||
(function(ctx, undefined) { | ||
(function() { | ||
@@ -16,6 +16,51 @@ var diffParser = require('./diff-parser.js').DiffParser; | ||
function SideBySidePrinter() { | ||
var matcher = Rematch.rematch(function(a, b) { | ||
var amod = a.content.substr(1); | ||
var bmod = b.content.substr(1); | ||
return Rematch.distance(amod, bmod); | ||
}); | ||
function SideBySidePrinter(config) { | ||
this.config = config; | ||
} | ||
SideBySidePrinter.prototype.generateSideBySideJsonHtml = function(diffFiles, config) { | ||
SideBySidePrinter.prototype.makeDiffHtml = function(file, diffs) { | ||
return '<div id="' + printerUtils.getHtmlId(file) + '" class="d2h-file-wrapper" data-lang="' + file.language + '">\n' + | ||
' <div class="d2h-file-header">\n' + | ||
' <div class="d2h-file-stats">\n' + | ||
' <span class="d2h-lines-added">' + | ||
' <span>+' + file.addedLines + '</span>\n' + | ||
' </span>\n' + | ||
' <span class="d2h-lines-deleted">' + | ||
' <span>-' + file.deletedLines + '</span>\n' + | ||
' </span>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-file-name">' + printerUtils.getDiffName(file) + '</div>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-files-diff">\n' + | ||
' <div class="d2h-file-side-diff">\n' + | ||
' <div class="d2h-code-wrapper">\n' + | ||
' <table class="d2h-diff-table">\n' + | ||
' <tbody class="d2h-diff-tbody">\n' + | ||
' ' + diffs.left + | ||
' </tbody>\n' + | ||
' </table>\n' + | ||
' </div>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-file-side-diff">\n' + | ||
' <div class="d2h-code-wrapper">\n' + | ||
' <table class="d2h-diff-table">\n' + | ||
' <tbody class="d2h-diff-tbody">\n' + | ||
' ' + diffs.right + | ||
' </tbody>\n' + | ||
' </table>\n' + | ||
' </div>\n' + | ||
' </div>\n' + | ||
' </div>\n' + | ||
' </div>\n'; | ||
}; | ||
SideBySidePrinter.prototype.generateSideBySideJsonHtml = function(diffFiles) { | ||
var that = this; | ||
return '<div class="d2h-wrapper">\n' + | ||
@@ -26,40 +71,8 @@ diffFiles.map(function(file) { | ||
if (file.blocks.length) { | ||
diffs = generateSideBySideFileHtml(file, config); | ||
diffs = that.generateSideBySideFileHtml(file); | ||
} else { | ||
diffs = generateEmptyDiff(); | ||
diffs = that.generateEmptyDiff(); | ||
} | ||
return '<div id="' + printerUtils.getHtmlId(file) + '" class="d2h-file-wrapper" data-lang="' + file.language + '">\n' + | ||
' <div class="d2h-file-header">\n' + | ||
' <div class="d2h-file-stats">\n' + | ||
' <span class="d2h-lines-added">' + | ||
' <span>+' + file.addedLines + '</span>\n' + | ||
' </span>\n' + | ||
' <span class="d2h-lines-deleted">' + | ||
' <span>-' + file.deletedLines + '</span>\n' + | ||
' </span>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-file-name">' + printerUtils.getDiffName(file) + '</div>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-files-diff">\n' + | ||
' <div class="d2h-file-side-diff">\n' + | ||
' <div class="d2h-code-wrapper">\n' + | ||
' <table class="d2h-diff-table">\n' + | ||
' <tbody class="d2h-diff-tbody">\n' + | ||
' ' + diffs.left + | ||
' </tbody>\n' + | ||
' </table>\n' + | ||
' </div>\n' + | ||
' </div>\n' + | ||
' <div class="d2h-file-side-diff">\n' + | ||
' <div class="d2h-code-wrapper">\n' + | ||
' <table class="d2h-diff-table">\n' + | ||
' <tbody class="d2h-diff-tbody">\n' + | ||
' ' + diffs.right + | ||
' </tbody>\n' + | ||
' </table>\n' + | ||
' </div>\n' + | ||
' </div>\n' + | ||
' </div>\n' + | ||
' </div>\n'; | ||
return that.makeDiffHtml(file, diffs); | ||
}).join('\n') + | ||
@@ -69,9 +82,13 @@ '</div>\n'; | ||
var matcher=Rematch.rematch(function(a,b) { | ||
var amod = a.content.substr(1), | ||
bmod = b.content.substr(1); | ||
return Rematch.distance(amod, bmod); | ||
}); | ||
SideBySidePrinter.prototype.makeSideHtml = function(blockHeader) { | ||
return '<tr>\n' + | ||
' <td class="d2h-code-side-linenumber ' + diffParser.LINE_TYPE.INFO + '"></td>\n' + | ||
' <td class="' + diffParser.LINE_TYPE.INFO + '">\n' + | ||
' <div class="d2h-code-side-line ' + diffParser.LINE_TYPE.INFO + '">' + blockHeader + '</div>\n' + | ||
' </td>\n' + | ||
'</tr>\n'; | ||
}; | ||
function generateSideBySideFileHtml(file, config) { | ||
SideBySidePrinter.prototype.generateSideBySideFileHtml = function(file) { | ||
var that = this; | ||
var fileHtml = {}; | ||
@@ -83,20 +100,8 @@ fileHtml.left = ''; | ||
fileHtml.left += '<tr>\n' + | ||
' <td class="d2h-code-side-linenumber ' + diffParser.LINE_TYPE.INFO + '"></td>\n' + | ||
' <td class="' + diffParser.LINE_TYPE.INFO + '">' + | ||
' <div class="d2h-code-side-line ' + diffParser.LINE_TYPE.INFO + '">' + | ||
' ' + utils.escape(block.header) + | ||
' </div>' + | ||
' </td>\n' + | ||
'</tr>\n'; | ||
fileHtml.left += that.makeSideHtml(utils.escape(block.header)); | ||
fileHtml.right += that.makeSideHtml(''); | ||
fileHtml.right += '<tr>\n' + | ||
' <td class="d2h-code-side-linenumber ' + diffParser.LINE_TYPE.INFO + '"></td>\n' + | ||
' <td class="' + diffParser.LINE_TYPE.INFO + '">' + | ||
' <div class="d2h-code-side-line ' + diffParser.LINE_TYPE.INFO + '"></div>' + | ||
' </td>\n' + | ||
'</tr>\n'; | ||
var oldLines = []; | ||
var newLines = []; | ||
function processChangeBlock() { | ||
@@ -106,3 +111,4 @@ var matches; | ||
var deleteType; | ||
var doMatching = config.matching === "lines" || config.matching === "words"; | ||
var doMatching = that.config.matching === 'lines' || that.config.matching === 'words'; | ||
if (doMatching) { | ||
@@ -113,58 +119,63 @@ matches = matcher(oldLines, newLines); | ||
} else { | ||
matches = [[oldLines,newLines]]; | ||
matches = [[oldLines, newLines]]; | ||
insertType = diffParser.LINE_TYPE.INSERTS; | ||
deleteType = diffParser.LINE_TYPE.DELETES; | ||
} | ||
matches.forEach(function(match){ | ||
var oldLines = match[0]; | ||
var newLines = match[1]; | ||
var tmpHtml; | ||
var j = 0; | ||
var oldLine, newLine, | ||
common = Math.min(oldLines.length, newLines.length), | ||
max = Math.max(oldLines.length, newLines.length); | ||
for (j = 0; j < common; j++) { | ||
oldLine = oldLines[j]; | ||
newLine = newLines[j]; | ||
config.isCombined = file.isCombined; | ||
matches.forEach(function(match) { | ||
oldLines = match[0]; | ||
newLines = match[1]; | ||
var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, config); | ||
var common = Math.min(oldLines.length, newLines.length); | ||
var max = Math.max(oldLines.length, newLines.length); | ||
for (var j = 0; j < common; j++) { | ||
var oldLine = oldLines[j]; | ||
var newLine = newLines[j]; | ||
that.config.isCombined = file.isCombined; | ||
var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); | ||
fileHtml.left += | ||
generateSingleLineHtml(deleteType, oldLine.oldNumber, | ||
that.generateSingleLineHtml(deleteType, oldLine.oldNumber, | ||
diff.first.line, diff.first.prefix); | ||
fileHtml.right += | ||
generateSingleLineHtml(insertType, newLine.newNumber, | ||
that.generateSingleLineHtml(insertType, newLine.newNumber, | ||
diff.second.line, diff.second.prefix); | ||
} | ||
if (max > common) { | ||
var oldSlice = oldLines.slice(common), | ||
newSlice = newLines.slice(common); | ||
tmpHtml = processLines(oldLines.slice(common), newLines.slice(common)); | ||
fileHtml.left += tmpHtml.left; | ||
fileHtml.right += tmpHtml.right; | ||
} | ||
} | ||
if (max > common) { | ||
var oldSlice = oldLines.slice(common); | ||
var newSlice = newLines.slice(common); | ||
var tmpHtml = that.processLines(oldSlice, newSlice); | ||
fileHtml.left += tmpHtml.left; | ||
fileHtml.right += tmpHtml.right; | ||
} | ||
}); | ||
oldLines = []; | ||
newLines = []; | ||
} | ||
for (var i = 0; i < block.lines.length; i++) { | ||
var line = block.lines[i]; | ||
var prefix = line[0]; | ||
var prefix = line.content[0]; | ||
var escapedLine = utils.escape(line.content.substr(1)); | ||
if ( line.type !== diffParser.LINE_TYPE.INSERTS && | ||
(newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) { | ||
if (line.type !== diffParser.LINE_TYPE.INSERTS && | ||
(newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) { | ||
processChangeBlock(); | ||
} | ||
if (line.type == diffParser.LINE_TYPE.CONTEXT) { | ||
fileHtml.left += generateSingleLineHtml(line.type, line.oldNumber, escapedLine, prefix); | ||
fileHtml.right += generateSingleLineHtml(line.type, line.newNumber, escapedLine, prefix); | ||
} else if (line.type == diffParser.LINE_TYPE.INSERTS && !oldLines.length) { | ||
fileHtml.left += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, '', '', ''); | ||
fileHtml.right += generateSingleLineHtml(line.type, line.newNumber, escapedLine, prefix); | ||
} else if (line.type == diffParser.LINE_TYPE.DELETES) { | ||
if (line.type === diffParser.LINE_TYPE.CONTEXT) { | ||
fileHtml.left += that.generateSingleLineHtml(line.type, line.oldNumber, escapedLine, prefix); | ||
fileHtml.right += that.generateSingleLineHtml(line.type, line.newNumber, escapedLine, prefix); | ||
} else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) { | ||
fileHtml.left += that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, '', '', ''); | ||
fileHtml.right += that.generateSingleLineHtml(line.type, line.newNumber, escapedLine, prefix); | ||
} else if (line.type === diffParser.LINE_TYPE.DELETES) { | ||
oldLines.push(line); | ||
} else if (line.type == diffParser.LINE_TYPE.INSERTS && !!oldLines.length) { | ||
} else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) { | ||
newLines.push(line); | ||
@@ -181,5 +192,6 @@ } else { | ||
return fileHtml; | ||
} | ||
}; | ||
function processLines(oldLines, newLines) { | ||
SideBySidePrinter.prototype.processLines = function(oldLines, newLines) { | ||
var that = this; | ||
var fileHtml = {}; | ||
@@ -190,5 +202,5 @@ fileHtml.left = ''; | ||
var maxLinesNumber = Math.max(oldLines.length, newLines.length); | ||
for (j = 0; j < maxLinesNumber; j++) { | ||
var oldLine = oldLines[j]; | ||
var newLine = newLines[j]; | ||
for (var i = 0; i < maxLinesNumber; i++) { | ||
var oldLine = oldLines[i]; | ||
var newLine = newLines[i]; | ||
var oldContent; | ||
@@ -198,2 +210,3 @@ var newContent; | ||
var newPrefix; | ||
if (oldLine) { | ||
@@ -203,2 +216,3 @@ oldContent = utils.escape(oldLine.content.substr(1)); | ||
} | ||
if (newLine) { | ||
@@ -208,11 +222,12 @@ newContent = utils.escape(newLine.content.substr(1)); | ||
} | ||
if (oldLine && newLine) { | ||
fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); | ||
fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, newContent, newPrefix); | ||
fileHtml.left += that.generateSingleLineHtml(oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); | ||
fileHtml.right += that.generateSingleLineHtml(newLine.type, newLine.newNumber, newContent, newPrefix); | ||
} else if (oldLine) { | ||
fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); | ||
fileHtml.right += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, '', '', ''); | ||
fileHtml.left += that.generateSingleLineHtml(oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); | ||
fileHtml.right += that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, '', '', ''); | ||
} else if (newLine) { | ||
fileHtml.left += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, '', '', ''); | ||
fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, newContent, newPrefix); | ||
fileHtml.left += that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, '', '', ''); | ||
fileHtml.right += that.generateSingleLineHtml(newLine.type, newLine.newNumber, newContent, newPrefix); | ||
} else { | ||
@@ -224,5 +239,14 @@ console.error('How did it get here?'); | ||
return fileHtml; | ||
} | ||
}; | ||
function generateSingleLineHtml(type, number, content, prefix) { | ||
SideBySidePrinter.prototype.makeSingleLineHtml = function(type, number, htmlContent, htmlPrefix) { | ||
return '<tr>\n' + | ||
' <td class="d2h-code-side-linenumber ' + type + '">' + number + '</td>\n' + | ||
' <td class="' + type + '">' + | ||
' <div class="d2h-code-side-line ' + type + '">' + htmlPrefix + htmlContent + '</div>' + | ||
' </td>\n' + | ||
' </tr>\n'; | ||
}; | ||
SideBySidePrinter.prototype.generateSingleLineHtml = function(type, number, content, prefix) { | ||
var htmlPrefix = ''; | ||
@@ -238,11 +262,6 @@ if (prefix) { | ||
return '<tr>\n' + | ||
' <td class="d2h-code-side-linenumber ' + type + '">' + number + '</td>\n' + | ||
' <td class="' + type + '">' + | ||
' <div class="d2h-code-side-line ' + type + '">' + htmlPrefix + htmlContent + '</div>' + | ||
' </td>\n' + | ||
' </tr>\n'; | ||
} | ||
return this.makeSingleLineHtml(type, number, htmlContent, htmlPrefix); | ||
}; | ||
function generateEmptyDiff() { | ||
SideBySidePrinter.prototype.generateEmptyDiff = function() { | ||
var fileHtml = {}; | ||
@@ -260,6 +279,6 @@ fileHtml.right = ''; | ||
return fileHtml; | ||
} | ||
}; | ||
module.exports['SideBySidePrinter'] = new SideBySidePrinter(); | ||
module.exports.SideBySidePrinter = SideBySidePrinter; | ||
})(this); | ||
})(); |
@@ -8,3 +8,3 @@ /* | ||
(function(ctx, undefined) { | ||
(function() { | ||
@@ -22,6 +22,2 @@ function Utils() { | ||
Utils.prototype.getRandomId = function(prefix) { | ||
return prefix + "-" + Math.random().toString(36).slice(-3); | ||
}; | ||
Utils.prototype.startsWith = function(str, start) { | ||
@@ -46,4 +42,4 @@ if (typeof start === 'object') { | ||
module.exports['Utils'] = new Utils(); | ||
module.exports.Utils = new Utils(); | ||
})(this); | ||
})(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
53309
14
1334
165
8
Updateddiff@^2.2.1