From 2238fde45652422fe9e03765e67ef3c4ecc4d1d9 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Tue, 19 Nov 2019 00:46:04 +0900 Subject: [PATCH] Fixed wrong nesting selector parse. --- .../resolver/css-selector-resolver.ts | 57 +- lib/styles/utils/selectors.ts | 2 +- package-lock.json | 2 +- package.json | 2 +- .../fixtures/index/@nest-concat04/ast.json | 480 +++++++++ .../index/@nest-concat04/selectors-text.json | 20 + .../index/@nest-concat04/selectors.json | 220 ++++ .../fixtures/index/@nest-concat04/source.vue | 13 + .../index/scss-nest-concat01/ast.json | 952 ++++++++++++++++++ .../scss-nest-concat01/selectors-text.json | 43 + .../index/scss-nest-concat01/selectors.json | 543 ++++++++++ .../index/scss-nest-concat01/source.vue | 22 + 12 files changed, 2328 insertions(+), 28 deletions(-) create mode 100644 tests/lib/styles/fixtures/index/@nest-concat04/ast.json create mode 100644 tests/lib/styles/fixtures/index/@nest-concat04/selectors-text.json create mode 100644 tests/lib/styles/fixtures/index/@nest-concat04/selectors.json create mode 100644 tests/lib/styles/fixtures/index/@nest-concat04/source.vue create mode 100644 tests/lib/styles/fixtures/index/scss-nest-concat01/ast.json create mode 100644 tests/lib/styles/fixtures/index/scss-nest-concat01/selectors-text.json create mode 100644 tests/lib/styles/fixtures/index/scss-nest-concat01/selectors.json create mode 100644 tests/lib/styles/fixtures/index/scss-nest-concat01/source.vue diff --git a/lib/styles/selectors/resolver/css-selector-resolver.ts b/lib/styles/selectors/resolver/css-selector-resolver.ts index 5161b7bc..83aa5846 100644 --- a/lib/styles/selectors/resolver/css-selector-resolver.ts +++ b/lib/styles/selectors/resolver/css-selector-resolver.ts @@ -4,6 +4,7 @@ import { isTypeSelector, findNestingSelectors, hasNodesSelector, + isSelectorCombinator, } from "../../utils/selectors" import { VCSSStyleSheet, @@ -202,8 +203,8 @@ export class CSSSelectorResolver { parentSelectors: ResolvedSelector[], container: VCSSNode, ) { - const nesting = findNestingSelectors(selectorNodes).next().value - if (!nesting) { + const nestingNext = findNestingSelectors(selectorNodes).next() + if (nestingNext.done) { // Must be nest-containing, which means it contains a nesting selector in it somewhere. return [new ResolvedSelector(selectorNodes, container)] } @@ -211,35 +212,41 @@ export class CSSSelectorResolver { nestingIndex, nodes: hasNestingNodes, node: nestingNode, - } = nesting + } = nestingNext.value - const nestingLeftNode = hasNestingNodes[nestingIndex - 1] - const nestingRightNode = hasNestingNodes[(nestingIndex as number) + 1] + const beforeSelector = hasNestingNodes.slice(0, nestingIndex) + const afterSelector = hasNestingNodes.slice(nestingIndex + 1) + const nestingLeftNode = + beforeSelector.length > 0 + ? beforeSelector[beforeSelector.length - 1] + : null + const nestingRightNode = + afterSelector.length > 0 ? afterSelector[0] : null const maybeJoinLeft = - nestingLeftNode && nestingLeftNode.range[1] === nestingNode.range[0] - const needJoinRight = + nestingLeftNode && + nestingLeftNode.range[1] === nestingNode.range[0] && + !isSelectorCombinator(nestingLeftNode) + const maybeJoinRight = nestingRightNode && nestingNode.range[1] === nestingRightNode.range[0] && isTypeSelector(nestingRightNode) - const beforeSelector = hasNestingNodes.slice(0, nestingIndex) - const afterSelector = hasNestingNodes.slice( - (nestingIndex as number) + 1, - ) - let resolved = parentSelectors.map(p => { const before = [...beforeSelector] const after = [...afterSelector] const parentSelector = [...p.selector] const needJoinLeft = maybeJoinLeft && isTypeSelector(parentSelector[0]) + const needJoinRight = + maybeJoinRight && + !isSelectorCombinator(parentSelector[parentSelector.length - 1]) if (needJoinLeft && needJoinRight && parentSelector.length === 1) { - // concat both (e.g. `bar { @nest foo-&-baz {} }` -> .foo-bar-baz) + // concat both (e.g. `bar { @nest .foo-&-baz {} }` -> .foo-bar-baz) before.push( newNestingConcatBothSelectorNodes( - before.pop() as VCSSTypeSelector, - parentSelector.shift() as VCSSSelectorNode, - after.shift() as VCSSSelectorNode, + before.pop() as VCSSSelectorValueNode, + parentSelector.shift() as VCSSTypeSelector, + after.shift() as VCSSTypeSelector, nestingNode, ), ) @@ -248,8 +255,8 @@ export class CSSSelectorResolver { // concat left (e.g. `bar { @nest .foo-& {} }` -> .foo-bar) before.push( newNestingConcatLeftSelectorNodes( - before.pop() as VCSSTypeSelector, - parentSelector.shift() as VCSSSelectorNode, + before.pop() as VCSSSelectorValueNode, + parentSelector.shift() as VCSSTypeSelector, nestingNode, ), ) @@ -259,7 +266,7 @@ export class CSSSelectorResolver { after.unshift( newNestingConcatRightSelectorNodes( parentSelector.pop() as VCSSSelectorValueNode, - after.shift() as VCSSSelectorValueNode, + after.shift() as VCSSTypeSelector, nestingNode, ), ) @@ -302,9 +309,9 @@ export class CSSSelectorResolver { * Creates a selector node that concats the left and right selectors of the parent selector and the nested selector. */ function newNestingConcatBothSelectorNodes( - left: VCSSTypeSelector, - parent: VCSSSelectorNode, - right: VCSSSelectorNode, + left: VCSSSelectorValueNode, + parent: VCSSTypeSelector, + right: VCSSTypeSelector, _nesting: any, ) { const loc = { @@ -326,8 +333,8 @@ function newNestingConcatBothSelectorNodes( * Creates a selector node that concats the left selectors of the parent selector and the nested selector. */ function newNestingConcatLeftSelectorNodes( - left: VCSSTypeSelector, - parent: VCSSSelectorNode, + left: VCSSSelectorValueNode, + parent: VCSSTypeSelector, nesting: VCSSNestingSelector, ) { const loc = { @@ -349,7 +356,7 @@ function newNestingConcatLeftSelectorNodes( */ function newNestingConcatRightSelectorNodes( parent: VCSSSelectorValueNode, - right: VCSSSelectorValueNode, + right: VCSSTypeSelector, nesting: VCSSNestingSelector, ) { const loc = { diff --git a/lib/styles/utils/selectors.ts b/lib/styles/utils/selectors.ts index f092dfe4..4c95464a 100644 --- a/lib/styles/utils/selectors.ts +++ b/lib/styles/utils/selectors.ts @@ -180,7 +180,7 @@ export function isNestingAtRule( return isVCSSAtRule(node) && node.name === "nest" } -type NestingInfo = { +export type NestingInfo = { node: VCSSNestingSelector nodes: VCSSSelectorNode[] nestingIndex: number diff --git a/package-lock.json b/package-lock.json index ecc5ac3b..cba92faa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-vue-scoped-css", - "version": "0.2.0", + "version": "0.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 54b0202d..50e6a824 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-vue-scoped-css", - "version": "0.2.0", + "version": "0.2.1", "description": "ESLint plugin for Scoped CSS in Vue.js", "main": "dist/index.js", "scripts": { diff --git a/tests/lib/styles/fixtures/index/@nest-concat04/ast.json b/tests/lib/styles/fixtures/index/@nest-concat04/ast.json new file mode 100644 index 00000000..d9eb9313 --- /dev/null +++ b/tests/lib/styles/fixtures/index/@nest-concat04/ast.json @@ -0,0 +1,480 @@ +{ + "type": "VCSSStyleSheet", + "loc": { + "start": { + "line": 4, + "column": 14 + }, + "end": { + "line": 13, + "column": 0 + } + }, + "start": 49, + "end": 134, + "range": [ + 49, + 134 + ], + "nodes": [ + { + "type": "VCSSStyleRule", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 12, + "column": 1 + } + }, + "start": 50, + "end": 133, + "range": [ + 50, + 133 + ], + "selectorText": "-foo", + "rawSelectorText": "-foo", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 4 + } + }, + "start": 50, + "end": 54, + "range": [ + 50, + 54 + ], + "nodes": [ + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 4 + } + }, + "start": 50, + "end": 54, + "range": [ + 50, + 54 + ], + "value": "-foo", + "selector": "-foo" + } + ] + } + ], + "nodes": [ + { + "type": "VCSSAtRule", + "loc": { + "start": { + "line": 6, + "column": 2 + }, + "end": { + "line": 7, + "column": 3 + } + }, + "start": 59, + "end": 80, + "range": [ + 59, + 80 + ], + "name": "nest", + "paramsText": ".bar&-baz", + "rawParamsText": ".bar&-baz", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 17 + } + }, + "start": 65, + "end": 74, + "range": [ + 65, + 74 + ], + "nodes": [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 12 + } + }, + "start": 65, + "end": 69, + "range": [ + 65, + 69 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSNestingSelector", + "loc": { + "start": { + "line": 6, + "column": 12 + }, + "end": { + "line": 6, + "column": 13 + } + }, + "start": 69, + "end": 70, + "range": [ + 69, + 70 + ], + "value": "&", + "selector": "&" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 6, + "column": 13 + }, + "end": { + "line": 6, + "column": 17 + } + }, + "start": 70, + "end": 74, + "range": [ + 70, + 74 + ], + "value": "-baz", + "selector": "-baz" + } + ] + } + ], + "nodes": [] + }, + { + "type": "VCSSAtRule", + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 9, + "column": 3 + } + }, + "start": 83, + "end": 105, + "range": [ + 83, + 105 + ], + "name": "nest", + "paramsText": ".bar&>-baz", + "rawParamsText": ".bar&>-baz", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 8, + "column": 8 + }, + "end": { + "line": 8, + "column": 18 + } + }, + "start": 89, + "end": 99, + "range": [ + 89, + 99 + ], + "nodes": [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 8, + "column": 8 + }, + "end": { + "line": 8, + "column": 12 + } + }, + "start": 89, + "end": 93, + "range": [ + 89, + 93 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSNestingSelector", + "loc": { + "start": { + "line": 8, + "column": 12 + }, + "end": { + "line": 8, + "column": 13 + } + }, + "start": 93, + "end": 94, + "range": [ + 93, + 94 + ], + "value": "&", + "selector": "&" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 8, + "column": 13 + }, + "end": { + "line": 8, + "column": 14 + } + }, + "start": 94, + "end": 95, + "range": [ + 94, + 95 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 8, + "column": 14 + }, + "end": { + "line": 8, + "column": 18 + } + }, + "start": 95, + "end": 99, + "range": [ + 95, + 99 + ], + "value": "-baz", + "selector": "-baz" + } + ] + } + ], + "nodes": [] + }, + { + "type": "VCSSAtRule", + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 11, + "column": 3 + } + }, + "start": 108, + "end": 131, + "range": [ + 108, + 131 + ], + "name": "nest", + "paramsText": ".bar>&>-baz", + "rawParamsText": ".bar>&>-baz", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 10, + "column": 8 + }, + "end": { + "line": 10, + "column": 19 + } + }, + "start": 114, + "end": 125, + "range": [ + 114, + 125 + ], + "nodes": [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 10, + "column": 8 + }, + "end": { + "line": 10, + "column": 12 + } + }, + "start": 114, + "end": 118, + "range": [ + 114, + 118 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 10, + "column": 13 + } + }, + "start": 118, + "end": 119, + "range": [ + 118, + 119 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSNestingSelector", + "loc": { + "start": { + "line": 10, + "column": 13 + }, + "end": { + "line": 10, + "column": 14 + } + }, + "start": 119, + "end": 120, + "range": [ + 119, + 120 + ], + "value": "&", + "selector": "&" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 10, + "column": 14 + }, + "end": { + "line": 10, + "column": 15 + } + }, + "start": 120, + "end": 121, + "range": [ + 120, + 121 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 10, + "column": 15 + }, + "end": { + "line": 10, + "column": 19 + } + }, + "start": 121, + "end": 125, + "range": [ + 121, + 125 + ], + "value": "-baz", + "selector": "-baz" + } + ] + } + ], + "nodes": [] + } + ] + } + ], + "comments": [], + "errors": [] +} \ No newline at end of file diff --git a/tests/lib/styles/fixtures/index/@nest-concat04/selectors-text.json b/tests/lib/styles/fixtures/index/@nest-concat04/selectors-text.json new file mode 100644 index 00000000..b7fd5623 --- /dev/null +++ b/tests/lib/styles/fixtures/index/@nest-concat04/selectors-text.json @@ -0,0 +1,20 @@ +[ + [ + "-foo" + ], + [ + ".bar-foo-baz" + ], + [ + ".bar-foo", + ">", + "-baz" + ], + [ + ".bar", + ">", + "-foo", + ">", + "-baz" + ] +] \ No newline at end of file diff --git a/tests/lib/styles/fixtures/index/@nest-concat04/selectors.json b/tests/lib/styles/fixtures/index/@nest-concat04/selectors.json new file mode 100644 index 00000000..f2a70f81 --- /dev/null +++ b/tests/lib/styles/fixtures/index/@nest-concat04/selectors.json @@ -0,0 +1,220 @@ +[ + [ + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 4 + } + }, + "start": 50, + "end": 54, + "range": [ + 50, + 54 + ], + "value": "-foo", + "selector": "-foo" + } + ], + [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 6, + "column": 8 + }, + "end": { + "line": 6, + "column": 17 + } + }, + "start": 65, + "end": 74, + "range": [ + 65, + 74 + ], + "value": "bar-foo-baz", + "selector": ".bar-foo-baz" + } + ], + [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 8, + "column": 8 + }, + "end": { + "line": 8, + "column": 13 + } + }, + "start": 89, + "end": 94, + "range": [ + 89, + 94 + ], + "value": "bar-foo", + "selector": ".bar-foo" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 8, + "column": 13 + }, + "end": { + "line": 8, + "column": 14 + } + }, + "start": 94, + "end": 95, + "range": [ + 94, + 95 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 8, + "column": 14 + }, + "end": { + "line": 8, + "column": 18 + } + }, + "start": 95, + "end": 99, + "range": [ + 95, + 99 + ], + "value": "-baz", + "selector": "-baz" + } + ], + [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 10, + "column": 8 + }, + "end": { + "line": 10, + "column": 12 + } + }, + "start": 114, + "end": 118, + "range": [ + 114, + 118 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 10, + "column": 12 + }, + "end": { + "line": 10, + "column": 13 + } + }, + "start": 118, + "end": 119, + "range": [ + 118, + 119 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 4 + } + }, + "start": 50, + "end": 54, + "range": [ + 50, + 54 + ], + "value": "-foo", + "selector": "-foo" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 10, + "column": 14 + }, + "end": { + "line": 10, + "column": 15 + } + }, + "start": 120, + "end": 121, + "range": [ + 120, + 121 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 10, + "column": 15 + }, + "end": { + "line": 10, + "column": 19 + } + }, + "start": 121, + "end": 125, + "range": [ + 121, + 125 + ], + "value": "-baz", + "selector": "-baz" + } + ] +] \ No newline at end of file diff --git a/tests/lib/styles/fixtures/index/@nest-concat04/source.vue b/tests/lib/styles/fixtures/index/@nest-concat04/source.vue new file mode 100644 index 00000000..ce623dc1 --- /dev/null +++ b/tests/lib/styles/fixtures/index/@nest-concat04/source.vue @@ -0,0 +1,13 @@ + + diff --git a/tests/lib/styles/fixtures/index/scss-nest-concat01/ast.json b/tests/lib/styles/fixtures/index/scss-nest-concat01/ast.json new file mode 100644 index 00000000..b581d8a5 --- /dev/null +++ b/tests/lib/styles/fixtures/index/scss-nest-concat01/ast.json @@ -0,0 +1,952 @@ +{ + "type": "VCSSStyleSheet", + "loc": { + "start": { + "line": 4, + "column": 26 + }, + "end": { + "line": 22, + "column": 0 + } + }, + "start": 61, + "end": 197, + "range": [ + 61, + 197 + ], + "nodes": [ + { + "type": "VCSSStyleRule", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 12, + "column": 1 + } + }, + "start": 62, + "end": 127, + "range": [ + 62, + 127 + ], + "selectorText": "-foo", + "rawSelectorText": "-foo", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 4 + } + }, + "start": 62, + "end": 66, + "range": [ + 62, + 66 + ], + "nodes": [ + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 4 + } + }, + "start": 62, + "end": 66, + "range": [ + 62, + 66 + ], + "value": "-foo", + "selector": "-foo" + } + ] + } + ], + "nodes": [ + { + "type": "VCSSStyleRule", + "loc": { + "start": { + "line": 6, + "column": 2 + }, + "end": { + "line": 7, + "column": 3 + } + }, + "start": 71, + "end": 86, + "range": [ + 71, + 86 + ], + "selectorText": ".bar&-baz", + "rawSelectorText": ".bar&-baz", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 6, + "column": 2 + }, + "end": { + "line": 6, + "column": 11 + } + }, + "start": 71, + "end": 80, + "range": [ + 71, + 80 + ], + "nodes": [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 6, + "column": 2 + }, + "end": { + "line": 6, + "column": 6 + } + }, + "start": 71, + "end": 75, + "range": [ + 71, + 75 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSNestingSelector", + "loc": { + "start": { + "line": 6, + "column": 6 + }, + "end": { + "line": 6, + "column": 7 + } + }, + "start": 75, + "end": 76, + "range": [ + 75, + 76 + ], + "value": "&", + "selector": "&" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 6, + "column": 7 + }, + "end": { + "line": 6, + "column": 11 + } + }, + "start": 76, + "end": 80, + "range": [ + 76, + 80 + ], + "value": "-baz", + "selector": "-baz" + } + ] + } + ], + "nodes": [] + }, + { + "type": "VCSSStyleRule", + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 9, + "column": 3 + } + }, + "start": 89, + "end": 105, + "range": [ + 89, + 105 + ], + "selectorText": ".bar&>-baz", + "rawSelectorText": ".bar&>-baz", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 8, + "column": 12 + } + }, + "start": 89, + "end": 99, + "range": [ + 89, + 99 + ], + "nodes": [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 8, + "column": 6 + } + }, + "start": 89, + "end": 93, + "range": [ + 89, + 93 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSNestingSelector", + "loc": { + "start": { + "line": 8, + "column": 6 + }, + "end": { + "line": 8, + "column": 7 + } + }, + "start": 93, + "end": 94, + "range": [ + 93, + 94 + ], + "value": "&", + "selector": "&" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 8, + "column": 7 + }, + "end": { + "line": 8, + "column": 8 + } + }, + "start": 94, + "end": 95, + "range": [ + 94, + 95 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 8, + "column": 8 + }, + "end": { + "line": 8, + "column": 12 + } + }, + "start": 95, + "end": 99, + "range": [ + 95, + 99 + ], + "value": "-baz", + "selector": "-baz" + } + ] + } + ], + "nodes": [] + }, + { + "type": "VCSSStyleRule", + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 11, + "column": 3 + } + }, + "start": 108, + "end": 125, + "range": [ + 108, + 125 + ], + "selectorText": ".bar>&>-baz", + "rawSelectorText": ".bar>&>-baz", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 10, + "column": 13 + } + }, + "start": 108, + "end": 119, + "range": [ + 108, + 119 + ], + "nodes": [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 10, + "column": 6 + } + }, + "start": 108, + "end": 112, + "range": [ + 108, + 112 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 7 + } + }, + "start": 112, + "end": 113, + "range": [ + 112, + 113 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSNestingSelector", + "loc": { + "start": { + "line": 10, + "column": 7 + }, + "end": { + "line": 10, + "column": 8 + } + }, + "start": 113, + "end": 114, + "range": [ + 113, + 114 + ], + "value": "&", + "selector": "&" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 10, + "column": 8 + }, + "end": { + "line": 10, + "column": 9 + } + }, + "start": 114, + "end": 115, + "range": [ + 114, + 115 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 10, + "column": 9 + }, + "end": { + "line": 10, + "column": 13 + } + }, + "start": 115, + "end": 119, + "range": [ + 115, + 119 + ], + "value": "-baz", + "selector": "-baz" + } + ] + } + ], + "nodes": [] + } + ] + }, + { + "type": "VCSSStyleRule", + "loc": { + "start": { + "line": 14, + "column": 0 + }, + "end": { + "line": 21, + "column": 1 + } + }, + "start": 129, + "end": 196, + "range": [ + 129, + 196 + ], + "selectorText": "-foo >", + "rawSelectorText": "-foo >", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 14, + "column": 0 + }, + "end": { + "line": 14, + "column": 6 + } + }, + "start": 129, + "end": 135, + "range": [ + 129, + 135 + ], + "nodes": [ + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 14, + "column": 0 + }, + "end": { + "line": 14, + "column": 4 + } + }, + "start": 129, + "end": 133, + "range": [ + 129, + 133 + ], + "value": "-foo", + "selector": "-foo" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 14, + "column": 5 + }, + "end": { + "line": 14, + "column": 6 + } + }, + "start": 134, + "end": 135, + "range": [ + 134, + 135 + ], + "value": ">", + "selector": ">" + } + ] + } + ], + "nodes": [ + { + "type": "VCSSStyleRule", + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 16, + "column": 3 + } + }, + "start": 140, + "end": 155, + "range": [ + 140, + 155 + ], + "selectorText": ".bar&-baz", + "rawSelectorText": ".bar&-baz", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 15, + "column": 11 + } + }, + "start": 140, + "end": 149, + "range": [ + 140, + 149 + ], + "nodes": [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 15, + "column": 6 + } + }, + "start": 140, + "end": 144, + "range": [ + 140, + 144 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSNestingSelector", + "loc": { + "start": { + "line": 15, + "column": 6 + }, + "end": { + "line": 15, + "column": 7 + } + }, + "start": 144, + "end": 145, + "range": [ + 144, + 145 + ], + "value": "&", + "selector": "&" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 15, + "column": 7 + }, + "end": { + "line": 15, + "column": 11 + } + }, + "start": 145, + "end": 149, + "range": [ + 145, + 149 + ], + "value": "-baz", + "selector": "-baz" + } + ] + } + ], + "nodes": [] + }, + { + "type": "VCSSStyleRule", + "loc": { + "start": { + "line": 17, + "column": 2 + }, + "end": { + "line": 18, + "column": 3 + } + }, + "start": 158, + "end": 174, + "range": [ + 158, + 174 + ], + "selectorText": ".bar&>-baz", + "rawSelectorText": ".bar&>-baz", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 17, + "column": 2 + }, + "end": { + "line": 17, + "column": 12 + } + }, + "start": 158, + "end": 168, + "range": [ + 158, + 168 + ], + "nodes": [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 17, + "column": 2 + }, + "end": { + "line": 17, + "column": 6 + } + }, + "start": 158, + "end": 162, + "range": [ + 158, + 162 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSNestingSelector", + "loc": { + "start": { + "line": 17, + "column": 6 + }, + "end": { + "line": 17, + "column": 7 + } + }, + "start": 162, + "end": 163, + "range": [ + 162, + 163 + ], + "value": "&", + "selector": "&" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + }, + "start": 163, + "end": 164, + "range": [ + 163, + 164 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 12 + } + }, + "start": 164, + "end": 168, + "range": [ + 164, + 168 + ], + "value": "-baz", + "selector": "-baz" + } + ] + } + ], + "nodes": [] + }, + { + "type": "VCSSStyleRule", + "loc": { + "start": { + "line": 19, + "column": 2 + }, + "end": { + "line": 20, + "column": 3 + } + }, + "start": 177, + "end": 194, + "range": [ + 177, + 194 + ], + "selectorText": ".bar>&>-baz", + "rawSelectorText": ".bar>&>-baz", + "selectors": [ + { + "type": "VCSSSelector", + "loc": { + "start": { + "line": 19, + "column": 2 + }, + "end": { + "line": 19, + "column": 13 + } + }, + "start": 177, + "end": 188, + "range": [ + 177, + 188 + ], + "nodes": [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 19, + "column": 2 + }, + "end": { + "line": 19, + "column": 6 + } + }, + "start": 177, + "end": 181, + "range": [ + 177, + 181 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 19, + "column": 6 + }, + "end": { + "line": 19, + "column": 7 + } + }, + "start": 181, + "end": 182, + "range": [ + 181, + 182 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSNestingSelector", + "loc": { + "start": { + "line": 19, + "column": 7 + }, + "end": { + "line": 19, + "column": 8 + } + }, + "start": 182, + "end": 183, + "range": [ + 182, + 183 + ], + "value": "&", + "selector": "&" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 9 + } + }, + "start": 183, + "end": 184, + "range": [ + 183, + 184 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 13 + } + }, + "start": 184, + "end": 188, + "range": [ + 184, + 188 + ], + "value": "-baz", + "selector": "-baz" + } + ] + } + ], + "nodes": [] + } + ] + } + ], + "comments": [], + "errors": [] +} \ No newline at end of file diff --git a/tests/lib/styles/fixtures/index/scss-nest-concat01/selectors-text.json b/tests/lib/styles/fixtures/index/scss-nest-concat01/selectors-text.json new file mode 100644 index 00000000..d7f84f3a --- /dev/null +++ b/tests/lib/styles/fixtures/index/scss-nest-concat01/selectors-text.json @@ -0,0 +1,43 @@ +[ + [ + "-foo" + ], + [ + ".bar-foo-baz" + ], + [ + ".bar-foo", + ">", + "-baz" + ], + [ + ".bar", + ">", + "-foo", + ">", + "-baz" + ], + [ + "-foo", + ">" + ], + [ + ".bar-foo", + ">", + "-baz" + ], + [ + ".bar-foo", + ">", + ">", + "-baz" + ], + [ + ".bar", + ">", + "-foo", + ">", + ">", + "-baz" + ] +] \ No newline at end of file diff --git a/tests/lib/styles/fixtures/index/scss-nest-concat01/selectors.json b/tests/lib/styles/fixtures/index/scss-nest-concat01/selectors.json new file mode 100644 index 00000000..19c96765 --- /dev/null +++ b/tests/lib/styles/fixtures/index/scss-nest-concat01/selectors.json @@ -0,0 +1,543 @@ +[ + [ + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 4 + } + }, + "start": 62, + "end": 66, + "range": [ + 62, + 66 + ], + "value": "-foo", + "selector": "-foo" + } + ], + [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 6, + "column": 2 + }, + "end": { + "line": 6, + "column": 11 + } + }, + "start": 71, + "end": 80, + "range": [ + 71, + 80 + ], + "value": "bar-foo-baz", + "selector": ".bar-foo-baz" + } + ], + [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 8, + "column": 2 + }, + "end": { + "line": 8, + "column": 7 + } + }, + "start": 89, + "end": 94, + "range": [ + 89, + 94 + ], + "value": "bar-foo", + "selector": ".bar-foo" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 8, + "column": 7 + }, + "end": { + "line": 8, + "column": 8 + } + }, + "start": 94, + "end": 95, + "range": [ + 94, + 95 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 8, + "column": 8 + }, + "end": { + "line": 8, + "column": 12 + } + }, + "start": 95, + "end": 99, + "range": [ + 95, + 99 + ], + "value": "-baz", + "selector": "-baz" + } + ], + [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 10, + "column": 2 + }, + "end": { + "line": 10, + "column": 6 + } + }, + "start": 108, + "end": 112, + "range": [ + 108, + 112 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 10, + "column": 6 + }, + "end": { + "line": 10, + "column": 7 + } + }, + "start": 112, + "end": 113, + "range": [ + 112, + 113 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 4 + } + }, + "start": 62, + "end": 66, + "range": [ + 62, + 66 + ], + "value": "-foo", + "selector": "-foo" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 10, + "column": 8 + }, + "end": { + "line": 10, + "column": 9 + } + }, + "start": 114, + "end": 115, + "range": [ + 114, + 115 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 10, + "column": 9 + }, + "end": { + "line": 10, + "column": 13 + } + }, + "start": 115, + "end": 119, + "range": [ + 115, + 119 + ], + "value": "-baz", + "selector": "-baz" + } + ], + [ + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 14, + "column": 0 + }, + "end": { + "line": 14, + "column": 4 + } + }, + "start": 129, + "end": 133, + "range": [ + 129, + 133 + ], + "value": "-foo", + "selector": "-foo" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 14, + "column": 5 + }, + "end": { + "line": 14, + "column": 6 + } + }, + "start": 134, + "end": 135, + "range": [ + 134, + 135 + ], + "value": ">", + "selector": ">" + } + ], + [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 15, + "column": 2 + }, + "end": { + "line": 15, + "column": 7 + } + }, + "start": 140, + "end": 145, + "range": [ + 140, + 145 + ], + "value": "bar-foo", + "selector": ".bar-foo" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 14, + "column": 5 + }, + "end": { + "line": 14, + "column": 6 + } + }, + "start": 134, + "end": 135, + "range": [ + 134, + 135 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 15, + "column": 7 + }, + "end": { + "line": 15, + "column": 11 + } + }, + "start": 145, + "end": 149, + "range": [ + 145, + 149 + ], + "value": "-baz", + "selector": "-baz" + } + ], + [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 17, + "column": 2 + }, + "end": { + "line": 17, + "column": 7 + } + }, + "start": 158, + "end": 163, + "range": [ + 158, + 163 + ], + "value": "bar-foo", + "selector": ".bar-foo" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 14, + "column": 5 + }, + "end": { + "line": 14, + "column": 6 + } + }, + "start": 134, + "end": 135, + "range": [ + 134, + 135 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 17, + "column": 7 + }, + "end": { + "line": 17, + "column": 8 + } + }, + "start": 163, + "end": 164, + "range": [ + 163, + 164 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 17, + "column": 8 + }, + "end": { + "line": 17, + "column": 12 + } + }, + "start": 164, + "end": 168, + "range": [ + 164, + 168 + ], + "value": "-baz", + "selector": "-baz" + } + ], + [ + { + "type": "VCSSClassSelector", + "loc": { + "start": { + "line": 19, + "column": 2 + }, + "end": { + "line": 19, + "column": 6 + } + }, + "start": 177, + "end": 181, + "range": [ + 177, + 181 + ], + "value": "bar", + "selector": ".bar" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 19, + "column": 6 + }, + "end": { + "line": 19, + "column": 7 + } + }, + "start": 181, + "end": 182, + "range": [ + 181, + 182 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 14, + "column": 0 + }, + "end": { + "line": 14, + "column": 4 + } + }, + "start": 129, + "end": 133, + "range": [ + 129, + 133 + ], + "value": "-foo", + "selector": "-foo" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 14, + "column": 5 + }, + "end": { + "line": 14, + "column": 6 + } + }, + "start": 134, + "end": 135, + "range": [ + 134, + 135 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSSelectorCombinator", + "loc": { + "start": { + "line": 19, + "column": 8 + }, + "end": { + "line": 19, + "column": 9 + } + }, + "start": 183, + "end": 184, + "range": [ + 183, + 184 + ], + "value": ">", + "selector": ">" + }, + { + "type": "VCSSTypeSelector", + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 13 + } + }, + "start": 184, + "end": 188, + "range": [ + 184, + 188 + ], + "value": "-baz", + "selector": "-baz" + } + ] +] \ No newline at end of file diff --git a/tests/lib/styles/fixtures/index/scss-nest-concat01/source.vue b/tests/lib/styles/fixtures/index/scss-nest-concat01/source.vue new file mode 100644 index 00000000..d858d6f6 --- /dev/null +++ b/tests/lib/styles/fixtures/index/scss-nest-concat01/source.vue @@ -0,0 +1,22 @@ + +