UNPKG

10.4 kBJavaScriptView Raw
1var __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};
12import * as Rematch from './rematch';
13import * as renderUtils from './render-utils';
14import { LineType, } from './types';
15export var defaultLineByLineRendererConfig = __assign(__assign({}, renderUtils.defaultRenderConfig), { renderNothingWhenEmpty: false, matchingMaxComparisons: 2500, maxLineSizeInBlockForComparison: 200 });
16var genericTemplatesPath = 'generic';
17var baseTemplatesPath = 'line-by-line';
18var iconsBaseTemplatesPath = 'icon';
19var tagsBaseTemplatesPath = 'tag';
20var 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: renderUtils.escapeForHtml(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 === ' ' ? '&nbsp;' : line.prefix,
205 content: line.content,
206 lineNumber: lineNumberHtml,
207 });
208 };
209 return LineByLineRenderer;
210}());
211export default LineByLineRenderer;
212//# sourceMappingURL=line-by-line-renderer.js.map
\No newline at end of file