diff --git a/src/__tests__/line-by-line-tests.ts b/src/__tests__/line-by-line-tests.ts index a3673ad..4e1ae32 100644 --- a/src/__tests__/line-by-line-tests.ts +++ b/src/__tests__/line-by-line-tests.ts @@ -23,9 +23,19 @@ describe('LineByLineRenderer', () => { describe('makeLineHtml', () => { it('should work for insertions', () => { + const file = { + addedLines: 12, + deletedLines: 41, + language: 'js', + oldName: 'my/file/name.js', + newName: 'my/file/name.js', + isCombined: false, + isGitDiff: false, + blocks: [], + }; const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); - const fileHtml = lineByLineRenderer.generateSingleLineHtml({ + const fileHtml = lineByLineRenderer.generateSingleLineHtml(file, { type: CSSLineClass.INSERTS, prefix: '+', content: 'test', @@ -49,9 +59,19 @@ describe('LineByLineRenderer', () => { }); it('should work for deletions', () => { + const file = { + addedLines: 12, + deletedLines: 41, + language: 'js', + oldName: 'my/file/name.js', + newName: 'my/file/name.js', + isCombined: false, + isGitDiff: false, + blocks: [], + }; const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); - const fileHtml = lineByLineRenderer.generateSingleLineHtml({ + const fileHtml = lineByLineRenderer.generateSingleLineHtml(file, { type: CSSLineClass.DELETES, prefix: '-', content: 'test', @@ -75,9 +95,19 @@ describe('LineByLineRenderer', () => { }); it('should convert indents into non breakin spaces (2 white spaces)', () => { + const file = { + addedLines: 12, + deletedLines: 41, + language: 'js', + oldName: 'my/file/name.js', + newName: 'my/file/name.js', + isCombined: false, + isGitDiff: false, + blocks: [], + }; const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); - const fileHtml = lineByLineRenderer.generateSingleLineHtml({ + const fileHtml = lineByLineRenderer.generateSingleLineHtml(file, { type: CSSLineClass.INSERTS, prefix: '+', content: ' test', @@ -101,9 +131,19 @@ describe('LineByLineRenderer', () => { }); it('should convert indents into non breakin spaces (4 white spaces)', () => { + const file = { + addedLines: 12, + deletedLines: 41, + language: 'js', + oldName: 'my/file/name.js', + newName: 'my/file/name.js', + isCombined: false, + isGitDiff: false, + blocks: [], + }; const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); - const fileHtml = lineByLineRenderer.generateSingleLineHtml({ + const fileHtml = lineByLineRenderer.generateSingleLineHtml(file, { type: CSSLineClass.INSERTS, prefix: '+', content: ' test', @@ -127,9 +167,19 @@ describe('LineByLineRenderer', () => { }); it('should preserve tabs', () => { + const file = { + addedLines: 12, + deletedLines: 41, + language: 'js', + oldName: 'my/file/name.js', + newName: 'my/file/name.js', + isCombined: false, + isGitDiff: false, + blocks: [], + }; const hoganUtils = new HoganJsUtils({}); const lineByLineRenderer = new LineByLineRenderer(hoganUtils, {}); - const fileHtml = lineByLineRenderer.generateSingleLineHtml({ + const fileHtml = lineByLineRenderer.generateSingleLineHtml(file, { type: CSSLineClass.INSERTS, prefix: '+', content: '\ttest', diff --git a/src/line-by-line-renderer.ts b/src/line-by-line-renderer.ts index 77b5f18..bbbe61e 100644 --- a/src/line-by-line-renderer.ts +++ b/src/line-by-line-renderer.ts @@ -115,7 +115,7 @@ export default class LineByLineRenderer { this.applyLineGrouping(block).forEach(([contextLines, oldLines, newLines]) => { if (oldLines.length && newLines.length && !contextLines.length) { this.applyRematchMatching(oldLines, newLines, matcher).map(([oldLines, newLines]) => { - const { left, right } = this.processChangedLines(file.isCombined, oldLines, newLines); + const { left, right } = this.processChangedLines(file, file.isCombined, oldLines, newLines); lines.push(...left); lines.push(...right); }); @@ -135,6 +135,20 @@ export default class LineByLineRenderer { } else if (oldLines.length || newLines.length) { const { left, right } = this.processChangedLines(file.isCombined, oldLines, newLines); lines.push(...left); + lines.push(...right); + lines.push( + this.generateSingleLineHtml(file, { + type: renderUtils.CSSLineClass.CONTEXT, + prefix: prefix, + content: content, + oldNumber: line.oldNumber, + newNumber: line.newNumber, + }), + ); + }); + } else if (oldLines.length || newLines.length) { + const { left, right } = this.processChangedLines(file, file.isCombined, oldLines, newLines); + lines.push(...left); lines.push(...right); } else { console.error('Unknown state reached while processing groups of lines', contextLines, oldLines, newLines); @@ -205,7 +219,8 @@ export default class LineByLineRenderer { return doMatching ? matcher(oldLines, newLines) : [[oldLines, newLines]]; } - processChangedLines(isCombined: boolean, oldLines: DiffLine[], newLines: DiffLine[]): FileHtml { + + processChangedLines(file: DiffFile, isCombined: boolean, oldLines: DiffLine[], newLines: DiffLine[]): FileHtml { const fileHtml: FileHtml = { left: [], right: [], @@ -257,7 +272,7 @@ export default class LineByLineRenderer { } : undefined; - const { left, right } = this.generateLineHtml(preparedOldLine, preparedNewLine); + const { left, right } = this.generateLineHtml(file, preparedOldLine, preparedNewLine); fileHtml.left.push(left); fileHtml.right.push(right); } @@ -265,14 +280,14 @@ export default class LineByLineRenderer { return fileHtml; } - generateLineHtml(oldLine?: DiffPreparedLine, newLine?: DiffPreparedLine): LineHtml { + generateLineHtml(file: DiffFile, oldLine?: DiffPreparedLine, newLine?: DiffPreparedLine): LineHtml { return { - left: this.generateSingleLineHtml(oldLine), - right: this.generateSingleLineHtml(newLine), + left: this.generateSingleLineHtml(file, oldLine), + right: this.generateSingleLineHtml(file, newLine), }; } - generateSingleLineHtml(line?: DiffPreparedLine): string { + generateSingleLineHtml(file: DiffFile, line?: DiffPreparedLine): string { if (line === undefined) return ''; const oldLineNumberHtml = this.hoganUtils.render(genericTemplatesPath, 'line-number', { @@ -292,6 +307,9 @@ export default class LineByLineRenderer { contentClass: 'd2h-code-line', prefix: line.prefix === ' ' ? ' ' : line.prefix, content: line.content, + lineNumber: lineNumberHtml, + line, + file, }); return oldLineNumberHtml.concat(newLineNumberHtml, newLineContentHtml);