1 | var __assign = (this && this.__assign) || function () {
|
2 | __assign = Object.assign || function(t) {
|
3 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4 | s = arguments[i];
|
5 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6 | t[p] = s[p];
|
7 | }
|
8 | return t;
|
9 | };
|
10 | return __assign.apply(this, arguments);
|
11 | };
|
12 | import * as Rematch from './rematch';
|
13 | import * as renderUtils from './render-utils';
|
14 | import { LineType, } from './types';
|
15 | export var defaultLineByLineRendererConfig = __assign(__assign({}, renderUtils.defaultRenderConfig), { renderNothingWhenEmpty: false, matchingMaxComparisons: 2500, maxLineSizeInBlockForComparison: 200 });
|
16 | var genericTemplatesPath = 'generic';
|
17 | var baseTemplatesPath = 'line-by-line';
|
18 | var iconsBaseTemplatesPath = 'icon';
|
19 | var tagsBaseTemplatesPath = 'tag';
|
20 | var LineByLineRenderer = (function () {
|
21 | function LineByLineRenderer(hoganUtils, config) {
|
22 | if (config === void 0) { config = {}; }
|
23 | this.hoganUtils = hoganUtils;
|
24 | this.config = __assign(__assign({}, defaultLineByLineRendererConfig), config);
|
25 | }
|
26 | LineByLineRenderer.prototype.render = function (diffFiles) {
|
27 | var _this = this;
|
28 | var diffsHtml = diffFiles
|
29 | .map(function (file) {
|
30 | var diffs;
|
31 | if (file.blocks.length) {
|
32 | diffs = _this.generateFileHtml(file);
|
33 | }
|
34 | else {
|
35 | diffs = _this.generateEmptyDiff();
|
36 | }
|
37 | return _this.makeFileDiffHtml(file, diffs);
|
38 | })
|
39 | .join('\n');
|
40 | return this.hoganUtils.render(genericTemplatesPath, 'wrapper', { content: diffsHtml });
|
41 | };
|
42 | LineByLineRenderer.prototype.makeFileDiffHtml = function (file, diffs) {
|
43 | if (this.config.renderNothingWhenEmpty && Array.isArray(file.blocks) && file.blocks.length === 0)
|
44 | return '';
|
45 | var fileDiffTemplate = this.hoganUtils.template(baseTemplatesPath, 'file-diff');
|
46 | var filePathTemplate = this.hoganUtils.template(genericTemplatesPath, 'file-path');
|
47 | var fileIconTemplate = this.hoganUtils.template(iconsBaseTemplatesPath, 'file');
|
48 | var fileTagTemplate = this.hoganUtils.template(tagsBaseTemplatesPath, renderUtils.getFileIcon(file));
|
49 | return fileDiffTemplate.render({
|
50 | file: file,
|
51 | fileHtmlId: renderUtils.getHtmlId(file),
|
52 | diffs: diffs,
|
53 | filePath: filePathTemplate.render({
|
54 | fileDiffName: renderUtils.filenameDiff(file),
|
55 | }, {
|
56 | fileIcon: fileIconTemplate,
|
57 | fileTag: fileTagTemplate,
|
58 | }),
|
59 | });
|
60 | };
|
61 | LineByLineRenderer.prototype.generateEmptyDiff = function () {
|
62 | return this.hoganUtils.render(genericTemplatesPath, 'empty-diff', {
|
63 | contentClass: 'd2h-code-line',
|
64 | CSSLineClass: renderUtils.CSSLineClass,
|
65 | });
|
66 | };
|
67 | LineByLineRenderer.prototype.generateFileHtml = function (file) {
|
68 | var _this = this;
|
69 | var matcher = Rematch.newMatcherFn(Rematch.newDistanceFn(function (e) { return renderUtils.deconstructLine(e.content, file.isCombined).content; }));
|
70 | return file.blocks
|
71 | .map(function (block) {
|
72 | var lines = _this.hoganUtils.render(genericTemplatesPath, 'block-header', {
|
73 | CSSLineClass: renderUtils.CSSLineClass,
|
74 | blockHeader: block.header,
|
75 | lineClass: 'd2h-code-linenumber',
|
76 | contentClass: 'd2h-code-line',
|
77 | });
|
78 | _this.applyLineGroupping(block).forEach(function (_a) {
|
79 | var contextLines = _a[0], oldLines = _a[1], newLines = _a[2];
|
80 | if (oldLines.length && newLines.length && !contextLines.length) {
|
81 | _this.applyRematchMatching(oldLines, newLines, matcher).map(function (_a) {
|
82 | var oldLines = _a[0], newLines = _a[1];
|
83 | var _b = _this.processChangedLines(file.isCombined, oldLines, newLines), left = _b.left, right = _b.right;
|
84 | lines += left;
|
85 | lines += right;
|
86 | });
|
87 | }
|
88 | else if (contextLines.length) {
|
89 | contextLines.forEach(function (line) {
|
90 | var _a = renderUtils.deconstructLine(line.content, file.isCombined), prefix = _a.prefix, content = _a.content;
|
91 | lines += _this.generateSingleLineHtml({
|
92 | type: renderUtils.CSSLineClass.CONTEXT,
|
93 | prefix: prefix,
|
94 | content: content,
|
95 | oldNumber: line.oldNumber,
|
96 | newNumber: line.newNumber,
|
97 | });
|
98 | });
|
99 | }
|
100 | else if (oldLines.length || newLines.length) {
|
101 | var _b = _this.processChangedLines(file.isCombined, oldLines, newLines), left = _b.left, right = _b.right;
|
102 | lines += left;
|
103 | lines += right;
|
104 | }
|
105 | else {
|
106 | console.error('Unknown state reached while processing groups of lines', contextLines, oldLines, newLines);
|
107 | }
|
108 | });
|
109 | return lines;
|
110 | })
|
111 | .join('\n');
|
112 | };
|
113 | LineByLineRenderer.prototype.applyLineGroupping = function (block) {
|
114 | var blockLinesGroups = [];
|
115 | var oldLines = [];
|
116 | var newLines = [];
|
117 | for (var i = 0; i < block.lines.length; i++) {
|
118 | var diffLine = block.lines[i];
|
119 | if ((diffLine.type !== LineType.INSERT && newLines.length) ||
|
120 | (diffLine.type === LineType.CONTEXT && oldLines.length > 0)) {
|
121 | blockLinesGroups.push([[], oldLines, newLines]);
|
122 | oldLines = [];
|
123 | newLines = [];
|
124 | }
|
125 | if (diffLine.type === LineType.CONTEXT) {
|
126 | blockLinesGroups.push([[diffLine], [], []]);
|
127 | }
|
128 | else if (diffLine.type === LineType.INSERT && oldLines.length === 0) {
|
129 | blockLinesGroups.push([[], [], [diffLine]]);
|
130 | }
|
131 | else if (diffLine.type === LineType.INSERT && oldLines.length > 0) {
|
132 | newLines.push(diffLine);
|
133 | }
|
134 | else if (diffLine.type === LineType.DELETE) {
|
135 | oldLines.push(diffLine);
|
136 | }
|
137 | }
|
138 | if (oldLines.length || newLines.length) {
|
139 | blockLinesGroups.push([[], oldLines, newLines]);
|
140 | oldLines = [];
|
141 | newLines = [];
|
142 | }
|
143 | return blockLinesGroups;
|
144 | };
|
145 | LineByLineRenderer.prototype.applyRematchMatching = function (oldLines, newLines, matcher) {
|
146 | var comparisons = oldLines.length * newLines.length;
|
147 | var maxLineSizeInBlock = Math.max.apply(null, [0].concat(oldLines.concat(newLines).map(function (elem) { return elem.content.length; })));
|
148 | var doMatching = comparisons < this.config.matchingMaxComparisons &&
|
149 | maxLineSizeInBlock < this.config.maxLineSizeInBlockForComparison &&
|
150 | (this.config.matching === 'lines' || this.config.matching === 'words');
|
151 | return doMatching ? matcher(oldLines, newLines) : [[oldLines, newLines]];
|
152 | };
|
153 | LineByLineRenderer.prototype.processChangedLines = function (isCombined, oldLines, newLines) {
|
154 | var fileHtml = {
|
155 | right: '',
|
156 | left: '',
|
157 | };
|
158 | var maxLinesNumber = Math.max(oldLines.length, newLines.length);
|
159 | for (var i = 0; i < maxLinesNumber; i++) {
|
160 | var oldLine = oldLines[i];
|
161 | var newLine = newLines[i];
|
162 | var diff = oldLine !== undefined && newLine !== undefined
|
163 | ? renderUtils.diffHighlight(oldLine.content, newLine.content, isCombined, this.config)
|
164 | : undefined;
|
165 | var preparedOldLine = oldLine !== undefined && oldLine.oldNumber !== undefined
|
166 | ? __assign(__assign({}, (diff !== undefined
|
167 | ? {
|
168 | prefix: diff.oldLine.prefix,
|
169 | content: diff.oldLine.content,
|
170 | type: renderUtils.CSSLineClass.DELETE_CHANGES,
|
171 | }
|
172 | : __assign(__assign({}, renderUtils.deconstructLine(oldLine.content, isCombined)), { type: renderUtils.toCSSClass(oldLine.type) }))), { oldNumber: oldLine.oldNumber, newNumber: oldLine.newNumber }) : undefined;
|
173 | var preparedNewLine = newLine !== undefined && newLine.newNumber !== undefined
|
174 | ? __assign(__assign({}, (diff !== undefined
|
175 | ? {
|
176 | prefix: diff.newLine.prefix,
|
177 | content: diff.newLine.content,
|
178 | type: renderUtils.CSSLineClass.INSERT_CHANGES,
|
179 | }
|
180 | : __assign(__assign({}, renderUtils.deconstructLine(newLine.content, isCombined)), { type: renderUtils.toCSSClass(newLine.type) }))), { oldNumber: newLine.oldNumber, newNumber: newLine.newNumber }) : undefined;
|
181 | var _a = this.generateLineHtml(preparedOldLine, preparedNewLine), left = _a.left, right = _a.right;
|
182 | fileHtml.left += left;
|
183 | fileHtml.right += right;
|
184 | }
|
185 | return fileHtml;
|
186 | };
|
187 | LineByLineRenderer.prototype.generateLineHtml = function (oldLine, newLine) {
|
188 | return {
|
189 | left: this.generateSingleLineHtml(oldLine),
|
190 | right: this.generateSingleLineHtml(newLine),
|
191 | };
|
192 | };
|
193 | LineByLineRenderer.prototype.generateSingleLineHtml = function (line) {
|
194 | if (line === undefined)
|
195 | return '';
|
196 | var lineNumberHtml = this.hoganUtils.render(baseTemplatesPath, 'numbers', {
|
197 | oldNumber: line.oldNumber || '',
|
198 | newNumber: line.newNumber || '',
|
199 | });
|
200 | return this.hoganUtils.render(genericTemplatesPath, 'line', {
|
201 | type: line.type,
|
202 | lineClass: 'd2h-code-linenumber',
|
203 | contentClass: 'd2h-code-line',
|
204 | prefix: line.prefix === ' ' ? ' ' : line.prefix,
|
205 | content: line.content,
|
206 | lineNumber: lineNumberHtml,
|
207 | });
|
208 | };
|
209 | return LineByLineRenderer;
|
210 | }());
|
211 | export default LineByLineRenderer;
|
212 |
|
\ | No newline at end of file |