v-code-diff 1.13.1 → 1.14.0
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.
- package/README.md +23 -5
- package/dist/v2/index.cjs +26 -0
- package/dist/v2/index.es.js +1727 -1604
- package/dist/v2/index.umd.js +26 -19
- package/dist/v2.7/index.cjs +26 -0
- package/dist/v2.7/index.es.js +1487 -1420
- package/dist/v2.7/index.umd.js +26 -19
- package/dist/v3/index.cjs +26 -0
- package/dist/v3/index.es.js +1905 -1808
- package/dist/v3/index.umd.js +26 -19
- package/package.json +25 -14
- package/scripts/perf-test.ts +40 -0
- package/scripts/postinstall.cjs +15 -18
- package/scripts/utils.cjs +4 -19
- package/src/CodeDiff.vue +11 -9
- package/src/split/SplitLine.vue +9 -5
- package/src/split/SplitViewer.vue +34 -2
- package/src/style.scss +18 -0
- package/src/types.ts +2 -0
- package/src/unified/UnifiedLine.vue +1 -1
- package/src/unified/UnifiedViewer.vue +34 -2
- package/src/utils.ts +164 -54
- package/dist/v2/index.cjs.js +0 -19
- package/dist/v2.7/index.cjs.js +0 -19
- package/dist/v3/index.cjs.js +0 -19
package/src/utils.ts
CHANGED
|
@@ -7,10 +7,23 @@ import type { DiffLine, DiffStat, SplitLineChange, SplitLineUnchanges, SplitView
|
|
|
7
7
|
|
|
8
8
|
const MODIFIED_START_TAG = '<code-diff-modified>'
|
|
9
9
|
const MODIFIED_CLOSE_TAG = '</code-diff-modified>'
|
|
10
|
+
const MAX_INLINE_DIFF_LENGTH = 10_000
|
|
11
|
+
export const RENDER_BATCH_SIZE = 1_000
|
|
10
12
|
|
|
11
13
|
const startEntity = MODIFIED_START_TAG.replace('<', '<').replace('>', '>')
|
|
12
14
|
const closeEntity = MODIFIED_CLOSE_TAG.replace('<', '<').replace('>', '>')
|
|
13
15
|
|
|
16
|
+
function escapeHtml(code: string): string {
|
|
17
|
+
const entities: Record<string, string> = {
|
|
18
|
+
'&': '&',
|
|
19
|
+
'<': '<',
|
|
20
|
+
'>': '>',
|
|
21
|
+
'"': '"',
|
|
22
|
+
'\'': ''',
|
|
23
|
+
}
|
|
24
|
+
return code.replace(/[&<>"']/g, char => entities[char])
|
|
25
|
+
}
|
|
26
|
+
|
|
14
27
|
function lineType(diff: Diff.Change): DiffType {
|
|
15
28
|
if (diff === undefined)
|
|
16
29
|
return DiffType.EQUAL
|
|
@@ -21,44 +34,117 @@ function lineType(diff: Diff.Change): DiffType {
|
|
|
21
34
|
return DiffType.EQUAL
|
|
22
35
|
}
|
|
23
36
|
|
|
24
|
-
function
|
|
25
|
-
if (typeof prev === 'undefined')
|
|
26
|
-
return current
|
|
27
|
-
if (
|
|
28
|
-
return prev
|
|
37
|
+
function renderChangedLines(prev?: string, current?: string, diffStyle = 'word', force = false): [string | undefined, string | undefined] {
|
|
38
|
+
if (typeof prev === 'undefined' || typeof current === 'undefined')
|
|
39
|
+
return [prev, current]
|
|
40
|
+
if (!force && prev.length + current.length > MAX_INLINE_DIFF_LENGTH)
|
|
41
|
+
return [prev, current]
|
|
29
42
|
|
|
30
43
|
type RenderFunctionType = (prev: string, old: string) => Change[]
|
|
31
44
|
const func: RenderFunctionType = diffStyle === 'char' ? Diff.diffChars : Diff.diffWords
|
|
32
|
-
|
|
45
|
+
const changes = func(prev, current)
|
|
46
|
+
const oldLine = changes
|
|
47
|
+
.filter(word => lineType(word) !== DiffType.ADD)
|
|
48
|
+
.map(word =>
|
|
49
|
+
lineType(word) === DiffType.DELETE ? `${MODIFIED_START_TAG}${word.value}${MODIFIED_CLOSE_TAG}` : word.value,
|
|
50
|
+
)
|
|
51
|
+
.join('')
|
|
52
|
+
const newLine = changes
|
|
33
53
|
.filter(word => lineType(word) !== DiffType.DELETE)
|
|
34
54
|
.map(word =>
|
|
35
55
|
lineType(word) === DiffType.ADD ? `${MODIFIED_START_TAG}${word.value}${MODIFIED_CLOSE_TAG}` : word.value,
|
|
36
56
|
)
|
|
37
57
|
.join('')
|
|
58
|
+
return [oldLine, newLine]
|
|
38
59
|
}
|
|
39
60
|
|
|
40
61
|
function diffLines(prev: string, current: string) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
if (prev === current) {
|
|
63
|
+
return prev
|
|
64
|
+
? [{ count: prev.replace(/\n$/, '').split('\n').length, value: prev }]
|
|
65
|
+
: []
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const prevHasFinalNewline = prev.endsWith('\n')
|
|
69
|
+
const currentHasFinalNewline = current.endsWith('\n')
|
|
70
|
+
if (prevHasFinalNewline !== currentHasFinalNewline) {
|
|
71
|
+
if (prevHasFinalNewline)
|
|
72
|
+
prev = prev.slice(0, -1)
|
|
73
|
+
else
|
|
74
|
+
current = current.slice(0, -1)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let changes: Diff.Change[] | undefined
|
|
78
|
+
if (prev.length + current.length >= 100_000 && prev.includes('\n') && current.includes('\n')) {
|
|
79
|
+
const prevLines = prev ? prev.replace(/\n$/, '').split('\n') : []
|
|
80
|
+
const currentLines = current ? current.replace(/\n$/, '').split('\n') : []
|
|
81
|
+
const prevLineSet = new Set(prevLines)
|
|
82
|
+
const currentLineSet = new Set(currentLines)
|
|
83
|
+
const [smallerSet, largerSet] = prevLineSet.size < currentLineSet.size
|
|
84
|
+
? [prevLineSet, currentLineSet]
|
|
85
|
+
: [currentLineSet, prevLineSet]
|
|
86
|
+
let sharedLines = 0
|
|
87
|
+
for (const line of smallerSet) {
|
|
88
|
+
if (largerSet.has(line))
|
|
89
|
+
sharedLines++
|
|
90
|
+
}
|
|
91
|
+
const overlap = smallerSet.size ? sharedLines / smallerSet.size : 0
|
|
92
|
+
const exceedsDmpLineLimit = prevLineSet.size >= 40_000 || prevLineSet.size + currentLineSet.size - sharedLines >= 65_535
|
|
93
|
+
const changedUniqueLines = prevLineSet.size + currentLineSet.size - sharedLines * 2
|
|
94
|
+
|
|
95
|
+
if (overlap < 0.01 || (exceedsDmpLineLimit && changedUniqueLines > 200)) {
|
|
96
|
+
// ponytail: complex large inputs use whole-file replacements; revisit if detailed move detection becomes necessary.
|
|
97
|
+
changes = []
|
|
98
|
+
if (prev)
|
|
99
|
+
changes.push({ count: prevLines.length, value: prev, removed: true })
|
|
100
|
+
if (current)
|
|
101
|
+
changes.push({ count: currentLines.length, value: current, added: true })
|
|
102
|
+
}
|
|
103
|
+
else if (exceedsDmpLineLimit) {
|
|
104
|
+
changes = Diff.diffLines(prev, current)
|
|
56
105
|
}
|
|
57
|
-
|
|
58
|
-
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!changes) {
|
|
109
|
+
const dmp = new DiffMatchPatch()
|
|
110
|
+
const a = dmp.diff_linesToChars_(prev, current)
|
|
111
|
+
const linePrev = a.chars1
|
|
112
|
+
const lineCurrent = a.chars2
|
|
113
|
+
const lineArray = a.lineArray
|
|
114
|
+
const diffs: any[] = dmp.diff_main(linePrev, lineCurrent, false)
|
|
115
|
+
dmp.diff_charsToLines_(diffs, lineArray)
|
|
116
|
+
changes = diffs.map((x) => {
|
|
117
|
+
const [type, text] = x
|
|
118
|
+
const count = text.replace(/\n$/, '').split('\n').length
|
|
119
|
+
const change: Diff.Change = {
|
|
120
|
+
count,
|
|
121
|
+
value: text,
|
|
122
|
+
removed: type === DIFF_DELETE,
|
|
123
|
+
added: type === DIFF_INSERT,
|
|
124
|
+
}
|
|
125
|
+
return change
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (prevHasFinalNewline !== currentHasFinalNewline) {
|
|
130
|
+
changes.push({
|
|
131
|
+
count: 1,
|
|
132
|
+
value: '',
|
|
133
|
+
removed: prevHasFinalNewline,
|
|
134
|
+
added: currentHasFinalNewline,
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return changes
|
|
59
139
|
}
|
|
60
140
|
|
|
61
141
|
function getHighlightCode(language: string, code: string) {
|
|
142
|
+
if (typeof document === 'undefined' || language === 'plaintext') {
|
|
143
|
+
return escapeHtml(code)
|
|
144
|
+
.replace(new RegExp(startEntity, 'g'), '<span class="x">')
|
|
145
|
+
.replace(new RegExp(closeEntity, 'g'), '</span>')
|
|
146
|
+
}
|
|
147
|
+
|
|
62
148
|
const hasModifiedTags = code.match(new RegExp(`(${MODIFIED_START_TAG}|${MODIFIED_CLOSE_TAG})`, 'g'))
|
|
63
149
|
|
|
64
150
|
if (!hasModifiedTags)
|
|
@@ -135,6 +221,28 @@ function getHighlightCode(language: string, code: string) {
|
|
|
135
221
|
.replace(new RegExp(closeEntity, 'g'), '</span>')
|
|
136
222
|
}
|
|
137
223
|
|
|
224
|
+
export function highlightUnifiedLine(line: UnifiedLineChange, language: string) {
|
|
225
|
+
if (line.highlighted)
|
|
226
|
+
return
|
|
227
|
+
line.code = getHighlightCode(language, line.code)
|
|
228
|
+
line.highlighted = true
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function highlightSplitLine(line: SplitLineChange, language: string) {
|
|
232
|
+
if (line.highlighted)
|
|
233
|
+
return
|
|
234
|
+
const leftCode = line.left.code
|
|
235
|
+
if (leftCode !== undefined)
|
|
236
|
+
line.left.code = getHighlightCode(language, leftCode)
|
|
237
|
+
|
|
238
|
+
if (line.right.code !== undefined) {
|
|
239
|
+
line.right.code = line.left.type === DiffType.EQUAL && line.right.type === DiffType.EQUAL && line.right.code === leftCode
|
|
240
|
+
? line.left.code
|
|
241
|
+
: getHighlightCode(language, line.right.code)
|
|
242
|
+
}
|
|
243
|
+
line.highlighted = true
|
|
244
|
+
}
|
|
245
|
+
|
|
138
246
|
function calcDiffStat(changes: Change[], ignoreRegex?: RegExp): DiffStat {
|
|
139
247
|
const count = (s: string, c: string) => (s.match(new RegExp(c, 'g')) || []).length
|
|
140
248
|
const ignoreCount = (lines: string[]) => lines.filter(line => ignoreRegex?.test(line)).length
|
|
@@ -145,12 +253,20 @@ function calcDiffStat(changes: Change[], ignoreRegex?: RegExp): DiffStat {
|
|
|
145
253
|
let ignoreDeletionsNum = 0
|
|
146
254
|
for (const change of changes) {
|
|
147
255
|
if (change.added) {
|
|
256
|
+
if (!ignoreRegex) {
|
|
257
|
+
additionsNum += change.count ?? 0
|
|
258
|
+
continue
|
|
259
|
+
}
|
|
148
260
|
const ignoreNum = ignoreCount(change.value.trim().split('\n'))
|
|
149
261
|
additionsNum += count(change.value.trim(), '\n') + 1 - ignoreNum
|
|
150
262
|
ignoreAdditionsNum += ignoreNum
|
|
151
263
|
continue
|
|
152
264
|
}
|
|
153
265
|
if (change.removed) {
|
|
266
|
+
if (!ignoreRegex) {
|
|
267
|
+
deletionsNum += change.count ?? 0
|
|
268
|
+
continue
|
|
269
|
+
}
|
|
154
270
|
const ignoreNum = ignoreCount(change.value.trim().split('\n'))
|
|
155
271
|
deletionsNum += count(change.value.trim(), '\n') + 1 - ignoreNum
|
|
156
272
|
ignoreDeletionsNum += ignoreNum
|
|
@@ -207,25 +323,24 @@ export function createSplitDiff(
|
|
|
207
323
|
let left: DiffLine = newEmptySplitDiff()
|
|
208
324
|
let right: DiffLine = newEmptySplitDiff()
|
|
209
325
|
|
|
210
|
-
const highlightCode = getHighlightCode(language, line)
|
|
211
326
|
if (curType === DiffType.EQUAL) {
|
|
212
327
|
delNum++
|
|
213
328
|
addNum++
|
|
214
329
|
|
|
215
|
-
left = newSplitDiff(DiffType.EQUAL, delNum,
|
|
216
|
-
right = newSplitDiff(DiffType.EQUAL, addNum,
|
|
330
|
+
left = newSplitDiff(DiffType.EQUAL, delNum, line)
|
|
331
|
+
right = newSplitDiff(DiffType.EQUAL, addNum, line)
|
|
217
332
|
}
|
|
218
333
|
if (curType === DiffType.DELETE) {
|
|
219
334
|
delNum++
|
|
220
335
|
|
|
221
|
-
left = newSplitDiff(DiffType.DELETE, delNum,
|
|
336
|
+
left = newSplitDiff(DiffType.DELETE, delNum, line)
|
|
222
337
|
right = newEmptySplitDiff()
|
|
223
338
|
}
|
|
224
339
|
if (curType === DiffType.ADD) {
|
|
225
340
|
addNum++
|
|
226
341
|
|
|
227
342
|
left = newEmptySplitDiff()
|
|
228
|
-
right = newSplitDiff(DiffType.ADD, addNum,
|
|
343
|
+
right = newSplitDiff(DiffType.ADD, addNum, line)
|
|
229
344
|
}
|
|
230
345
|
rawChanges.push({ left, right })
|
|
231
346
|
}
|
|
@@ -239,10 +354,9 @@ export function createSplitDiff(
|
|
|
239
354
|
delNum++
|
|
240
355
|
addNum++
|
|
241
356
|
|
|
242
|
-
const highlightCode = getHighlightCode(language, line)
|
|
243
357
|
rawChanges.push({
|
|
244
|
-
left: newSplitDiff(DiffType.EQUAL, delNum,
|
|
245
|
-
right: newSplitDiff(DiffType.EQUAL, addNum,
|
|
358
|
+
left: newSplitDiff(DiffType.EQUAL, delNum, line),
|
|
359
|
+
right: newSplitDiff(DiffType.EQUAL, addNum, line),
|
|
246
360
|
})
|
|
247
361
|
}
|
|
248
362
|
}
|
|
@@ -255,7 +369,7 @@ export function createSplitDiff(
|
|
|
255
369
|
delNum++
|
|
256
370
|
|
|
257
371
|
rawChanges.push({
|
|
258
|
-
left: newSplitDiff(DiffType.DELETE, delNum,
|
|
372
|
+
left: newSplitDiff(DiffType.DELETE, delNum, line),
|
|
259
373
|
right: newEmptySplitDiff(),
|
|
260
374
|
})
|
|
261
375
|
}
|
|
@@ -272,8 +386,9 @@ export function createSplitDiff(
|
|
|
272
386
|
|
|
273
387
|
const [curLine, nextLine] = [curLines[j], nextLines[j]]
|
|
274
388
|
const shouldRenderWords = forceInlineComparison || curLines.length === nextLines.length
|
|
275
|
-
const leftLine = shouldRenderWords
|
|
276
|
-
|
|
389
|
+
const [leftLine, rightLine] = shouldRenderWords
|
|
390
|
+
? renderChangedLines(curLine, nextLine, diffStyle, forceInlineComparison)
|
|
391
|
+
: [curLine, nextLine]
|
|
277
392
|
|
|
278
393
|
// 忽略匹配的行等价于相等
|
|
279
394
|
const leftDiffType = ignoreRegex?.test(curLine) ? DiffType.EQUAL : DiffType.DELETE
|
|
@@ -281,11 +396,11 @@ export function createSplitDiff(
|
|
|
281
396
|
|
|
282
397
|
const left
|
|
283
398
|
= j < cur.count!
|
|
284
|
-
? newSplitDiff(leftDiffType, delNum,
|
|
399
|
+
? newSplitDiff(leftDiffType, delNum, leftLine!)
|
|
285
400
|
: newEmptySplitDiff()
|
|
286
401
|
const right
|
|
287
402
|
= j < next.count!
|
|
288
|
-
? newSplitDiff(rightDiffType, addNum,
|
|
403
|
+
? newSplitDiff(rightDiffType, addNum, rightLine!)
|
|
289
404
|
: newEmptySplitDiff()
|
|
290
405
|
|
|
291
406
|
rawChanges.push({ left, right })
|
|
@@ -298,7 +413,7 @@ export function createSplitDiff(
|
|
|
298
413
|
addNum++
|
|
299
414
|
rawChanges.push({
|
|
300
415
|
left: newEmptySplitDiff(),
|
|
301
|
-
right: newSplitDiff(DiffType.ADD, addNum,
|
|
416
|
+
right: newSplitDiff(DiffType.ADD, addNum, line),
|
|
302
417
|
})
|
|
303
418
|
}
|
|
304
419
|
}
|
|
@@ -307,6 +422,7 @@ export function createSplitDiff(
|
|
|
307
422
|
if (oldString === newString) {
|
|
308
423
|
for (let i = 0; i < rawChanges.length; i++)
|
|
309
424
|
rawChanges[i].fold = false
|
|
425
|
+
rawChanges.slice(0, RENDER_BATCH_SIZE).forEach(line => highlightSplitLine(line, language))
|
|
310
426
|
|
|
311
427
|
return result
|
|
312
428
|
}
|
|
@@ -353,6 +469,7 @@ export function createSplitDiff(
|
|
|
353
469
|
unchanges = []
|
|
354
470
|
}
|
|
355
471
|
result.changes = processedChanges
|
|
472
|
+
result.changes.filter(line => !line.hide).slice(0, RENDER_BATCH_SIZE).forEach(line => highlightSplitLine(line, language))
|
|
356
473
|
|
|
357
474
|
return result
|
|
358
475
|
}
|
|
@@ -404,11 +521,9 @@ export function createUnifiedDiff(
|
|
|
404
521
|
if (curType === DiffType.ADD)
|
|
405
522
|
addNum++
|
|
406
523
|
|
|
407
|
-
const code = getHighlightCode(language, line)
|
|
408
|
-
|
|
409
524
|
rawChanges.push({
|
|
410
525
|
type: curType,
|
|
411
|
-
code,
|
|
526
|
+
code: line,
|
|
412
527
|
addNum: curType === DiffType.DELETE ? undefined : addNum,
|
|
413
528
|
delNum: curType === DiffType.ADD ? undefined : delNum,
|
|
414
529
|
})
|
|
@@ -422,9 +537,7 @@ export function createUnifiedDiff(
|
|
|
422
537
|
for (const line of curLines) {
|
|
423
538
|
delNum++
|
|
424
539
|
addNum++
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
rawChanges.push({ type: DiffType.EQUAL, code, delNum, addNum })
|
|
540
|
+
rawChanges.push({ type: DiffType.EQUAL, code: line, delNum, addNum })
|
|
428
541
|
}
|
|
429
542
|
}
|
|
430
543
|
|
|
@@ -433,28 +546,26 @@ export function createUnifiedDiff(
|
|
|
433
546
|
if (curType === DiffType.DELETE) {
|
|
434
547
|
// 下一处差异为新增,且删除与新增行数相同时,对每行依次 diff
|
|
435
548
|
if (nextType === DiffType.ADD && (curLines.length === nextLines.length || forceInlineComparison)) {
|
|
549
|
+
const maxCount = Math.max(curLines.length, nextLines.length)
|
|
550
|
+
const renderedLines = Array.from({ length: maxCount }, (_, index) => renderChangedLines(curLines[index], nextLines[index], diffStyle, forceInlineComparison))
|
|
436
551
|
for (let j = 0; j < curLines.length; j++) {
|
|
437
552
|
const curLine = curLines[j]
|
|
438
|
-
const nextLine = nextLines[j]
|
|
439
553
|
delNum++
|
|
440
554
|
|
|
441
|
-
const code = getHighlightCode(language, renderWords(nextLine, curLine, diffStyle))
|
|
442
555
|
rawChanges.push({
|
|
443
556
|
type: ignoreRegex?.test(curLine) ? DiffType.EQUAL : DiffType.DELETE,
|
|
444
|
-
code
|
|
557
|
+
code: renderedLines[j][0]!,
|
|
445
558
|
delNum,
|
|
446
559
|
})
|
|
447
560
|
}
|
|
448
561
|
|
|
449
562
|
for (let j = 0; j < nextLines.length; j++) {
|
|
450
|
-
const curLine = curLines[j]
|
|
451
563
|
const nextLine = nextLines[j]
|
|
452
564
|
addNum++
|
|
453
565
|
|
|
454
|
-
const code = getHighlightCode(language, renderWords(curLine, nextLine, diffStyle))
|
|
455
566
|
rawChanges.push({
|
|
456
567
|
type: ignoreRegex?.test(nextLine) ? DiffType.EQUAL : DiffType.ADD,
|
|
457
|
-
code
|
|
568
|
+
code: renderedLines[j][1]!,
|
|
458
569
|
addNum,
|
|
459
570
|
})
|
|
460
571
|
}
|
|
@@ -466,8 +577,7 @@ export function createUnifiedDiff(
|
|
|
466
577
|
for (const line of curLines) {
|
|
467
578
|
delNum++
|
|
468
579
|
|
|
469
|
-
|
|
470
|
-
rawChanges.push({ type: DiffType.DELETE, code, delNum })
|
|
580
|
+
rawChanges.push({ type: DiffType.DELETE, code: line, delNum })
|
|
471
581
|
}
|
|
472
582
|
}
|
|
473
583
|
}
|
|
@@ -475,9 +585,7 @@ export function createUnifiedDiff(
|
|
|
475
585
|
if (curType === DiffType.ADD) {
|
|
476
586
|
for (const line of curLines) {
|
|
477
587
|
addNum++
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
rawChanges.push({ type: DiffType.ADD, code, addNum })
|
|
588
|
+
rawChanges.push({ type: DiffType.ADD, code: line, addNum })
|
|
481
589
|
}
|
|
482
590
|
}
|
|
483
591
|
}
|
|
@@ -496,6 +604,7 @@ export function createUnifiedDiff(
|
|
|
496
604
|
if (oldString === newString) {
|
|
497
605
|
for (let i = 0; i < rawChanges.length; i++)
|
|
498
606
|
rawChanges[i].fold = false
|
|
607
|
+
rawChanges.slice(0, RENDER_BATCH_SIZE).forEach(line => highlightUnifiedLine(line, language))
|
|
499
608
|
|
|
500
609
|
return result
|
|
501
610
|
}
|
|
@@ -534,6 +643,7 @@ export function createUnifiedDiff(
|
|
|
534
643
|
unchanges = []
|
|
535
644
|
}
|
|
536
645
|
result.changes = processedChanges
|
|
646
|
+
result.changes.filter(line => !line.hide).slice(0, RENDER_BATCH_SIZE).forEach(line => highlightUnifiedLine(line, language))
|
|
537
647
|
|
|
538
648
|
return result
|
|
539
649
|
}
|