diff2html/diff2html.min.js
2015-01-24 22:22:20 +00:00

1 line
No EOL
8.8 KiB
JavaScript

!function(window){var ClassVariable;return ClassVariable=function(){function Diff2Html(){}function escape(str){return str.slice(0).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\t/g," ")}function startsWith(str,start){return 0===str.indexOf(start)}function valueOrEmpty(value){return value?value:""}function diffHighlight(diffLine1,diffLine2){var highlightedLine=diffString(diffLine1.substr(1),diffLine2.substr(1));return{o:diffLine1.charAt(0)+removeIns(highlightedLine),n:diffLine2.charAt(0)+removeDel(highlightedLine)}}var LINE_TYPE={INSERTS:"d2h-ins",DELETES:"d2h-del",CONTEXT:"d2h-cntx",INFO:"d2h-info"};Diff2Html.prototype.getPrettyHtmlFromDiff=function(diffInput){var diffJson=generateDiffJson(diffInput);return generateJsonHtml(diffJson)},Diff2Html.prototype.getJsonFromDiff=function(diffInput){return generateDiffJson(diffInput)},Diff2Html.prototype.getPrettyHtmlFromJson=function(diffJson){return generateJsonHtml(diffJson)},Diff2Html.prototype.getPrettySideBySideHtmlFromDiff=function(diffInput){var diffJson=generateDiffJson(diffInput);return generateSideBySideJsonHtml(diffJson)},Diff2Html.prototype.getPrettySideBySideHtmlFromJson=function(diffJson){return generateSideBySideJsonHtml(diffJson)};var instance,generateDiffJson=function(diffInput){var files=[],currentFile=null,currentBlock=null,oldLine=null,newLine=null,saveBlock=function(){currentBlock&&(currentFile.blocks.push(currentBlock),currentBlock=null)},saveFile=function(){currentFile&&currentFile.newName&&(files.push(currentFile),currentFile=null)},startFile=function(){saveBlock(),saveFile(),currentFile={},currentFile.blocks=[],currentFile.deletedLines=0,currentFile.addedLines=0},startBlock=function(line){saveBlock();var values=/^@@ -(\d+),\d+ \+(\d+),\d+ @@.*/.exec(line)||/^@@@ -(\d+),\d+ -\d+,\d+ \+(\d+),\d+ @@@.*/.exec(line)||[0,0,0];oldLine=values[1],newLine=values[2],currentBlock={},currentBlock.lines=[],currentBlock.oldStartLine=oldLine,currentBlock.newStartLine=newLine,currentBlock.header=line},createLine=function(line){var currentLine={};currentLine.content=line,startsWith(line,"+")||startsWith(line," +")?(currentFile.addedLines++,currentLine.type=LINE_TYPE.INSERTS,currentLine.oldNumber=null,currentLine.newNumber=newLine++,currentBlock.lines.push(currentLine)):startsWith(line,"-")||startsWith(line," -")?(currentFile.deletedLines++,currentLine.type=LINE_TYPE.DELETES,currentLine.oldNumber=oldLine++,currentLine.newNumber=null,currentBlock.lines.push(currentLine)):(currentLine.type=LINE_TYPE.CONTEXT,currentLine.oldNumber=oldLine++,currentLine.newNumber=newLine++,currentBlock.lines.push(currentLine))},diffLines=diffInput.split("\n");return diffLines.forEach(function(line){if(line&&!startsWith(line,"*")&&!startsWith(line,"new")&&!startsWith(line,"index")){var values=[];startsWith(line,"diff")?startFile():currentFile&&!currentFile.oldName&&(values=/^--- a\/(\S+).*$/.exec(line))?currentFile.oldName=values[1]:currentFile&&!currentFile.newName&&(values=/^\+\+\+ b\/(\S+).*$/.exec(line))?currentFile.newName=values[1]:currentFile&&startsWith(line,"@@")?startBlock(line):currentBlock&&createLine(line)}}),saveBlock(),saveFile(),files},generateJsonHtml=function(diffFiles){return'<div class="d2h-wrapper">\n'+diffFiles.map(function(file){return'<div class="d2h-file-wrapper">\n <div class="d2h-file-header">\n <div class="d2h-file-stats">\n <span class="d2h-lines-added">+'+file.addedLines+'</span>\n <span class="d2h-lines-deleted">-'+file.deletedLines+'</span>\n </div>\n <div class="d2h-file-name">'+getDiffName(file.oldName,file.newName)+'</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 '+generateFileHtml(file)+" </tbody>\n </table>\n </div>\n </div>\n </div>\n"}).join("\n")+"</div>\n"},generateFileHtml=function(file){return file.blocks.map(function(block){for(var lines='<tr>\n <td class="d2h-code-linenumber '+LINE_TYPE.INFO+'" colspan="2"></td>\n <td class="'+LINE_TYPE.INFO+'"> <div class="d2h-code-line '+LINE_TYPE.INFO+'">'+escape(block.header)+"</div> </td>\n</tr>\n",i=0;i<block.lines.length;i++){var prevLine=block.lines[i-1],line=block.lines[i],newLine=block.lines[i+1],nextNewLine=block.lines[i+2],isOppositeTypeTwoLineBlock=line.type==LINE_TYPE.DELETES&&newLine&&newLine.type==LINE_TYPE.INSERTS&&(!nextNewLine||nextNewLine&&nextNewLine.type!=LINE_TYPE.INSERTS)&&(!prevLine||prevLine&&prevLine.type!=LINE_TYPE.DELETES),escapedLine=escape(line.content);if(isOppositeTypeTwoLineBlock){var nextEscapedLine=escape(newLine.content),diff=diffHighlight(escapedLine,nextEscapedLine);lines+=generateLineHtml(line.type,line.oldNumber,line.newNumber,diff.o)+generateLineHtml(newLine.type,newLine.oldNumber,newLine.newNumber,diff.n),i++}else lines+=generateLineHtml(line.type,line.oldNumber,line.newNumber,escapedLine)}return lines}).join("\n")},generateLineHtml=function(type,oldNumber,newNumber,content){return'<tr>\n <td class="d2h-code-linenumber '+type+'"> <div class="line-num1">'+valueOrEmpty(oldNumber)+'</div> <div class="line-num2">'+valueOrEmpty(newNumber)+'</div> </td>\n <td class="'+type+'"> <div class="d2h-code-line '+type+'">'+content+"</div> </td>\n</tr>\n"},generateSideBySideJsonHtml=function(diffFiles){return'<div class="d2h-wrapper">\n'+diffFiles.map(function(file){var diffs=generateSideBySideFileHtml(file);return'<div class="d2h-file-wrapper">\n <div class="d2h-file-header">\n <div class="d2h-file-stats">\n <span class="d2h-lines-added">+'+file.addedLines+'</span>\n <span class="d2h-lines-deleted">-'+file.deletedLines+'</span>\n </div>\n <div class="d2h-file-name">'+getDiffName(file.oldName,file.newName)+'</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"}).join("\n")+"</div>\n"},generateSideBySideFileHtml=function(file){var fileHtml={};return fileHtml.left="",fileHtml.right="",file.blocks.forEach(function(block){fileHtml.left+='<tr>\n <td class="d2h-code-side-linenumber '+LINE_TYPE.INFO+'"></td>\n <td class="'+LINE_TYPE.INFO+'" colspan="3"> <div class="d2h-code-side-line '+LINE_TYPE.INFO+'">'+escape(block.header)+"</div> </td>\n</tr>\n",fileHtml.right+='<tr>\n <td class="d2h-code-side-linenumber '+LINE_TYPE.INFO+'"></td>\n <td class="'+LINE_TYPE.INFO+'" colspan="3"> <div class="d2h-code-side-line '+LINE_TYPE.INFO+'"></div> </td>\n</tr>\n';for(var i=0;i<block.lines.length;i++){var prevLine=block.lines[i-1],line=block.lines[i],newLine=block.lines[i+1],nextNewLine=block.lines[i+2],isOpositeTypeTwoLineBlock=line.type==LINE_TYPE.DELETES&&newLine&&newLine.type==LINE_TYPE.INSERTS&&(!nextNewLine||nextNewLine&&nextNewLine.type!=LINE_TYPE.INSERTS)&&(!prevLine||prevLine&&prevLine.type!=LINE_TYPE.DELETES),escapedLine=escape(line.content);if(isOpositeTypeTwoLineBlock){var nextEscapedLine=escape(newLine.content),diff=diffHighlight(escapedLine,nextEscapedLine);fileHtml.left+=generateSingleLineHtml(line.type,line.oldNumber,diff.o),fileHtml.right+=generateSingleLineHtml(newLine.type,newLine.newNumber,diff.n),i++}else line.type==LINE_TYPE.DELETES?(fileHtml.left+=generateSingleLineHtml(line.type,line.oldNumber,escapedLine),fileHtml.right+=generateSingleLineHtml(LINE_TYPE.CONTEXT,"","","")):line.type==LINE_TYPE.INSERTS?(fileHtml.left+=generateSingleLineHtml(LINE_TYPE.CONTEXT,"","",""),fileHtml.right+=generateSingleLineHtml(line.type,line.newNumber,escapedLine)):(fileHtml.left+=generateSingleLineHtml(line.type,line.oldNumber,escapedLine),fileHtml.right+=generateSingleLineHtml(line.type,line.newNumber,escapedLine))}}),fileHtml},generateSingleLineHtml=function(type,number,content){return'<tr>\n <td class="d2h-code-side-linenumber '+type+'">'+number+'</td>\n <td class="'+type+'"> <div class="d2h-code-side-line '+type+'">'+content+"</div> </td>\n </tr>\n"},getDiffName=function(oldFilename,newFilename){return oldFilename&&newFilename&&oldFilename!==newFilename?oldFilename+" -> "+newFilename:newFilename?newFilename:oldFilename?oldFilename:"Unknown filename"},removeIns=function(line){return line.replace(/(<ins>((.|\n)*?)<\/ins>)/g,"")},removeDel=function(line){return line.replace(/(<del>((.|\n)*?)<\/del>)/g,"")};return{getInstance:function(){return void 0===instance&&(instance=new Diff2Html,instance.constructor=null),instance}}}(),window.Diff2Html=ClassVariable.getInstance(),window.Diff2Html}(window);