@@ -8,7 +8,19 @@ import type { SyntaxLineWithTemplate } from "../file";
88import type { DiffLine } from "./diff-line" ;
99import type { SyntaxLine } from "@git-diff-view/lowlight" ;
1010
11- const defaultTransform = ( content : string ) => escapeHtml ( content ) . replace ( / \n / g, "" ) . replace ( / \r / g, "" ) ;
11+ let enableFastDiffTemplate = false ;
12+
13+ export const getEnableFastDiffTemplate = ( ) => enableFastDiffTemplate ;
14+
15+ export const setEnableFastDiffTemplate = ( enable : boolean ) => {
16+ enableFastDiffTemplate = enable ;
17+ } ;
18+
19+ export const resetEnableFastDiffTemplate = ( ) => {
20+ enableFastDiffTemplate = false ;
21+ } ;
22+
23+ export const defaultTransform = ( content : string ) => escapeHtml ( content ) . replace ( / \n / g, "" ) . replace ( / \r / g, "" ) ;
1224
1325export const getPlainDiffTemplate = ( {
1426 diffLine,
@@ -77,7 +89,7 @@ export const getPlainDiffTemplateByFastDiff = ({
7789
7890 let template = `` ;
7991
80- changes . range . forEach ( ( { type, str, location , length } , index , array ) => {
92+ changes . range . forEach ( ( { type, str, startIndex , endIndex } , index , array ) => {
8193 const isLatest = index === array . length - 1 ;
8294 if ( type === 0 ) {
8395 template += `<span>${ transform ( str ) } ` ;
@@ -87,7 +99,7 @@ export const getPlainDiffTemplateByFastDiff = ({
8799 : "" ;
88100 template += `</span>` ;
89101 } else {
90- template += `<span data-range-start="${ location } " data-range-end="${ location + length } ">` ;
102+ template += `<span data-range-start="${ startIndex } " data-range-end="${ endIndex } ">` ;
91103 template += `<span data-diff-highlight style="background-color: var(${ operator === "add" ? addContentHighlightBGName : delContentHighlightBGName } );border-radius: 0.2em;">${ transform ( str ) } ` ;
92104 template +=
93105 isLatest && changes . newLineSymbol
@@ -166,6 +178,125 @@ export const getSyntaxDiffTemplate = ({
166178 diffLine . syntaxTemplateMode = "relative" ;
167179} ;
168180
181+ export const getSyntaxDiffTemplateByFastDiff = ( {
182+ diffLine,
183+ syntaxLine,
184+ operator,
185+ } : {
186+ diffLine : DiffLine ;
187+ syntaxLine : SyntaxLineWithTemplate ;
188+ operator : "add" | "del" ;
189+ } ) => {
190+ if ( ! syntaxLine ) return ;
191+
192+ if ( diffLine . syntaxTemplate && diffLine . syntaxTemplateMode === "fast-diff" ) return ;
193+
194+ const changes = diffLine . diffChanges ;
195+
196+ if ( ! changes || ! changes . hasLineChange ) return ;
197+
198+ const transform = isTransformEnabled ( ) ? processTransformTemplateContent : defaultTransform ;
199+
200+ let template = "" ;
201+
202+ const allRange = changes . range . filter ( ( item ) => item . type !== 0 ) ;
203+
204+ let rangeIndex = 0 ;
205+
206+ syntaxLine ?. nodeList ?. forEach ( ( { node, wrapper } , index , array ) => {
207+ template += `<span data-start="${ node . startIndex } " data-end="${ node . endIndex } " class="${ (
208+ wrapper ?. properties ?. className || [ ]
209+ ) ?. join ( " " ) } " style="${ wrapper ?. properties ?. style || "" } ">`;
210+
211+ let range = allRange [ rangeIndex ] ;
212+
213+ const isLastNode = index === array . length - 1 ;
214+
215+ for ( let i = 0 ; i < node . value . length ; i ++ ) {
216+ const index = node . startIndex + i ;
217+ const value = node . value [ i ] ;
218+ const isLastStr = i === node . value . length - 1 ;
219+ const isEndStr = isLastNode && i === node . value . length - 1 ;
220+ if ( range ) {
221+ // before start
222+ if ( index < range . startIndex ) {
223+ template += transform ( value ) ;
224+ if ( isEndStr && changes . newLineSymbol ) {
225+ template += `<span data-newline-symbol data-diff-highlight style="background-color: var(${ operator === "add" ? addContentHighlightBGName : delContentHighlightBGName } );border-radius: 0.2em;">${ getSymbol ( changes . newLineSymbol ) } </span>` ;
226+ }
227+ // start of range
228+ } else if ( index === range . startIndex ) {
229+ // current range all in the same node
230+ const isInSameNode = range . endIndex <= node . endIndex ;
231+ if ( isInSameNode ) {
232+ template += `<span data-diff-highlight style="background-color: var(${ operator === "add" ? addContentHighlightBGName : delContentHighlightBGName } );border-radius: 0.2em;">` ;
233+ } else {
234+ template += `<span data-diff-highlight style="background-color: var(${ operator === "add" ? addContentHighlightBGName : delContentHighlightBGName } );border-top-left-radius: 0.2em;border-bottom-left-radius: 0.2em;">` ;
235+ }
236+ template += transform ( value ) ;
237+ if ( isEndStr && changes . newLineSymbol ) {
238+ template += `<span data-newline-symbol>${ getSymbol ( changes . newLineSymbol ) } </span>` ;
239+ }
240+ if ( isLastStr ) {
241+ template += `</span>` ;
242+ } else if ( range . startIndex === range . endIndex ) {
243+ template += `</span>` ;
244+ rangeIndex ++ ;
245+ range = allRange [ rangeIndex ] ;
246+ }
247+ // inside range
248+ } else if ( index < range . endIndex ) {
249+ if ( i === 0 ) {
250+ // current range all in the same node
251+ const isInSameNode = range . startIndex >= node . startIndex && range . endIndex <= node . endIndex ;
252+ // current range end is in the same node
253+ const isEndInSameNode = range . endIndex <= node . endIndex ;
254+ template += isInSameNode
255+ ? `<span data-diff-highlight style="background-color: var(${ operator === "add" ? addContentHighlightBGName : delContentHighlightBGName } );border-radius: 0.2em;">`
256+ : isEndInSameNode
257+ ? `<span data-diff-highlight style="background-color: var(${ operator === "add" ? addContentHighlightBGName : delContentHighlightBGName } );border-top-right-radius: 0.2em;border-bottom-right-radius: 0.2em;">`
258+ // current range crosses the node boundary
259+ : `<span data-diff-highlight style="background-color: var(${ operator === "add" ? addContentHighlightBGName : delContentHighlightBGName } );">` ;
260+ }
261+ template += transform ( value ) ;
262+ if ( isEndStr && changes . newLineSymbol ) {
263+ template += `<span data-newline-symbol>${ getSymbol ( changes . newLineSymbol ) } </span>` ;
264+ }
265+ if ( isLastStr ) {
266+ template += `</span>` ;
267+ }
268+ // end of range
269+ } else if ( index === range . endIndex ) {
270+ // current range all in the same node
271+ const isInSameNode = range . startIndex >= node . startIndex ;
272+ if ( isInSameNode ) {
273+ template += transform ( value ) ;
274+ } else {
275+ if ( i === 0 ) {
276+ template += `<span data-diff-highlight style="background-color: var(${ operator === "add" ? addContentHighlightBGName : delContentHighlightBGName } );border-top-right-radius: 0.2em;border-bottom-right-radius: 0.2em;">` ;
277+ }
278+ template += transform ( value ) ;
279+ }
280+ if ( isEndStr && changes . newLineSymbol ) {
281+ template += `<span data-newline-symbol>${ getSymbol ( changes . newLineSymbol ) } </span>` ;
282+ }
283+ template += `</span>` ;
284+ rangeIndex ++ ;
285+ range = allRange [ rangeIndex ] ;
286+ // after range
287+ }
288+ } else {
289+ template += transform ( value ) ;
290+ }
291+ }
292+ template += `</span>` ;
293+ } ) ;
294+
295+ diffLine . syntaxTemplate = template ;
296+
297+ diffLine . syntaxTemplateMode = "fast-diff" ;
298+ } ;
299+
169300export const getSyntaxLineTemplate = ( line : SyntaxLine ) => {
170301 let template = "" ;
171302
0 commit comments