Skip to content

Commit 09fe259

Browse files
authored
Fixed wrong nesting selector parse. (#14)
1 parent 884d017 commit 09fe259

File tree

12 files changed

+2328
-28
lines changed

12 files changed

+2328
-28
lines changed

lib/styles/selectors/resolver/css-selector-resolver.ts

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
isTypeSelector,
55
findNestingSelectors,
66
hasNodesSelector,
7+
isSelectorCombinator,
78
} from "../../utils/selectors"
89
import {
910
VCSSStyleSheet,
@@ -202,44 +203,50 @@ export class CSSSelectorResolver {
202203
parentSelectors: ResolvedSelector[],
203204
container: VCSSNode,
204205
) {
205-
const nesting = findNestingSelectors(selectorNodes).next().value
206-
if (!nesting) {
206+
const nestingNext = findNestingSelectors(selectorNodes).next()
207+
if (nestingNext.done) {
207208
// Must be nest-containing, which means it contains a nesting selector in it somewhere.
208209
return [new ResolvedSelector(selectorNodes, container)]
209210
}
210211
const {
211212
nestingIndex,
212213
nodes: hasNestingNodes,
213214
node: nestingNode,
214-
} = nesting
215+
} = nestingNext.value
215216

216-
const nestingLeftNode = hasNestingNodes[nestingIndex - 1]
217-
const nestingRightNode = hasNestingNodes[(nestingIndex as number) + 1]
217+
const beforeSelector = hasNestingNodes.slice(0, nestingIndex)
218+
const afterSelector = hasNestingNodes.slice(nestingIndex + 1)
219+
const nestingLeftNode =
220+
beforeSelector.length > 0
221+
? beforeSelector[beforeSelector.length - 1]
222+
: null
223+
const nestingRightNode =
224+
afterSelector.length > 0 ? afterSelector[0] : null
218225
const maybeJoinLeft =
219-
nestingLeftNode && nestingLeftNode.range[1] === nestingNode.range[0]
220-
const needJoinRight =
226+
nestingLeftNode &&
227+
nestingLeftNode.range[1] === nestingNode.range[0] &&
228+
!isSelectorCombinator(nestingLeftNode)
229+
const maybeJoinRight =
221230
nestingRightNode &&
222231
nestingNode.range[1] === nestingRightNode.range[0] &&
223232
isTypeSelector(nestingRightNode)
224233

225-
const beforeSelector = hasNestingNodes.slice(0, nestingIndex)
226-
const afterSelector = hasNestingNodes.slice(
227-
(nestingIndex as number) + 1,
228-
)
229-
230234
let resolved = parentSelectors.map(p => {
231235
const before = [...beforeSelector]
232236
const after = [...afterSelector]
233237
const parentSelector = [...p.selector]
234238
const needJoinLeft =
235239
maybeJoinLeft && isTypeSelector(parentSelector[0])
240+
const needJoinRight =
241+
maybeJoinRight &&
242+
!isSelectorCombinator(parentSelector[parentSelector.length - 1])
236243
if (needJoinLeft && needJoinRight && parentSelector.length === 1) {
237-
// concat both (e.g. `bar { @nest foo-&-baz {} }` -> .foo-bar-baz)
244+
// concat both (e.g. `bar { @nest .foo-&-baz {} }` -> .foo-bar-baz)
238245
before.push(
239246
newNestingConcatBothSelectorNodes(
240-
before.pop() as VCSSTypeSelector,
241-
parentSelector.shift() as VCSSSelectorNode,
242-
after.shift() as VCSSSelectorNode,
247+
before.pop() as VCSSSelectorValueNode,
248+
parentSelector.shift() as VCSSTypeSelector,
249+
after.shift() as VCSSTypeSelector,
243250
nestingNode,
244251
),
245252
)
@@ -248,8 +255,8 @@ export class CSSSelectorResolver {
248255
// concat left (e.g. `bar { @nest .foo-& {} }` -> .foo-bar)
249256
before.push(
250257
newNestingConcatLeftSelectorNodes(
251-
before.pop() as VCSSTypeSelector,
252-
parentSelector.shift() as VCSSSelectorNode,
258+
before.pop() as VCSSSelectorValueNode,
259+
parentSelector.shift() as VCSSTypeSelector,
253260
nestingNode,
254261
),
255262
)
@@ -259,7 +266,7 @@ export class CSSSelectorResolver {
259266
after.unshift(
260267
newNestingConcatRightSelectorNodes(
261268
parentSelector.pop() as VCSSSelectorValueNode,
262-
after.shift() as VCSSSelectorValueNode,
269+
after.shift() as VCSSTypeSelector,
263270
nestingNode,
264271
),
265272
)
@@ -302,9 +309,9 @@ export class CSSSelectorResolver {
302309
* Creates a selector node that concats the left and right selectors of the parent selector and the nested selector.
303310
*/
304311
function newNestingConcatBothSelectorNodes(
305-
left: VCSSTypeSelector,
306-
parent: VCSSSelectorNode,
307-
right: VCSSSelectorNode,
312+
left: VCSSSelectorValueNode,
313+
parent: VCSSTypeSelector,
314+
right: VCSSTypeSelector,
308315
_nesting: any,
309316
) {
310317
const loc = {
@@ -326,8 +333,8 @@ function newNestingConcatBothSelectorNodes(
326333
* Creates a selector node that concats the left selectors of the parent selector and the nested selector.
327334
*/
328335
function newNestingConcatLeftSelectorNodes(
329-
left: VCSSTypeSelector,
330-
parent: VCSSSelectorNode,
336+
left: VCSSSelectorValueNode,
337+
parent: VCSSTypeSelector,
331338
nesting: VCSSNestingSelector,
332339
) {
333340
const loc = {
@@ -349,7 +356,7 @@ function newNestingConcatLeftSelectorNodes(
349356
*/
350357
function newNestingConcatRightSelectorNodes(
351358
parent: VCSSSelectorValueNode,
352-
right: VCSSSelectorValueNode,
359+
right: VCSSTypeSelector,
353360
nesting: VCSSNestingSelector,
354361
) {
355362
const loc = {

lib/styles/utils/selectors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ export function isNestingAtRule(
180180
return isVCSSAtRule(node) && node.name === "nest"
181181
}
182182

183-
type NestingInfo = {
183+
export type NestingInfo = {
184184
node: VCSSNestingSelector
185185
nodes: VCSSSelectorNode[]
186186
nestingIndex: number

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "eslint-plugin-vue-scoped-css",
3-
"version": "0.2.0",
3+
"version": "0.2.1",
44
"description": "ESLint plugin for Scoped CSS in Vue.js",
55
"main": "dist/index.js",
66
"scripts": {

0 commit comments

Comments
 (0)