@git-diff-view/react 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -72,340 +72,86 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
72
72
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
73
73
  };
74
74
 
75
- /******************************************************************************
76
- Copyright (c) Microsoft Corporation.
77
-
78
- Permission to use, copy, modify, and/or distribute this software for any
79
- purpose with or without fee is hereby granted.
80
-
81
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
82
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
83
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
84
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
85
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
86
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
87
- PERFORMANCE OF THIS SOFTWARE.
88
- ***************************************************************************** */
89
- /* global Reflect, Promise, SuppressedError, Symbol */
90
-
91
-
92
- function __classPrivateFieldGet(receiver, state, kind, f) {
93
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
94
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
95
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
96
- }
97
-
98
- function __classPrivateFieldSet(receiver, state, value, kind, f) {
99
- if (kind === "m") throw new TypeError("Private method is not writable");
100
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
101
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
102
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
103
- }
104
-
105
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
106
- var e = new Error(message);
107
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
108
- };
109
-
110
- const processAST = (ast) => {
111
- let lineNumber = 1;
112
- const syntaxObj = {};
113
- const loopAST = (nodes, wrapper) => {
114
- nodes.forEach((node) => {
115
- if (node.type === "text") {
116
- if (node.value.indexOf("\n") === -1) {
117
- const valueLength = node.value.length;
118
- if (!syntaxObj[lineNumber]) {
119
- node.startIndex = 0;
120
- node.endIndex = valueLength - 1;
121
- const item = {
122
- value: node.value,
123
- lineNumber,
124
- valueLength,
125
- nodeList: [{ node, wrapper }],
126
- };
127
- syntaxObj[lineNumber] = item;
128
- }
129
- else {
130
- node.startIndex = syntaxObj[lineNumber].valueLength;
131
- node.endIndex = node.startIndex + valueLength - 1;
132
- syntaxObj[lineNumber].value += node.value;
133
- syntaxObj[lineNumber].valueLength += valueLength;
134
- syntaxObj[lineNumber].nodeList.push({ node, wrapper });
135
- }
136
- node.lineNumber = lineNumber;
137
- return;
138
- }
139
- const lines = node.value.split("\n");
140
- node.children = node.children || [];
141
- for (let i = 0; i < lines.length; i++) {
142
- const _value = i === lines.length - 1 ? lines[i] : lines[i] + "\n";
143
- const _lineNumber = i === 0 ? lineNumber : ++lineNumber;
144
- const _valueLength = _value.length;
145
- const _node = {
146
- type: "text",
147
- value: _value,
148
- startIndex: Infinity,
149
- endIndex: Infinity,
150
- lineNumber: _lineNumber,
151
- };
152
- if (!syntaxObj[_lineNumber]) {
153
- _node.startIndex = 0;
154
- _node.endIndex = _valueLength - 1;
155
- const item = {
156
- value: _value,
157
- lineNumber: _lineNumber,
158
- valueLength: _valueLength,
159
- nodeList: [{ node: _node, wrapper }],
160
- };
161
- syntaxObj[_lineNumber] = item;
162
- }
163
- else {
164
- _node.startIndex = syntaxObj[_lineNumber].valueLength;
165
- _node.endIndex = _node.startIndex + _valueLength - 1;
166
- syntaxObj[_lineNumber].value += _value;
167
- syntaxObj[_lineNumber].valueLength += _valueLength;
168
- syntaxObj[_lineNumber].nodeList.push({ node: _node, wrapper });
169
- }
170
- node.children.push(_node);
171
- }
172
- node.lineNumber = lineNumber;
173
- return;
174
- }
175
- if (node.children) {
176
- loopAST(node.children, node);
177
- node.lineNumber = lineNumber;
178
- }
179
- });
180
- };
181
- loopAST(ast.children);
182
- return { syntaxFileObject: syntaxObj, syntaxFileLineNumber: lineNumber };
183
- };
184
-
185
- const lowlight = lowlight$1.createLowlight(lowlight$1.all);
186
- // !SEE https://github.com/highlightjs/highlightjs-vue
187
- lowlight.register("vue", function hljsDefineVue(hljs) {
188
- return {
189
- subLanguage: "xml",
190
- contains: [
191
- hljs.COMMENT("<!--", "-->", {
192
- relevance: 10,
193
- }),
194
- {
195
- begin: /^(\s*)(<script>)/gm,
196
- end: /^(\s*)(<\/script>)/gm,
197
- subLanguage: "javascript",
198
- excludeBegin: true,
199
- excludeEnd: true,
200
- },
201
- {
202
- begin: /^(?:\s*)(?:<script\s+lang=(["'])ts\1>)/gm,
203
- end: /^(\s*)(<\/script>)/gm,
204
- subLanguage: "typescript",
205
- excludeBegin: true,
206
- excludeEnd: true,
207
- },
208
- {
209
- begin: /^(\s*)(<style(\s+scoped)?>)/gm,
210
- end: /^(\s*)(<\/style>)/gm,
211
- subLanguage: "css",
212
- excludeBegin: true,
213
- excludeEnd: true,
214
- },
215
- {
216
- begin: /^(?:\s*)(?:<style(?:\s+scoped)?\s+lang=(["'])(?:s[ca]ss)\1(?:\s+scoped)?>)/gm,
217
- end: /^(\s*)(<\/style>)/gm,
218
- subLanguage: "scss",
219
- excludeBegin: true,
220
- excludeEnd: true,
221
- },
222
- {
223
- begin: /^(?:\s*)(?:<style(?:\s+scoped)?\s+lang=(["'])stylus\1(?:\s+scoped)?>)/gm,
224
- end: /^(\s*)(<\/style>)/gm,
225
- subLanguage: "stylus",
226
- excludeBegin: true,
227
- excludeEnd: true,
228
- },
229
- ],
230
- };
231
- });
232
- const instance = { name: "lowlight" };
233
- let _maxLineToIgnoreSyntax = 2000;
234
- const _ignoreSyntaxHighlightList = [];
235
- Object.defineProperty(instance, "maxLineToIgnoreSyntax", {
236
- get: () => _maxLineToIgnoreSyntax,
237
- });
238
- Object.defineProperty(instance, "setMaxLineToIgnoreSyntax", {
239
- value: (v) => {
240
- _maxLineToIgnoreSyntax = v;
241
- },
242
- });
243
- Object.defineProperty(instance, "ignoreSyntaxHighlightList", {
244
- get: () => _ignoreSyntaxHighlightList,
245
- });
246
- Object.defineProperty(instance, "setIgnoreSyntaxHighlightList", {
247
- value: (v) => {
248
- _ignoreSyntaxHighlightList.length = 0;
249
- _ignoreSyntaxHighlightList.push(...v);
250
- },
251
- });
252
- Object.defineProperty(instance, "getAST", {
253
- value: (raw, fileName, lang) => {
254
- let hasRegisteredLang = true;
255
- if (!lowlight.registered(lang)) {
256
- console.warn(`not support current lang: ${lang} yet`);
257
- hasRegisteredLang = false;
258
- }
259
- if (fileName &&
260
- highlighter.ignoreSyntaxHighlightList.some((item) => item instanceof RegExp ? item.test(fileName) : fileName === item)) {
261
- console.warn(`ignore syntax for current file, because the fileName is in the ignoreSyntaxHighlightList: ${fileName}`);
262
- return;
263
- }
264
- if (hasRegisteredLang) {
265
- return lowlight.highlight(lang, raw);
266
- }
267
- else {
268
- return lowlight.highlightAuto(raw);
269
- }
270
- },
271
- });
272
- Object.defineProperty(instance, "processAST", {
273
- value: (ast) => {
274
- return processAST(ast);
275
- },
276
- });
277
- const highlighter = instance;
278
-
279
- var _Cache_keyArray, _Cache_maxLength;
280
- class Cache extends Map {
281
- constructor() {
282
- super(...arguments);
283
- _Cache_keyArray.set(this, []);
284
- _Cache_maxLength.set(this, 30);
285
- }
286
- setMaxLength(length) {
287
- __classPrivateFieldSet(this, _Cache_maxLength, length, "f");
288
- this._checkLength();
289
- }
290
- set(key, value) {
291
- if (this.has(key))
292
- return this;
293
- __classPrivateFieldGet(this, _Cache_keyArray, "f").push(key);
294
- this._checkLength();
295
- return super.set(key, value);
296
- }
297
- _checkLength() {
298
- while (__classPrivateFieldGet(this, _Cache_keyArray, "f").length > __classPrivateFieldGet(this, _Cache_maxLength, "f")) {
299
- const key = __classPrivateFieldGet(this, _Cache_keyArray, "f").shift();
300
- this.delete(key);
301
- }
302
- }
303
- }
304
- _Cache_keyArray = new WeakMap(), _Cache_maxLength = new WeakMap();
305
-
306
- var _File_instances, _File_doCheck;
307
- const map = new Cache();
308
- const devKey = "@git-diff-cache";
309
- map.setMaxLength(50);
310
- map.name = "@git-diff-view/core";
311
- if (typeof globalThis !== "undefined") {
312
- if (Array.isArray(globalThis[devKey])) {
313
- globalThis[devKey] = globalThis[devKey].filter((i) => i !== map);
314
- if (globalThis[devKey].length > 0) {
315
- console.warn("there are multiple instance of @git-diff-view/core in the one environment!");
316
- }
317
- globalThis[devKey].push(map);
318
- }
319
- else {
320
- globalThis[devKey] = [map];
321
- }
322
- }
323
- class File {
324
- constructor(raw, lang, fileName) {
325
- _File_instances.add(this);
326
- this.raw = raw;
327
- this.lang = lang;
328
- this.fileName = fileName;
329
- this.rawFile = {};
330
- this.hasDoRaw = false;
331
- this.syntaxFile = {};
332
- this.hasDoSyntax = false;
333
- this.maxLineNumber = 0;
334
- Object.defineProperty(this, "__v_skip", { value: true });
335
- }
336
- doSyntax({ registerHighlighter }) {
337
- if (!this.raw || this.hasDoSyntax)
338
- return;
339
- const _highlighter = registerHighlighter || highlighter;
340
- if (this.syntaxLength) {
341
- console.error("current file already doSyntax before!");
342
- return;
343
- }
344
- if (this.rawLength > _highlighter.maxLineToIgnoreSyntax) {
345
- console.warn(`ignore syntax for current file, because the rawLength is too long: ${this.rawLength}`);
346
- return;
347
- }
348
- this.ast = _highlighter.getAST(this.raw, this.fileName, this.lang);
349
- if (!this.ast)
350
- return;
351
- const { syntaxFileObject, syntaxFileLineNumber } = _highlighter.processAST(this.ast);
352
- this.syntaxFile = syntaxFileObject;
353
- this.syntaxLength = syntaxFileLineNumber;
354
- this.highlighterName = _highlighter.name;
355
- {
356
- __classPrivateFieldGet(this, _File_instances, "m", _File_doCheck).call(this);
357
- }
358
- this.hasDoSyntax = true;
359
- }
360
- doRaw() {
361
- if (!this.raw || this.hasDoRaw)
362
- return;
363
- const rawString = this.raw;
364
- const rawArray = rawString.split("\n");
365
- this.rawLength = rawArray.length;
366
- this.maxLineNumber = rawArray.length;
367
- this.rawFile = {};
368
- for (let i = 0; i < rawArray.length; i++) {
369
- this.rawFile[i + 1] = i < rawArray.length - 1 ? rawArray[i] + "\n" : rawArray[i];
75
+ exports.DiffHunkExpansionType = void 0;
76
+ (function (DiffHunkExpansionType) {
77
+ /** The hunk header cannot be expanded at all. */
78
+ DiffHunkExpansionType["None"] = "None";
79
+ /**
80
+ * The hunk header can be expanded up exclusively. Only the first hunk can be
81
+ * expanded up exclusively.
82
+ */
83
+ DiffHunkExpansionType["Up"] = "Up";
84
+ /**
85
+ * The hunk header can be expanded down exclusively. Only the last hunk (if
86
+ * it's the dummy hunk with only one line) can be expanded down exclusively.
87
+ */
88
+ DiffHunkExpansionType["Down"] = "Down";
89
+ /** The hunk header can be expanded both up and down. */
90
+ DiffHunkExpansionType["Both"] = "Both";
91
+ /**
92
+ * The hunk header represents a short gap that, when expanded, will
93
+ * result in merging this hunk and the hunk above.
94
+ */
95
+ DiffHunkExpansionType["Short"] = "Short";
96
+ })(exports.DiffHunkExpansionType || (exports.DiffHunkExpansionType = {}));
97
+ /** each diff is made up of a number of hunks */
98
+ class DiffHunk {
99
+ /**
100
+ * @param header The details from the diff hunk header about the line start and patch length.
101
+ * @param lines The contents - context and changes - of the diff section.
102
+ * @param unifiedDiffStart The diff hunk's start position in the overall file diff.
103
+ * @param unifiedDiffEnd The diff hunk's end position in the overall file diff.
104
+ */
105
+ constructor(header, lines, unifiedDiffStart, unifiedDiffEnd, expansionType) {
106
+ this.header = header;
107
+ this.lines = lines;
108
+ this.unifiedDiffStart = unifiedDiffStart;
109
+ this.unifiedDiffEnd = unifiedDiffEnd;
110
+ this.expansionType = expansionType;
111
+ }
112
+ equals(other) {
113
+ if (this === other) {
114
+ return true;
370
115
  }
371
- // reduce 对于大数组性能很差
372
- // this.rawFile = rawArray.reduce(
373
- // (p, item, index) => ({
374
- // ...p,
375
- // [index + 1]: index < rawArray.length - 1 ? item + "\n" : item,
376
- // }),
377
- // {}
378
- // );
379
- this.hasDoRaw = true;
116
+ return (this.header.equals(other.header) &&
117
+ this.unifiedDiffStart === other.unifiedDiffStart &&
118
+ this.unifiedDiffEnd === other.unifiedDiffEnd &&
119
+ this.expansionType === other.expansionType &&
120
+ this.lines.length === other.lines.length &&
121
+ this.lines.every((xLine, ix) => xLine.equals(other.lines[ix])));
380
122
  }
381
123
  }
382
- _File_instances = new WeakSet(), _File_doCheck = function _File_doCheck() {
383
- if (this.rawLength && this.syntaxLength) {
384
- if (this.rawLength !== this.syntaxLength) {
385
- console.warn("the rawLength not match for the syntaxLength");
386
- }
387
- Object.values(this.syntaxFile).forEach(({ value, lineNumber }) => {
388
- if (value !== this.rawFile[lineNumber]) {
389
- console.log("some line not match:" + value + " __ " + this.rawFile[lineNumber] + " __ at: " + lineNumber + " lineNumber");
390
- }
391
- });
124
+ /** details about the start and end of a diff hunk */
125
+ class DiffHunkHeader {
126
+ /**
127
+ * @param oldStartLine The line in the old (or original) file where this diff hunk starts.
128
+ * @param oldLineCount The number of lines in the old (or original) file that this diff hunk covers
129
+ * @param newStartLine The line in the new file where this diff hunk starts.
130
+ * @param newLineCount The number of lines in the new file that this diff hunk covers.
131
+ */
132
+ constructor(oldStartLine, oldLineCount, newStartLine, newLineCount) {
133
+ this.oldStartLine = oldStartLine;
134
+ this.oldLineCount = oldLineCount;
135
+ this.newStartLine = newStartLine;
136
+ this.newLineCount = newLineCount;
392
137
  }
393
- };
394
- const getFile = (raw, lang, fileName) => {
395
- const key = raw + "--" + "0.0.10" + "--" + lang;
396
- if (map.has(key))
397
- return map.get(key);
398
- const file = new File(raw, lang, fileName);
399
- map.set(key, file);
400
- return file;
401
- };
402
- const _cacheMap = map;
138
+ toDiffLineRepresentation() {
139
+ return `@@ -${this.oldStartLine},${this.oldLineCount} +${this.newStartLine},${this.newLineCount} @@`;
140
+ }
141
+ equals(other) {
142
+ return (this.oldStartLine === other.oldStartLine &&
143
+ this.oldLineCount === other.oldLineCount &&
144
+ this.newStartLine === other.newStartLine &&
145
+ this.oldStartLine === other.oldStartLine);
146
+ }
147
+ }
403
148
 
404
149
  exports.NewLineSymbol = void 0;
405
150
  (function (NewLineSymbol) {
406
151
  NewLineSymbol[NewLineSymbol["CRLF"] = 1] = "CRLF";
407
152
  NewLineSymbol[NewLineSymbol["CR"] = 2] = "CR";
408
153
  NewLineSymbol[NewLineSymbol["LF"] = 3] = "LF";
154
+ NewLineSymbol[NewLineSymbol["NEWLINE"] = 4] = "NEWLINE";
409
155
  })(exports.NewLineSymbol || (exports.NewLineSymbol = {}));
410
156
  const maxLength = 1000;
411
157
  /** Get the maximum position in the range. */
@@ -430,25 +176,31 @@ function commonLength(stringA, rangeA, stringB, rangeB, reverse) {
430
176
  function isInValidString(s) {
431
177
  return s.trim().length === 0 || s.length >= maxLength;
432
178
  }
179
+ // TODO maybe could use the original content line
433
180
  /** Get the changed ranges in the strings, relative to each other. */
434
- function relativeChanges(stringA, stringB) {
181
+ function relativeChanges(addition, deletion) {
182
+ const stringA = addition.text;
183
+ const stringB = deletion.text;
435
184
  let bRange = { location: 0, length: stringB.length };
436
185
  let aRange = { location: 0, length: stringA.length };
437
186
  const _stringA = stringA.trimEnd();
438
187
  const _stringB = stringB.trimEnd();
439
188
  const aEndStr = stringA.slice(-2);
440
189
  const bEndStr = stringB.slice(-2);
441
- if (_stringA === _stringB && aEndStr !== bEndStr && (aEndStr === "\r\n" || bEndStr === "\r\n")) {
190
+ const hasNewLineChanged = addition.noTrailingNewLine !== deletion.noTrailingNewLine;
191
+ const aSymbol = aEndStr === "\r\n" ? exports.NewLineSymbol.CRLF : aEndStr.endsWith("\r") ? exports.NewLineSymbol.CR : exports.NewLineSymbol.LF;
192
+ const bSymbol = bEndStr === "\r\n" ? exports.NewLineSymbol.CRLF : bEndStr.endsWith("\r") ? exports.NewLineSymbol.CR : exports.NewLineSymbol.LF;
193
+ if (_stringA === _stringB && (hasNewLineChanged || aSymbol !== bSymbol)) {
442
194
  return {
443
195
  stringARange: {
444
196
  location: _stringA.length,
445
197
  length: stringA.length - _stringA.length,
446
- newLineSymbol: aEndStr === "\r\n" ? exports.NewLineSymbol.CRLF : aEndStr.endsWith("\r") ? exports.NewLineSymbol.CR : exports.NewLineSymbol.LF,
198
+ newLineSymbol: hasNewLineChanged ? exports.NewLineSymbol.NEWLINE : aSymbol,
447
199
  },
448
200
  stringBRange: {
449
201
  location: _stringB.length,
450
202
  length: stringB.length - _stringB.length,
451
- newLineSymbol: bEndStr === "\r\n" ? exports.NewLineSymbol.CRLF : bEndStr.endsWith("\r") ? exports.NewLineSymbol.CR : exports.NewLineSymbol.LF,
203
+ newLineSymbol: hasNewLineChanged ? exports.NewLineSymbol.NEWLINE : bSymbol,
452
204
  },
453
205
  };
454
206
  }
@@ -472,10 +224,12 @@ function relativeChanges(stringA, stringB) {
472
224
  return { stringARange: aRange, stringBRange: bRange };
473
225
  }
474
226
  /** Check two string have a diff range */
475
- function hasRelativeChange(stringA, stringB) {
476
- const _stringA = stringA.trim();
477
- const _stringB = stringB.trim();
478
- const { stringARange, stringBRange } = relativeChanges(_stringA, _stringB);
227
+ function hasRelativeChange(addition, deletion) {
228
+ const _stringA = addition.text.trim();
229
+ const _stringB = deletion.text.trim();
230
+ const _addition = addition.clone(_stringA);
231
+ const _deletion = deletion.clone(_stringB);
232
+ const { stringARange, stringBRange } = relativeChanges(_addition, _deletion);
479
233
  return (stringARange.location > 0 ||
480
234
  stringBRange.location > 0 ||
481
235
  stringARange.length < _stringA.length ||
@@ -523,6 +277,9 @@ class DiffLine {
523
277
  this.newLineNumber === other.newLineNumber &&
524
278
  this.noTrailingNewLine === other.noTrailingNewLine);
525
279
  }
280
+ clone(text) {
281
+ return new DiffLine(text, this.type, this.originalLineNumber, this.oldLineNumber, this.newLineNumber);
282
+ }
526
283
  }
527
284
  const checkDiffLineIncludeChange = (diffLine) => {
528
285
  if (!diffLine)
@@ -530,82 +287,8 @@ const checkDiffLineIncludeChange = (diffLine) => {
530
287
  return diffLine.type === exports.DiffLineType.Add || diffLine.type === exports.DiffLineType.Delete;
531
288
  };
532
289
 
533
- var DiffHunkExpansionType;
534
- (function (DiffHunkExpansionType) {
535
- /** The hunk header cannot be expanded at all. */
536
- DiffHunkExpansionType["None"] = "None";
537
- /**
538
- * The hunk header can be expanded up exclusively. Only the first hunk can be
539
- * expanded up exclusively.
540
- */
541
- DiffHunkExpansionType["Up"] = "Up";
542
- /**
543
- * The hunk header can be expanded down exclusively. Only the last hunk (if
544
- * it's the dummy hunk with only one line) can be expanded down exclusively.
545
- */
546
- DiffHunkExpansionType["Down"] = "Down";
547
- /** The hunk header can be expanded both up and down. */
548
- DiffHunkExpansionType["Both"] = "Both";
549
- /**
550
- * The hunk header represents a short gap that, when expanded, will
551
- * result in merging this hunk and the hunk above.
552
- */
553
- DiffHunkExpansionType["Short"] = "Short";
554
- })(DiffHunkExpansionType || (DiffHunkExpansionType = {}));
555
- /** each diff is made up of a number of hunks */
556
- class DiffHunk {
557
- /**
558
- * @param header The details from the diff hunk header about the line start and patch length.
559
- * @param lines The contents - context and changes - of the diff section.
560
- * @param unifiedDiffStart The diff hunk's start position in the overall file diff.
561
- * @param unifiedDiffEnd The diff hunk's end position in the overall file diff.
562
- */
563
- constructor(header, lines, unifiedDiffStart, unifiedDiffEnd, expansionType) {
564
- this.header = header;
565
- this.lines = lines;
566
- this.unifiedDiffStart = unifiedDiffStart;
567
- this.unifiedDiffEnd = unifiedDiffEnd;
568
- this.expansionType = expansionType;
569
- }
570
- equals(other) {
571
- if (this === other) {
572
- return true;
573
- }
574
- return (this.header.equals(other.header) &&
575
- this.unifiedDiffStart === other.unifiedDiffStart &&
576
- this.unifiedDiffEnd === other.unifiedDiffEnd &&
577
- this.expansionType === other.expansionType &&
578
- this.lines.length === other.lines.length &&
579
- this.lines.every((xLine, ix) => xLine.equals(other.lines[ix])));
580
- }
581
- }
582
- /** details about the start and end of a diff hunk */
583
- class DiffHunkHeader {
584
- /**
585
- * @param oldStartLine The line in the old (or original) file where this diff hunk starts.
586
- * @param oldLineCount The number of lines in the old (or original) file that this diff hunk covers
587
- * @param newStartLine The line in the new file where this diff hunk starts.
588
- * @param newLineCount The number of lines in the new file that this diff hunk covers.
589
- */
590
- constructor(oldStartLine, oldLineCount, newStartLine, newLineCount) {
591
- this.oldStartLine = oldStartLine;
592
- this.oldLineCount = oldLineCount;
593
- this.newStartLine = newStartLine;
594
- this.newLineCount = newLineCount;
595
- }
596
- toDiffLineRepresentation() {
597
- return `@@ -${this.oldStartLine},${this.oldLineCount} +${this.newStartLine},${this.newLineCount} @@`;
598
- }
599
- equals(other) {
600
- return (this.oldStartLine === other.oldStartLine &&
601
- this.oldLineCount === other.oldLineCount &&
602
- this.newStartLine === other.newStartLine &&
603
- this.oldStartLine === other.oldStartLine);
604
- }
605
- }
606
-
607
290
  /** How many new lines will be added to a diff hunk by default. */
608
- const DefaultDiffExpansionStep = 20;
291
+ const DefaultDiffExpansionStep = 40;
609
292
  function assertNever(_, message) {
610
293
  throw new Error(message);
611
294
  }
@@ -652,17 +335,17 @@ function getHunkHeaderExpansionType(hunkIndex, hunkHeader, previousHunk) {
652
335
  if (hunkIndex === 0) {
653
336
  // The top hunk can only be expanded if there is content above it
654
337
  if (hunkHeader.oldStartLine > 1 && hunkHeader.newStartLine > 1) {
655
- return DiffHunkExpansionType.Up;
338
+ return exports.DiffHunkExpansionType.Up;
656
339
  }
657
340
  else {
658
- return DiffHunkExpansionType.None;
341
+ return exports.DiffHunkExpansionType.None;
659
342
  }
660
343
  }
661
344
  else if (distanceToPrevious <= DefaultDiffExpansionStep) {
662
- return DiffHunkExpansionType.Short;
345
+ return exports.DiffHunkExpansionType.Short;
663
346
  }
664
347
  else {
665
- return DiffHunkExpansionType.Both;
348
+ return exports.DiffHunkExpansionType.Both;
666
349
  }
667
350
  }
668
351
  const numIterator = (num, cb) => {
@@ -683,9 +366,9 @@ const getDiffRange = (additions, deletions) => {
683
366
  for (let i = 0; i < len; i++) {
684
367
  const addition = additions[i];
685
368
  const deletion = deletions[i];
686
- const hasDiffRange = hasRelativeChange(addition.text, deletion.text);
369
+ const hasDiffRange = hasRelativeChange(addition, deletion);
687
370
  if (hasDiffRange) {
688
- const { stringARange, stringBRange } = relativeChanges(addition.text, deletion.text);
371
+ const { stringARange, stringBRange } = relativeChanges(addition, deletion);
689
372
  addition.needRematch = true;
690
373
  addition.range = stringARange;
691
374
  deletion.needRematch = true;
@@ -736,299 +419,644 @@ class DiffParser {
736
419
  this.reset();
737
420
  }
738
421
  /**
739
- * Resets the internal parser state so that it can be reused.
422
+ * Resets the internal parser state so that it can be reused.
423
+ *
424
+ * This is done automatically at the end of each parse run.
425
+ */
426
+ reset() {
427
+ this.ls = 0;
428
+ this.le = -1;
429
+ this.text = "";
430
+ }
431
+ /**
432
+ * Aligns the internal character pointers at the boundaries of
433
+ * the next line.
434
+ *
435
+ * Returns true if successful or false if the end of the diff
436
+ * has been reached.
437
+ */
438
+ nextLine() {
439
+ this.ls = this.le + 1;
440
+ // We've reached the end of the diff
441
+ if (this.ls >= this.text.length) {
442
+ return false;
443
+ }
444
+ this.le = this.text.indexOf("\n", this.ls);
445
+ // If we can't find the next newline character we'll put our
446
+ // end pointer at the end of the diff string
447
+ if (this.le === -1) {
448
+ this.le = this.text.length;
449
+ }
450
+ // We've succeeded if there's anything to read in between the
451
+ // start and the end
452
+ return this.ls !== this.le;
453
+ }
454
+ /**
455
+ * Advances to the next line and returns it as a substring
456
+ * of the raw diff text. Returns null if end of diff was
457
+ * reached.
458
+ */
459
+ readLine(header) {
460
+ if (header) {
461
+ return this.nextLine() ? this.text.substring(this.ls, this.le) : null;
462
+ }
463
+ else {
464
+ return this.nextLine() ? this.text.substring(this.ls + 1, this.le + 1) : null;
465
+ }
466
+ }
467
+ /** Tests if the current line starts with the given search text */
468
+ lineStartsWith(searchString) {
469
+ return this.text.startsWith(searchString, this.ls);
470
+ }
471
+ /** Tests if the current line ends with the given search text */
472
+ lineEndsWith(searchString) {
473
+ return this.text.endsWith(searchString, this.le);
474
+ }
475
+ /**
476
+ * Returns the starting character of the next line without
477
+ * advancing the internal state. Returns null if advancing
478
+ * would mean reaching the end of the diff.
479
+ */
480
+ peek() {
481
+ const p = this.le + 1;
482
+ return p < this.text.length ? this.text[p] : null;
483
+ }
484
+ /**
485
+ * Parse the diff header, meaning everything from the
486
+ * start of the diff output to the end of the line beginning
487
+ * with +++
488
+ *
489
+ * Example diff header:
490
+ *
491
+ * diff --git a/app/src/lib/diff-parser.ts b/app/src/lib/diff-parser.ts
492
+ * index e1d4871..3bd3ee0 100644
493
+ * --- a/app/src/lib/diff-parser.ts
494
+ * +++ b/app/src/lib/diff-parser.ts
495
+ *
496
+ * Returns an object with information extracted from the diff
497
+ * header (currently whether it's a binary patch) or null if
498
+ * the end of the diff was reached before the +++ line could be
499
+ * found (which is a valid state).
500
+ */
501
+ parseDiffHeader() {
502
+ // TODO: There's information in here that we might want to
503
+ // capture, such as mode changes
504
+ while (this.nextLine()) {
505
+ if (this.lineStartsWith("Binary files ") && this.lineEndsWith("differ")) {
506
+ return { isBinary: true };
507
+ }
508
+ if (this.lineStartsWith("+++")) {
509
+ return { isBinary: false };
510
+ }
511
+ }
512
+ // It's not an error to not find the +++ line, see the
513
+ // 'parses diff of empty file' test in diff-parser-tests.ts
514
+ return null;
515
+ }
516
+ /**
517
+ * Attempts to convert a RegExp capture group into a number.
518
+ * If the group doesn't exist or wasn't captured the function
519
+ * will return the value of the defaultValue parameter or throw
520
+ * an error if no default value was provided. If the captured
521
+ * string can't be converted to a number an error will be thrown.
522
+ */
523
+ numberFromGroup(m, group, defaultValue = null) {
524
+ const str = m[group];
525
+ if (!str) {
526
+ if (!defaultValue) {
527
+ throw new Error(`Group ${group} missing from regexp match and no defaultValue was provided`);
528
+ }
529
+ return defaultValue;
530
+ }
531
+ const num = parseInt(str, 10);
532
+ if (isNaN(num)) {
533
+ throw new Error(`Could not parse capture group ${group} into number: ${str}`);
534
+ }
535
+ return num;
536
+ }
537
+ /**
538
+ * Parses a hunk header or throws an error if the given line isn't
539
+ * a well-formed hunk header.
740
540
  *
741
- * This is done automatically at the end of each parse run.
541
+ * We currently only extract the line number information and
542
+ * ignore any hunk headings.
543
+ *
544
+ * Example hunk header (text within ``):
545
+ *
546
+ * `@@ -84,10 +82,8 @@ export function parseRawDiff(lines: ReadonlyArray<string>): Diff {`
547
+ *
548
+ * Where everything after the last @@ is what's known as the hunk, or section, heading
742
549
  */
743
- reset() {
744
- this.ls = 0;
745
- this.le = -1;
746
- this.text = "";
550
+ parseHunkHeader(line) {
551
+ const m = diffHeaderRe.exec(line);
552
+ if (!m) {
553
+ throw new Error(`Invalid hunk header format`);
554
+ }
555
+ // If endLines are missing default to 1, see diffHeaderRe docs
556
+ const oldStartLine = this.numberFromGroup(m, 1);
557
+ const oldLineCount = this.numberFromGroup(m, 2, 1);
558
+ const newStartLine = this.numberFromGroup(m, 3);
559
+ const newLineCount = this.numberFromGroup(m, 4, 1);
560
+ return new DiffHunkHeader(oldStartLine, oldLineCount, newStartLine, newLineCount);
747
561
  }
748
562
  /**
749
- * Aligns the internal character pointers at the boundaries of
750
- * the next line.
563
+ * Convenience function which lets us leverage the type system to
564
+ * prove exhaustive checks in parseHunk.
751
565
  *
752
- * Returns true if successful or false if the end of the diff
753
- * has been reached.
566
+ * Takes an arbitrary string and checks to see if the first character
567
+ * of that string is one of the allowed prefix characters for diff
568
+ * lines (ie lines in between hunk headers).
754
569
  */
755
- nextLine() {
756
- this.ls = this.le + 1;
757
- // We've reached the end of the diff
758
- if (this.ls >= this.text.length) {
759
- return false;
570
+ parseLinePrefix(c) {
571
+ // Since we know that DiffLinePrefixChars and the DiffLinePrefix type
572
+ // include the same characters we can tell the type system that we
573
+ // now know that c[0] is one of the characters in the DifflinePrefix set
574
+ if (c && c.length && DiffLinePrefixChars.has(c[0])) {
575
+ return c[0];
576
+ }
577
+ return null;
578
+ }
579
+ /**
580
+ * Parses a hunk, including its header or throws an error if the diff doesn't
581
+ * contain a well-formed diff hunk at the current position.
582
+ *
583
+ * Expects that the position has been advanced to the beginning of a presumed
584
+ * diff hunk header.
585
+ *
586
+ * @param linesConsumed The number of unified diff lines consumed up until
587
+ * this point by the diff parser. Used to give the
588
+ * position and length (in lines) of the parsed hunk
589
+ * relative to the overall parsed diff. These numbers
590
+ * have no real meaning in the context of a diff and
591
+ * are only used to aid the app in line-selections.
592
+ */
593
+ parseHunk(linesConsumed, hunkIndex, previousHunk) {
594
+ const headerLine = this.readLine(true);
595
+ if (!headerLine) {
596
+ throw new Error("Expected hunk header but reached end of diff");
597
+ }
598
+ const header = this.parseHunkHeader(headerLine);
599
+ const lines = new Array();
600
+ lines.push(new DiffLine(headerLine, exports.DiffLineType.Hunk, 1, null, null));
601
+ let c;
602
+ let rollingDiffBeforeCounter = header.oldStartLine;
603
+ let rollingDiffAfterCounter = header.newStartLine;
604
+ let diffLineNumber = linesConsumed;
605
+ while ((c = this.parseLinePrefix(this.peek()))) {
606
+ const line = this.readLine(false);
607
+ diffLineNumber++;
608
+ if (!line) {
609
+ throw new Error("Expected unified diff line but reached end of diff");
610
+ }
611
+ // A marker indicating that the last line in the original or the new file
612
+ // is missing a trailing newline. In other words, the presence of this marker
613
+ // means that the new and/or original file lacks a trailing newline.
614
+ //
615
+ // When we find it we have to look up the previous line and set the
616
+ // noTrailingNewLine flag
617
+ if (c === DiffPrefixNoNewline) {
618
+ // See https://github.com/git/git/blob/21f862b498925194f8f1ebe8203b7a7df756555b/apply.c#L1725-L1732
619
+ if (line.length < 12) {
620
+ throw new Error(`Expected "no newline at end of file" marker to be at least 12 bytes long`);
621
+ }
622
+ const previousLineIndex = lines.length - 1;
623
+ const previousLine = lines[previousLineIndex];
624
+ lines[previousLineIndex] = previousLine.withNoTrailingNewLine(true);
625
+ continue;
626
+ }
627
+ let diffLine;
628
+ if (c === DiffPrefixAdd) {
629
+ diffLine = new DiffLine(line, exports.DiffLineType.Add, diffLineNumber, null, rollingDiffAfterCounter++);
630
+ }
631
+ else if (c === DiffPrefixDelete) {
632
+ diffLine = new DiffLine(line, exports.DiffLineType.Delete, diffLineNumber, rollingDiffBeforeCounter++, null);
633
+ }
634
+ else if (c === DiffPrefixContext) {
635
+ diffLine = new DiffLine(line, exports.DiffLineType.Context, diffLineNumber, rollingDiffBeforeCounter++, rollingDiffAfterCounter++);
636
+ }
637
+ else {
638
+ return assertNever(c, `Unknown DiffLinePrefix: ${c}`);
639
+ }
640
+ lines.push(diffLine);
641
+ }
642
+ if (lines.length === 1) {
643
+ throw new Error("Malformed diff, empty hunk");
644
+ }
645
+ return new DiffHunk(header, lines, linesConsumed, linesConsumed + lines.length - 1, getHunkHeaderExpansionType(hunkIndex, header, previousHunk));
646
+ }
647
+ /**
648
+ * Parse a well-formed unified diff into hunks and lines.
649
+ *
650
+ * @param text A unified diff produced by git diff, git log --patch
651
+ * or any other git plumbing command that produces unified
652
+ * diffs.
653
+ */
654
+ parse(text) {
655
+ this.text = text;
656
+ try {
657
+ const headerInfo = this.parseDiffHeader();
658
+ const headerEnd = this.le;
659
+ const header = this.text.substring(0, headerEnd);
660
+ // empty diff
661
+ if (!headerInfo) {
662
+ return {
663
+ header,
664
+ contents: "",
665
+ hunks: [],
666
+ isBinary: false,
667
+ maxLineNumber: 0,
668
+ hasHiddenBidiChars: false,
669
+ };
670
+ }
671
+ if (headerInfo.isBinary) {
672
+ return {
673
+ header,
674
+ contents: "",
675
+ hunks: [],
676
+ isBinary: true,
677
+ maxLineNumber: 0,
678
+ hasHiddenBidiChars: false,
679
+ };
680
+ }
681
+ const hunks = new Array();
682
+ let linesConsumed = 0;
683
+ let previousHunk = null;
684
+ do {
685
+ const hunk = this.parseHunk(linesConsumed, hunks.length, previousHunk);
686
+ hunks.push(hunk);
687
+ previousHunk = hunk;
688
+ linesConsumed += hunk.lines.length;
689
+ } while (this.peek());
690
+ const contents = this.text
691
+ .substring(headerEnd + 1, this.le)
692
+ // Note that this simply returns a reference to the
693
+ // substring if no match is found, it does not create
694
+ // a new string instance.
695
+ .replace(/\n\/g, "");
696
+ return {
697
+ header,
698
+ contents,
699
+ hunks,
700
+ isBinary: headerInfo.isBinary,
701
+ maxLineNumber: getLargestLineNumber(hunks),
702
+ hasHiddenBidiChars: HiddenBidiCharsRegex.test(text),
703
+ };
704
+ }
705
+ finally {
706
+ this.reset();
707
+ }
708
+ }
709
+ }
710
+ const parseInstance = new DiffParser();
711
+
712
+ /******************************************************************************
713
+ Copyright (c) Microsoft Corporation.
714
+
715
+ Permission to use, copy, modify, and/or distribute this software for any
716
+ purpose with or without fee is hereby granted.
717
+
718
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
719
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
720
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
721
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
722
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
723
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
724
+ PERFORMANCE OF THIS SOFTWARE.
725
+ ***************************************************************************** */
726
+ /* global Reflect, Promise, SuppressedError, Symbol */
727
+
728
+
729
+ function __classPrivateFieldGet(receiver, state, kind, f) {
730
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
731
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
732
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
733
+ }
734
+
735
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
736
+ if (kind === "m") throw new TypeError("Private method is not writable");
737
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
738
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
739
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
740
+ }
741
+
742
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
743
+ var e = new Error(message);
744
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
745
+ };
746
+
747
+ const processAST = (ast) => {
748
+ let lineNumber = 1;
749
+ const syntaxObj = {};
750
+ const loopAST = (nodes, wrapper) => {
751
+ nodes.forEach((node) => {
752
+ if (node.type === "text") {
753
+ if (node.value.indexOf("\n") === -1) {
754
+ const valueLength = node.value.length;
755
+ if (!syntaxObj[lineNumber]) {
756
+ node.startIndex = 0;
757
+ node.endIndex = valueLength - 1;
758
+ const item = {
759
+ value: node.value,
760
+ lineNumber,
761
+ valueLength,
762
+ nodeList: [{ node, wrapper }],
763
+ };
764
+ syntaxObj[lineNumber] = item;
765
+ }
766
+ else {
767
+ node.startIndex = syntaxObj[lineNumber].valueLength;
768
+ node.endIndex = node.startIndex + valueLength - 1;
769
+ syntaxObj[lineNumber].value += node.value;
770
+ syntaxObj[lineNumber].valueLength += valueLength;
771
+ syntaxObj[lineNumber].nodeList.push({ node, wrapper });
772
+ }
773
+ node.lineNumber = lineNumber;
774
+ return;
775
+ }
776
+ const lines = node.value.split("\n");
777
+ node.children = node.children || [];
778
+ for (let i = 0; i < lines.length; i++) {
779
+ const _value = i === lines.length - 1 ? lines[i] : lines[i] + "\n";
780
+ const _lineNumber = i === 0 ? lineNumber : ++lineNumber;
781
+ const _valueLength = _value.length;
782
+ const _node = {
783
+ type: "text",
784
+ value: _value,
785
+ startIndex: Infinity,
786
+ endIndex: Infinity,
787
+ lineNumber: _lineNumber,
788
+ };
789
+ if (!syntaxObj[_lineNumber]) {
790
+ _node.startIndex = 0;
791
+ _node.endIndex = _valueLength - 1;
792
+ const item = {
793
+ value: _value,
794
+ lineNumber: _lineNumber,
795
+ valueLength: _valueLength,
796
+ nodeList: [{ node: _node, wrapper }],
797
+ };
798
+ syntaxObj[_lineNumber] = item;
799
+ }
800
+ else {
801
+ _node.startIndex = syntaxObj[_lineNumber].valueLength;
802
+ _node.endIndex = _node.startIndex + _valueLength - 1;
803
+ syntaxObj[_lineNumber].value += _value;
804
+ syntaxObj[_lineNumber].valueLength += _valueLength;
805
+ syntaxObj[_lineNumber].nodeList.push({ node: _node, wrapper });
806
+ }
807
+ node.children.push(_node);
808
+ }
809
+ node.lineNumber = lineNumber;
810
+ return;
811
+ }
812
+ if (node.children) {
813
+ loopAST(node.children, node);
814
+ node.lineNumber = lineNumber;
815
+ }
816
+ });
817
+ };
818
+ loopAST(ast.children);
819
+ return { syntaxFileObject: syntaxObj, syntaxFileLineNumber: lineNumber };
820
+ };
821
+
822
+ const lowlight = lowlight$1.createLowlight(lowlight$1.all);
823
+ // !SEE https://github.com/highlightjs/highlightjs-vue
824
+ lowlight.register("vue", function hljsDefineVue(hljs) {
825
+ return {
826
+ subLanguage: "xml",
827
+ contains: [
828
+ hljs.COMMENT("<!--", "-->", {
829
+ relevance: 10,
830
+ }),
831
+ {
832
+ begin: /^(\s*)(<script>)/gm,
833
+ end: /^(\s*)(<\/script>)/gm,
834
+ subLanguage: "javascript",
835
+ excludeBegin: true,
836
+ excludeEnd: true,
837
+ },
838
+ {
839
+ begin: /^(?:\s*)(?:<script\s+lang=(["'])ts\1>)/gm,
840
+ end: /^(\s*)(<\/script>)/gm,
841
+ subLanguage: "typescript",
842
+ excludeBegin: true,
843
+ excludeEnd: true,
844
+ },
845
+ {
846
+ begin: /^(\s*)(<style(\s+scoped)?>)/gm,
847
+ end: /^(\s*)(<\/style>)/gm,
848
+ subLanguage: "css",
849
+ excludeBegin: true,
850
+ excludeEnd: true,
851
+ },
852
+ {
853
+ begin: /^(?:\s*)(?:<style(?:\s+scoped)?\s+lang=(["'])(?:s[ca]ss)\1(?:\s+scoped)?>)/gm,
854
+ end: /^(\s*)(<\/style>)/gm,
855
+ subLanguage: "scss",
856
+ excludeBegin: true,
857
+ excludeEnd: true,
858
+ },
859
+ {
860
+ begin: /^(?:\s*)(?:<style(?:\s+scoped)?\s+lang=(["'])stylus\1(?:\s+scoped)?>)/gm,
861
+ end: /^(\s*)(<\/style>)/gm,
862
+ subLanguage: "stylus",
863
+ excludeBegin: true,
864
+ excludeEnd: true,
865
+ },
866
+ ],
867
+ };
868
+ });
869
+ const instance = { name: "lowlight" };
870
+ let _maxLineToIgnoreSyntax = 2000;
871
+ const _ignoreSyntaxHighlightList = [];
872
+ Object.defineProperty(instance, "maxLineToIgnoreSyntax", {
873
+ get: () => _maxLineToIgnoreSyntax,
874
+ });
875
+ Object.defineProperty(instance, "setMaxLineToIgnoreSyntax", {
876
+ value: (v) => {
877
+ _maxLineToIgnoreSyntax = v;
878
+ },
879
+ });
880
+ Object.defineProperty(instance, "ignoreSyntaxHighlightList", {
881
+ get: () => _ignoreSyntaxHighlightList,
882
+ });
883
+ Object.defineProperty(instance, "setIgnoreSyntaxHighlightList", {
884
+ value: (v) => {
885
+ _ignoreSyntaxHighlightList.length = 0;
886
+ _ignoreSyntaxHighlightList.push(...v);
887
+ },
888
+ });
889
+ Object.defineProperty(instance, "getAST", {
890
+ value: (raw, fileName, lang) => {
891
+ let hasRegisteredLang = true;
892
+ if (!lowlight.registered(lang)) {
893
+ console.warn(`not support current lang: ${lang} yet`);
894
+ hasRegisteredLang = false;
760
895
  }
761
- this.le = this.text.indexOf("\n", this.ls);
762
- // If we can't find the next newline character we'll put our
763
- // end pointer at the end of the diff string
764
- if (this.le === -1) {
765
- this.le = this.text.length;
896
+ if (fileName &&
897
+ highlighter.ignoreSyntaxHighlightList.some((item) => item instanceof RegExp ? item.test(fileName) : fileName === item)) {
898
+ console.warn(`ignore syntax for current file, because the fileName is in the ignoreSyntaxHighlightList: ${fileName}`);
899
+ return;
766
900
  }
767
- // We've succeeded if there's anything to read in between the
768
- // start and the end
769
- return this.ls !== this.le;
770
- }
771
- /**
772
- * Advances to the next line and returns it as a substring
773
- * of the raw diff text. Returns null if end of diff was
774
- * reached.
775
- */
776
- readLine(header) {
777
- if (header) {
778
- return this.nextLine() ? this.text.substring(this.ls, this.le) : null;
901
+ if (hasRegisteredLang) {
902
+ return lowlight.highlight(lang, raw);
779
903
  }
780
904
  else {
781
- return this.nextLine() ? this.text.substring(this.ls + 1, this.le + 1) : null;
905
+ return lowlight.highlightAuto(raw);
782
906
  }
907
+ },
908
+ });
909
+ Object.defineProperty(instance, "processAST", {
910
+ value: (ast) => {
911
+ return processAST(ast);
912
+ },
913
+ });
914
+ Object.defineProperty(instance, "hasRegisteredCurrentLang", {
915
+ value: (lang) => {
916
+ return lowlight.registered(lang);
917
+ },
918
+ });
919
+ const highlighter = instance;
920
+
921
+ var _Cache_keyArray, _Cache_maxLength;
922
+ class Cache extends Map {
923
+ constructor() {
924
+ super(...arguments);
925
+ _Cache_keyArray.set(this, []);
926
+ _Cache_maxLength.set(this, 30);
783
927
  }
784
- /** Tests if the current line starts with the given search text */
785
- lineStartsWith(searchString) {
786
- return this.text.startsWith(searchString, this.ls);
787
- }
788
- /** Tests if the current line ends with the given search text */
789
- lineEndsWith(searchString) {
790
- return this.text.endsWith(searchString, this.le);
791
- }
792
- /**
793
- * Returns the starting character of the next line without
794
- * advancing the internal state. Returns null if advancing
795
- * would mean reaching the end of the diff.
796
- */
797
- peek() {
798
- const p = this.le + 1;
799
- return p < this.text.length ? this.text[p] : null;
928
+ setMaxLength(length) {
929
+ __classPrivateFieldSet(this, _Cache_maxLength, length, "f");
930
+ this._checkLength();
800
931
  }
801
- /**
802
- * Parse the diff header, meaning everything from the
803
- * start of the diff output to the end of the line beginning
804
- * with +++
805
- *
806
- * Example diff header:
807
- *
808
- * diff --git a/app/src/lib/diff-parser.ts b/app/src/lib/diff-parser.ts
809
- * index e1d4871..3bd3ee0 100644
810
- * --- a/app/src/lib/diff-parser.ts
811
- * +++ b/app/src/lib/diff-parser.ts
812
- *
813
- * Returns an object with information extracted from the diff
814
- * header (currently whether it's a binary patch) or null if
815
- * the end of the diff was reached before the +++ line could be
816
- * found (which is a valid state).
817
- */
818
- parseDiffHeader() {
819
- // TODO: There's information in here that we might want to
820
- // capture, such as mode changes
821
- while (this.nextLine()) {
822
- if (this.lineStartsWith("Binary files ") && this.lineEndsWith("differ")) {
823
- return { isBinary: true };
824
- }
825
- if (this.lineStartsWith("+++")) {
826
- return { isBinary: false };
827
- }
828
- }
829
- // It's not an error to not find the +++ line, see the
830
- // 'parses diff of empty file' test in diff-parser-tests.ts
831
- return null;
932
+ set(key, value) {
933
+ if (this.has(key))
934
+ return this;
935
+ __classPrivateFieldGet(this, _Cache_keyArray, "f").push(key);
936
+ this._checkLength();
937
+ return super.set(key, value);
832
938
  }
833
- /**
834
- * Attempts to convert a RegExp capture group into a number.
835
- * If the group doesn't exist or wasn't captured the function
836
- * will return the value of the defaultValue parameter or throw
837
- * an error if no default value was provided. If the captured
838
- * string can't be converted to a number an error will be thrown.
839
- */
840
- numberFromGroup(m, group, defaultValue = null) {
841
- const str = m[group];
842
- if (!str) {
843
- if (!defaultValue) {
844
- throw new Error(`Group ${group} missing from regexp match and no defaultValue was provided`);
845
- }
846
- return defaultValue;
847
- }
848
- const num = parseInt(str, 10);
849
- if (isNaN(num)) {
850
- throw new Error(`Could not parse capture group ${group} into number: ${str}`);
939
+ _checkLength() {
940
+ while (__classPrivateFieldGet(this, _Cache_keyArray, "f").length > __classPrivateFieldGet(this, _Cache_maxLength, "f")) {
941
+ const key = __classPrivateFieldGet(this, _Cache_keyArray, "f").shift();
942
+ this.delete(key);
851
943
  }
852
- return num;
853
944
  }
854
- /**
855
- * Parses a hunk header or throws an error if the given line isn't
856
- * a well-formed hunk header.
857
- *
858
- * We currently only extract the line number information and
859
- * ignore any hunk headings.
860
- *
861
- * Example hunk header (text within ``):
862
- *
863
- * `@@ -84,10 +82,8 @@ export function parseRawDiff(lines: ReadonlyArray<string>): Diff {`
864
- *
865
- * Where everything after the last @@ is what's known as the hunk, or section, heading
866
- */
867
- parseHunkHeader(line) {
868
- const m = diffHeaderRe.exec(line);
869
- if (!m) {
870
- throw new Error(`Invalid hunk header format`);
945
+ }
946
+ _Cache_keyArray = new WeakMap(), _Cache_maxLength = new WeakMap();
947
+
948
+ var _File_instances, _File_doCheck;
949
+ const map = new Cache();
950
+ const devKey = "@git-diff-cache";
951
+ map.setMaxLength(50);
952
+ map.name = "@git-diff-view/core";
953
+ if (typeof globalThis !== "undefined") {
954
+ if (Array.isArray(globalThis[devKey])) {
955
+ globalThis[devKey] = globalThis[devKey].filter((i) => i !== map);
956
+ if (globalThis[devKey].length > 0) {
957
+ console.warn("there are multiple instance of @git-diff-view/core in the one environment!");
871
958
  }
872
- // If endLines are missing default to 1, see diffHeaderRe docs
873
- const oldStartLine = this.numberFromGroup(m, 1);
874
- const oldLineCount = this.numberFromGroup(m, 2, 1);
875
- const newStartLine = this.numberFromGroup(m, 3);
876
- const newLineCount = this.numberFromGroup(m, 4, 1);
877
- return new DiffHunkHeader(oldStartLine, oldLineCount, newStartLine, newLineCount);
959
+ globalThis[devKey].push(map);
878
960
  }
879
- /**
880
- * Convenience function which lets us leverage the type system to
881
- * prove exhaustive checks in parseHunk.
882
- *
883
- * Takes an arbitrary string and checks to see if the first character
884
- * of that string is one of the allowed prefix characters for diff
885
- * lines (ie lines in between hunk headers).
886
- */
887
- parseLinePrefix(c) {
888
- // Since we know that DiffLinePrefixChars and the DiffLinePrefix type
889
- // include the same characters we can tell the type system that we
890
- // now know that c[0] is one of the characters in the DifflinePrefix set
891
- if (c && c.length && DiffLinePrefixChars.has(c[0])) {
892
- return c[0];
893
- }
894
- return null;
961
+ else {
962
+ globalThis[devKey] = [map];
895
963
  }
896
- /**
897
- * Parses a hunk, including its header or throws an error if the diff doesn't
898
- * contain a well-formed diff hunk at the current position.
899
- *
900
- * Expects that the position has been advanced to the beginning of a presumed
901
- * diff hunk header.
902
- *
903
- * @param linesConsumed The number of unified diff lines consumed up until
904
- * this point by the diff parser. Used to give the
905
- * position and length (in lines) of the parsed hunk
906
- * relative to the overall parsed diff. These numbers
907
- * have no real meaning in the context of a diff and
908
- * are only used to aid the app in line-selections.
909
- */
910
- parseHunk(linesConsumed, hunkIndex, previousHunk) {
911
- const headerLine = this.readLine(true);
912
- if (!headerLine) {
913
- throw new Error("Expected hunk header but reached end of diff");
964
+ }
965
+ class File {
966
+ static createInstance(data) {
967
+ const file = new File(data === null || data === void 0 ? void 0 : data.raw, data === null || data === void 0 ? void 0 : data.lang, data === null || data === void 0 ? void 0 : data.fileName);
968
+ file.ast = data === null || data === void 0 ? void 0 : data.ast;
969
+ file.rawFile = data === null || data === void 0 ? void 0 : data.rawFile;
970
+ file.hasDoRaw = data === null || data === void 0 ? void 0 : data.hasDoRaw;
971
+ file.rawLength = data === null || data === void 0 ? void 0 : data.rawLength;
972
+ file.syntaxFile = data === null || data === void 0 ? void 0 : data.syntaxFile;
973
+ file.hasDoSyntax = data === null || data === void 0 ? void 0 : data.hasDoSyntax;
974
+ file.syntaxLength = data === null || data === void 0 ? void 0 : data.syntaxLength;
975
+ file.highlighterName = data === null || data === void 0 ? void 0 : data.highlighterName;
976
+ file.maxLineNumber = data === null || data === void 0 ? void 0 : data.maxLineNumber;
977
+ return file;
978
+ }
979
+ constructor(raw, lang, fileName) {
980
+ _File_instances.add(this);
981
+ this.raw = raw;
982
+ this.lang = lang;
983
+ this.fileName = fileName;
984
+ this.rawFile = {};
985
+ this.hasDoRaw = false;
986
+ this.syntaxFile = {};
987
+ this.hasDoSyntax = false;
988
+ this.maxLineNumber = 0;
989
+ Object.defineProperty(this, "__v_skip", { value: true });
990
+ }
991
+ doSyntax({ registerHighlighter }) {
992
+ if (!this.raw || this.hasDoSyntax)
993
+ return;
994
+ const _highlighter = registerHighlighter || highlighter;
995
+ if (this.syntaxLength) {
996
+ console.error("current file already doSyntax before!");
997
+ return;
914
998
  }
915
- const header = this.parseHunkHeader(headerLine);
916
- const lines = new Array();
917
- lines.push(new DiffLine(headerLine, exports.DiffLineType.Hunk, 1, null, null));
918
- let c;
919
- let rollingDiffBeforeCounter = header.oldStartLine;
920
- let rollingDiffAfterCounter = header.newStartLine;
921
- let diffLineNumber = linesConsumed;
922
- while ((c = this.parseLinePrefix(this.peek()))) {
923
- const line = this.readLine(false);
924
- diffLineNumber++;
925
- if (!line) {
926
- throw new Error("Expected unified diff line but reached end of diff");
927
- }
928
- // A marker indicating that the last line in the original or the new file
929
- // is missing a trailing newline. In other words, the presence of this marker
930
- // means that the new and/or original file lacks a trailing newline.
931
- //
932
- // When we find it we have to look up the previous line and set the
933
- // noTrailingNewLine flag
934
- if (c === DiffPrefixNoNewline) {
935
- // See https://github.com/git/git/blob/21f862b498925194f8f1ebe8203b7a7df756555b/apply.c#L1725-L1732
936
- if (line.length < 12) {
937
- throw new Error(`Expected "no newline at end of file" marker to be at least 12 bytes long`);
938
- }
939
- const previousLineIndex = lines.length - 1;
940
- const previousLine = lines[previousLineIndex];
941
- lines[previousLineIndex] = previousLine.withNoTrailingNewLine(true);
942
- continue;
943
- }
944
- let diffLine;
945
- if (c === DiffPrefixAdd) {
946
- diffLine = new DiffLine(line, exports.DiffLineType.Add, diffLineNumber, null, rollingDiffAfterCounter++);
947
- }
948
- else if (c === DiffPrefixDelete) {
949
- diffLine = new DiffLine(line, exports.DiffLineType.Delete, diffLineNumber, rollingDiffBeforeCounter++, null);
950
- }
951
- else if (c === DiffPrefixContext) {
952
- diffLine = new DiffLine(line, exports.DiffLineType.Context, diffLineNumber, rollingDiffBeforeCounter++, rollingDiffAfterCounter++);
953
- }
954
- else {
955
- return assertNever(c, `Unknown DiffLinePrefix: ${c}`);
956
- }
957
- lines.push(diffLine);
999
+ if (this.rawLength > _highlighter.maxLineToIgnoreSyntax) {
1000
+ console.warn(`ignore syntax for current file, because the rawLength is too long: ${this.rawLength}`);
1001
+ return;
958
1002
  }
959
- if (lines.length === 1) {
960
- throw new Error("Malformed diff, empty hunk");
1003
+ this.ast = _highlighter.getAST(this.raw, this.fileName, this.lang);
1004
+ if (!this.ast)
1005
+ return;
1006
+ const { syntaxFileObject, syntaxFileLineNumber } = _highlighter.processAST(this.ast);
1007
+ this.syntaxFile = syntaxFileObject;
1008
+ this.syntaxLength = syntaxFileLineNumber;
1009
+ this.highlighterName = _highlighter.name;
1010
+ {
1011
+ __classPrivateFieldGet(this, _File_instances, "m", _File_doCheck).call(this);
961
1012
  }
962
- return new DiffHunk(header, lines, linesConsumed, linesConsumed + lines.length - 1, getHunkHeaderExpansionType(hunkIndex, header, previousHunk));
1013
+ this.hasDoSyntax = true;
963
1014
  }
964
- /**
965
- * Parse a well-formed unified diff into hunks and lines.
966
- *
967
- * @param text A unified diff produced by git diff, git log --patch
968
- * or any other git plumbing command that produces unified
969
- * diffs.
970
- */
971
- parse(text) {
972
- this.text = text;
973
- try {
974
- const headerInfo = this.parseDiffHeader();
975
- const headerEnd = this.le;
976
- const header = this.text.substring(0, headerEnd);
977
- // empty diff
978
- if (!headerInfo) {
979
- return {
980
- header,
981
- contents: "",
982
- hunks: [],
983
- isBinary: false,
984
- maxLineNumber: 0,
985
- hasHiddenBidiChars: false,
986
- };
987
- }
988
- if (headerInfo.isBinary) {
989
- return {
990
- header,
991
- contents: "",
992
- hunks: [],
993
- isBinary: true,
994
- maxLineNumber: 0,
995
- hasHiddenBidiChars: false,
996
- };
997
- }
998
- const hunks = new Array();
999
- let linesConsumed = 0;
1000
- let previousHunk = null;
1001
- do {
1002
- const hunk = this.parseHunk(linesConsumed, hunks.length, previousHunk);
1003
- hunks.push(hunk);
1004
- previousHunk = hunk;
1005
- linesConsumed += hunk.lines.length;
1006
- } while (this.peek());
1007
- const contents = this.text
1008
- .substring(headerEnd + 1, this.le)
1009
- // Note that this simply returns a reference to the
1010
- // substring if no match is found, it does not create
1011
- // a new string instance.
1012
- .replace(/\n\/g, "");
1013
- return {
1014
- header,
1015
- contents,
1016
- hunks,
1017
- isBinary: headerInfo.isBinary,
1018
- maxLineNumber: getLargestLineNumber(hunks),
1019
- hasHiddenBidiChars: HiddenBidiCharsRegex.test(text),
1020
- };
1021
- }
1022
- finally {
1023
- this.reset();
1015
+ doRaw() {
1016
+ if (!this.raw || this.hasDoRaw)
1017
+ return;
1018
+ const rawString = this.raw;
1019
+ const rawArray = rawString.split("\n");
1020
+ this.rawLength = rawArray.length;
1021
+ this.maxLineNumber = rawArray.length;
1022
+ this.rawFile = {};
1023
+ for (let i = 0; i < rawArray.length; i++) {
1024
+ this.rawFile[i + 1] = i < rawArray.length - 1 ? rawArray[i] + "\n" : rawArray[i];
1024
1025
  }
1026
+ // reduce 对于大数组性能很差
1027
+ // this.rawFile = rawArray.reduce(
1028
+ // (p, item, index) => ({
1029
+ // ...p,
1030
+ // [index + 1]: index < rawArray.length - 1 ? item + "\n" : item,
1031
+ // }),
1032
+ // {}
1033
+ // );
1034
+ this.hasDoRaw = true;
1025
1035
  }
1026
1036
  }
1027
- const parseInstance = new DiffParser();
1037
+ _File_instances = new WeakSet(), _File_doCheck = function _File_doCheck() {
1038
+ if (this.rawLength && this.syntaxLength) {
1039
+ if (this.rawLength !== this.syntaxLength) {
1040
+ console.warn("the rawLength not match for the syntaxLength");
1041
+ }
1042
+ Object.values(this.syntaxFile).forEach(({ value, lineNumber }) => {
1043
+ if (value !== this.rawFile[lineNumber]) {
1044
+ console.log("some line not match:" + value + " __ " + this.rawFile[lineNumber] + " __ at: " + lineNumber + " lineNumber");
1045
+ }
1046
+ });
1047
+ }
1048
+ };
1049
+ const getFile = (raw, lang, fileName) => {
1050
+ const key = raw + "--" + "0.0.12" + "--" + lang;
1051
+ if (map.has(key))
1052
+ return map.get(key);
1053
+ const file = new File(raw, lang, fileName);
1054
+ map.set(key, file);
1055
+ return file;
1056
+ };
1057
+ const _cacheMap = map;
1028
1058
 
1029
- /* eslint-disable @typescript-eslint/ban-ts-comment */
1030
- /* eslint-disable max-lines */
1031
- var _DiffFile_instances, _DiffFile_oldFileResult, _DiffFile_newFileResult, _DiffFile_diffListResults, _DiffFile_diffLines, _DiffFile_oldFileDiffLines, _DiffFile_newFileDiffLines, _DiffFile_oldFileLines, _DiffFile_newFileLines, _DiffFile_oldFileSyntaxLines, _DiffFile_newFileSyntaxLines, _DiffFile_oldFilePlaceholderLines, _DiffFile_newFilePlaceholderLines, _DiffFile_splitLeftLines, _DiffFile_splitRightLines, _DiffFile_splitHunksLines, _DiffFile_unifiedLines, _DiffFile_unifiedHunksLines, _DiffFile_listeners, _DiffFile_hasInitRaw, _DiffFile_hasInitSyntax, _DiffFile_hasBuildSplit, _DiffFile_hasBuildUnified, _DiffFile_updateCount, _DiffFile_composeByDiff, _DiffFile_highlighterName, _DiffFile_id, _DiffFile_clonedInstance, _DiffFile_doDiff, _DiffFile_doFile, _DiffFile_composeRaw, _DiffFile_composeFile, _DiffFile_composeDiff, _DiffFile_composeSyntax, _DiffFile_getOldDiffLine, _DiffFile_getNewDiffLine, _DiffFile_getOldRawLine, _DiffFile_getNewRawLine;
1059
+ var _DiffFile_instances, _DiffFile_oldFileResult, _DiffFile_newFileResult, _DiffFile_diffListResults, _DiffFile_diffLines, _DiffFile_oldFileDiffLines, _DiffFile_newFileDiffLines, _DiffFile_oldFileLines, _DiffFile_newFileLines, _DiffFile_oldFileSyntaxLines, _DiffFile_newFileSyntaxLines, _DiffFile_oldFilePlaceholderLines, _DiffFile_newFilePlaceholderLines, _DiffFile_splitLeftLines, _DiffFile_splitRightLines, _DiffFile_splitHunksLines, _DiffFile_unifiedLines, _DiffFile_unifiedHunksLines, _DiffFile_listeners, _DiffFile_hasInitRaw, _DiffFile_hasInitSyntax, _DiffFile_hasBuildSplit, _DiffFile_hasBuildUnified, _DiffFile_updateCount, _DiffFile_composeByDiff, _DiffFile_composeByMerge, _DiffFile_composeByFullMerge, _DiffFile_highlighterName, _DiffFile_id, _DiffFile_clonedInstance, _DiffFile_doDiff, _DiffFile_doFile, _DiffFile_composeRaw, _DiffFile_composeFile, _DiffFile_composeDiff, _DiffFile_composeSyntax, _DiffFile_getOldDiffLine, _DiffFile_getNewDiffLine, _DiffFile_getOldRawLine, _DiffFile_getNewRawLine;
1032
1060
  const composeLen = 40;
1033
1061
  const idSet = new Set();
1034
1062
  class DiffFile {
@@ -1036,7 +1064,12 @@ class DiffFile {
1036
1064
  var _a, _b, _c, _d, _e, _f;
1037
1065
  const instance = new DiffFile(((_a = data === null || data === void 0 ? void 0 : data.oldFile) === null || _a === void 0 ? void 0 : _a.fileName) || "", ((_b = data === null || data === void 0 ? void 0 : data.oldFile) === null || _b === void 0 ? void 0 : _b.content) || "", ((_c = data === null || data === void 0 ? void 0 : data.newFile) === null || _c === void 0 ? void 0 : _c.fileName) || "", ((_d = data === null || data === void 0 ? void 0 : data.newFile) === null || _d === void 0 ? void 0 : _d.content) || "", (data === null || data === void 0 ? void 0 : data.hunks) || [], ((_e = data === null || data === void 0 ? void 0 : data.oldFile) === null || _e === void 0 ? void 0 : _e.fileLang) || "", ((_f = data === null || data === void 0 ? void 0 : data.newFile) === null || _f === void 0 ? void 0 : _f.fileLang) || "");
1038
1066
  if (bundle) {
1039
- instance.mergeBundle(bundle);
1067
+ if (bundle.isFullMerge) {
1068
+ instance._mergeFullBundle(bundle);
1069
+ }
1070
+ else {
1071
+ instance.mergeBundle(bundle);
1072
+ }
1040
1073
  }
1041
1074
  return instance;
1042
1075
  }
@@ -1069,8 +1102,10 @@ class DiffFile {
1069
1102
  _DiffFile_hasBuildUnified.set(this, false);
1070
1103
  _DiffFile_updateCount.set(this, 0);
1071
1104
  _DiffFile_composeByDiff.set(this, false);
1105
+ _DiffFile_composeByMerge.set(this, false);
1106
+ _DiffFile_composeByFullMerge.set(this, false);
1072
1107
  _DiffFile_highlighterName.set(this, void 0);
1073
- this._version_ = "0.0.10";
1108
+ this._version_ = "0.0.12";
1074
1109
  this._oldFileContent = "";
1075
1110
  this._oldFileLang = "";
1076
1111
  this._newFileContent = "";
@@ -1078,9 +1113,9 @@ class DiffFile {
1078
1113
  this.diffLineLength = 0;
1079
1114
  this.splitLineLength = 0;
1080
1115
  this.unifiedLineLength = 0;
1081
- this.expandSplitAll = false;
1082
- this.expandUnifiedAll = false;
1083
- this.hasCollapsed = false;
1116
+ this.hasExpandSplitAll = false;
1117
+ this.hasExpandUnifiedAll = false;
1118
+ this.hasSomeLineCollapsed = false;
1084
1119
  _DiffFile_id.set(this, "");
1085
1120
  _DiffFile_clonedInstance.set(this, new Map());
1086
1121
  this.getSplitLeftLine = (index) => {
@@ -1219,13 +1254,13 @@ class DiffFile {
1219
1254
  Object.keys(__classPrivateFieldGet(this, _DiffFile_splitHunksLines, "f") || {}).forEach((key) => {
1220
1255
  this.onSplitHunkExpand("all", +key, false);
1221
1256
  });
1222
- this.expandSplitAll = true;
1257
+ this.hasExpandSplitAll = true;
1223
1258
  }
1224
1259
  else {
1225
1260
  Object.keys(__classPrivateFieldGet(this, _DiffFile_unifiedHunksLines, "f") || {}).forEach((key) => {
1226
1261
  this.onUnifiedHunkExpand("all", +key, false);
1227
1262
  });
1228
- this.expandUnifiedAll = true;
1263
+ this.hasExpandUnifiedAll = true;
1229
1264
  }
1230
1265
  this.notifyAll();
1231
1266
  };
@@ -1257,7 +1292,7 @@ class DiffFile {
1257
1292
  __classPrivateFieldGet(this, _DiffFile_splitHunksLines, "f")[item.splitInfo.endHiddenIndex] = item;
1258
1293
  }
1259
1294
  });
1260
- this.expandSplitAll = false;
1295
+ this.hasExpandSplitAll = false;
1261
1296
  }
1262
1297
  else {
1263
1298
  Object.values(__classPrivateFieldGet(this, _DiffFile_unifiedLines, "f") || {}).forEach((item) => {
@@ -1279,7 +1314,7 @@ class DiffFile {
1279
1314
  __classPrivateFieldGet(this, _DiffFile_unifiedHunksLines, "f")[item.unifiedInfo.endHiddenIndex] = item;
1280
1315
  }
1281
1316
  });
1282
- this.expandUnifiedAll = false;
1317
+ this.hasExpandUnifiedAll = false;
1283
1318
  }
1284
1319
  this.notifyAll();
1285
1320
  };
@@ -1331,7 +1366,7 @@ class DiffFile {
1331
1366
  const unifiedLineLength = this.unifiedLineLength;
1332
1367
  const composeByDiff = __classPrivateFieldGet(this, _DiffFile_composeByDiff, "f");
1333
1368
  const highlighterName = __classPrivateFieldGet(this, _DiffFile_highlighterName, "f");
1334
- const hasCollapsed = this.hasCollapsed;
1369
+ const hasSomeLineCollapsed = this.hasSomeLineCollapsed;
1335
1370
  // split
1336
1371
  const splitLeftLines = __classPrivateFieldGet(this, _DiffFile_splitLeftLines, "f");
1337
1372
  const splitRightLines = __classPrivateFieldGet(this, _DiffFile_splitRightLines, "f");
@@ -1362,8 +1397,9 @@ class DiffFile {
1362
1397
  unifiedHunkLines,
1363
1398
  highlighterName,
1364
1399
  composeByDiff,
1365
- hasCollapsed,
1400
+ hasSomeLineCollapsed,
1366
1401
  version,
1402
+ isFullMerge: false,
1367
1403
  };
1368
1404
  };
1369
1405
  this.mergeBundle = (data) => {
@@ -1383,12 +1419,14 @@ class DiffFile {
1383
1419
  __classPrivateFieldSet(this, _DiffFile_newFilePlaceholderLines, data.newFilePlaceholderLines, "f");
1384
1420
  this.splitLineLength = data.splitLineLength;
1385
1421
  this.unifiedLineLength = data.unifiedLineLength;
1386
- this.hasCollapsed = data.hasCollapsed;
1422
+ this.hasSomeLineCollapsed = data.hasSomeLineCollapsed;
1387
1423
  __classPrivateFieldSet(this, _DiffFile_splitLeftLines, data.splitLeftLines, "f");
1388
1424
  __classPrivateFieldSet(this, _DiffFile_splitRightLines, data.splitRightLines, "f");
1389
1425
  __classPrivateFieldSet(this, _DiffFile_splitHunksLines, data.splitHunkLines, "f");
1390
1426
  __classPrivateFieldSet(this, _DiffFile_unifiedLines, data.unifiedLines, "f");
1391
1427
  __classPrivateFieldSet(this, _DiffFile_unifiedHunksLines, data.unifiedHunkLines, "f");
1428
+ // mark this instance as a merged instance
1429
+ __classPrivateFieldSet(this, _DiffFile_composeByMerge, true, "f");
1392
1430
  if (this._version_ !== data.version) {
1393
1431
  console.error("the version of the `diffInstance` is not match, some error may happen!");
1394
1432
  }
@@ -1425,14 +1463,21 @@ class DiffFile {
1425
1463
  return Object.assign(Object.assign({}, bundle), { oldFileResult,
1426
1464
  newFileResult,
1427
1465
  diffLines,
1428
- diffListResults });
1466
+ diffListResults,
1467
+ // get current instance is a fullMerge instance or not
1468
+ isFullMerge: __classPrivateFieldGet(this, _DiffFile_composeByMerge, "f") ? __classPrivateFieldGet(this, _DiffFile_composeByFullMerge, "f") : true });
1429
1469
  };
1430
1470
  this._mergeFullBundle = (data) => {
1431
1471
  this.mergeBundle(data);
1432
- __classPrivateFieldSet(this, _DiffFile_oldFileResult, data.oldFileResult, "f");
1433
- __classPrivateFieldSet(this, _DiffFile_newFileResult, data.newFileResult, "f");
1434
- __classPrivateFieldSet(this, _DiffFile_diffLines, data.diffLines, "f");
1435
- __classPrivateFieldSet(this, _DiffFile_diffListResults, data.diffListResults, "f");
1472
+ try {
1473
+ __classPrivateFieldSet(this, _DiffFile_oldFileResult, File.createInstance(data.oldFileResult), "f");
1474
+ __classPrivateFieldSet(this, _DiffFile_newFileResult, File.createInstance(data.newFileResult), "f");
1475
+ __classPrivateFieldSet(this, _DiffFile_diffLines, data.diffLines, "f");
1476
+ __classPrivateFieldSet(this, _DiffFile_diffListResults, data.diffListResults, "f");
1477
+ __classPrivateFieldSet(this, _DiffFile_composeByFullMerge, data.isFullMerge, "f");
1478
+ }
1479
+ catch (_a) {
1480
+ }
1436
1481
  };
1437
1482
  this._destroy = () => {
1438
1483
  this.clearId();
@@ -1507,6 +1552,10 @@ class DiffFile {
1507
1552
  var _a, _b;
1508
1553
  if (__classPrivateFieldGet(this, _DiffFile_hasInitSyntax, "f"))
1509
1554
  return;
1555
+ if (__classPrivateFieldGet(this, _DiffFile_composeByMerge, "f") && !__classPrivateFieldGet(this, _DiffFile_composeByFullMerge, "f")) {
1556
+ console.error(`this instance can not do syntax because of the data missing, try to use '_getFullBundle' & '_mergeFullBundle' instead of 'getBundle' & 'mergeBundle'`);
1557
+ return;
1558
+ }
1510
1559
  __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_composeSyntax).call(this, { registerHighlighter });
1511
1560
  __classPrivateFieldSet(this, _DiffFile_highlighterName, ((_a = __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f")) === null || _a === void 0 ? void 0 : _a.highlighterName) || ((_b = __classPrivateFieldGet(this, _DiffFile_newFileResult, "f")) === null || _b === void 0 ? void 0 : _b.highlighterName) || __classPrivateFieldGet(this, _DiffFile_highlighterName, "f"), "f");
1512
1561
  __classPrivateFieldSet(this, _DiffFile_hasInitSyntax, true, "f");
@@ -1609,7 +1658,7 @@ class DiffFile {
1609
1658
  hideStart = len;
1610
1659
  }
1611
1660
  if (isHidden) {
1612
- this.hasCollapsed = true;
1661
+ this.hasSomeLineCollapsed = true;
1613
1662
  }
1614
1663
  prevIsHidden = isHidden;
1615
1664
  if (oldDiffLine && newDiffLine && !oldLineHasChange && !newLineHasChange) {
@@ -1740,7 +1789,7 @@ class DiffFile {
1740
1789
  hideStart = len;
1741
1790
  }
1742
1791
  if (isHidden) {
1743
- this.hasCollapsed = true;
1792
+ this.hasSomeLineCollapsed = true;
1744
1793
  }
1745
1794
  prevIsHidden = isHidden;
1746
1795
  if (oldDiffLine && newDiffLine && !oldLineHasChange && !newLineHasChange) {
@@ -1786,7 +1835,7 @@ class DiffFile {
1786
1835
  this.notifyAll();
1787
1836
  }
1788
1837
  }
1789
- _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap(), _DiffFile_diffListResults = new WeakMap(), _DiffFile_diffLines = new WeakMap(), _DiffFile_oldFileDiffLines = new WeakMap(), _DiffFile_newFileDiffLines = new WeakMap(), _DiffFile_oldFileLines = new WeakMap(), _DiffFile_newFileLines = new WeakMap(), _DiffFile_oldFileSyntaxLines = new WeakMap(), _DiffFile_newFileSyntaxLines = new WeakMap(), _DiffFile_oldFilePlaceholderLines = new WeakMap(), _DiffFile_newFilePlaceholderLines = new WeakMap(), _DiffFile_splitLeftLines = new WeakMap(), _DiffFile_splitRightLines = new WeakMap(), _DiffFile_splitHunksLines = new WeakMap(), _DiffFile_unifiedLines = new WeakMap(), _DiffFile_unifiedHunksLines = new WeakMap(), _DiffFile_listeners = new WeakMap(), _DiffFile_hasInitRaw = new WeakMap(), _DiffFile_hasInitSyntax = new WeakMap(), _DiffFile_hasBuildSplit = new WeakMap(), _DiffFile_hasBuildUnified = new WeakMap(), _DiffFile_updateCount = new WeakMap(), _DiffFile_composeByDiff = new WeakMap(), _DiffFile_highlighterName = new WeakMap(), _DiffFile_id = new WeakMap(), _DiffFile_clonedInstance = new WeakMap(), _DiffFile_instances = new WeakSet(), _DiffFile_doDiff = function _DiffFile_doDiff() {
1838
+ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap(), _DiffFile_diffListResults = new WeakMap(), _DiffFile_diffLines = new WeakMap(), _DiffFile_oldFileDiffLines = new WeakMap(), _DiffFile_newFileDiffLines = new WeakMap(), _DiffFile_oldFileLines = new WeakMap(), _DiffFile_newFileLines = new WeakMap(), _DiffFile_oldFileSyntaxLines = new WeakMap(), _DiffFile_newFileSyntaxLines = new WeakMap(), _DiffFile_oldFilePlaceholderLines = new WeakMap(), _DiffFile_newFilePlaceholderLines = new WeakMap(), _DiffFile_splitLeftLines = new WeakMap(), _DiffFile_splitRightLines = new WeakMap(), _DiffFile_splitHunksLines = new WeakMap(), _DiffFile_unifiedLines = new WeakMap(), _DiffFile_unifiedHunksLines = new WeakMap(), _DiffFile_listeners = new WeakMap(), _DiffFile_hasInitRaw = new WeakMap(), _DiffFile_hasInitSyntax = new WeakMap(), _DiffFile_hasBuildSplit = new WeakMap(), _DiffFile_hasBuildUnified = new WeakMap(), _DiffFile_updateCount = new WeakMap(), _DiffFile_composeByDiff = new WeakMap(), _DiffFile_composeByMerge = new WeakMap(), _DiffFile_composeByFullMerge = new WeakMap(), _DiffFile_highlighterName = new WeakMap(), _DiffFile_id = new WeakMap(), _DiffFile_clonedInstance = new WeakMap(), _DiffFile_instances = new WeakSet(), _DiffFile_doDiff = function _DiffFile_doDiff() {
1790
1839
  if (!this._diffList)
1791
1840
  return;
1792
1841
  __classPrivateFieldSet(this, _DiffFile_diffListResults, this._diffList.map((s) => parseInstance.parse(s)), "f");
@@ -1816,31 +1865,33 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
1816
1865
  let oldLineNumber = 1;
1817
1866
  let oldFileContent = "";
1818
1867
  let newFileContent = "";
1819
- while (oldLineNumber <= this.diffLineLength) {
1820
- const index = oldLineNumber++;
1821
- const diffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getOldDiffLine).call(this, index);
1822
- if (diffLine) {
1823
- oldFileContent += diffLine.text;
1868
+ let hasSymbolChanged = false;
1869
+ while (oldLineNumber <= this.diffLineLength || newLineNumber <= this.diffLineLength) {
1870
+ const oldIndex = oldLineNumber++;
1871
+ const newIndex = newLineNumber++;
1872
+ const oldDiffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getOldDiffLine).call(this, oldIndex);
1873
+ const newDiffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getNewDiffLine).call(this, newIndex);
1874
+ if (oldDiffLine) {
1875
+ oldFileContent += oldDiffLine.text;
1824
1876
  }
1825
1877
  else {
1826
1878
  // empty line for placeholder
1827
1879
  oldFileContent += "\n";
1828
- oldFilePlaceholderLines[index] = true;
1880
+ oldFilePlaceholderLines[oldIndex] = true;
1829
1881
  }
1830
- }
1831
- while (newLineNumber <= this.diffLineLength) {
1832
- const index = newLineNumber++;
1833
- const diffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getNewDiffLine).call(this, index);
1834
- if (diffLine) {
1835
- newFileContent += diffLine.text;
1882
+ if (newDiffLine) {
1883
+ newFileContent += newDiffLine.text;
1836
1884
  }
1837
1885
  else {
1838
1886
  // empty line for placeholder
1839
1887
  newFileContent += "\n";
1840
- newFilePlaceholderLines[index] = true;
1888
+ newFilePlaceholderLines[newIndex] = true;
1889
+ }
1890
+ if (!hasSymbolChanged && oldDiffLine && newDiffLine) {
1891
+ hasSymbolChanged = hasSymbolChanged || oldDiffLine.noTrailingNewLine !== newDiffLine.noTrailingNewLine;
1841
1892
  }
1842
1893
  }
1843
- if (oldFileContent === newFileContent)
1894
+ if (!hasSymbolChanged && oldFileContent === newFileContent)
1844
1895
  return;
1845
1896
  this._oldFileContent = oldFileContent;
1846
1897
  this._newFileContent = newFileContent;
@@ -1855,21 +1906,25 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
1855
1906
  let newLineNumber = 1;
1856
1907
  let oldLineNumber = 1;
1857
1908
  let newFileContent = "";
1909
+ let hasSymbolChanged = false;
1858
1910
  while (oldLineNumber <= __classPrivateFieldGet(this, _DiffFile_oldFileResult, "f").maxLineNumber) {
1859
1911
  const newDiffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getNewDiffLine).call(this, newLineNumber++);
1912
+ const oldDiffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getOldDiffLine).call(this, oldLineNumber);
1860
1913
  if (newDiffLine) {
1861
1914
  newFileContent += newDiffLine.text;
1862
1915
  oldLineNumber = newDiffLine.oldLineNumber ? newDiffLine.oldLineNumber + 1 : oldLineNumber;
1863
1916
  }
1864
1917
  else {
1865
- const oldDiffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getOldDiffLine).call(this, oldLineNumber);
1866
1918
  if (!oldDiffLine) {
1867
1919
  newFileContent += __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getOldRawLine).call(this, oldLineNumber);
1868
1920
  }
1869
1921
  oldLineNumber++;
1870
1922
  }
1923
+ if (!hasSymbolChanged && newDiffLine && oldDiffLine) {
1924
+ hasSymbolChanged = hasSymbolChanged || newDiffLine.noTrailingNewLine !== oldDiffLine.noTrailingNewLine;
1925
+ }
1871
1926
  }
1872
- if (newFileContent === this._oldFileContent)
1927
+ if (!hasSymbolChanged && newFileContent === this._oldFileContent)
1873
1928
  return;
1874
1929
  this._newFileContent = newFileContent;
1875
1930
  __classPrivateFieldSet(this, _DiffFile_newFileResult, getFile(this._newFileContent, this._newFileLang, this._newFileName), "f");
@@ -1878,21 +1933,25 @@ _DiffFile_oldFileResult = new WeakMap(), _DiffFile_newFileResult = new WeakMap()
1878
1933
  let oldLineNumber = 1;
1879
1934
  let newLineNumber = 1;
1880
1935
  let oldFileContent = "";
1936
+ let hasSymbolChanged = false;
1881
1937
  while (newLineNumber <= __classPrivateFieldGet(this, _DiffFile_newFileResult, "f").maxLineNumber) {
1882
1938
  const oldDiffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getOldDiffLine).call(this, oldLineNumber++);
1939
+ const newDiffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getNewDiffLine).call(this, newLineNumber);
1883
1940
  if (oldDiffLine) {
1884
1941
  oldFileContent += oldDiffLine.text;
1885
1942
  newLineNumber = oldDiffLine.newLineNumber ? oldDiffLine.newLineNumber + 1 : newLineNumber;
1886
1943
  }
1887
1944
  else {
1888
- const newDiffLine = __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getNewDiffLine).call(this, newLineNumber);
1889
1945
  if (!newDiffLine) {
1890
1946
  oldFileContent += __classPrivateFieldGet(this, _DiffFile_instances, "m", _DiffFile_getNewRawLine).call(this, newLineNumber);
1891
1947
  }
1892
1948
  newLineNumber++;
1893
1949
  }
1950
+ if (!hasSymbolChanged && newDiffLine && oldDiffLine) {
1951
+ hasSymbolChanged = hasSymbolChanged || newDiffLine.noTrailingNewLine !== oldDiffLine.noTrailingNewLine;
1952
+ }
1894
1953
  }
1895
- if (oldFileContent === this._newFileContent)
1954
+ if (!hasSymbolChanged && oldFileContent === this._newFileContent)
1896
1955
  return;
1897
1956
  this._oldFileContent = oldFileContent;
1898
1957
  __classPrivateFieldSet(this, _DiffFile_oldFileResult, getFile(this._oldFileContent, this._oldFileLang, this._oldFileName), "f");
@@ -2090,7 +2149,7 @@ const getUnifiedContentLine = (diffFile) => {
2090
2149
  return lines.filter((line) => line.type === exports.DiffFileLineType.content);
2091
2150
  };
2092
2151
 
2093
- const versions = "0.0.10";
2152
+ const versions = "0.0.12";
2094
2153
 
2095
2154
  const useUnmount = (cb, deps) => {
2096
2155
  const ref = React.useRef(cb);
@@ -2427,6 +2486,11 @@ const _DiffSplitHunkLineGitLab = ({ index, diffFile, side, lineNumber, }) => {
2427
2486
  var _a;
2428
2487
  const currentHunk = diffFile.getSplitHunkLine(index);
2429
2488
  const expandEnabled = diffFile.getExpandEnabled();
2489
+ useSyncHeight({
2490
+ selector: `tr[data-line="${lineNumber}-hunk"]`,
2491
+ side: exports.SplitSide[exports.SplitSide.old],
2492
+ enable: side === exports.SplitSide.new,
2493
+ });
2430
2494
  const couldExpand = expandEnabled && currentHunk && currentHunk.splitInfo;
2431
2495
  const isExpandAll = currentHunk &&
2432
2496
  currentHunk.splitInfo &&
@@ -2480,8 +2544,8 @@ const DiffSplitHunkLine$1 = ({ index, diffFile, side, lineNumber, }) => {
2480
2544
 
2481
2545
  const DiffSplitAddWidget = ({ side, className, lineNumber, onWidgetClick, onOpenAddWidget, }) => {
2482
2546
  return (React__namespace.createElement("div", { className: "diff-add-widget-wrapper" + (className ? " " + className : ""), style: {
2483
- width: "calc(var(--diff-font-size--) * 1.4)",
2484
- height: "calc(var(--diff-font-size--) * 1.4)",
2547
+ width: `calc(var(${diffFontSizeName}) * 1.4)`,
2548
+ height: `calc(var(${diffFontSizeName}) * 1.4)`,
2485
2549
  } },
2486
2550
  React__namespace.createElement("button", { className: "diff-add-widget w-full h-full invisible cursor-pointer rounded-md flex items-center justify-center transition-transform origin-center group-hover:visible hover:scale-110", style: {
2487
2551
  color: `var(${addWidgetColorName})`,
@@ -2495,8 +2559,8 @@ const DiffSplitAddWidget = ({ side, className, lineNumber, onWidgetClick, onOpen
2495
2559
  };
2496
2560
  const DiffUnifiedAddWidget = ({ lineNumber, side, onWidgetClick, onOpenAddWidget, }) => {
2497
2561
  return (React__namespace.createElement("div", { className: "diff-add-widget-wrapper absolute left-[100%] top-[1px] translate-x-[-50%]", style: {
2498
- width: "calc(var(--diff-font-size--) * 1.4)",
2499
- height: "calc(var(--diff-font-size--) * 1.4)",
2562
+ width: `calc(var(${diffFontSizeName}) * 1.4)`,
2563
+ height: `calc(var(${diffFontSizeName}) * 1.4)`,
2500
2564
  } },
2501
2565
  React__namespace.createElement("button", { className: "diff-add-widget w-full h-full invisible cursor-pointer rounded-md flex items-center justify-center transition-transform origin-center group-hover:visible hover:scale-110", style: {
2502
2566
  color: `var(${addWidgetColorName})`,
@@ -2509,6 +2573,12 @@ const DiffUnifiedAddWidget = ({ lineNumber, side, onWidgetClick, onOpenAddWidget
2509
2573
  } }, "+")));
2510
2574
  };
2511
2575
 
2576
+ const DiffNoNewLine = () => {
2577
+ return (React__namespace.createElement("svg", { "aria-label": "No newline at end of file", role: "img", viewBox: "0 0 16 16", version: "1.1", fill: "currentColor" },
2578
+ React__namespace.createElement("path", { d: "M4.25 7.25a.75.75 0 0 0 0 1.5h7.5a.75.75 0 0 0 0-1.5h-7.5Z" }),
2579
+ React__namespace.createElement("path", { d: "M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-1.5 0a6.5 6.5 0 1 0-13 0 6.5 6.5 0 0 0 13 0Z" })));
2580
+ };
2581
+
2512
2582
  const temp = {};
2513
2583
  const formatStringToCamelCase = (str) => {
2514
2584
  const splitted = str.split("-");
@@ -2533,7 +2603,7 @@ const getStyleObjectFromString = memoFunc((str) => {
2533
2603
  });
2534
2604
  return style;
2535
2605
  });
2536
- const DiffString = ({ rawLine, diffLine, operator, }) => {
2606
+ const DiffString = ({ rawLine, diffLine, operator, enableWrap, }) => {
2537
2607
  const range = diffLine === null || diffLine === void 0 ? void 0 : diffLine.range;
2538
2608
  if (range) {
2539
2609
  const str1 = rawLine.slice(0, range.location);
@@ -2552,19 +2622,27 @@ const DiffString = ({ rawLine, diffLine, operator, }) => {
2552
2622
  ? "␊"
2553
2623
  : isNewLineSymbolChanged === exports.NewLineSymbol.CR
2554
2624
  ? "␍"
2555
- : "␍␊"}`
2625
+ : isNewLineSymbolChanged === exports.NewLineSymbol.CRLF
2626
+ ? "␍␊"
2627
+ : ""}`
2556
2628
  : str2),
2557
- str3)));
2629
+ str3),
2630
+ isNewLineSymbolChanged === exports.NewLineSymbol.NEWLINE && diffLine.noTrailingNewLine && (React__namespace.createElement("span", { "data-no-newline-at-end-of-file": true, className: enableWrap ? "block text-red-500" : "inline-block align-middle text-red-500", style: {
2631
+ width: `var(${diffFontSizeName})`,
2632
+ height: `var(${diffFontSizeName})`,
2633
+ } },
2634
+ React__namespace.createElement(DiffNoNewLine, null)))));
2558
2635
  }
2559
2636
  return React__namespace.createElement("span", { className: "diff-line-content-raw" }, rawLine);
2560
2637
  };
2561
- const DiffSyntax = ({ rawLine, diffLine, operator, syntaxLine, }) => {
2638
+ const DiffSyntax = ({ rawLine, diffLine, operator, syntaxLine, enableWrap, }) => {
2562
2639
  var _a, _b;
2563
2640
  if (!syntaxLine) {
2564
2641
  return React__namespace.createElement(DiffString, { rawLine: rawLine, diffLine: diffLine, operator: operator });
2565
2642
  }
2566
2643
  const range = diffLine === null || diffLine === void 0 ? void 0 : diffLine.range;
2567
2644
  if (range) {
2645
+ const isNewLineSymbolChanged = range.newLineSymbol;
2568
2646
  return (React__namespace.createElement("span", { className: "diff-line-syntax-raw" },
2569
2647
  React__namespace.createElement("span", { "data-range-start": range.location, "data-range-end": range.location + range.length }, (_a = syntaxLine.nodeList) === null || _a === void 0 ? void 0 : _a.map(({ node, wrapper }, index) => {
2570
2648
  var _a, _b, _c, _d, _e, _f;
@@ -2581,7 +2659,6 @@ const DiffSyntax = ({ rawLine, diffLine, operator, syntaxLine, }) => {
2581
2659
  const isEnd = str3.length || node.endIndex === range.location + range.length - 1;
2582
2660
  const isLast = str2.includes("\n");
2583
2661
  const _str2 = isLast ? str2.replace("\n", "") : str2;
2584
- const isNewLineSymbolChanged = range.newLineSymbol;
2585
2662
  return (React__namespace.createElement("span", { key: index, "data-start": node.startIndex, "data-end": node.endIndex, className: (_e = (_d = wrapper === null || wrapper === void 0 ? void 0 : wrapper.properties) === null || _d === void 0 ? void 0 : _d.className) === null || _e === void 0 ? void 0 : _e.join(" "), style: getStyleObjectFromString(((_f = wrapper === null || wrapper === void 0 ? void 0 : wrapper.properties) === null || _f === void 0 ? void 0 : _f.style) || "") },
2586
2663
  str1,
2587
2664
  React__namespace.createElement("span", { "data-diff-highlight": true, style: {
@@ -2595,11 +2672,18 @@ const DiffSyntax = ({ rawLine, diffLine, operator, syntaxLine, }) => {
2595
2672
  ? "␊"
2596
2673
  : isNewLineSymbolChanged === exports.NewLineSymbol.CR
2597
2674
  ? "␍"
2598
- : "␍␊"}`
2675
+ : isNewLineSymbolChanged === exports.NewLineSymbol.CRLF
2676
+ ? "␍␊"
2677
+ : ""}`
2599
2678
  : str2),
2600
2679
  str3));
2601
2680
  }
2602
- }))));
2681
+ })),
2682
+ isNewLineSymbolChanged === exports.NewLineSymbol.NEWLINE && diffLine.noTrailingNewLine && (React__namespace.createElement("span", { "data-no-newline-at-end-of-file": true, className: enableWrap ? "block text-red-500" : "inline-block align-middle text-red-500", style: {
2683
+ width: `var(${diffFontSizeName})`,
2684
+ height: `var(${diffFontSizeName})`,
2685
+ } },
2686
+ React__namespace.createElement(DiffNoNewLine, null)))));
2603
2687
  }
2604
2688
  return (React__namespace.createElement("span", { className: "diff-line-syntax-raw" }, (_b = syntaxLine === null || syntaxLine === void 0 ? void 0 : syntaxLine.nodeList) === null || _b === void 0 ? void 0 : _b.map(({ node, wrapper }, index) => {
2605
2689
  var _a, _b, _c;
@@ -2616,7 +2700,7 @@ const DiffContent = ({ diffLine, rawLine, syntaxLine, enableWrap, enableHighligh
2616
2700
  wordBreak: enableWrap ? "break-all" : "initial",
2617
2701
  } },
2618
2702
  React__namespace.createElement("span", { "data-operator": isAdded ? "+" : isDelete ? "-" : undefined, className: "diff-line-content-operator inline-block w-[1.5em] ml-[-1.5em] indent-[0.2em] select-none" }, isAdded ? "+" : isDelete ? "-" : " "),
2619
- enableHighlight && syntaxLine && !isMaxLineLengthToIgnoreSyntax ? (React__namespace.createElement(DiffSyntax, { operator: isAdded ? "add" : isDelete ? "del" : undefined, rawLine: rawLine, diffLine: diffLine, syntaxLine: syntaxLine })) : (React__namespace.createElement(DiffString, { operator: isAdded ? "add" : isDelete ? "del" : undefined, rawLine: rawLine, diffLine: diffLine }))));
2703
+ enableHighlight && syntaxLine && !isMaxLineLengthToIgnoreSyntax ? (React__namespace.createElement(DiffSyntax, { operator: isAdded ? "add" : isDelete ? "del" : undefined, rawLine: rawLine, diffLine: diffLine, syntaxLine: syntaxLine, enableWrap: enableWrap })) : (React__namespace.createElement(DiffString, { operator: isAdded ? "add" : isDelete ? "del" : undefined, rawLine: rawLine, diffLine: diffLine, enableWrap: enableWrap }))));
2620
2704
  };
2621
2705
 
2622
2706
  const DiffWidgetContext = React.createContext(null);
@@ -2765,7 +2849,7 @@ const DiffSplitViewNormal = React.memo(({ diffFile }) => {
2765
2849
  [asideWidth]: `${Math.round(width)}px`,
2766
2850
  overscrollBehaviorX: "none",
2767
2851
  fontFamily: "Menlo, Consolas, monospace",
2768
- fontSize: "var(--diff-font-size--)",
2852
+ fontSize: `var(${diffFontSizeName})`,
2769
2853
  } },
2770
2854
  React__namespace.createElement(DiffSplitViewTable, { side: exports.SplitSide.old, diffFile: diffFile })),
2771
2855
  React__namespace.createElement("div", { className: "diff-split-line w-[1.5px] bg-[rgb(222,222,222)]" }),
@@ -2774,7 +2858,7 @@ const DiffSplitViewNormal = React.memo(({ diffFile }) => {
2774
2858
  [asideWidth]: `${Math.round(width)}px`,
2775
2859
  overscrollBehaviorX: "none",
2776
2860
  fontFamily: "Menlo, Consolas, monospace",
2777
- fontSize: "var(--diff-font-size--)",
2861
+ fontSize: `var(${diffFontSizeName})`,
2778
2862
  } },
2779
2863
  React__namespace.createElement(DiffSplitViewTable, { side: exports.SplitSide.new, diffFile: diffFile }))));
2780
2864
  });
@@ -3065,7 +3149,7 @@ const DiffSplitViewWrap = React.memo(({ diffFile }) => {
3065
3149
  return (React__namespace.createElement("div", { className: "split-diff-view split-diff-view-normal w-full" },
3066
3150
  React__namespace.createElement("div", { className: "diff-table-wrapper w-full", style: {
3067
3151
  fontFamily: "Menlo, Consolas, monospace",
3068
- fontSize: "var(--diff-font-size--)",
3152
+ fontSize: `var(${diffFontSizeName})`,
3069
3153
  } },
3070
3154
  React__namespace.createElement(Style, { useSelector: splitSideInfo, id: `diff-root${diffFile.getId()}` }),
3071
3155
  React__namespace.createElement("table", { className: "diff-table border-collapse table-fixed w-full" },
@@ -3378,7 +3462,7 @@ const DiffUnifiedView = React.memo(({ diffFile }) => {
3378
3462
  // @ts-ignore
3379
3463
  [asideWidth]: `${Math.round(width)}px`,
3380
3464
  fontFamily: "Menlo, Consolas, monospace",
3381
- fontSize: "var(--diff-font-size--)",
3465
+ fontSize: `var(${diffFontSizeName})`,
3382
3466
  } },
3383
3467
  React__namespace.createElement("table", { className: "unified-diff-table border-collapse w-full" },
3384
3468
  React__namespace.createElement("colgroup", null,
@@ -3508,7 +3592,7 @@ const _InternalDiffView = (props) => {
3508
3592
  ]);
3509
3593
  const value = React.useMemo(() => ({ useDiffContext }), [useDiffContext]);
3510
3594
  return (React__namespace.createElement(DiffViewContext.Provider, { value: value },
3511
- React__namespace.createElement("div", { className: "diff-tailwindcss-wrapper", "data-component": "git-diff-view", "data-version": `${"0.0.10"}`, "data-highlighter": diffFile._getHighlighterName() },
3595
+ React__namespace.createElement("div", { className: "diff-tailwindcss-wrapper", "data-component": "git-diff-view", "data-version": `${"0.0.12"}`, "data-highlighter": diffFile._getHighlighterName() },
3512
3596
  React__namespace.createElement("div", { className: "diff-style-root", style: {
3513
3597
  // @ts-ignore
3514
3598
  [diffFontSizeName]: diffViewFontSize + "px",
@@ -3561,18 +3645,23 @@ const DiffViewWithRef = (props, ref) => {
3561
3645
  };
3562
3646
  const DiffView = React.forwardRef(DiffViewWithRef);
3563
3647
  DiffView.displayName = "DiffView";
3564
- const version = "0.0.10";
3648
+ const version = "0.0.12";
3565
3649
 
3566
3650
  exports.DefaultDiffExpansionStep = DefaultDiffExpansionStep;
3567
3651
  exports.DiffFile = DiffFile;
3652
+ exports.DiffHunk = DiffHunk;
3653
+ exports.DiffHunkHeader = DiffHunkHeader;
3568
3654
  exports.DiffLine = DiffLine;
3655
+ exports.DiffParser = DiffParser;
3569
3656
  exports.DiffView = DiffView;
3570
3657
  exports.DiffViewContext = DiffViewContext;
3571
3658
  exports.File = File;
3659
+ exports.HiddenBidiCharsRegex = HiddenBidiCharsRegex;
3572
3660
  exports._cacheMap = _cacheMap;
3573
3661
  exports.assertNever = assertNever;
3574
3662
  exports.checkDiffLineIncludeChange = checkDiffLineIncludeChange;
3575
3663
  exports.composeLen = composeLen;
3664
+ exports.diffFontSizeName = diffFontSizeName;
3576
3665
  exports.getDiffRange = getDiffRange;
3577
3666
  exports.getFile = getFile;
3578
3667
  exports.getHunkHeaderExpansionType = getHunkHeaderExpansionType;
@@ -3585,6 +3674,7 @@ exports.getUnifiedLines = getUnifiedLines;
3585
3674
  exports.hasRelativeChange = hasRelativeChange;
3586
3675
  exports.highlighter = highlighter;
3587
3676
  exports.numIterator = numIterator;
3677
+ exports.parseInstance = parseInstance;
3588
3678
  exports.processAST = processAST;
3589
3679
  exports.relativeChanges = relativeChanges;
3590
3680
  exports.useDiffViewContext = useDiffViewContext;