Skip to content

Commit 4669a54

Browse files
committed
refactor(language-core): extract generateEscaped
1 parent 4e93e73 commit 4669a54

File tree

2 files changed

+37
-40
lines changed

2 files changed

+37
-40
lines changed

packages/language-core/lib/codegen/template/styleScopedClasses.ts

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import type * as ts from 'typescript';
33
import { getNodeText } from '../../parsers/scriptSetupRanges';
44
import type { Code } from '../../types';
55
import { endOfLine, normalizeAttributeValue } from '../utils';
6+
import { generateEscaped } from '../utils/escaped';
67
import type { TemplateCodegenContext } from './context';
78
import type { TemplateCodegenOptions } from './index';
89

10+
const classNameEscapeRegex = /([\\'])/;
11+
912
export function* generateStyleScopedClassReferences(
1013
ctx: TemplateCodegenContext,
1114
withDot = false
@@ -31,7 +34,13 @@ export function* generateStyleScopedClassReferences(
3134
yield `'`;
3235

3336
// fix https://github.com/vuejs/language-tools/issues/4537
34-
yield* escapeString(source, className, offset, ['\\', '\'']);
37+
yield* generateEscaped(
38+
className,
39+
source,
40+
offset,
41+
ctx.codeFeatures.navigationAndAdditionalCompletion,
42+
classNameEscapeRegex
43+
);
3544
yield `'`;
3645
yield [
3746
'',
@@ -41,45 +50,6 @@ export function* generateStyleScopedClassReferences(
4150
];
4251
yield `]} */${endOfLine}`;
4352
}
44-
45-
function* escapeString(source: string, className: string, offset: number, escapeTargets: string[]): Generator<Code> {
46-
let count = 0;
47-
48-
const currentEscapeTargets = [...escapeTargets];
49-
const firstEscapeTarget = currentEscapeTargets.shift()!;
50-
const splitted = className.split(firstEscapeTarget);
51-
52-
for (let i = 0; i < splitted.length; i++) {
53-
const part = splitted[i];
54-
const partLength = part.length;
55-
56-
if (escapeTargets.length > 0) {
57-
yield* escapeString(source, part, offset + count, [...currentEscapeTargets]);
58-
} else {
59-
yield [
60-
part,
61-
source,
62-
offset + count,
63-
ctx.codeFeatures.navigationAndAdditionalCompletion,
64-
];
65-
}
66-
67-
if (i !== splitted.length - 1) {
68-
yield '\\';
69-
70-
yield [
71-
firstEscapeTarget,
72-
source,
73-
offset + count + partLength,
74-
ctx.codeFeatures.navigationAndAdditionalCompletion,
75-
];
76-
77-
count += partLength + 1;
78-
} else {
79-
count += partLength;
80-
}
81-
}
82-
}
8353
}
8454

8555
export function collectStyleScopedClassReferences(
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { Code, VueCodeInformation } from "../../types";
2+
3+
export function* generateEscaped(
4+
text: string,
5+
source: string,
6+
offset: number,
7+
features: VueCodeInformation,
8+
escapeTarget: RegExp
9+
): Generator<Code> {
10+
const parts = text.split(escapeTarget);
11+
let isEscapeTarget = false;
12+
13+
for (let i = 0; i < parts.length; i++) {
14+
const part = parts[i];
15+
if (isEscapeTarget) {
16+
yield `\\`;
17+
}
18+
yield [
19+
part,
20+
source,
21+
offset,
22+
i === 0 ? features : { __combineOffset: i },
23+
];
24+
offset += part.length;
25+
isEscapeTarget = !isEscapeTarget;
26+
}
27+
}

0 commit comments

Comments
 (0)