Skip to content

Commit 812592c

Browse files
authored
fix(language-plugin-pug): compute offset correctly of pug class (#4652)
1 parent 6722371 commit 812592c

File tree

2 files changed

+52
-20
lines changed

2 files changed

+52
-20
lines changed

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

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -614,22 +614,40 @@ function* generateReferencesForScopedCssClasses(
614614
&& prop.name === 'class'
615615
&& prop.value
616616
) {
617-
let startOffset = prop.value.loc.start.offset;
618-
let content = prop.value.loc.source;
619-
let isWrapped = false;
620-
if (
621-
(content.startsWith(`'`) && content.endsWith(`'`))
622-
|| (content.startsWith(`"`) && content.endsWith(`"`))
623-
) {
624-
content = content.slice(1, -1);
625-
isWrapped = true;
626-
}
627-
if (content) {
628-
const classes = collectClasses(content, startOffset + (isWrapped ? 1 : 0));
629-
ctx.scopedClasses.push(...classes);
617+
if (options.template.lang === 'pug') {
618+
const getClassOffset = Reflect.get(prop.value.loc.start, 'getClassOffset') as (offset: number) => number;
619+
const content = prop.value.loc.source.slice(1, -1);
620+
621+
let startOffset = 1;
622+
for (const className of content.split(' ')) {
623+
if (className) {
624+
ctx.scopedClasses.push({
625+
source: 'template',
626+
className,
627+
offset: getClassOffset(startOffset),
628+
});
629+
}
630+
startOffset += className.length + 1;
631+
}
630632
}
631633
else {
632-
ctx.emptyClassOffsets.push(startOffset);
634+
let startOffset = prop.value.loc.start.offset;
635+
let content = prop.value.loc.source;
636+
let isWrapped = false;
637+
if (
638+
(content.startsWith(`'`) && content.endsWith(`'`))
639+
|| (content.startsWith(`"`) && content.endsWith(`"`))
640+
) {
641+
content = content.slice(1, -1);
642+
isWrapped = true;
643+
}
644+
if (content) {
645+
const classes = collectClasses(content, startOffset + (isWrapped ? 1 : 0));
646+
ctx.scopedClasses.push(...classes);
647+
}
648+
else {
649+
ctx.emptyClassOffsets.push(startOffset);
650+
}
633651
}
634652
}
635653
else if (

packages/language-plugin-pug/index.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,18 @@ const plugin: VueLanguagePlugin = ({ modules }) => {
3737
const proxys = new WeakMap();
3838
return new Proxy(target, {
3939
get(target, prop, receiver) {
40+
if (prop === 'getClassOffset') {
41+
// div.foo#baz.bar
42+
// ^^^ ^^^
43+
// class=" foo bar"
44+
// ^^^ ^^^
45+
// NOTE: we need to expose source offset getter
46+
return function(startOffset: number) {
47+
return getOffset(target.offset + startOffset);
48+
};
49+
}
4050
if (prop === 'offset') {
41-
const htmlOffset = target.offset;
42-
const nums: number[] = [];
43-
for (const mapped of map.toSourceLocation(htmlOffset)) {
44-
nums.push(mapped[0]);
45-
}
46-
return Math.max(-1, ...nums);
51+
return getOffset(target.offset);
4752
}
4853
const value = Reflect.get(target, prop, receiver);
4954
if (typeof value === 'object' && value !== null) {
@@ -59,6 +64,15 @@ const plugin: VueLanguagePlugin = ({ modules }) => {
5964
}
6065
});
6166
}
67+
68+
function getOffset(offset: number) {
69+
const htmlOffset = offset;
70+
const nums: number[] = [];
71+
for (const mapped of map.toSourceLocation(htmlOffset)) {
72+
nums.push(mapped[0]);
73+
}
74+
return Math.max(-1, ...nums);
75+
}
6276
}
6377
}
6478
},

0 commit comments

Comments
 (0)