diff --git a/diff2html.js b/diff2html.js index fd5fa20..5bac827 100644 --- a/diff2html.js +++ b/diff2html.js @@ -18,7 +18,7 @@ function Diff2Html() { */ Diff2Html.prototype.getPrettyHtmlFromDiff = function (diffInput) { var diffJson = diffParser.generateDiffJson(diffInput); - return htmlPrinter.generateJsonHtml(diffJson); + return htmlPrinter.generateLineByLineJsonHtml(diffJson); }; /* @@ -32,7 +32,7 @@ Diff2Html.prototype.getJsonFromDiff = function (diffInput) { * Generates pretty html from a json object */ Diff2Html.prototype.getPrettyHtmlFromJson = function (diffJson) { - return htmlPrinter.generateJsonHtml(diffJson); + return htmlPrinter.generateLineByLineJsonHtml(diffJson); }; /* diff --git a/index.html b/index.html index 95ffb1a..ef2dbe0 100644 --- a/index.html +++ b/index.html @@ -21,6 +21,9 @@ + + + diff --git a/src/html-printer.js b/src/html-printer.js index 47f1eec..2e1d685 100644 --- a/src/html-printer.js +++ b/src/html-printer.js @@ -5,306 +5,12 @@ * */ -var diffParser = new DiffParser(); -var utils = new Utils(); -var jsDiff = JsDiff; +var lineByLinePrinter = new LineByLinePrinter(); +var sideBySidePrinter = new SideBySidePrinter(); function HtmlPrinter() { } -HtmlPrinter.prototype.generateJsonHtml = function (diffFiles) { - return "
\n" + - diffFiles.map(function (file) { - return "
\n" + - "
\n" + - "
\n" + - " +" + file.addedLines + "\n" + - " -" + file.deletedLines + "\n" + - "
\n" + - "
" + getDiffName(file.oldName, file.newName) + "
\n" + - "
\n" + - "
\n" + - "
\n" + - " \n" + - " \n" + - " " + generateFileHtml(file) + - " \n" + - "
\n" + - "
\n" + - "
\n" + - "
\n"; - }).join("\n") + - "
\n"; -}; +HtmlPrinter.prototype.generateLineByLineJsonHtml = lineByLinePrinter.generateLineByLineJsonHtml; -var generateFileHtml = function (file) { - return file.blocks.map(function (block) { - - var lines = "\n" + - " \n" + - " " + - "
" + utils.escape(block.header) + "
" + - " \n" + - "\n"; - - var oldLines = [], newLines = []; - var processedOldLines = [], processedNewLines = []; - - for (var i = 0; i < block.lines.length; i++) { - var line = block.lines[i]; - var escapedLine = utils.escape(line.content); - - if (line.type == diffParser.LINE_TYPE.CONTEXT && !oldLines.length && !newLines.length) { - lines += generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine); - } else if (line.type == diffParser.LINE_TYPE.INSERTS && !oldLines.length && !newLines.length) { - lines += generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine); - } else if (line.type == diffParser.LINE_TYPE.DELETES && !newLines.length) { - oldLines.push(line); - } else if (line.type == diffParser.LINE_TYPE.INSERTS && oldLines.length > newLines.length) { - newLines.push(line); - } else { - var j = 0; - var oldLine, newLine; - var oldEscapedLine, newEscapedLine; - - if (oldLines.length === newLines.length) { - for (j = 0; j < oldLines.length; j++) { - oldLine = oldLines[j]; - newLine = newLines[j]; - oldEscapedLine = utils.escape(oldLine.content); - newEscapedLine = utils.escape(newLine.content); - - var diff = diffHighlight(oldEscapedLine, newEscapedLine, file.isTripleDiff); - - processedOldLines += generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, diff.o); - processedNewLines += generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, diff.n); - } - - lines += processedOldLines + processedNewLines; - } else { - for (j = 0; j < oldLines.length; j++) { - oldLine = oldLines[j]; - oldEscapedLine = utils.escape(oldLine.content); - lines += generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine); - } - - for (j = 0; j < newLines.length; j++) { - newLine = newLines[j]; - newEscapedLine = utils.escape(newLine.content); - lines += generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine); - } - } - - oldLines = []; - newLines = []; - processedOldLines = []; - processedNewLines = []; - i--; - } - } - - return lines; - }).join("\n"); -}; - -var generateLineHtml = function (type, oldNumber, newNumber, content) { - return "\n" + - " " + - "
" + utils.valueOrEmpty(oldNumber) + "
" + - "
" + utils.valueOrEmpty(newNumber) + "
" + - " \n" + - " " + - "
" + content + "
" + - " \n" + - "\n"; -}; - -/* - * Side By Side HTML - */ - -HtmlPrinter.prototype.generateSideBySideJsonHtml = function (diffFiles) { - return "
\n" + - diffFiles.map(function (file) { - var diffs = generateSideBySideFileHtml(file); - - return "
\n" + - "
\n" + - "
\n" + - " +" + file.addedLines + "\n" + - " -" + file.deletedLines + "\n" + - "
\n" + - "
" + getDiffName(file.oldName, file.newName) + "
\n" + - "
\n" + - "
\n" + - "
\n" + - "
\n" + - " \n" + - " \n" + - " " + diffs.left + - " \n" + - "
\n" + - "
\n" + - "
\n" + - "
\n" + - "
\n" + - " \n" + - " \n" + - " " + diffs.right + - " \n" + - "
\n" + - "
\n" + - "
\n" + - "
\n" + - "
\n"; - }).join("\n") + - "
\n"; -}; - -var generateSideBySideFileHtml = function (file) { - var fileHtml = {}; - fileHtml.left = ""; - fileHtml.right = ""; - - file.blocks.forEach(function (block) { - - fileHtml.left += "\n" + - " \n" + - " " + - "
" + utils.escape(block.header) + "
" + - " \n" + - "\n"; - - fileHtml.right += "\n" + - " \n" + - " " + - "
" + - " \n" + - "\n"; - - var oldLines = [], newLines = []; - - for (var i = 0; i < block.lines.length; i++) { - var line = block.lines[i]; - var escapedLine = utils.escape(line.content); - - if (line.type == diffParser.LINE_TYPE.CONTEXT && !oldLines.length && !newLines.length) { - fileHtml.left += generateSingleLineHtml(line.type, line.oldNumber, escapedLine); - fileHtml.right += generateSingleLineHtml(line.type, line.newNumber, escapedLine); - } else if (line.type == diffParser.LINE_TYPE.INSERTS && !oldLines.length && !newLines.length) { - fileHtml.left += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, "", "", ""); - fileHtml.right += generateSingleLineHtml(line.type, line.newNumber, escapedLine); - } else if (line.type == diffParser.LINE_TYPE.DELETES && !newLines.length) { - oldLines.push(line); - } else if (line.type == diffParser.LINE_TYPE.INSERTS && oldLines.length > newLines.length) { - newLines.push(line); - } else { - var j = 0; - var oldLine, newLine; - var oldEscapedLine, newEscapedLine; - - if (oldLines.length === newLines.length) { - for (j = 0; j < oldLines.length; j++) { - oldLine = oldLines[j]; - newLine = newLines[j]; - oldEscapedLine = utils.escape(oldLine.content); - newEscapedLine = utils.escape(newLine.content); - - var diff = diffHighlight(oldEscapedLine, newEscapedLine, file.isTripleDiff); - - fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, diff.o); - fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, diff.n); - } - } else { - var maxLinesNumber = Math.max(oldLines.length, newLines.length); - for (j = 0; j < maxLinesNumber; j++) { - oldLine = oldLines[j]; - newLine = newLines[j]; - - if (oldLine && newLine) { - fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, utils.escape(oldLine.content)); - fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, utils.escape(newLine.content)); - } else if (oldLine) { - fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, utils.escape(oldLine.content)); - fileHtml.right += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, "", "", ""); - } else if (newLine) { - fileHtml.left += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, "", "", ""); - fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, utils.escape(newLine.content)); - } else { - console.error("How did it get here?"); - } - } - } - - oldLines = []; - newLines = []; - i--; - } - } - }); - - return fileHtml; -}; - -var generateSingleLineHtml = function (type, number, content) { - return "\n" + - " " + number + "\n" + - " " + - "
" + content + "
" + - " \n" + - " \n"; -}; - -/* - * HTML Helpers - */ - -var getDiffName = function (oldFilename, newFilename) { - if (oldFilename && newFilename && oldFilename !== newFilename) { - return oldFilename + " -> " + newFilename; - } else if (newFilename) { - return newFilename; - } else if (oldFilename) { - return oldFilename; - } else { - return "Unknown filename"; - } -}; - -var removeIns = function (line) { - return line.replace(/(((.|\n)*?)<\/ins>)/g, ""); -}; - -var removeDel = function (line) { - return line.replace(/(((.|\n)*?)<\/del>)/g, ""); -}; - -function diffHighlight(diffLine1, diffLine2, isTripleDiff) { - var lineStart1, lineStart2; - - var prefixSize = 1; - - if (isTripleDiff) prefixSize = 2; - - lineStart1 = diffLine1.substr(0, prefixSize); - lineStart2 = diffLine2.substr(0, prefixSize); - - diffLine1 = diffLine1.substr(prefixSize); - diffLine2 = diffLine2.substr(prefixSize); - - var diff = jsDiff.diffChars(diffLine1, diffLine2); - - var highlightedLine = ""; - - diff.forEach(function (part) { - var elemType = part.added ? 'ins' : part.removed ? 'del' : null; - - if (elemType !== null) highlightedLine += "<" + elemType + ">" + part.value + ""; - else highlightedLine += part.value; - }); - - return { - o: lineStart1 + removeIns(highlightedLine), - n: lineStart2 + removeDel(highlightedLine) - } -} +HtmlPrinter.prototype.generateSideBySideJsonHtml = sideBySidePrinter.generateSideBySideJsonHtml; diff --git a/src/line-by-line-printer.js b/src/line-by-line-printer.js new file mode 100644 index 0000000..7970d0f --- /dev/null +++ b/src/line-by-line-printer.js @@ -0,0 +1,120 @@ +/* + * + * LineByLinePrinter (line-by-line-printer.js) + * Author: rtfpessoa + * + */ + +var diffParser = new DiffParser(); +var printerUtils = new PrinterUtils(); +var utils = new Utils(); + +function LineByLinePrinter() { +} + +LineByLinePrinter.prototype.generateLineByLineJsonHtml = function (diffFiles) { + return "
\n" + + diffFiles.map(function (file) { + return "
\n" + + "
\n" + + "
\n" + + " +" + file.addedLines + "\n" + + " -" + file.deletedLines + "\n" + + "
\n" + + "
" + printerUtils.getDiffName(file.oldName, file.newName) + "
\n" + + "
\n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + " " + generateFileHtml(file) + + " \n" + + "
\n" + + "
\n" + + "
\n" + + "
\n"; + }).join("\n") + + "
\n"; +}; + +function generateFileHtml(file) { + return file.blocks.map(function (block) { + + var lines = "\n" + + " \n" + + " " + + "
" + utils.escape(block.header) + "
" + + " \n" + + "\n"; + + var oldLines = [], newLines = []; + var processedOldLines = [], processedNewLines = []; + + for (var i = 0; i < block.lines.length; i++) { + var line = block.lines[i]; + var escapedLine = utils.escape(line.content); + + if (line.type == diffParser.LINE_TYPE.CONTEXT && !oldLines.length && !newLines.length) { + lines += generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine); + } else if (line.type == diffParser.LINE_TYPE.INSERTS && !oldLines.length && !newLines.length) { + lines += generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine); + } else if (line.type == diffParser.LINE_TYPE.DELETES && !newLines.length) { + oldLines.push(line); + } else if (line.type == diffParser.LINE_TYPE.INSERTS && oldLines.length > newLines.length) { + newLines.push(line); + } else { + var j = 0; + var oldLine, newLine; + var oldEscapedLine, newEscapedLine; + + if (oldLines.length === newLines.length) { + for (j = 0; j < oldLines.length; j++) { + oldLine = oldLines[j]; + newLine = newLines[j]; + oldEscapedLine = utils.escape(oldLine.content); + newEscapedLine = utils.escape(newLine.content); + + var diff = printerUtils.diffHighlight(oldEscapedLine, newEscapedLine, file.isTripleDiff); + + processedOldLines += generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, diff.o); + processedNewLines += generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, diff.n); + } + + lines += processedOldLines + processedNewLines; + } else { + for (j = 0; j < oldLines.length; j++) { + oldLine = oldLines[j]; + oldEscapedLine = utils.escape(oldLine.content); + lines += generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine); + } + + for (j = 0; j < newLines.length; j++) { + newLine = newLines[j]; + newEscapedLine = utils.escape(newLine.content); + lines += generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine); + } + } + + oldLines = []; + newLines = []; + processedOldLines = []; + processedNewLines = []; + i--; + } + } + + return lines; + }).join("\n"); +} + +function generateLineHtml(type, oldNumber, newNumber, content) { + return "\n" + + " " + + "
" + utils.valueOrEmpty(oldNumber) + "
" + + "
" + utils.valueOrEmpty(newNumber) + "
" + + " \n" + + " " + + "
" + content + "
" + + " \n" + + "\n"; +} diff --git a/src/printer-utils.js b/src/printer-utils.js new file mode 100644 index 0000000..a547a5a --- /dev/null +++ b/src/printer-utils.js @@ -0,0 +1,61 @@ +/* + * + * PrinterUtils (printer-utils.js) + * Author: rtfpessoa + * + */ + +var jsDiff = JsDiff; + +function PrinterUtils() { +} + +PrinterUtils.prototype.getDiffName = function (oldFilename, newFilename) { + if (oldFilename && newFilename && oldFilename !== newFilename) { + return oldFilename + " -> " + newFilename; + } else if (newFilename) { + return newFilename; + } else if (oldFilename) { + return oldFilename; + } else { + return "Unknown filename"; + } +}; + +PrinterUtils.prototype.diffHighlight = function (diffLine1, diffLine2, isTripleDiff) { + var lineStart1, lineStart2; + + var prefixSize = 1; + + if (isTripleDiff) prefixSize = 2; + + lineStart1 = diffLine1.substr(0, prefixSize); + lineStart2 = diffLine2.substr(0, prefixSize); + + diffLine1 = diffLine1.substr(prefixSize); + diffLine2 = diffLine2.substr(prefixSize); + + var diff = jsDiff.diffChars(diffLine1, diffLine2); + + var highlightedLine = ""; + + diff.forEach(function (part) { + var elemType = part.added ? 'ins' : part.removed ? 'del' : null; + + if (elemType !== null) highlightedLine += "<" + elemType + ">" + part.value + ""; + else highlightedLine += part.value; + }); + + return { + o: lineStart1 + removeIns(highlightedLine), + n: lineStart2 + removeDel(highlightedLine) + } +}; + +function removeIns(line) { + return line.replace(/(((.|\n)*?)<\/ins>)/g, ""); +} + +function removeDel(line) { + return line.replace(/(((.|\n)*?)<\/del>)/g, ""); +} diff --git a/src/side-by-side-printer.js b/src/side-by-side-printer.js new file mode 100644 index 0000000..6ec08f1 --- /dev/null +++ b/src/side-by-side-printer.js @@ -0,0 +1,145 @@ +/* + * + * HtmlPrinter (html-printer.js) + * Author: rtfpessoa + * + */ + +var diffParser = new DiffParser(); +var printerUtils = new PrinterUtils(); +var utils = new Utils(); + +function SideBySidePrinter() { +} + +SideBySidePrinter.prototype.generateSideBySideJsonHtml = function (diffFiles) { + return "
\n" + + diffFiles.map(function (file) { + var diffs = generateSideBySideFileHtml(file); + + return "
\n" + + "
\n" + + "
\n" + + " +" + file.addedLines + "\n" + + " -" + file.deletedLines + "\n" + + "
\n" + + "
" + printerUtils.getDiffName(file.oldName, file.newName) + "
\n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + " " + diffs.left + + " \n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + " " + diffs.right + + " \n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + "
\n"; + }).join("\n") + + "
\n"; +}; + +function generateSideBySideFileHtml(file) { + var fileHtml = {}; + fileHtml.left = ""; + fileHtml.right = ""; + + file.blocks.forEach(function (block) { + + fileHtml.left += "\n" + + " \n" + + " " + + "
" + utils.escape(block.header) + "
" + + " \n" + + "\n"; + + fileHtml.right += "\n" + + " \n" + + " " + + "
" + + " \n" + + "\n"; + + var oldLines = [], newLines = []; + + for (var i = 0; i < block.lines.length; i++) { + var line = block.lines[i]; + var escapedLine = utils.escape(line.content); + + if (line.type == diffParser.LINE_TYPE.CONTEXT && !oldLines.length && !newLines.length) { + fileHtml.left += generateSingleLineHtml(line.type, line.oldNumber, escapedLine); + fileHtml.right += generateSingleLineHtml(line.type, line.newNumber, escapedLine); + } else if (line.type == diffParser.LINE_TYPE.INSERTS && !oldLines.length && !newLines.length) { + fileHtml.left += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, "", "", ""); + fileHtml.right += generateSingleLineHtml(line.type, line.newNumber, escapedLine); + } else if (line.type == diffParser.LINE_TYPE.DELETES && !newLines.length) { + oldLines.push(line); + } else if (line.type == diffParser.LINE_TYPE.INSERTS && oldLines.length > newLines.length) { + newLines.push(line); + } else { + var j = 0; + var oldLine, newLine; + var oldEscapedLine, newEscapedLine; + + if (oldLines.length === newLines.length) { + for (j = 0; j < oldLines.length; j++) { + oldLine = oldLines[j]; + newLine = newLines[j]; + oldEscapedLine = utils.escape(oldLine.content); + newEscapedLine = utils.escape(newLine.content); + + var diff = printerUtils.diffHighlight(oldEscapedLine, newEscapedLine, file.isTripleDiff); + + fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, diff.o); + fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, diff.n); + } + } else { + var maxLinesNumber = Math.max(oldLines.length, newLines.length); + for (j = 0; j < maxLinesNumber; j++) { + oldLine = oldLines[j]; + newLine = newLines[j]; + + if (oldLine && newLine) { + fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, utils.escape(oldLine.content)); + fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, utils.escape(newLine.content)); + } else if (oldLine) { + fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, utils.escape(oldLine.content)); + fileHtml.right += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, "", "", ""); + } else if (newLine) { + fileHtml.left += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, "", "", ""); + fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, utils.escape(newLine.content)); + } else { + console.error("How did it get here?"); + } + } + } + + oldLines = []; + newLines = []; + i--; + } + } + }); + + return fileHtml; +} + +function generateSingleLineHtml(type, number, content) { + return "\n" + + " " + number + "\n" + + " " + + "
" + content + "
" + + " \n" + + " \n"; +}