Skip to content

Commit 27da54d

Browse files
committed
fix selector location
1 parent cc7dfe8 commit 27da54d

File tree

2 files changed

+59
-13
lines changed

2 files changed

+59
-13
lines changed

.changeset/selfish-squids-sneeze.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-vue-scoped-css": patch
3+
---
4+
5+
fix: vcssselector location

lib/styles/parser/selector/css-selector-parser.ts

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,9 @@ export class CSSSelectorParser {
271271
end: number,
272272
parent: VCSSNode,
273273
): VCSSSelectorNode | null {
274-
let source = this.sourceCode.text.slice(start, end);
274+
const sourceCode = this.sourceCode;
275+
const code = sourceCode.text;
276+
let source = code.slice(start, end);
275277
const beforeSpaces = /^\s+/u.exec(source);
276278
if (beforeSpaces?.[0]) {
277279
// adjust before spaces
@@ -292,24 +294,63 @@ export class CSSSelectorParser {
292294
loc.end = this.sourceCode.getLocFromIndex(end);
293295
source = source.slice(0, -afterSpaces[0].length);
294296
}
295-
const beforeTrivials = /^\(\s*/u.exec(source);
296-
const afterTrivials = /\s*\)$/u.exec(source);
297-
if (beforeTrivials?.[0] && afterTrivials?.[0]) {
298-
// adjust before trivial tokens
299-
// `:not(.bar)`
300-
// ^ ^
301297

298+
adjustBeforeParenLocation();
299+
adjustAfterParenLocation();
300+
301+
return new VCSSSelector(node, loc, start, end, {
302+
parent: parent as VCSSStyleRule | VCSSAtRule,
303+
});
304+
305+
/**
306+
* Adjust before paren token
307+
* `:not(.bar)`
308+
* ^
309+
*/
310+
function adjustBeforeParenLocation() {
311+
const beforeTrivials = /^\(\s*/u.exec(source);
312+
if (!beforeTrivials?.[0]) return;
313+
let withinParen = false;
314+
for (let index = end - 1; index < code.length; index++) {
315+
const ch = code[index];
316+
if (ch === ")") {
317+
withinParen = true;
318+
break;
319+
} else if (ch?.trim() && index !== end - 1) {
320+
return;
321+
}
322+
}
323+
if (!withinParen) return;
302324
// eslint-disable-next-line no-param-reassign -- ignore
303325
start = start + beforeTrivials[0].length;
304-
loc.start = this.sourceCode.getLocFromIndex(start);
326+
loc.start = sourceCode.getLocFromIndex(start);
327+
source = source.slice(beforeTrivials[0].length);
328+
}
329+
330+
/**
331+
* Adjust after paren token
332+
* `:not(.bar)`
333+
* ^
334+
*/
335+
function adjustAfterParenLocation() {
336+
const afterTrivials = /\s*\)$/u.exec(source);
337+
if (!afterTrivials?.[0]) return;
338+
let withinParen = false;
339+
for (let index = start; index >= 0; index--) {
340+
const ch = code[index];
341+
if (ch === "(") {
342+
withinParen = true;
343+
break;
344+
} else if (ch?.trim() && index !== start) {
345+
return;
346+
}
347+
}
348+
if (!withinParen) return;
305349
// eslint-disable-next-line no-param-reassign -- ignore
306350
end = end - afterTrivials[0].length;
307-
loc.end = this.sourceCode.getLocFromIndex(end);
308-
source = source.slice(beforeTrivials[0].length, -afterTrivials[0].length);
351+
loc.end = sourceCode.getLocFromIndex(end);
352+
source = source.slice(0, -afterTrivials[0].length);
309353
}
310-
return new VCSSSelector(node, loc, start, end, {
311-
parent: parent as VCSSStyleRule | VCSSAtRule,
312-
});
313354
}
314355

315356
/**

0 commit comments

Comments
 (0)