Skip to content

Commit 72d09ac

Browse files
performance
1 parent 1e9b824 commit 72d09ac

File tree

15 files changed

+749
-293
lines changed

15 files changed

+749
-293
lines changed

packages/core/index.d.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ declare class File$1 {
1616
rawFile: Record<number, string>;
1717
hasDoRaw: boolean;
1818
rawLength?: number;
19-
syntaxFile: Record<number, SyntaxLine>;
19+
syntaxFile: Record<number, SyntaxLineWithTemplate>;
2020
hasDoSyntax: boolean;
2121
syntaxLength?: number;
2222
highlighterName?: DiffHighlighter["name"];
@@ -93,8 +93,8 @@ export declare class DiffFile {
9393
onAllCollapse: (mode: "split" | "unified") => void;
9494
getOldFileContent: () => string;
9595
getNewFileContent: () => string;
96-
getOldSyntaxLine: (lineNumber: number) => SyntaxLine;
97-
getNewSyntaxLine: (lineNumber: number) => SyntaxLine;
96+
getOldSyntaxLine: (lineNumber: number) => SyntaxLineWithTemplate;
97+
getNewSyntaxLine: (lineNumber: number) => SyntaxLineWithTemplate;
9898
subscribe: (listener: (() => void) & {
9999
isSyncExternal?: boolean;
100100
}) => () => void;
@@ -108,11 +108,11 @@ export declare class DiffFile {
108108
hasBuildUnified: boolean;
109109
oldFileLines: Record<number, string>;
110110
oldFileDiffLines: Record<string, DiffLineItem>;
111-
oldFileSyntaxLines: Record<number, SyntaxLine>;
111+
oldFileSyntaxLines: Record<number, SyntaxLineWithTemplate>;
112112
oldFilePlaceholderLines: Record<string, boolean>;
113113
newFileLines: Record<number, string>;
114114
newFileDiffLines: Record<string, DiffLineItem>;
115-
newFileSyntaxLines: Record<number, SyntaxLine>;
115+
newFileSyntaxLines: Record<number, SyntaxLineWithTemplate>;
116116
newFilePlaceholderLines: Record<string, boolean>;
117117
splitLineLength: number;
118118
unifiedLineLength: number;
@@ -157,11 +157,11 @@ export declare class DiffFile {
157157
hasBuildUnified: boolean;
158158
oldFileLines: Record<number, string>;
159159
oldFileDiffLines: Record<string, DiffLineItem>;
160-
oldFileSyntaxLines: Record<number, SyntaxLine>;
160+
oldFileSyntaxLines: Record<number, SyntaxLineWithTemplate>;
161161
oldFilePlaceholderLines: Record<string, boolean>;
162162
newFileLines: Record<number, string>;
163163
newFileDiffLines: Record<string, DiffLineItem>;
164-
newFileSyntaxLines: Record<number, SyntaxLine>;
164+
newFileSyntaxLines: Record<number, SyntaxLineWithTemplate>;
165165
newFilePlaceholderLines: Record<string, boolean>;
166166
splitLineLength: number;
167167
unifiedLineLength: number;
@@ -232,7 +232,9 @@ export declare class DiffLine {
232232
readonly noTrailingNewLine: boolean;
233233
changes?: IRange;
234234
diffChanges?: DiffRange;
235-
constructor(text: string, type: DiffLineType, originalLineNumber: number | null, oldLineNumber: number | null, newLineNumber: number | null, noTrailingNewLine?: boolean, changes?: IRange, diffChanges?: DiffRange);
235+
plainTemplate?: string;
236+
syntaxTemplate?: string;
237+
constructor(text: string, type: DiffLineType, originalLineNumber: number | null, oldLineNumber: number | null, newLineNumber: number | null, noTrailingNewLine?: boolean, changes?: IRange, diffChanges?: DiffRange, plainTemplate?: string, syntaxTemplate?: string);
236238
withNoTrailingNewLine(noTrailingNewLine: boolean): DiffLine;
237239
isIncludeableLine(): boolean;
238240
equals(other: DiffLine): boolean;
@@ -382,13 +384,25 @@ export declare const checkCurrentLineIsHidden: (diffFile: DiffFile, lineNumber:
382384
};
383385
export declare const checkDiffLineIncludeChange: (diffLine?: DiffLine) => boolean;
384386
export declare const disableCache: () => void;
385-
export declare const getDiffRange: (additions: DiffLine[], deletions: DiffLine[], { getAdditionRaw, getDeletionRaw, }: {
387+
export declare const getDiffRange: (additions: DiffLine[], deletions: DiffLine[], { getAdditionRaw, getDeletionRaw, getAdditionSyntax, getDeletionSyntax, }: {
386388
getAdditionRaw: (lineNumber: number) => string;
387389
getDeletionRaw: (lineNumber: number) => string;
390+
getAdditionSyntax: (lineNumber: number) => SyntaxLineWithTemplate;
391+
getDeletionSyntax: (lineNumber: number) => SyntaxLineWithTemplate;
388392
}) => void;
389393
export declare const getLang: (fileName: string) => string;
394+
export declare const getPlainTemplate: ({ diffLine, rawLine, operator, }: {
395+
diffLine: DiffLine;
396+
rawLine: string;
397+
operator: "add" | "del";
398+
}) => void;
390399
export declare const getSplitContentLines: (diffFile: DiffFile) => DiffSplitContentLineItem[];
391400
export declare const getSplitLines: (diffFile: DiffFile) => DiffSplitLineItem[];
401+
export declare const getSyntaxTemplate: ({ diffLine, syntaxLine, operator, }: {
402+
diffLine: DiffLine;
403+
syntaxLine: SyntaxLineWithTemplate;
404+
operator: "add" | "del";
405+
}) => void;
392406
export declare const getUnifiedContentLine: (diffFile: DiffFile) => DiffUnifiedContentLineItem[];
393407
export declare const getUnifiedLines: (diffFile: DiffFile) => DiffUnifiedLineItem[];
394408
export declare const highlighter: DiffHighlighter;
@@ -453,6 +467,7 @@ export declare function diffChanges(addition: DiffLine, deletion: DiffLine): {
453467
addRange: DiffRange;
454468
delRange: DiffRange;
455469
};
470+
export declare function escapeHtml(string: unknown): string;
456471
export declare function getFile(raw: string, lang: DiffHighlighterLang, theme: "light" | "dark", fileName?: string, uuid?: string): File$1;
457472
export declare function getFile(raw: string, lang: string, theme: "light" | "dark", fileName?: string, uuid?: string): File$1;
458473
/**
@@ -649,6 +664,9 @@ export type SyntaxLine = {
649664
wrapper?: SyntaxNode;
650665
}[];
651666
};
667+
export type SyntaxLineWithTemplate = SyntaxLine & {
668+
template?: string;
669+
};
652670
// Generated by dts-bundle-generator v9.5.1
653671
export type SyntaxNode = {
654672
type: string;

packages/core/src/diff-file.ts

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,14 @@ export class DiffFile {
451451
return this.#getOldRawLine(lineNumber);
452452
};
453453

454+
const getAdditionSyntax = (lineNumber: number) => {
455+
return this.#getNewSyntaxLine(lineNumber);
456+
};
457+
458+
const getDeletionSyntax = (lineNumber: number) => {
459+
return this.#getOldSyntaxLine(lineNumber);
460+
};
461+
454462
this.#diffLines = [];
455463

456464
this.additionLength = 0;
@@ -472,13 +480,18 @@ export class DiffFile {
472480
deletions.push(line);
473481
this.deletionLength++;
474482
} else {
475-
getDiffRange(additions, deletions, { getAdditionRaw, getDeletionRaw });
483+
getDiffRange(additions, deletions, {
484+
getAdditionRaw,
485+
getDeletionRaw,
486+
getAdditionSyntax,
487+
getDeletionSyntax,
488+
});
476489
additions = [];
477490
deletions = [];
478491
}
479492
tmp.push(line);
480493
});
481-
getDiffRange(additions, deletions, { getAdditionRaw, getDeletionRaw });
494+
getDiffRange(additions, deletions, { getAdditionRaw, getDeletionRaw, getAdditionSyntax, getDeletionSyntax });
482495
});
483496
});
484497

@@ -585,6 +598,28 @@ export class DiffFile {
585598
this.#newFileSyntaxLines = this.#newFileResult?.syntaxFile;
586599
}
587600

601+
#doSyntax({ registerHighlighter }: { registerHighlighter?: Omit<DiffHighlighter, "getHighlighterEngine"> } = {}) {
602+
if (this.#highlighterType === "class") return;
603+
604+
if (this.#composeByMerge && !this.#composeByFullMerge) {
605+
if (__DEV__) {
606+
console.error(
607+
`this instance can not do syntax because of the data missing, try to use '_getFullBundle' & '_mergeFullBundle' instead of 'getBundle' & 'mergeBundle'`
608+
);
609+
}
610+
611+
return;
612+
}
613+
614+
this.#composeSyntax({ registerHighlighter });
615+
616+
this.#highlighterName =
617+
this.#oldFileResult?.highlighterName || this.#newFileResult?.highlighterName || this.#highlighterName;
618+
619+
this.#highlighterType =
620+
this.#oldFileResult?.highlighterType || this.#newFileResult?.highlighterType || this.#highlighterType;
621+
}
622+
588623
#getOldDiffLine(lineNumber: number | null) {
589624
if (!lineNumber) return;
590625
return this.#oldFileDiffLines?.[lineNumber];
@@ -603,6 +638,14 @@ export class DiffFile {
603638
return this.#newFileLines?.[lineNumber];
604639
}
605640

641+
#getOldSyntaxLine(lineNumber: number) {
642+
return this.#oldFileSyntaxLines?.[lineNumber];
643+
}
644+
645+
#getNewSyntaxLine(lineNumber: number) {
646+
return this.#newFileSyntaxLines?.[lineNumber];
647+
}
648+
606649
initId() {
607650
let id = "--" + Math.random().toString().slice(2);
608651

@@ -641,25 +684,12 @@ export class DiffFile {
641684
initSyntax({ registerHighlighter }: { registerHighlighter?: Omit<DiffHighlighter, "getHighlighterEngine"> } = {}) {
642685
if (this.#hasInitSyntax && (!this.#_theme || this.#theme === this.#_theme)) return;
643686

644-
if (this.#highlighterType === "class") return;
687+
this.#doSyntax({ registerHighlighter });
645688

646-
if (this.#composeByMerge && !this.#composeByFullMerge) {
647-
if (__DEV__) {
648-
console.error(
649-
`this instance can not do syntax because of the data missing, try to use '_getFullBundle' & '_mergeFullBundle' instead of 'getBundle' & 'mergeBundle'`
650-
);
651-
}
689+
// reset diff
690+
this.#diffListResults = [];
652691

653-
return;
654-
}
655-
656-
this.#composeSyntax({ registerHighlighter });
657-
658-
this.#highlighterName =
659-
this.#oldFileResult?.highlighterName || this.#newFileResult?.highlighterName || this.#highlighterName;
660-
661-
this.#highlighterType =
662-
this.#oldFileResult?.highlighterType || this.#newFileResult?.highlighterType || this.#highlighterType;
692+
this.#composeDiff();
663693

664694
this.#hasInitSyntax = true;
665695
}
@@ -1584,3 +1614,11 @@ export class DiffFile {
15841614
this.#theme = undefined;
15851615
};
15861616
}
1617+
1618+
if (__DEV__) {
1619+
Object.defineProperty(DiffFile.prototype, "__full_bundle__", {
1620+
get: function (this: DiffFile) {
1621+
return this._getFullBundle();
1622+
},
1623+
});
1624+
}

packages/core/src/escape-html.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// copy from https://github.com/vuejs/core/blob/main/packages/shared/src/escapeHtml.ts
2+
3+
const escapeRE = /["'&<>]/;
4+
5+
export function escapeHtml(string: unknown): string {
6+
const str = "" + string;
7+
const match = escapeRE.exec(str);
8+
9+
if (!match) {
10+
return str;
11+
}
12+
13+
let html = "";
14+
let escaped: string;
15+
let index: number;
16+
let lastIndex = 0;
17+
for (index = match.index; index < str.length; index++) {
18+
switch (str.charCodeAt(index)) {
19+
case 34: // "
20+
escaped = "&quot;";
21+
break;
22+
case 38: // &
23+
escaped = "&amp;";
24+
break;
25+
case 39: // '
26+
escaped = "&#39;";
27+
break;
28+
case 60: // <
29+
escaped = "&lt;";
30+
break;
31+
case 62: // >
32+
escaped = "&gt;";
33+
break;
34+
default:
35+
continue;
36+
}
37+
38+
if (lastIndex !== index) {
39+
html += str.slice(lastIndex, index);
40+
}
41+
42+
lastIndex = index + 1;
43+
html += escaped;
44+
}
45+
46+
return lastIndex !== index ? html + str.slice(lastIndex, index) : html;
47+
}

packages/core/src/file.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { highlighter } from "@git-diff-view/lowlight";
22

33
import { Cache } from "./cache";
4+
import { escapeHtml } from "./escape-html";
5+
46

57
import type { DiffAST, DiffHighlighter, DiffHighlighterLang, SyntaxLine } from "@git-diff-view/lowlight";
68

@@ -26,6 +28,22 @@ if (__DEV__ && typeof globalThis !== "undefined") {
2628
}
2729
}
2830

31+
export type SyntaxLineWithTemplate = SyntaxLine & {
32+
template?: string;
33+
};
34+
35+
const getSyntaxLineTemplate = (line: SyntaxLine) => {
36+
let template = "";
37+
38+
line?.nodeList?.forEach(({ node, wrapper }) => {
39+
template += `<span data-start="${node.startIndex}" data-end="${node.endIndex}" class="${(
40+
wrapper?.properties?.className || []
41+
)?.join(" ")}" style="${wrapper?.properties?.style || ""}">${escapeHtml(node.value)}</span>`;
42+
});
43+
44+
return template;
45+
};
46+
2947
export class File {
3048
ast?: DiffAST;
3149

@@ -35,7 +53,7 @@ export class File {
3553

3654
rawLength?: number;
3755

38-
syntaxFile: Record<number, SyntaxLine> = {};
56+
syntaxFile: Record<number, SyntaxLineWithTemplate> = {};
3957

4058
hasDoSyntax: boolean = false;
4159

@@ -126,6 +144,11 @@ export class File {
126144

127145
const { syntaxFileObject, syntaxFileLineNumber } = supportEngin.processAST(this.ast);
128146

147+
// get syntax template
148+
Object.values(syntaxFileObject).forEach((line: SyntaxLineWithTemplate) => {
149+
line.template = getSyntaxLineTemplate(line);
150+
});
151+
129152
this.syntaxFile = syntaxFileObject;
130153

131154
this.syntaxLength = syntaxFileLineNumber;

packages/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from "./parse";
22
export * from "./file";
33
export * from "./diff-file";
4+
export * from "./escape-html";
45
export * from "./diff-file-utils";
56

67
export * from "@git-diff-view/lowlight";

packages/core/src/parse/diff-line.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ export class DiffLine {
2020
public readonly newLineNumber: number | null,
2121
public readonly noTrailingNewLine: boolean = false,
2222
public changes?: IRange,
23-
public diffChanges?: DiffRange
23+
public diffChanges?: DiffRange,
24+
public plainTemplate?: string,
25+
public syntaxTemplate?: string
2426
) {}
2527

2628
public withNoTrailingNewLine(noTrailingNewLine: boolean): DiffLine {

0 commit comments

Comments
 (0)