From 6a47f8f3a55cc73d8b84d7fcd23023c3a6da5758 Mon Sep 17 00:00:00 2001 From: Rodrigo Fernandes Date: Mon, 5 Sep 2016 22:13:51 +0100 Subject: [PATCH] Fix convert &nbps; to proper white spaces with white-space wrap --- src/line-by-line-printer.js | 31 +++++++++++------ src/printer-utils.js | 18 ++++++++++ src/side-by-side-printer.js | 43 ++++++++++++++---------- src/ui/css/diff2html.css | 22 ++++++++---- src/utils.js | 4 --- test/line-by-line-tests.js | 54 ++++++++++++++++-------------- test/side-by-side-printer-tests.js | 12 +++---- test/utils-tests.js | 14 -------- 8 files changed, 114 insertions(+), 84 deletions(-) diff --git a/src/line-by-line-printer.js b/src/line-by-line-printer.js index cb18638..b07eb53 100644 --- a/src/line-by-line-printer.js +++ b/src/line-by-line-printer.js @@ -120,15 +120,15 @@ var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); processedOldLines += - that.makeLineHtml(deleteType, oldLine.oldNumber, oldLine.newNumber, + that.makeLineHtml(file.isCombined, deleteType, oldLine.oldNumber, oldLine.newNumber, diff.first.line, diff.first.prefix); processedNewLines += - that.makeLineHtml(insertType, newLine.oldNumber, newLine.newNumber, + that.makeLineHtml(file.isCombined, insertType, newLine.oldNumber, newLine.newNumber, diff.second.line, diff.second.prefix); } lines += processedOldLines + processedNewLines; - lines += that._processLines(oldLines.slice(common), newLines.slice(common)); + lines += that._processLines(file.isCombined, oldLines.slice(common), newLines.slice(common)); }); oldLines = []; @@ -145,9 +145,9 @@ } if (line.type === diffParser.LINE_TYPE.CONTEXT) { - lines += that.makeLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine); + 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(line.type, line.oldNumber, line.newNumber, escapedLine); + lines += that.makeLineHtml(file.isCombined, 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 && Boolean(oldLines.length)) { @@ -164,37 +164,46 @@ }).join('\n'); }; - LineByLinePrinter.prototype._processLines = function(oldLines, newLines) { + LineByLinePrinter.prototype._processLines = function(isCombined, oldLines, newLines) { var lines = ''; for (var i = 0; i < oldLines.length; i++) { var oldLine = oldLines[i]; var oldEscapedLine = utils.escape(oldLine.content); - lines += this.makeLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine); + lines += this.makeLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine); } for (var j = 0; j < newLines.length; j++) { var newLine = newLines[j]; var newEscapedLine = utils.escape(newLine.content); - lines += this.makeLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine); + lines += this.makeLineHtml(isCombined, newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine); } return lines; }; - LineByLinePrinter.prototype.makeLineHtml = function(type, oldNumber, newNumber, content, prefix) { + LineByLinePrinter.prototype.makeLineHtml = function(isCombined, type, oldNumber, newNumber, content, possiblePrefix) { var lineNumberTemplate = hoganUtils.render(baseTemplatesPath, 'numbers', { oldNumber: utils.valueOrEmpty(oldNumber), newNumber: utils.valueOrEmpty(newNumber) }); + var lineWithoutPrefix = content; + var prefix = possiblePrefix; + + if (!prefix) { + var lineWithPrefix = printerUtils.separatePrefix(isCombined, content); + prefix = lineWithPrefix.prefix; + lineWithoutPrefix = lineWithPrefix.line; + } + return hoganUtils.render(genericTemplatesPath, 'line', { type: type, lineClass: 'd2h-code-linenumber', contentClass: 'd2h-code-line', - prefix: prefix && utils.convertWhiteSpaceToNonBreakingSpace(prefix), - content: content && utils.convertWhiteSpaceToNonBreakingSpace(content), + prefix: prefix, + content: lineWithoutPrefix, lineNumber: lineNumberTemplate }); }; diff --git a/src/printer-utils.js b/src/printer-utils.js index b4e39f5..3e0ab0d 100644 --- a/src/printer-utils.js +++ b/src/printer-utils.js @@ -15,6 +15,24 @@ function PrinterUtils() { } + PrinterUtils.prototype.separatePrefix = function(isCombined, line) { + var prefix; + var lineWithoutPrefix; + + if (isCombined) { + prefix = line.substring(0, 2); + lineWithoutPrefix = line.substring(2); + } else { + prefix = line.substring(0, 1); + lineWithoutPrefix = line.substring(1); + } + + return { + 'prefix': prefix, + 'line': lineWithoutPrefix + }; + }; + PrinterUtils.prototype.getHtmlId = function(file) { var hashCode = function(text) { var i, chr, len; diff --git a/src/side-by-side-printer.js b/src/side-by-side-printer.js index c554835..bbf1dc8 100644 --- a/src/side-by-side-printer.js +++ b/src/side-by-side-printer.js @@ -122,10 +122,10 @@ var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); fileHtml.left += - that.generateSingleLineHtml(deleteType, oldLine.oldNumber, + that.generateSingleLineHtml(file.isCombined, deleteType, oldLine.oldNumber, diff.first.line, diff.first.prefix); fileHtml.right += - that.generateSingleLineHtml(insertType, newLine.newNumber, + that.generateSingleLineHtml(file.isCombined, insertType, newLine.newNumber, diff.second.line, diff.second.prefix); } @@ -133,7 +133,7 @@ var oldSlice = oldLines.slice(common); var newSlice = newLines.slice(common); - var tmpHtml = that.processLines(oldSlice, newSlice); + var tmpHtml = that.processLines(file.isCombined, oldSlice, newSlice); fileHtml.left += tmpHtml.left; fileHtml.right += tmpHtml.right; } @@ -154,11 +154,11 @@ } 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); + 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(diffParser.LINE_TYPE.CONTEXT, '', '', ''); - fileHtml.right += that.generateSingleLineHtml(line.type, line.newNumber, escapedLine, prefix); + fileHtml.left += that.generateSingleLineHtml(file.isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); + fileHtml.right += that.generateSingleLineHtml(file.isCombined, 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 && Boolean(oldLines.length)) { @@ -175,7 +175,7 @@ return fileHtml; }; - SideBySidePrinter.prototype.processLines = function(oldLines, newLines) { + SideBySidePrinter.prototype.processLines = function(isCombined, oldLines, newLines) { var that = this; var fileHtml = {}; fileHtml.left = ''; @@ -201,14 +201,14 @@ } if (oldLine && newLine) { - fileHtml.left += that.generateSingleLineHtml(oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); - fileHtml.right += that.generateSingleLineHtml(newLine.type, newLine.newNumber, newContent, newPrefix); + 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(oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); - fileHtml.right += that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, '', '', ''); + fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); + fileHtml.right += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); } else if (newLine) { - fileHtml.left += that.generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, '', '', ''); - fileHtml.right += that.generateSingleLineHtml(newLine.type, newLine.newNumber, newContent, newPrefix); + fileHtml.left += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); + fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix); } else { console.error('How did it get here?'); } @@ -217,14 +217,23 @@ return fileHtml; }; - SideBySidePrinter.prototype.generateSingleLineHtml = function(type, number, content, prefix) { + SideBySidePrinter.prototype.generateSingleLineHtml = function(isCombined, type, number, content, possiblePrefix) { + var lineWithoutPrefix = content; + var prefix = possiblePrefix; + + if (!prefix) { + var lineWithPrefix = printerUtils.separatePrefix(isCombined, content); + prefix = lineWithPrefix.prefix; + lineWithoutPrefix = lineWithPrefix.line; + } + return hoganUtils.render(genericTemplatesPath, 'line', { type: type, lineClass: 'd2h-code-side-linenumber', contentClass: 'd2h-code-side-line', - prefix: prefix && utils.convertWhiteSpaceToNonBreakingSpace(prefix), - content: content && utils.convertWhiteSpaceToNonBreakingSpace(content), + prefix: prefix, + content: lineWithoutPrefix, lineNumber: number }); }; diff --git a/src/ui/css/diff2html.css b/src/ui/css/diff2html.css index 88f41a4..c25f9e3 100644 --- a/src/ui/css/diff2html.css +++ b/src/ui/css/diff2html.css @@ -47,8 +47,8 @@ display: -ms-flexbox; display: flex; -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; + -ms-flex-align: center; + align-items: center; width: 100%; font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 15px; @@ -98,18 +98,20 @@ } .d2h-code-line { - display: block; + display: inline-block; white-space: nowrap; padding: 0 10px; margin-left: 80px; + height: 20px; + line-height: 20px; } .d2h-code-side-line { - display: block; + display: inline-block; white-space: nowrap; padding: 0 10px; - height: 18px; - line-height: 18px; + height: 20px; + line-height: 20px; margin-left: 50px; } @@ -129,17 +131,23 @@ text-decoration: none; background-color: #97f295; border-radius: 0.2em; + text-align: left; } .d2h-code-line-prefix { - float: left; + display: inline; background: none; padding: 0; + word-wrap: normal; + white-space: pre; } .d2h-code-line-ctn { + display: inline; background: none; padding: 0; + word-wrap: normal; + white-space: pre; } .line-num1 { diff --git a/src/utils.js b/src/utils.js index 341204c..173d05e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -9,10 +9,6 @@ function Utils() { } - Utils.prototype.convertWhiteSpaceToNonBreakingSpace = function(str) { - return str.slice(0).replace(/ /g, ' '); - }; - Utils.prototype.escape = function(str) { return str.slice(0) .replace(/&/g, '&') diff --git a/test/line-by-line-tests.js b/test/line-by-line-tests.js index a0ba661..9cad0d0 100644 --- a/test/line-by-line-tests.js +++ b/test/line-by-line-tests.js @@ -26,8 +26,8 @@ describe('LineByLinePrinter', function() { var diffParser = require('../src/diff-parser.js').DiffParser; var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml( - diffParser.LINE_TYPE.INSERTS, '', 30, '+', 'test'); + var fileHtml = lineByLinePrinter.makeLineHtml(false, + diffParser.LINE_TYPE.INSERTS, '', 30, 'test', '+'); fileHtml = fileHtml.replace(/\n\n+/g, '\n'); var expected = '\n' + ' \n' + @@ -36,8 +36,8 @@ describe('LineByLinePrinter', function() { ' \n' + ' \n' + '
\n' + - ' test\n' + - ' +\n' + + ' +\n' + + ' test\n' + '
\n' + ' \n' + ''; @@ -48,8 +48,8 @@ describe('LineByLinePrinter', function() { it('should work for deletions', function() { var diffParser = require('../src/diff-parser.js').DiffParser; var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml( - diffParser.LINE_TYPE.DELETES, 30, '', '-', 'test'); + var fileHtml = lineByLinePrinter.makeLineHtml(false, + diffParser.LINE_TYPE.DELETES, 30, '', 'test', '-'); fileHtml = fileHtml.replace(/\n\n+/g, '\n'); var expected = '\n' + ' \n' + @@ -58,8 +58,8 @@ describe('LineByLinePrinter', function() { ' \n' + ' \n' + '
\n' + - ' test\n' + - ' -\n' + + ' -\n' + + ' test\n' + '
\n' + ' \n' + ''; @@ -70,8 +70,8 @@ describe('LineByLinePrinter', function() { it('should convert indents into non breakin spaces (2 white spaces)', function() { var diffParser = require('../src/diff-parser.js').DiffParser; var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml( - diffParser.LINE_TYPE.INSERTS, '', 30, '+', ' test'); + var fileHtml = lineByLinePrinter.makeLineHtml(false, + diffParser.LINE_TYPE.INSERTS, '', 30, ' test', '+'); fileHtml = fileHtml.replace(/\n\n+/g, '\n'); var expected = '\n' + ' \n' + @@ -80,8 +80,8 @@ describe('LineByLinePrinter', function() { ' \n' + ' \n' + '
\n' + - '   test\n' + - ' +\n' + + ' +\n' + + ' test\n' + '
\n' + ' \n' + ''; @@ -92,8 +92,8 @@ describe('LineByLinePrinter', function() { it('should convert indents into non breakin spaces (4 white spaces)', function() { var diffParser = require('../src/diff-parser.js').DiffParser; var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml( - diffParser.LINE_TYPE.INSERTS, '', 30, '+', ' test'); + var fileHtml = lineByLinePrinter.makeLineHtml(false, + diffParser.LINE_TYPE.INSERTS, '', 30, ' test', '+'); fileHtml = fileHtml.replace(/\n\n+/g, '\n'); var expected = '\n' + ' \n' + @@ -102,8 +102,8 @@ describe('LineByLinePrinter', function() { ' \n' + ' \n' + '
\n' + - '     test\n' + - ' +\n' + + ' +\n' + + ' test\n' + '
\n' + ' \n' + ''; @@ -114,8 +114,8 @@ describe('LineByLinePrinter', function() { it('should convert indents into non breakin spaces (one tab)', function() { var diffParser = require('../src/diff-parser.js').DiffParser; var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml( - diffParser.LINE_TYPE.INSERTS, '', 30, '+', Utils.escape('\ttest')); + var fileHtml = lineByLinePrinter.makeLineHtml(false, + diffParser.LINE_TYPE.INSERTS, '', 30, Utils.escape('\ttest'), '+'); fileHtml = fileHtml.replace(/\n\n+/g, '\n'); var expected = '\n' + ' \n' + @@ -125,8 +125,8 @@ describe('LineByLinePrinter', function() { ' \n' + ' \n' + '
\n' + - '     test\n' + - ' +\n' + + ' +\n' + + ' test\n' + '
\n' + ' \n' + ''; @@ -452,7 +452,7 @@ describe('LineByLinePrinter', function() { newNumber: 1 }]; - var html = lineByLinePrinter._processLines(oldLines, newLines); + var html = lineByLinePrinter._processLines(false, oldLines, newLines); var expected = '\n' + @@ -462,7 +462,8 @@ describe('LineByLinePrinter', function() { ' \n' + ' \n' + '
\n' + - ' -test\n' + + ' -\n' + + ' test\n' + '
\n' + ' \n' + '\n' + @@ -472,7 +473,8 @@ describe('LineByLinePrinter', function() { ' \n' + ' \n' + '
\n' + - ' +test1r\n' + + ' +\n' + + ' test1r\n' + '
\n' + ' \n' + ''; @@ -540,7 +542,8 @@ describe('LineByLinePrinter', function() { ' \n' + ' \n' + '
\n' + - '  one context line\n' + + ' \n' + + ' one context line\n' + '
\n' + ' \n' + '\n' + @@ -572,7 +575,8 @@ describe('LineByLinePrinter', function() { ' \n' + ' \n' + '
\n' + - ' +test2r\n' + + ' +\n' + + ' test2r\n' + '
\n' + ' \n' + ''; diff --git a/test/side-by-side-printer-tests.js b/test/side-by-side-printer-tests.js index b90e2c2..c625f6d 100644 --- a/test/side-by-side-printer-tests.js +++ b/test/side-by-side-printer-tests.js @@ -83,7 +83,7 @@ describe('SideBySidePrinter', function() { ' \n' + ' \n' + '
\n' + - '  \n' + + ' \n' + ' context\n' + '
\n' + ' \n' + @@ -120,7 +120,7 @@ describe('SideBySidePrinter', function() { ' \n' + ' \n' + '
\n' + - '  \n' + + ' \n' + ' context\n' + '
\n' + ' \n' + @@ -141,7 +141,7 @@ describe('SideBySidePrinter', function() { ' \n' + '
\n' + ' +\n' + - ' another added\n' + + ' another added\n' + '
\n' + ' \n' + ''; @@ -156,7 +156,7 @@ describe('SideBySidePrinter', function() { var diffParser = require('../src/diff-parser.js').DiffParser; var sideBySidePrinter = new SideBySidePrinter({}); - var fileHtml = sideBySidePrinter.generateSingleLineHtml( + var fileHtml = sideBySidePrinter.generateSingleLineHtml(false, diffParser.LINE_TYPE.INSERTS, 30, 'test', '+'); var expected = '\n' + ' \n' + @@ -176,7 +176,7 @@ describe('SideBySidePrinter', function() { var diffParser = require('../src/diff-parser.js').DiffParser; var sideBySidePrinter = new SideBySidePrinter({}); - var fileHtml = sideBySidePrinter.generateSingleLineHtml( + var fileHtml = sideBySidePrinter.generateSingleLineHtml(false, diffParser.LINE_TYPE.DELETES, 30, 'test', '-'); var expected = '\n' + ' \n' + @@ -366,7 +366,7 @@ describe('SideBySidePrinter', function() { }]; var sideBySidePrinter = new SideBySidePrinter({matching: 'lines'}); - var html = sideBySidePrinter.processLines(oldLines, newLines); + var html = sideBySidePrinter.processLines(false, oldLines, newLines); var expectedLeft = '\n' + ' \n' + diff --git a/test/utils-tests.js b/test/utils-tests.js index aa2d944..69f9ab5 100644 --- a/test/utils-tests.js +++ b/test/utils-tests.js @@ -22,18 +22,4 @@ describe('Utils', function() { assert.equal(expected, result); }); }); - describe('convertWhiteSpaceToNonBreakingSpace', function() { - it('should escape 1 whitespaces with  ', function() { - var result = Utils.convertWhiteSpaceToNonBreakingSpace(' '); - assert.equal(' ', result); - }); - it('should escape 2 whitespaces with  ', function() { - var result = Utils.convertWhiteSpaceToNonBreakingSpace(' '); - assert.equal('  ', result); - }); - it('should escape 4 whitespaces with  ', function() { - var result = Utils.convertWhiteSpaceToNonBreakingSpace(' '); - assert.equal('    ', result); - }); - }); });