UNPKG

11.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 defaultSideBySideRendererConfig = __assign(__assign({}, renderUtils.defaultRenderConfig), { renderNothingWhenEmpty: false, matchingMaxComparisons: 2500, maxLineSizeInBlockForComparison: 200 });
16var genericTemplatesPath = 'generic';
17var baseTemplatesPath = 'side-by-side';
18var iconsBaseTemplatesPath = 'icon';
19var tagsBaseTemplatesPath = 'tag';
20var SideBySideRenderer = (function () {
21 function SideBySideRenderer(hoganUtils, config) {
22 if (config === void 0) { config = {}; }
23 this.hoganUtils = hoganUtils;
24 this.config = __assign(__assign({}, defaultSideBySideRendererConfig), config);
25 }
26 SideBySideRenderer.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 SideBySideRenderer.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 SideBySideRenderer.prototype.generateEmptyDiff = function () {
62 return {
63 right: '',
64 left: this.hoganUtils.render(genericTemplatesPath, 'empty-diff', {
65 contentClass: 'd2h-code-side-line',
66 CSSLineClass: renderUtils.CSSLineClass,
67 }),
68 };
69 };
70 SideBySideRenderer.prototype.generateFileHtml = function (file) {
71 var _this = this;
72 var matcher = Rematch.newMatcherFn(Rematch.newDistanceFn(function (e) { return renderUtils.deconstructLine(e.content, file.isCombined).content; }));
73 return file.blocks
74 .map(function (block) {
75 var fileHtml = {
76 left: _this.makeHeaderHtml(block.header),
77 right: _this.makeHeaderHtml(''),
78 };
79 _this.applyLineGroupping(block).forEach(function (_a) {
80 var contextLines = _a[0], oldLines = _a[1], newLines = _a[2];
81 if (oldLines.length && newLines.length && !contextLines.length) {
82 _this.applyRematchMatching(oldLines, newLines, matcher).map(function (_a) {
83 var oldLines = _a[0], newLines = _a[1];
84 var _b = _this.processChangedLines(file.isCombined, oldLines, newLines), left = _b.left, right = _b.right;
85 fileHtml.left += left;
86 fileHtml.right += right;
87 });
88 }
89 else if (contextLines.length) {
90 contextLines.forEach(function (line) {
91 var _a = renderUtils.deconstructLine(line.content, file.isCombined), prefix = _a.prefix, content = _a.content;
92 var _b = _this.generateLineHtml({
93 type: renderUtils.CSSLineClass.CONTEXT,
94 prefix: prefix,
95 content: content,
96 number: line.oldNumber,
97 }, {
98 type: renderUtils.CSSLineClass.CONTEXT,
99 prefix: prefix,
100 content: content,
101 number: line.newNumber,
102 }), left = _b.left, right = _b.right;
103 fileHtml.left += left;
104 fileHtml.right += right;
105 });
106 }
107 else if (oldLines.length || newLines.length) {
108 var _b = _this.processChangedLines(file.isCombined, oldLines, newLines), left = _b.left, right = _b.right;
109 fileHtml.left += left;
110 fileHtml.right += right;
111 }
112 else {
113 console.error('Unknown state reached while processing groups of lines', contextLines, oldLines, newLines);
114 }
115 });
116 return fileHtml;
117 })
118 .reduce(function (accomulated, html) {
119 return { left: accomulated.left + html.left, right: accomulated.right + html.right };
120 }, { left: '', right: '' });
121 };
122 SideBySideRenderer.prototype.applyLineGroupping = function (block) {
123 var blockLinesGroups = [];
124 var oldLines = [];
125 var newLines = [];
126 for (var i = 0; i < block.lines.length; i++) {
127 var diffLine = block.lines[i];
128 if ((diffLine.type !== LineType.INSERT && newLines.length) ||
129 (diffLine.type === LineType.CONTEXT && oldLines.length > 0)) {
130 blockLinesGroups.push([[], oldLines, newLines]);
131 oldLines = [];
132 newLines = [];
133 }
134 if (diffLine.type === LineType.CONTEXT) {
135 blockLinesGroups.push([[diffLine], [], []]);
136 }
137 else if (diffLine.type === LineType.INSERT && oldLines.length === 0) {
138 blockLinesGroups.push([[], [], [diffLine]]);
139 }
140 else if (diffLine.type === LineType.INSERT && oldLines.length > 0) {
141 newLines.push(diffLine);
142 }
143 else if (diffLine.type === LineType.DELETE) {
144 oldLines.push(diffLine);
145 }
146 }
147 if (oldLines.length || newLines.length) {
148 blockLinesGroups.push([[], oldLines, newLines]);
149 oldLines = [];
150 newLines = [];
151 }
152 return blockLinesGroups;
153 };
154 SideBySideRenderer.prototype.applyRematchMatching = function (oldLines, newLines, matcher) {
155 var comparisons = oldLines.length * newLines.length;
156 var maxLineSizeInBlock = Math.max.apply(null, [0].concat(oldLines.concat(newLines).map(function (elem) { return elem.content.length; })));
157 var doMatching = comparisons < this.config.matchingMaxComparisons &&
158 maxLineSizeInBlock < this.config.maxLineSizeInBlockForComparison &&
159 (this.config.matching === 'lines' || this.config.matching === 'words');
160 return doMatching ? matcher(oldLines, newLines) : [[oldLines, newLines]];
161 };
162 SideBySideRenderer.prototype.makeHeaderHtml = function (blockHeader) {
163 return this.hoganUtils.render(genericTemplatesPath, 'block-header', {
164 CSSLineClass: renderUtils.CSSLineClass,
165 blockHeader: renderUtils.escapeForHtml(blockHeader),
166 lineClass: 'd2h-code-side-linenumber',
167 contentClass: 'd2h-code-side-line',
168 });
169 };
170 SideBySideRenderer.prototype.processChangedLines = function (isCombined, oldLines, newLines) {
171 var fileHtml = {
172 right: '',
173 left: '',
174 };
175 var maxLinesNumber = Math.max(oldLines.length, newLines.length);
176 for (var i = 0; i < maxLinesNumber; i++) {
177 var oldLine = oldLines[i];
178 var newLine = newLines[i];
179 var diff = oldLine !== undefined && newLine !== undefined
180 ? renderUtils.diffHighlight(oldLine.content, newLine.content, isCombined, this.config)
181 : undefined;
182 var preparedOldLine = oldLine !== undefined && oldLine.oldNumber !== undefined
183 ? __assign(__assign({}, (diff !== undefined
184 ? {
185 prefix: diff.oldLine.prefix,
186 content: diff.oldLine.content,
187 type: renderUtils.CSSLineClass.DELETE_CHANGES,
188 }
189 : __assign(__assign({}, renderUtils.deconstructLine(oldLine.content, isCombined)), { type: renderUtils.toCSSClass(oldLine.type) }))), { number: oldLine.oldNumber }) : undefined;
190 var preparedNewLine = newLine !== undefined && newLine.newNumber !== undefined
191 ? __assign(__assign({}, (diff !== undefined
192 ? {
193 prefix: diff.newLine.prefix,
194 content: diff.newLine.content,
195 type: renderUtils.CSSLineClass.INSERT_CHANGES,
196 }
197 : __assign(__assign({}, renderUtils.deconstructLine(newLine.content, isCombined)), { type: renderUtils.toCSSClass(newLine.type) }))), { number: newLine.newNumber }) : undefined;
198 var _a = this.generateLineHtml(preparedOldLine, preparedNewLine), left = _a.left, right = _a.right;
199 fileHtml.left += left;
200 fileHtml.right += right;
201 }
202 return fileHtml;
203 };
204 SideBySideRenderer.prototype.generateLineHtml = function (oldLine, newLine) {
205 return {
206 left: this.generateSingleHtml(oldLine),
207 right: this.generateSingleHtml(newLine),
208 };
209 };
210 SideBySideRenderer.prototype.generateSingleHtml = function (line) {
211 var lineClass = 'd2h-code-side-linenumber';
212 var contentClass = 'd2h-code-side-line';
213 return this.hoganUtils.render(genericTemplatesPath, 'line', {
214 type: (line === null || line === void 0 ? void 0 : line.type) || renderUtils.CSSLineClass.CONTEXT + " d2h-emptyplaceholder",
215 lineClass: line !== undefined ? lineClass : lineClass + " d2h-code-side-emptyplaceholder",
216 contentClass: line !== undefined ? contentClass : contentClass + " d2h-code-side-emptyplaceholder",
217 prefix: (line === null || line === void 0 ? void 0 : line.prefix) === ' ' ? '&nbsp;' : line === null || line === void 0 ? void 0 : line.prefix,
218 content: line === null || line === void 0 ? void 0 : line.content,
219 lineNumber: line === null || line === void 0 ? void 0 : line.number,
220 });
221 };
222 return SideBySideRenderer;
223}());
224export default SideBySideRenderer;
225//# sourceMappingURL=side-by-side-renderer.js.map
\No newline at end of file