From f73095a5ce68bb3cdd9f2868204adc706334b762 Mon Sep 17 00:00:00 2001 From: hqyn1559 Date: Mon, 22 Apr 2019 19:38:23 +0800 Subject: [PATCH] float button discovering the next and previous diff --- src/diff2html.js | 10 ++++- src/float-button-printer.js | 25 +++++++++++ src/html-printer.js | 6 +++ src/line-by-line-printer.js | 50 +++++++++++++++++---- src/side-by-side-printer.js | 42 ++++++++++++++--- src/templates/diff2html-templates.js | 3 +- src/templates/generic-float-button.mustache | 6 +++ src/templates/generic-line.mustache | 2 +- src/ui/js/diff2html-ui.js | 28 ++++++++++++ 9 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 src/float-button-printer.js create mode 100644 src/templates/generic-float-button.mustache diff --git a/src/diff2html.js b/src/diff2html.js index 2da3271..af7208c 100644 --- a/src/diff2html.js +++ b/src/diff2html.js @@ -20,7 +20,8 @@ matchWordsThreshold: 0.25, matchingMaxComparisons: 2500, maxLineLengthHighlight: 10000, - renderNothingWhenEmpty: false + renderNothingWhenEmpty: false, + showButton: true }; /* @@ -42,6 +43,11 @@ diffJson = diffParser.generateDiffJson(diffInput, cfg); } + var floatButton = ''; + if (cfg.showButton === true) { + floatButton = htmlPrinter.generateFloatButton(); + } + var fileList = ''; if (cfg.showFiles === true) { fileList = htmlPrinter.generateFileListSummary(diffJson, cfg); @@ -54,7 +60,7 @@ diffOutput = htmlPrinter.generateLineByLineJsonHtml(diffJson, cfg); } - return fileList + diffOutput; + return floatButton + fileList + diffOutput; }; /* diff --git a/src/float-button-printer.js b/src/float-button-printer.js new file mode 100644 index 0000000..541907d --- /dev/null +++ b/src/float-button-printer.js @@ -0,0 +1,25 @@ +/* + * + * FloatButtonPrinter (float-button-printer.js) + * Author: PhoebeWho + * + */ + +(function() { + var hoganUtils; + + var genericTemplatesPath = 'generic'; + + function FloatButtonPrinter(config) { + this.config = config; + + var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils; + hoganUtils = new HoganJsUtils(config); + } + + FloatButtonPrinter.prototype.generateFloatButton = function() { + return hoganUtils.render(genericTemplatesPath, 'float-button', {}); + }; + + module.exports.FloatButtonPrinter = FloatButtonPrinter; +})(); diff --git a/src/html-printer.js b/src/html-printer.js index 13f8304..38cf5e3 100644 --- a/src/html-printer.js +++ b/src/html-printer.js @@ -9,6 +9,7 @@ var LineByLinePrinter = require('./line-by-line-printer.js').LineByLinePrinter; var SideBySidePrinter = require('./side-by-side-printer.js').SideBySidePrinter; var FileListPrinter = require('./file-list-printer.js').FileListPrinter; + var FloatButtonPrinter = require('./float-button-printer.js').FloatButtonPrinter; function HtmlPrinter() { } @@ -28,5 +29,10 @@ return fileListPrinter.generateFileList(diffJson); }; + HtmlPrinter.prototype.generateFloatButton = function() { + var floatButtonPrinter = new FloatButtonPrinter(); + return floatButtonPrinter.generateFloatButton(); + }; + module.exports.HtmlPrinter = new HtmlPrinter(); })(); diff --git a/src/line-by-line-printer.js b/src/line-by-line-printer.js index 8b41cc5..24ec452 100644 --- a/src/line-by-line-printer.js +++ b/src/line-by-line-printer.js @@ -10,6 +10,8 @@ var printerUtils = require('./printer-utils.js').PrinterUtils; var utils = require('./utils.js').Utils; var Rematch = require('./rematch.js').Rematch; + var diffBlockIdx = 0; + var blockFlag = true; var hoganUtils; @@ -87,6 +89,7 @@ var lines = that.makeColumnLineNumberHtml(block); var oldLines = []; var newLines = []; + blockFlag = true; function processChangeBlock() { var matches; @@ -124,10 +127,15 @@ that.config.isCombined = file.isCombined; var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); - + var tid = ''; + if (blockFlag && oldLines.length && newLines.length) { + tid = 'diff-block-' + diffBlockIdx; + diffBlockIdx += 1; + blockFlag = false; + } processedOldLines += that.makeLineHtml(file.isCombined, deleteType, oldLine.oldNumber, oldLine.newNumber, - diff.first.line, diff.first.prefix); + diff.first.line, diff.first.prefix, tid); processedNewLines += that.makeLineHtml(file.isCombined, insertType, newLine.oldNumber, newLine.newNumber, diff.second.line, diff.second.prefix); @@ -151,9 +159,16 @@ } if (line.type === diffParser.LINE_TYPE.CONTEXT) { + blockFlag = true; lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine); } else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) { - lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine); + var tid = ''; + if (blockFlag) { + tid = 'diff-block-' + diffBlockIdx; + diffBlockIdx += 1; + blockFlag = false; + } + lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine, '', tid); } else if (line.type === diffParser.LINE_TYPE.DELETES) { oldLines.push(line); } else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) { @@ -172,23 +187,36 @@ LineByLinePrinter.prototype._processLines = function(isCombined, oldLines, newLines) { var lines = ''; - + var LineBlockFlag = true; + var tid; for (var i = 0; i < oldLines.length; i++) { var oldLine = oldLines[i]; var oldEscapedLine = utils.escape(oldLine.content); - lines += this.makeLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine); + if (LineBlockFlag && blockFlag) { + tid = 'diff-block-' + diffBlockIdx; + diffBlockIdx += 1; + blockFlag = false; + LineBlockFlag = false; + } + lines += this.makeLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine, '', tid); } for (var j = 0; j < newLines.length; j++) { var newLine = newLines[j]; var newEscapedLine = utils.escape(newLine.content); - lines += this.makeLineHtml(isCombined, newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine); + if (LineBlockFlag && blockFlag) { + tid = 'diff-block-' + diffBlockIdx; + diffBlockIdx += 1; + blockFlag = false; + LineBlockFlag = false; + } + lines += this.makeLineHtml(isCombined, newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine, '', tid); } return lines; }; - LineByLinePrinter.prototype.makeLineHtml = function(isCombined, type, oldNumber, newNumber, content, possiblePrefix) { + LineByLinePrinter.prototype.makeLineHtml = function(isCombined, type, oldNumber, newNumber, content, possiblePrefix, tid) { var lineNumberTemplate = hoganUtils.render(baseTemplatesPath, 'numbers', { oldNumber: utils.valueOrEmpty(oldNumber), newNumber: utils.valueOrEmpty(newNumber) @@ -196,6 +224,11 @@ var lineWithoutPrefix = content; var prefix = possiblePrefix; + var idxStr = ''; + + if (tid) { + idxStr += tid; + } if (!prefix) { var lineWithPrefix = printerUtils.separatePrefix(isCombined, content); @@ -210,7 +243,8 @@ contentClass: 'd2h-code-line', prefix: prefix, content: lineWithoutPrefix, - lineNumber: lineNumberTemplate + lineNumber: lineNumberTemplate, + eleID: idxStr }); }; diff --git a/src/side-by-side-printer.js b/src/side-by-side-printer.js index 26067be..ecdea8a 100644 --- a/src/side-by-side-printer.js +++ b/src/side-by-side-printer.js @@ -10,6 +10,8 @@ var printerUtils = require('./printer-utils.js').PrinterUtils; var utils = require('./utils.js').Utils; var Rematch = require('./rematch.js').Rematch; + var diffBlockIdx = 0; + var blockFlag = true; var hoganUtils; @@ -89,6 +91,7 @@ var oldLines = []; var newLines = []; + blockFlag = true; function processChangeBlock() { var matches; @@ -124,10 +127,15 @@ that.config.isCombined = file.isCombined; var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); - + var tid = ''; + if (blockFlag && oldLines.length && newLines.length) { + tid = 'diff-block-' + diffBlockIdx; + diffBlockIdx += 1; + blockFlag = false; + } fileHtml.left += that.generateSingleLineHtml(file.isCombined, deleteType, oldLine.oldNumber, - diff.first.line, diff.first.prefix); + diff.first.line, diff.first.prefix, tid); fileHtml.right += that.generateSingleLineHtml(file.isCombined, insertType, newLine.newNumber, diff.second.line, diff.second.prefix); @@ -158,10 +166,17 @@ } if (line.type === diffParser.LINE_TYPE.CONTEXT) { + blockFlag = true; fileHtml.left += that.generateSingleLineHtml(file.isCombined, line.type, line.oldNumber, escapedLine, prefix); fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix); } else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) { - fileHtml.left += that.generateSingleLineHtml(file.isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); + var tid = ''; + if (blockFlag) { + tid = 'diff-block-' + diffBlockIdx; + diffBlockIdx += 1; + blockFlag = false; + } + fileHtml.left += that.generateSingleLineHtml(file.isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', '', tid); fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix); } else if (line.type === diffParser.LINE_TYPE.DELETES) { oldLines.push(line); @@ -184,6 +199,7 @@ var fileHtml = {}; fileHtml.left = ''; fileHtml.right = ''; + var LineBlockFlag = true; var maxLinesNumber = Math.max(oldLines.length, newLines.length); for (var i = 0; i < maxLinesNumber; i++) { @@ -208,7 +224,15 @@ fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix); } else if (oldLine) { - fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); + var tid = ''; + if (LineBlockFlag && blockFlag) { + tid = 'diff-block-' + diffBlockIdx; + diffBlockIdx += 1; + blockFlag = false; + LineBlockFlag = false; + } else { + } + fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix, tid); fileHtml.right += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); } else if (newLine) { fileHtml.left += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); @@ -221,11 +245,12 @@ return fileHtml; }; - SideBySidePrinter.prototype.generateSingleLineHtml = function(isCombined, type, number, content, possiblePrefix) { + SideBySidePrinter.prototype.generateSingleLineHtml = function(isCombined, type, number, content, possiblePrefix, tid) { var lineWithoutPrefix = content; var prefix = possiblePrefix; var lineClass = 'd2h-code-side-linenumber'; var contentClass = 'd2h-code-side-line'; + var idxStr = ''; if (!number && !content) { lineClass += ' d2h-code-side-emptyplaceholder'; @@ -233,6 +258,10 @@ type += ' d2h-emptyplaceholder'; } + if (tid) { + idxStr += tid; + } + if (!prefix) { var lineWithPrefix = printerUtils.separatePrefix(isCombined, content); prefix = lineWithPrefix.prefix; @@ -246,7 +275,8 @@ contentClass: contentClass, prefix: prefix, content: lineWithoutPrefix, - lineNumber: number + lineNumber: number, + eleID: idxStr }); }; diff --git a/src/templates/diff2html-templates.js b/src/templates/diff2html-templates.js index 945a9f2..79b4824 100644 --- a/src/templates/diff2html-templates.js +++ b/src/templates/diff2html-templates.js @@ -5,13 +5,14 @@ global.browserTemplates["file-summary-wrapper"] = new Hogan.Template({code: func global.browserTemplates["generic-column-line-number"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
");t.b(t.t(t.f("blockHeader",c,p,0)));t.b("
");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["generic-empty-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" File without changes");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["generic-file-path"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(t.rp("");t.b(t.v(t.f("fileDiffName",c,p,0)));t.b("");t.b("\n" + i);t.b(t.rp("");return t.fl(); },partials: {"\r");t.b("\n" + i);t.b(" \r");t.b("\n" + i);t.b(" \r");t.b("\n" + i);t.b(" \r");t.b("\n" + i);t.b(" \r");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["generic-line"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("lineNumber",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
");t.b("\n" + i);if(t.s(t.f("prefix",c,p,1),c,p,0,171,247,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" ");t.b(t.t(t.f("prefix",c,p,0)));t.b("");t.b("\n" + i);});c.pop();}if(t.s(t.f("content",c,p,1),c,p,0,279,353,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" ");t.b(t.t(t.f("content",c,p,0)));t.b("");t.b("\n" + i);});c.pop();}t.b("
");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["generic-wrapper"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("content",c,p,0)));t.b("\n" + i);t.b("
");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["icon-file-added"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["icon-file-changed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["icon-file-deleted"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["icon-file"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); +global.browserTemplates["icon-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["line-by-line-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("diffs",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["line-by-line-numbers"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
");t.b(t.v(t.f("oldNumber",c,p,0)));t.b("
");t.b("\n" + i);t.b("
");t.b(t.v(t.f("newNumber",c,p,0)));t.b("
");return t.fl(); },partials: {}, subs: { }}); global.browserTemplates["side-by-side-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.d("diffs.left",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.d("diffs.right",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");return t.fl(); },partials: {}, subs: { }}); diff --git a/src/templates/generic-float-button.mustache b/src/templates/generic-float-button.mustache new file mode 100644 index 0000000..f8379f5 --- /dev/null +++ b/src/templates/generic-float-button.mustache @@ -0,0 +1,6 @@ +
+ + + + +
\ No newline at end of file diff --git a/src/templates/generic-line.mustache b/src/templates/generic-line.mustache index 901c655..7eaa72b 100644 --- a/src/templates/generic-line.mustache +++ b/src/templates/generic-line.mustache @@ -1,5 +1,5 @@ - + {{{lineNumber}}} diff --git a/src/ui/js/diff2html-ui.js b/src/ui/js/diff2html-ui.js index 979939b..50dfbb4 100644 --- a/src/ui/js/diff2html-ui.js +++ b/src/ui/js/diff2html-ui.js @@ -16,6 +16,7 @@ var diffJson = null; var defaultTarget = 'body'; var currentSelectionColumnId = -1; + var currentDiffBlockIdx = -1; function Diff2HtmlUI(config) { var cfg = config || {}; @@ -190,6 +191,33 @@ clipboardData.setData('text', text); event.preventDefault(); }); + + body.on('mousedown', '.btn-previous', function() { + if (currentDiffBlockIdx === -1){ + return; + } + currentDiffBlockIdx -= 1; + var target = document.getElementById('diff-block-' + currentDiffBlockIdx); + if (target) { + var top = target.offsetTop + 200; + window.scrollTo(0, top); + } else { + currentDiffBlockIdx = 0; + alert('already first'); + } + }); + + body.on('mousedown', '.btn-next', function() { + currentDiffBlockIdx += 1; + var target = document.getElementById('diff-block-' + currentDiffBlockIdx); + if (target) { + var top = target.offsetTop + 200; + window.scrollTo(0, top); + } else { + currentDiffBlockIdx -= 1; + alert('already last'); + } + }); }; Diff2HtmlUI.prototype._getSelectedText = function() {