eslint-plugin-vue-scoped-css 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/rules/enforce-style-type.js +3 -9
- package/dist/rules/no-deprecated-deep-combinator.js +0 -1
- package/dist/rules/no-deprecated-v-enter-v-leave-class.js +3 -5
- package/dist/rules/no-parent-of-v-global.js +0 -1
- package/dist/rules/no-parsing-error.js +3 -4
- package/dist/rules/no-unused-keyframes.js +15 -5
- package/dist/rules/no-unused-selector.js +7 -4
- package/dist/rules/require-scoped.js +1 -3
- package/dist/rules/require-selector-used-inside.js +7 -4
- package/dist/rules/require-v-deep-argument.js +2 -5
- package/dist/rules/require-v-global-argument.js +0 -1
- package/dist/rules/require-v-slotted-argument.js +1 -3
- package/dist/rules/v-deep-pseudo-style.js +63 -0
- package/dist/rules/v-global-pseudo-style.js +63 -0
- package/dist/rules/v-slotted-pseudo-style.js +63 -0
- package/dist/styles/ast.js +1 -3
- package/dist/styles/context/comment-directive/index.js +5 -3
- package/dist/styles/context/vue-components/index.js +3 -3
- package/dist/styles/parser/css-parser.js +5 -1
- package/dist/styles/parser/selector/css-selector-parser.js +2 -5
- package/dist/styles/parser/selector/stylus-selector-parser.js +1 -2
- package/dist/styles/parser/stylus-parser.js +1 -3
- package/dist/styles/selectors/query/attribute-tracker.js +3 -18
- package/dist/styles/selectors/query/index.js +17 -28
- package/dist/styles/selectors/query/reference-expression.js +43 -0
- package/dist/styles/selectors/resolver/css-selector-resolver.js +3 -11
- package/dist/styles/utils/selectors.js +1 -1
- package/dist/utils/rules.js +15 -0
- package/package.json +126 -118
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ See [documents](https://future-architect.github.io/eslint-plugin-vue-scoped-css/
|
|
|
36
36
|
## Installation
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
npm install --save-dev eslint eslint-plugin-vue-scoped-css
|
|
39
|
+
npm install --save-dev eslint eslint-plugin-vue-scoped-css vue-eslint-parser
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
> **Requirements**
|
|
@@ -145,6 +145,9 @@ For example:
|
|
|
145
145
|
|:--------|:------------|:---|
|
|
146
146
|
| [vue-scoped-css/no-deprecated-v-enter-v-leave-class](https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/no-deprecated-v-enter-v-leave-class.html) | disallow v-enter and v-leave classes. | |
|
|
147
147
|
| [vue-scoped-css/require-selector-used-inside](https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/require-selector-used-inside.html) | disallow selectors defined that is not used inside `<template>` | |
|
|
148
|
+
| [vue-scoped-css/v-deep-pseudo-style](https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/v-deep-pseudo-style.html) | enforce `:deep()`/`::v-deep()` style | :wrench: |
|
|
149
|
+
| [vue-scoped-css/v-global-pseudo-style](https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/v-global-pseudo-style.html) | enforce `:global()`/`::v-global()` style | :wrench: |
|
|
150
|
+
| [vue-scoped-css/v-slotted-pseudo-style](https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/v-slotted-pseudo-style.html) | enforce `:slotted()`/`::v-slotted()` style | :wrench: |
|
|
148
151
|
|
|
149
152
|
## Deprecated
|
|
150
153
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
5
|
const lodash_1 = __importDefault(require("lodash"));
|
|
7
6
|
const context_1 = require("../styles/context");
|
|
8
7
|
const styleTypesAttrs = ["scoped", "module"];
|
|
@@ -63,9 +62,7 @@ module.exports = {
|
|
|
63
62
|
return [
|
|
64
63
|
fixer.removeRange([
|
|
65
64
|
prevToken.range[1],
|
|
66
|
-
attributes.length === 1
|
|
67
|
-
? nextToken.range[0]
|
|
68
|
-
: node.range[1],
|
|
65
|
+
attributes.length === 1 ? nextToken.range[0] : node.range[1],
|
|
69
66
|
]),
|
|
70
67
|
];
|
|
71
68
|
}
|
|
@@ -107,9 +104,7 @@ module.exports = {
|
|
|
107
104
|
node: node.startTag,
|
|
108
105
|
messageId: "forbiddenPlain",
|
|
109
106
|
data: {
|
|
110
|
-
attributes: allows
|
|
111
|
-
.map((allow) => `\`${allow}\``)
|
|
112
|
-
.join(" or "),
|
|
107
|
+
attributes: allows.map((allow) => `\`${allow}\``).join(" or "),
|
|
113
108
|
},
|
|
114
109
|
suggest: singleAllow
|
|
115
110
|
? [
|
|
@@ -120,8 +115,7 @@ module.exports = {
|
|
|
120
115
|
},
|
|
121
116
|
fix(fixer) {
|
|
122
117
|
const close = tokenStore.getLastToken(node.startTag);
|
|
123
|
-
return (close &&
|
|
124
|
-
fixer.insertTextBefore(close, ` ${singleAllow}`));
|
|
118
|
+
return (close && fixer.insertTextBefore(close, ` ${singleAllow}`));
|
|
125
119
|
},
|
|
126
120
|
},
|
|
127
121
|
]
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const context_1 = require("../styles/context");
|
|
4
3
|
const templates_1 = require("../utils/templates");
|
|
5
4
|
const attribute_tracker_1 = require("../styles/selectors/query/attribute-tracker");
|
|
@@ -66,13 +65,13 @@ module.exports = {
|
|
|
66
65
|
break;
|
|
67
66
|
}
|
|
68
67
|
if (node.type === "VCSSClassSelector") {
|
|
69
|
-
for (const { className, kind
|
|
68
|
+
for (const { className, kind } of deprecatedClassNames.values()) {
|
|
70
69
|
if (className.matchString(node.value)) {
|
|
71
70
|
deprecatedClasses.set(node, kind);
|
|
72
71
|
break;
|
|
73
72
|
}
|
|
74
73
|
}
|
|
75
|
-
for (const { className
|
|
74
|
+
for (const { className } of renamedClassNames.values()) {
|
|
76
75
|
if (className.matchString(node.value)) {
|
|
77
76
|
renamedClasses.add(node.value);
|
|
78
77
|
break;
|
|
@@ -133,8 +132,7 @@ module.exports = {
|
|
|
133
132
|
}
|
|
134
133
|
return {
|
|
135
134
|
"Program:exit"() {
|
|
136
|
-
for (const transition of (0, templates_1.getElements)(context, (element) => (0, templates_1.isTransitionElement)(element) ||
|
|
137
|
-
(0, templates_1.isTransitionGroupElement)(element))) {
|
|
135
|
+
for (const transition of (0, templates_1.getElements)(context, (element) => (0, templates_1.isTransitionElement)(element) || (0, templates_1.isTransitionGroupElement)(element))) {
|
|
138
136
|
const { hasEnterClass, hasLeaveClass } = verifyTransitionElementNode(transition);
|
|
139
137
|
if (hasEnterClass && hasLeaveClass) {
|
|
140
138
|
continue;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const context_1 = require("../styles/context");
|
|
4
3
|
module.exports = {
|
|
5
4
|
meta: {
|
|
@@ -10,7 +9,7 @@ module.exports = {
|
|
|
10
9
|
url: "https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/no-parsing-error.html",
|
|
11
10
|
},
|
|
12
11
|
fixable: null,
|
|
13
|
-
messages: {},
|
|
12
|
+
messages: { parsingError: "Parsing error: {{message}}." },
|
|
14
13
|
schema: [],
|
|
15
14
|
type: "problem",
|
|
16
15
|
},
|
|
@@ -24,7 +23,7 @@ module.exports = {
|
|
|
24
23
|
reporter.report({
|
|
25
24
|
node,
|
|
26
25
|
loc: node.loc.start,
|
|
27
|
-
|
|
26
|
+
messageId: "parsingError",
|
|
28
27
|
data: {
|
|
29
28
|
message: node.message.endsWith(".")
|
|
30
29
|
? node.message.slice(0, -1)
|
|
@@ -36,7 +35,7 @@ module.exports = {
|
|
|
36
35
|
reporter.report({
|
|
37
36
|
node: style.styleElement,
|
|
38
37
|
loc: style.invalid.loc,
|
|
39
|
-
|
|
38
|
+
messageId: "parsingError",
|
|
40
39
|
data: {
|
|
41
40
|
message: style.invalid.message,
|
|
42
41
|
},
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const template_1 = require("../styles/template");
|
|
4
3
|
const context_1 = require("../styles/context");
|
|
5
4
|
const style_1 = require("../styles/context/style");
|
|
@@ -15,13 +14,25 @@ module.exports = {
|
|
|
15
14
|
messages: {
|
|
16
15
|
unused: "The @keyframes `{{params}}` is unused.",
|
|
17
16
|
},
|
|
18
|
-
schema: [
|
|
17
|
+
schema: [
|
|
18
|
+
{
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
checkUnscoped: {
|
|
22
|
+
type: "boolean",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
additionalProperties: false,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
19
28
|
type: "suggestion",
|
|
20
29
|
},
|
|
21
30
|
create(context) {
|
|
31
|
+
var _a;
|
|
32
|
+
const checkUnscoped = Boolean((_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.checkUnscoped);
|
|
22
33
|
const styles = (0, context_1.getStyleContexts)(context)
|
|
23
34
|
.filter(style_1.isValidStyleContext)
|
|
24
|
-
.filter((style) => style.scoped);
|
|
35
|
+
.filter((style) => style.scoped || checkUnscoped);
|
|
25
36
|
if (!styles.length) {
|
|
26
37
|
return {};
|
|
27
38
|
}
|
|
@@ -50,8 +61,7 @@ module.exports = {
|
|
|
50
61
|
style.traverseNodes({
|
|
51
62
|
enterNode(node) {
|
|
52
63
|
if (node.type === "VCSSAtRule") {
|
|
53
|
-
if (/-?keyframes$/u.test(node.name) &&
|
|
54
|
-
node.identifier === "@") {
|
|
64
|
+
if (/-?keyframes$/u.test(node.name) && node.identifier === "@") {
|
|
55
65
|
keyframes.push({
|
|
56
66
|
params: template_1.Template.ofParams(node),
|
|
57
67
|
node,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const selectors_1 = require("../styles/selectors");
|
|
4
3
|
const selectors_2 = require("../styles/utils/selectors");
|
|
5
4
|
const query_1 = require("../styles/selectors/query");
|
|
@@ -80,6 +79,9 @@ module.exports = {
|
|
|
80
79
|
minItems: 0,
|
|
81
80
|
uniqueItems: true,
|
|
82
81
|
},
|
|
82
|
+
checkUnscoped: {
|
|
83
|
+
type: "boolean",
|
|
84
|
+
},
|
|
83
85
|
},
|
|
84
86
|
additionalProperties: false,
|
|
85
87
|
},
|
|
@@ -87,12 +89,14 @@ module.exports = {
|
|
|
87
89
|
type: "suggestion",
|
|
88
90
|
},
|
|
89
91
|
create(context) {
|
|
92
|
+
var _a;
|
|
90
93
|
if (!(0, utils_1.hasTemplateBlock)(context)) {
|
|
91
94
|
return {};
|
|
92
95
|
}
|
|
96
|
+
const checkUnscoped = Boolean((_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.checkUnscoped);
|
|
93
97
|
const styles = (0, context_1.getStyleContexts)(context)
|
|
94
98
|
.filter(style_1.isValidStyleContext)
|
|
95
|
-
.filter((style) => style.scoped);
|
|
99
|
+
.filter((style) => style.scoped || checkUnscoped);
|
|
96
100
|
if (!styles.length) {
|
|
97
101
|
return {};
|
|
98
102
|
}
|
|
@@ -160,8 +164,7 @@ module.exports = {
|
|
|
160
164
|
if (targetsQueryContext.elements.some(elements_1.isRootElement)) {
|
|
161
165
|
return;
|
|
162
166
|
}
|
|
163
|
-
targetsQueryContext =
|
|
164
|
-
targetsQueryContext.reverseQueryStep(comb);
|
|
167
|
+
targetsQueryContext = targetsQueryContext.reverseQueryStep(comb);
|
|
165
168
|
reportSelectorNodes.push(comb);
|
|
166
169
|
}
|
|
167
170
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const context_1 = require("../styles/context");
|
|
4
3
|
module.exports = {
|
|
5
4
|
meta: {
|
|
@@ -42,8 +41,7 @@ module.exports = {
|
|
|
42
41
|
messageId: "add",
|
|
43
42
|
fix(fixer) {
|
|
44
43
|
const close = tokenStore.getLastToken(node.startTag);
|
|
45
|
-
return (close
|
|
46
|
-
fixer.insertTextBefore(close, " scoped"));
|
|
44
|
+
return close && fixer.insertTextBefore(close, " scoped");
|
|
47
45
|
},
|
|
48
46
|
},
|
|
49
47
|
],
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const selectors_1 = require("../styles/selectors");
|
|
4
3
|
const selectors_2 = require("../styles/utils/selectors");
|
|
5
4
|
const query_1 = require("../styles/selectors/query");
|
|
@@ -63,6 +62,9 @@ module.exports = {
|
|
|
63
62
|
minItems: 0,
|
|
64
63
|
uniqueItems: true,
|
|
65
64
|
},
|
|
65
|
+
checkUnscoped: {
|
|
66
|
+
type: "boolean",
|
|
67
|
+
},
|
|
66
68
|
},
|
|
67
69
|
additionalProperties: false,
|
|
68
70
|
},
|
|
@@ -70,12 +72,14 @@ module.exports = {
|
|
|
70
72
|
type: "suggestion",
|
|
71
73
|
},
|
|
72
74
|
create(context) {
|
|
75
|
+
var _a;
|
|
73
76
|
if (!(0, utils_1.hasTemplateBlock)(context)) {
|
|
74
77
|
return {};
|
|
75
78
|
}
|
|
79
|
+
const checkUnscoped = Boolean((_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.checkUnscoped);
|
|
76
80
|
const styles = (0, context_1.getStyleContexts)(context)
|
|
77
81
|
.filter(style_1.isValidStyleContext)
|
|
78
|
-
.filter((style) => style.scoped);
|
|
82
|
+
.filter((style) => style.scoped || checkUnscoped);
|
|
79
83
|
if (!styles.length) {
|
|
80
84
|
return {};
|
|
81
85
|
}
|
|
@@ -108,8 +112,7 @@ module.exports = {
|
|
|
108
112
|
(0, selectors_2.isVueSpecialPseudo)(s));
|
|
109
113
|
for (let index = 0; index < selectorNodes.length; index++) {
|
|
110
114
|
const selectorNode = selectorNodes[index];
|
|
111
|
-
targetsQueryContext =
|
|
112
|
-
targetsQueryContext.queryStep(selectorNode);
|
|
115
|
+
targetsQueryContext = targetsQueryContext.queryStep(selectorNode);
|
|
113
116
|
if (!targetsQueryContext.elements.length) {
|
|
114
117
|
report(selectorNodes.slice(0, index + 1));
|
|
115
118
|
break;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const context_1 = require("../styles/context");
|
|
4
3
|
const selectors_1 = require("../styles/utils/selectors");
|
|
5
4
|
const css_nodes_1 = require("../styles/utils/css-nodes");
|
|
@@ -61,8 +60,7 @@ module.exports = {
|
|
|
61
60
|
return null;
|
|
62
61
|
}
|
|
63
62
|
const ruleNode = findHasSelectorsNode(node);
|
|
64
|
-
if (!(ruleNode === null || ruleNode === void 0 ? void 0 : ruleNode.nodes.every((n) => (0, css_nodes_1.isVCSSDeclarationProperty)(n) ||
|
|
65
|
-
(0, css_nodes_1.isVCSSComment)(n)))) {
|
|
63
|
+
if (!(ruleNode === null || ruleNode === void 0 ? void 0 : ruleNode.nodes.every((n) => (0, css_nodes_1.isVCSSDeclarationProperty)(n) || (0, css_nodes_1.isVCSSComment)(n)))) {
|
|
66
64
|
return null;
|
|
67
65
|
}
|
|
68
66
|
const last = nodes[nodes.length - 1];
|
|
@@ -80,8 +78,7 @@ module.exports = {
|
|
|
80
78
|
if ((0, selectors_1.isVDeepPseudoV2)(node)) {
|
|
81
79
|
report(node);
|
|
82
80
|
}
|
|
83
|
-
else if ((0, selectors_1.isVDeepPseudo)(node) &&
|
|
84
|
-
(0, selectors_1.isPseudoEmptyArguments)(node)) {
|
|
81
|
+
else if ((0, selectors_1.isVDeepPseudo)(node) && (0, selectors_1.isPseudoEmptyArguments)(node)) {
|
|
85
82
|
report(node);
|
|
86
83
|
}
|
|
87
84
|
},
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
2
|
const context_1 = require("../styles/context");
|
|
4
3
|
const selectors_1 = require("../styles/utils/selectors");
|
|
5
4
|
module.exports = {
|
|
@@ -35,8 +34,7 @@ module.exports = {
|
|
|
35
34
|
function verify(style) {
|
|
36
35
|
style.traverseSelectorNodes({
|
|
37
36
|
enterNode(node) {
|
|
38
|
-
if ((0, selectors_1.isVSlottedPseudo)(node) &&
|
|
39
|
-
(0, selectors_1.isPseudoEmptyArguments)(node)) {
|
|
37
|
+
if ((0, selectors_1.isVSlottedPseudo)(node) && (0, selectors_1.isPseudoEmptyArguments)(node)) {
|
|
40
38
|
report(node);
|
|
41
39
|
}
|
|
42
40
|
},
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const context_1 = require("../styles/context");
|
|
3
|
+
const selectors_1 = require("../styles/utils/selectors");
|
|
4
|
+
module.exports = {
|
|
5
|
+
meta: {
|
|
6
|
+
docs: {
|
|
7
|
+
description: "enforce `:deep()`/`::v-deep()` style",
|
|
8
|
+
categories: [],
|
|
9
|
+
default: "warn",
|
|
10
|
+
url: "https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/v-deep-pseudo-style.html",
|
|
11
|
+
},
|
|
12
|
+
fixable: "code",
|
|
13
|
+
messages: {
|
|
14
|
+
expectedDeep: "Expected ':deep()' instead of '::v-deep()'.",
|
|
15
|
+
expectedVDeep: "Expected '::v-deep()' instead of ':deep()'.",
|
|
16
|
+
},
|
|
17
|
+
schema: [{ enum: [":deep", "::v-deep"] }],
|
|
18
|
+
type: "suggestion",
|
|
19
|
+
},
|
|
20
|
+
create(context) {
|
|
21
|
+
const styles = (0, context_1.getStyleContexts)(context)
|
|
22
|
+
.filter(context_1.isValidStyleContext)
|
|
23
|
+
.filter((style) => style.scoped);
|
|
24
|
+
if (!styles.length) {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
const expected = (context.options[0] || ":deep");
|
|
28
|
+
const reporter = (0, context_1.getCommentDirectivesReporter)(context);
|
|
29
|
+
function report(node) {
|
|
30
|
+
reporter.report({
|
|
31
|
+
node,
|
|
32
|
+
loc: node.loc,
|
|
33
|
+
messageId: expected === ":deep" ? "expectedDeep" : "expectedVDeep",
|
|
34
|
+
fix(fixer) {
|
|
35
|
+
const nodeText = context.getSourceCode().text.slice(...node.range);
|
|
36
|
+
return fixer.replaceTextRange(node.range, nodeText.replace(/^(\s*)(?::deep|::v-deep)(\s*\()/u, (_, prefix, suffix) => `${prefix}${expected}${suffix}`));
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function verifyNode(node) {
|
|
41
|
+
if (node.value === expected) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
report(node);
|
|
45
|
+
}
|
|
46
|
+
function verify(style) {
|
|
47
|
+
style.traverseSelectorNodes({
|
|
48
|
+
enterNode(node) {
|
|
49
|
+
if ((0, selectors_1.isVDeepPseudo)(node) && !(0, selectors_1.isPseudoEmptyArguments)(node)) {
|
|
50
|
+
verifyNode(node);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
"Program:exit"() {
|
|
57
|
+
for (const style of styles) {
|
|
58
|
+
verify(style);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const context_1 = require("../styles/context");
|
|
3
|
+
const selectors_1 = require("../styles/utils/selectors");
|
|
4
|
+
module.exports = {
|
|
5
|
+
meta: {
|
|
6
|
+
docs: {
|
|
7
|
+
description: "enforce `:global()`/`::v-global()` style",
|
|
8
|
+
categories: [],
|
|
9
|
+
default: "warn",
|
|
10
|
+
url: "https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/v-global-pseudo-style.html",
|
|
11
|
+
},
|
|
12
|
+
fixable: "code",
|
|
13
|
+
messages: {
|
|
14
|
+
expectedGlobal: "Expected ':global()' instead of '::v-global()'.",
|
|
15
|
+
expectedVGlobal: "Expected '::v-global()' instead of ':global()'.",
|
|
16
|
+
},
|
|
17
|
+
schema: [{ enum: [":global", "::v-global"] }],
|
|
18
|
+
type: "suggestion",
|
|
19
|
+
},
|
|
20
|
+
create(context) {
|
|
21
|
+
const styles = (0, context_1.getStyleContexts)(context)
|
|
22
|
+
.filter(context_1.isValidStyleContext)
|
|
23
|
+
.filter((style) => style.scoped);
|
|
24
|
+
if (!styles.length) {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
const expected = (context.options[0] || ":global");
|
|
28
|
+
const reporter = (0, context_1.getCommentDirectivesReporter)(context);
|
|
29
|
+
function report(node) {
|
|
30
|
+
reporter.report({
|
|
31
|
+
node,
|
|
32
|
+
loc: node.loc,
|
|
33
|
+
messageId: expected === ":global" ? "expectedGlobal" : "expectedVGlobal",
|
|
34
|
+
fix(fixer) {
|
|
35
|
+
const nodeText = context.getSourceCode().text.slice(...node.range);
|
|
36
|
+
return fixer.replaceTextRange(node.range, nodeText.replace(/^(\s*)(?::global|::v-global)(\s*\()/u, (_, prefix, suffix) => `${prefix}${expected}${suffix}`));
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function verifyNode(node) {
|
|
41
|
+
if (node.value === expected) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
report(node);
|
|
45
|
+
}
|
|
46
|
+
function verify(style) {
|
|
47
|
+
style.traverseSelectorNodes({
|
|
48
|
+
enterNode(node) {
|
|
49
|
+
if ((0, selectors_1.isVGlobalPseudo)(node) && !(0, selectors_1.isPseudoEmptyArguments)(node)) {
|
|
50
|
+
verifyNode(node);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
"Program:exit"() {
|
|
57
|
+
for (const style of styles) {
|
|
58
|
+
verify(style);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const context_1 = require("../styles/context");
|
|
3
|
+
const selectors_1 = require("../styles/utils/selectors");
|
|
4
|
+
module.exports = {
|
|
5
|
+
meta: {
|
|
6
|
+
docs: {
|
|
7
|
+
description: "enforce `:slotted()`/`::v-slotted()` style",
|
|
8
|
+
categories: [],
|
|
9
|
+
default: "warn",
|
|
10
|
+
url: "https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/v-slotted-pseudo-style.html",
|
|
11
|
+
},
|
|
12
|
+
fixable: "code",
|
|
13
|
+
messages: {
|
|
14
|
+
expectedSlotted: "Expected ':slotted()' instead of '::v-slotted()'.",
|
|
15
|
+
expectedVSlotted: "Expected '::v-slotted()' instead of ':slotted()'.",
|
|
16
|
+
},
|
|
17
|
+
schema: [{ enum: [":slotted", "::v-slotted"] }],
|
|
18
|
+
type: "suggestion",
|
|
19
|
+
},
|
|
20
|
+
create(context) {
|
|
21
|
+
const styles = (0, context_1.getStyleContexts)(context)
|
|
22
|
+
.filter(context_1.isValidStyleContext)
|
|
23
|
+
.filter((style) => style.scoped);
|
|
24
|
+
if (!styles.length) {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
const expected = (context.options[0] || ":slotted");
|
|
28
|
+
const reporter = (0, context_1.getCommentDirectivesReporter)(context);
|
|
29
|
+
function report(node) {
|
|
30
|
+
reporter.report({
|
|
31
|
+
node,
|
|
32
|
+
loc: node.loc,
|
|
33
|
+
messageId: expected === ":slotted" ? "expectedSlotted" : "expectedVSlotted",
|
|
34
|
+
fix(fixer) {
|
|
35
|
+
const nodeText = context.getSourceCode().text.slice(...node.range);
|
|
36
|
+
return fixer.replaceTextRange(node.range, nodeText.replace(/^(\s*)(?::slotted|::v-slotted)(\s*\()/u, (_, prefix, suffix) => `${prefix}${expected}${suffix}`));
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function verifyNode(node) {
|
|
41
|
+
if (node.value === expected) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
report(node);
|
|
45
|
+
}
|
|
46
|
+
function verify(style) {
|
|
47
|
+
style.traverseSelectorNodes({
|
|
48
|
+
enterNode(node) {
|
|
49
|
+
if ((0, selectors_1.isVSlottedPseudo)(node) && !(0, selectors_1.isPseudoEmptyArguments)(node)) {
|
|
50
|
+
verifyNode(node);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
"Program:exit"() {
|
|
57
|
+
for (const style of styles) {
|
|
58
|
+
verify(style);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|
package/dist/styles/ast.js
CHANGED
|
@@ -48,9 +48,7 @@ class VCSSStyleRule extends HasParentNode {
|
|
|
48
48
|
}
|
|
49
49
|
else {
|
|
50
50
|
const raws = node.raws;
|
|
51
|
-
this.rawSelectorText = raws.selector
|
|
52
|
-
? raws.selector.raw
|
|
53
|
-
: node.selector;
|
|
51
|
+
this.rawSelectorText = raws.selector ? raws.selector.raw : node.selector;
|
|
54
52
|
}
|
|
55
53
|
this.selectors = (_b = props.selectors) !== null && _b !== void 0 ? _b : [];
|
|
56
54
|
this.nodes = (_c = props.nodes) !== null && _c !== void 0 ? _c : [];
|
|
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createCommentDirectivesReporter = exports.createCommentDirectives = exports.CommentDirectivesReporter = exports.CommentDirectives = void 0;
|
|
4
4
|
const COMMENT_DIRECTIVE_B = /^\s*(eslint-(?:en|dis)able)(?:\s+(\S|\S[\s\S]*\S))?\s*$/u;
|
|
5
5
|
const COMMENT_DIRECTIVE_L = /^\s*(eslint-disable(?:-next)?-line)(?:\s+(\S|\S[\s\S]*\S))?\s*$/u;
|
|
6
|
+
function stripDirectiveComment(value) {
|
|
7
|
+
return value.split(/\s-{2,}\s/u)[0];
|
|
8
|
+
}
|
|
6
9
|
function parse(pattern, comment) {
|
|
7
|
-
const match = pattern.exec(comment);
|
|
10
|
+
const match = pattern.exec(stripDirectiveComment(comment));
|
|
8
11
|
if (match == null) {
|
|
9
12
|
return null;
|
|
10
13
|
}
|
|
@@ -45,8 +48,7 @@ function processBlock(commentDirectives, comment) {
|
|
|
45
48
|
function processLine(commentDirectives, comment) {
|
|
46
49
|
const parsed = parse(COMMENT_DIRECTIVE_L, comment.text);
|
|
47
50
|
if (parsed != null && comment.loc.start.line === comment.loc.end.line) {
|
|
48
|
-
const line = comment.loc.start.line +
|
|
49
|
-
(parsed.type === "eslint-disable-line" ? 0 : 1);
|
|
51
|
+
const line = comment.loc.start.line + (parsed.type === "eslint-disable-line" ? 0 : 1);
|
|
50
52
|
const column = -1;
|
|
51
53
|
if (!parsed.rules.length) {
|
|
52
54
|
commentDirectives.disableLineAll({ line, column });
|
|
@@ -17,7 +17,7 @@ class VueComponentContext {
|
|
|
17
17
|
}
|
|
18
18
|
findVueComponentProperty(name) {
|
|
19
19
|
const properties = this.properties ||
|
|
20
|
-
(this.properties =
|
|
20
|
+
(this.properties = extractVueComponentProperties(this.node, this.context));
|
|
21
21
|
if (properties[UNKNOWN]) {
|
|
22
22
|
return null;
|
|
23
23
|
}
|
|
@@ -48,7 +48,7 @@ function createVueComponentContext(context) {
|
|
|
48
48
|
return new VueComponentContext(node, context);
|
|
49
49
|
}
|
|
50
50
|
exports.createVueComponentContext = createVueComponentContext;
|
|
51
|
-
function
|
|
51
|
+
function extractVueComponentProperties(vueNode, context) {
|
|
52
52
|
const result = {
|
|
53
53
|
data: {},
|
|
54
54
|
computed: {},
|
|
@@ -129,7 +129,7 @@ function extractVueComponentComputed(computedNode, context) {
|
|
|
129
129
|
continue;
|
|
130
130
|
}
|
|
131
131
|
const values = computed[keyName] || (computed[keyName] = []);
|
|
132
|
-
const
|
|
132
|
+
const value = p.value;
|
|
133
133
|
let func = value;
|
|
134
134
|
if (value.type === "ObjectExpression") {
|
|
135
135
|
const get = value.properties
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -63,8 +63,7 @@ class CSSSelectorParser {
|
|
|
63
63
|
astNode.nodes = (0, selectors_1.normalizePseudoParams)(astNode, this._postcssSelectorParserNodeChiildrenToASTNodes(offsetLocation, node, astNode));
|
|
64
64
|
}
|
|
65
65
|
else if (astNode.type === "VCSSSelector") {
|
|
66
|
-
astNode.nodes =
|
|
67
|
-
this._postcssSelectorParserNodeChiildrenToASTNodes(offsetLocation, node, astNode);
|
|
66
|
+
astNode.nodes = this._postcssSelectorParserNodeChiildrenToASTNodes(offsetLocation, node, astNode);
|
|
68
67
|
}
|
|
69
68
|
}
|
|
70
69
|
return astNode;
|
|
@@ -165,9 +164,7 @@ class CSSSelectorParser {
|
|
|
165
164
|
return astNode;
|
|
166
165
|
}
|
|
167
166
|
convertCommentNode(node, loc, start, end, parent) {
|
|
168
|
-
const text = node.value
|
|
169
|
-
.replace(/^\s*\/\*/u, "")
|
|
170
|
-
.replace(/\*\/\s*$/u, "");
|
|
167
|
+
const text = node.value.replace(/^\s*\/\*/u, "").replace(/\*\/\s*$/u, "");
|
|
171
168
|
this.commentContainer.push(new ast_1.VCSSComment(node, text, loc, start, end, {
|
|
172
169
|
parent,
|
|
173
170
|
}));
|
|
@@ -60,8 +60,7 @@ class StylusSelectorParser extends css_selector_parser_1.CSSSelectorParser {
|
|
|
60
60
|
replace(res, _random, { beforeCss }) {
|
|
61
61
|
const before = [...beforeCss];
|
|
62
62
|
let prev = before.pop();
|
|
63
|
-
while (prev != null &&
|
|
64
|
-
(prev.startsWith("/*") || !prev.trim())) {
|
|
63
|
+
while (prev != null && (prev.startsWith("/*") || !prev.trim())) {
|
|
65
64
|
prev = before.pop();
|
|
66
65
|
}
|
|
67
66
|
if (prev === null || prev === void 0 ? void 0 : prev.trim().endsWith(",")) {
|
|
@@ -26,9 +26,7 @@ class StylusParser extends css_parser_1.CSSParser {
|
|
|
26
26
|
return super.convertCommentNode(node, loc, start, end, parent);
|
|
27
27
|
}
|
|
28
28
|
getRaw(node, keyName) {
|
|
29
|
-
if (keyName === "between" ||
|
|
30
|
-
keyName === "before" ||
|
|
31
|
-
keyName === "after") {
|
|
29
|
+
if (keyName === "between" || keyName === "before" || keyName === "after") {
|
|
32
30
|
const stylus = super.getRaw(node, `stylus${keyName[0].toUpperCase()}${keyName.slice(1)}`);
|
|
33
31
|
if (stylus) {
|
|
34
32
|
return stylus;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const context_1 = require("../../context");
|
|
3
|
+
exports.getAttributeValueNodes = void 0;
|
|
5
4
|
const templates_1 = require("../../../utils/templates");
|
|
5
|
+
const reference_expression_1 = require("./reference-expression");
|
|
6
6
|
function getAttributeValueNodes(element, name, context) {
|
|
7
7
|
const results = [];
|
|
8
8
|
const { startTag } = element;
|
|
@@ -35,7 +35,7 @@ function getAttributeValueNodes(element, name, context) {
|
|
|
35
35
|
if (expression == null) {
|
|
36
36
|
continue;
|
|
37
37
|
}
|
|
38
|
-
const expressions = getReferenceExpressions(expression, context);
|
|
38
|
+
const expressions = (0, reference_expression_1.getReferenceExpressions)(expression, context);
|
|
39
39
|
if (!expressions) {
|
|
40
40
|
return null;
|
|
41
41
|
}
|
|
@@ -47,18 +47,3 @@ function getAttributeValueNodes(element, name, context) {
|
|
|
47
47
|
return results;
|
|
48
48
|
}
|
|
49
49
|
exports.getAttributeValueNodes = getAttributeValueNodes;
|
|
50
|
-
function getReferenceExpressions(expression, context) {
|
|
51
|
-
if (expression.type !== "Identifier") {
|
|
52
|
-
return [expression];
|
|
53
|
-
}
|
|
54
|
-
const vueComponent = (0, context_1.getVueComponentContext)(context);
|
|
55
|
-
if (!vueComponent) {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
const props = vueComponent.findVueComponentProperty(expression.name);
|
|
59
|
-
if (props == null) {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
return props;
|
|
63
|
-
}
|
|
64
|
-
exports.getReferenceExpressions = getReferenceExpressions;
|
|
@@ -9,6 +9,7 @@ const nodes_1 = require("../../utils/nodes");
|
|
|
9
9
|
const template_1 = require("../../template");
|
|
10
10
|
const templates_1 = require("../../../utils/templates");
|
|
11
11
|
const style_1 = require("../../context/style");
|
|
12
|
+
const reference_expression_1 = require("./reference-expression");
|
|
12
13
|
const TRANSITION_CLASS_BASES = [
|
|
13
14
|
"enter",
|
|
14
15
|
"enter-from",
|
|
@@ -141,7 +142,9 @@ function* queryStep(elements, selectorNode, document) {
|
|
|
141
142
|
}
|
|
142
143
|
yield* elements;
|
|
143
144
|
function query(els, selList) {
|
|
144
|
-
return selList.reduce((res, sel) => [
|
|
145
|
+
return selList.reduce((res, sel) => [
|
|
146
|
+
...queryStep(res, sel, document),
|
|
147
|
+
], els);
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
function* reverseQueryStep(elements, selectorNode, document) {
|
|
@@ -178,7 +181,9 @@ function* reverseQueryStep(elements, selectorNode, document) {
|
|
|
178
181
|
}
|
|
179
182
|
yield* queryStep(elements, selectorNode, document);
|
|
180
183
|
function query(els, selList) {
|
|
181
|
-
return selList.reduceRight((res, sel) => [
|
|
184
|
+
return selList.reduceRight((res, sel) => [
|
|
185
|
+
...reverseQueryStep(res, sel, document),
|
|
186
|
+
], els);
|
|
182
187
|
}
|
|
183
188
|
}
|
|
184
189
|
function* genDescendantElements(elements) {
|
|
@@ -558,30 +563,20 @@ function matchClassNameExpression(expression, className, document) {
|
|
|
558
563
|
}
|
|
559
564
|
function matchClassNameForArrayExpression(expression, className, document) {
|
|
560
565
|
for (const e of expression.elements) {
|
|
561
|
-
if (e.type === "
|
|
562
|
-
if (withinTemplate(e, document)) {
|
|
563
|
-
const expressions = (0, attribute_tracker_1.getReferenceExpressions)(e, document.context);
|
|
564
|
-
if (expressions) {
|
|
565
|
-
for (const e2 of expressions) {
|
|
566
|
-
if (matchClassNameExpression(e2, className, document)) {
|
|
567
|
-
return true;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
else {
|
|
573
|
-
if (matchClassNameExpression(e, className, document)) {
|
|
574
|
-
return true;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
else if (e.type === "SpreadElement") {
|
|
566
|
+
if (e.type === "SpreadElement") {
|
|
579
567
|
if (matchClassNameExpression(e.argument, className, document)) {
|
|
580
568
|
return true;
|
|
581
569
|
}
|
|
582
570
|
}
|
|
583
|
-
else
|
|
584
|
-
|
|
571
|
+
else {
|
|
572
|
+
const expressions = (0, reference_expression_1.getReferenceExpressions)(e, document.context);
|
|
573
|
+
if (expressions) {
|
|
574
|
+
for (const e2 of expressions) {
|
|
575
|
+
if (matchClassNameExpression(e2, className, document)) {
|
|
576
|
+
return true;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
585
580
|
}
|
|
586
581
|
}
|
|
587
582
|
return false;
|
|
@@ -625,12 +620,6 @@ function includesClassName(value, className) {
|
|
|
625
620
|
}
|
|
626
621
|
return value.divide(/\s+/u).some((s) => className.match(s));
|
|
627
622
|
}
|
|
628
|
-
function withinTemplate(expr, document) {
|
|
629
|
-
var _a;
|
|
630
|
-
const templateBody = document.context.getSourceCode().ast.templateBody;
|
|
631
|
-
const templateRange = (_a = templateBody === null || templateBody === void 0 ? void 0 : templateBody.range) !== null && _a !== void 0 ? _a : [0, 0];
|
|
632
|
-
return (templateRange[0] <= expr.range[0] && expr.range[1] <= templateRange[1]);
|
|
633
|
-
}
|
|
634
623
|
function* iterateUnique(gen) {
|
|
635
624
|
const found = new Set();
|
|
636
625
|
for (const e of gen()) {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getReferenceExpressions = void 0;
|
|
4
|
+
const context_1 = require("../../context");
|
|
5
|
+
function getReferenceExpressions(expression, context) {
|
|
6
|
+
var _a, _b, _c, _d;
|
|
7
|
+
if (expression.type === "ConditionalExpression") {
|
|
8
|
+
const { consequent, alternate } = expression;
|
|
9
|
+
return [
|
|
10
|
+
...((_a = getReferenceExpressions(consequent, context)) !== null && _a !== void 0 ? _a : [consequent]),
|
|
11
|
+
...((_b = getReferenceExpressions(alternate, context)) !== null && _b !== void 0 ? _b : [alternate]),
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
if (expression.type === "LogicalExpression") {
|
|
15
|
+
const { left, right } = expression;
|
|
16
|
+
return [
|
|
17
|
+
...((_c = getReferenceExpressions(left, context)) !== null && _c !== void 0 ? _c : [left]),
|
|
18
|
+
...((_d = getReferenceExpressions(right, context)) !== null && _d !== void 0 ? _d : [right]),
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
if (expression.type !== "Identifier") {
|
|
22
|
+
return [expression];
|
|
23
|
+
}
|
|
24
|
+
if (!withinTemplate(expression, context)) {
|
|
25
|
+
return [expression];
|
|
26
|
+
}
|
|
27
|
+
const vueComponent = (0, context_1.getVueComponentContext)(context);
|
|
28
|
+
if (!vueComponent) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const props = vueComponent.findVueComponentProperty(expression.name);
|
|
32
|
+
if (props == null) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return props;
|
|
36
|
+
}
|
|
37
|
+
exports.getReferenceExpressions = getReferenceExpressions;
|
|
38
|
+
function withinTemplate(expr, context) {
|
|
39
|
+
var _a;
|
|
40
|
+
const templateBody = context.getSourceCode().ast.templateBody;
|
|
41
|
+
const templateRange = (_a = templateBody === null || templateBody === void 0 ? void 0 : templateBody.range) !== null && _a !== void 0 ? _a : [0, 0];
|
|
42
|
+
return templateRange[0] <= expr.range[0] && expr.range[1] <= templateRange[1];
|
|
43
|
+
}
|
|
@@ -59,9 +59,7 @@ class CSSSelectorResolver {
|
|
|
59
59
|
return resolved;
|
|
60
60
|
}
|
|
61
61
|
isIgnoreNode(node) {
|
|
62
|
-
return ((0, css_nodes_1.isVCSSAtRule)(node) &&
|
|
63
|
-
node.name === "keyframes" &&
|
|
64
|
-
node.identifier === "@");
|
|
62
|
+
return ((0, css_nodes_1.isVCSSAtRule)(node) && node.name === "keyframes" && node.identifier === "@");
|
|
65
63
|
}
|
|
66
64
|
resolveNestingSelectors(owner, selectorNodes, parentSelectors, container) {
|
|
67
65
|
if ((0, selectors_1.isNestingAtRule)(container)) {
|
|
@@ -134,9 +132,7 @@ class CSSSelectorResolver {
|
|
|
134
132
|
const needJoinLeft = maybeJoinLeft && (0, selectors_1.isTypeSelector)(parentSelector[0]);
|
|
135
133
|
const needJoinRight = maybeJoinRight &&
|
|
136
134
|
!(0, selectors_1.isSelectorCombinator)(parentSelector[parentSelector.length - 1]);
|
|
137
|
-
if (needJoinLeft &&
|
|
138
|
-
needJoinRight &&
|
|
139
|
-
parentSelector.length === 1) {
|
|
135
|
+
if (needJoinLeft && needJoinRight && parentSelector.length === 1) {
|
|
140
136
|
before.push(newNestingConcatBothSelectorNodes(before.pop(), parentSelector.shift(), after.shift(), nestingNode));
|
|
141
137
|
}
|
|
142
138
|
else {
|
|
@@ -182,11 +178,7 @@ class CSSSelectorResolver {
|
|
|
182
178
|
resolved = resolved.map((selector) => {
|
|
183
179
|
const newNode = parent.copy();
|
|
184
180
|
newNode.nodes = selector.selector;
|
|
185
|
-
return new ResolvedSelector(owner, [
|
|
186
|
-
...before,
|
|
187
|
-
newNode,
|
|
188
|
-
...after,
|
|
189
|
-
]);
|
|
181
|
+
return new ResolvedSelector(owner, [...before, newNode, ...after]);
|
|
190
182
|
});
|
|
191
183
|
nestingTargetNode = parent;
|
|
192
184
|
}
|
|
@@ -49,7 +49,7 @@ function normalizePseudoParams(pseudo, nodes) {
|
|
|
49
49
|
}
|
|
50
50
|
exports.normalizePseudoParams = normalizePseudoParams;
|
|
51
51
|
function isVueSpecialPseudo(node) {
|
|
52
|
-
return
|
|
52
|
+
return isVDeepPseudo(node) || isVSlottedPseudo(node) || isVGlobalPseudo(node);
|
|
53
53
|
}
|
|
54
54
|
exports.isVueSpecialPseudo = isVueSpecialPseudo;
|
|
55
55
|
function isVDeepPseudoV2(node) {
|
package/dist/utils/rules.js
CHANGED
|
@@ -62,6 +62,21 @@ const baseRules = [
|
|
|
62
62
|
ruleName: "require-v-slotted-argument",
|
|
63
63
|
ruleId: "vue-scoped-css/require-v-slotted-argument",
|
|
64
64
|
},
|
|
65
|
+
{
|
|
66
|
+
rule: require("../rules/v-deep-pseudo-style"),
|
|
67
|
+
ruleName: "v-deep-pseudo-style",
|
|
68
|
+
ruleId: "vue-scoped-css/v-deep-pseudo-style",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
rule: require("../rules/v-global-pseudo-style"),
|
|
72
|
+
ruleName: "v-global-pseudo-style",
|
|
73
|
+
ruleId: "vue-scoped-css/v-global-pseudo-style",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
rule: require("../rules/v-slotted-pseudo-style"),
|
|
77
|
+
ruleName: "v-slotted-pseudo-style",
|
|
78
|
+
ruleId: "vue-scoped-css/v-slotted-pseudo-style",
|
|
79
|
+
},
|
|
65
80
|
];
|
|
66
81
|
exports.rules = baseRules.map((obj) => {
|
|
67
82
|
const rule = obj.rule;
|
package/package.json
CHANGED
|
@@ -1,122 +1,130 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
2
|
+
"name": "eslint-plugin-vue-scoped-css",
|
|
3
|
+
"version": "2.4.0",
|
|
4
|
+
"description": "ESLint plugin for Scoped CSS in Vue.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"prebuild": "npm run -s clean",
|
|
8
|
+
"build": "tsc --project ./tsconfig.build.json",
|
|
9
|
+
"clean": "rimraf .nyc_output dist coverage",
|
|
10
|
+
"lint": "eslint . --ext .js,.vue,.ts,.json",
|
|
11
|
+
"eslint-fix": "eslint . --ext .js,.vue,.ts,.json --fix",
|
|
12
|
+
"pretest": "npm run build",
|
|
13
|
+
"test:base": "mocha --require ts-node/register \"tests/**/*.ts\" --reporter dot --timeout 60000",
|
|
14
|
+
"test": "npm run test:nyc",
|
|
15
|
+
"test:nyc": "nyc --reporter=lcov npm run test:base",
|
|
16
|
+
"test:debug": "mocha --require ts-node/register/transpile-only \"tests/**/*.ts\" --reporter dot",
|
|
17
|
+
"test:watch": "npm run test:base -- --watch",
|
|
18
|
+
"update": "ts-node ./tools/update.ts && npm run eslint-fix && npm run test:nyc",
|
|
19
|
+
"new": "ts-node ./tools/new-rule.ts",
|
|
20
|
+
"docs:watch": "npm run vuepress -- dev --debug docs",
|
|
21
|
+
"docs:build": "npm run build && npm run vuepress -- build docs --no-cache",
|
|
22
|
+
"vuepress": "node --openssl-legacy-provider ./node_modules/vuepress/cli.js",
|
|
23
|
+
"preversion": "npm test && npm run update && git add .",
|
|
24
|
+
"version": "npm run lint -- --fix && git add .",
|
|
25
|
+
"version:ci": "npm run update && changeset version",
|
|
26
|
+
"prerelease": "npm run build",
|
|
27
|
+
"release": "changeset publish",
|
|
28
|
+
"updatefixture": "cross-env UPDATE_FIXTURE=\"true\" npm run test:base"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/future-architect/eslint-plugin-vue-scoped-css.git"
|
|
33
|
+
},
|
|
34
|
+
"author": "Yosuke Ota",
|
|
35
|
+
"funding": "https://github.com/sponsors/ota-meshi",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/future-architect/eslint-plugin-vue-scoped-css/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://future-architect.github.io/eslint-plugin-vue-scoped-css/",
|
|
41
|
+
"keywords": [
|
|
42
|
+
"eslint",
|
|
43
|
+
"eslintplugin",
|
|
44
|
+
"eslint-plugin",
|
|
45
|
+
"vue",
|
|
46
|
+
"style",
|
|
47
|
+
"scoped",
|
|
48
|
+
"css"
|
|
49
|
+
],
|
|
50
|
+
"files": [
|
|
51
|
+
"dist"
|
|
52
|
+
],
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@changesets/cli": "^2.24.2",
|
|
55
|
+
"@ota-meshi/eslint-plugin": "^0.13.0",
|
|
56
|
+
"@svitejs/changesets-changelog-github-compact": "^1.1.0",
|
|
57
|
+
"@types/eslint": "^8.0.0",
|
|
58
|
+
"@types/eslint-visitor-keys": "^1.0.0",
|
|
59
|
+
"@types/estree": "^1.0.0",
|
|
60
|
+
"@types/lodash": "^4.14.158",
|
|
61
|
+
"@types/mocha": "^10.0.0",
|
|
62
|
+
"@types/semver": "^7.3.1",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^5.49.0",
|
|
64
|
+
"@typescript-eslint/parser": "^5.49.0",
|
|
65
|
+
"cross-env": "^7.0.2",
|
|
66
|
+
"eslint": "^8.0.0",
|
|
67
|
+
"eslint-config-prettier": "^8.0.0",
|
|
68
|
+
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
69
|
+
"eslint-plugin-eslint-plugin": "^5.0.0",
|
|
70
|
+
"eslint-plugin-json-schema-validator": "^4.0.0",
|
|
71
|
+
"eslint-plugin-jsonc": "^2.0.0",
|
|
72
|
+
"eslint-plugin-node": "^11.1.0",
|
|
73
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
74
|
+
"eslint-plugin-regexp": "^1.0.0",
|
|
75
|
+
"eslint-plugin-vue": "^9.0.0",
|
|
76
|
+
"eslint-plugin-vue-scoped-css": "^2.0.0",
|
|
77
|
+
"eslint-plugin-yml": "^1.0.0",
|
|
78
|
+
"mocha": "^10.0.0",
|
|
79
|
+
"nyc": "^15.1.0",
|
|
80
|
+
"pack": "^2.2.0",
|
|
81
|
+
"prettier": "^2.0.5",
|
|
82
|
+
"raw-loader": "^4.0.1",
|
|
83
|
+
"rimraf": "^3.0.2",
|
|
84
|
+
"semver": "^7.3.2",
|
|
85
|
+
"stylelint": "^14.9.1",
|
|
86
|
+
"stylelint-config-recommended-vue": "^1.1.0",
|
|
87
|
+
"stylelint-config-standard": "^29.0.0",
|
|
88
|
+
"stylelint-stylus": "^0.17.0",
|
|
89
|
+
"ts-node": "^10.9.1",
|
|
90
|
+
"typescript": "^4.9.4",
|
|
91
|
+
"vue-eslint-editor": "^1.1.0",
|
|
92
|
+
"vue-eslint-parser": "^9.0.0",
|
|
93
|
+
"vuepress": "^1.8.2"
|
|
94
|
+
},
|
|
95
|
+
"dependencies": {
|
|
96
|
+
"eslint-utils": "^3.0.0",
|
|
97
|
+
"lodash": "^4.17.21",
|
|
98
|
+
"postcss": "^8.4.6",
|
|
99
|
+
"postcss-safe-parser": "^6.0.0",
|
|
100
|
+
"postcss-scss": "^4.0.3",
|
|
101
|
+
"postcss-selector-parser": "^6.0.9",
|
|
102
|
+
"postcss-styl": "^0.12.0"
|
|
103
|
+
},
|
|
104
|
+
"peerDependencies": {
|
|
105
|
+
"eslint": ">=5.0.0",
|
|
106
|
+
"vue-eslint-parser": ">=7.1.0"
|
|
107
|
+
},
|
|
108
|
+
"nyc": {
|
|
109
|
+
"include": [
|
|
110
|
+
"lib/*.ts",
|
|
111
|
+
"lib/**/*.ts"
|
|
45
112
|
],
|
|
46
|
-
"
|
|
47
|
-
|
|
113
|
+
"extension": [
|
|
114
|
+
".ts"
|
|
48
115
|
],
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"eslint-plugin-eslint-plugin": "^4.0.0",
|
|
64
|
-
"eslint-plugin-internal-rules": "file:./eslint-internal-rules",
|
|
65
|
-
"eslint-plugin-json-schema-validator": "^2.0.0",
|
|
66
|
-
"eslint-plugin-jsonc": "^2.0.0",
|
|
67
|
-
"eslint-plugin-node": "^11.1.0",
|
|
68
|
-
"eslint-plugin-prettier": "^4.0.0",
|
|
69
|
-
"eslint-plugin-regexp": "^1.0.0",
|
|
70
|
-
"eslint-plugin-vue": "^8.0.0",
|
|
71
|
-
"eslint-plugin-vue-scoped-css": "^2.0.0",
|
|
72
|
-
"eslint-plugin-yml": "^0.13.0",
|
|
73
|
-
"mocha": "^9.1.2",
|
|
74
|
-
"nyc": "^15.1.0",
|
|
75
|
-
"pack": "^2.2.0",
|
|
76
|
-
"prettier": "^2.0.5",
|
|
77
|
-
"raw-loader": "^4.0.1",
|
|
78
|
-
"rimraf": "^3.0.2",
|
|
79
|
-
"semver": "^7.3.2",
|
|
80
|
-
"stylelint": "^14.0.0",
|
|
81
|
-
"stylelint-config-recommended-vue": "^1.1.0",
|
|
82
|
-
"stylelint-config-standard": "^24.0.0",
|
|
83
|
-
"stylelint-plugin-stylus": "^0.13.0",
|
|
84
|
-
"ts-node": "^10.0.0",
|
|
85
|
-
"typescript": "^4.1.3",
|
|
86
|
-
"vue-eslint-editor": "^1.1.0",
|
|
87
|
-
"vue-eslint-parser": "^8.0.0",
|
|
88
|
-
"vuepress": "^1.8.2"
|
|
89
|
-
},
|
|
90
|
-
"dependencies": {
|
|
91
|
-
"eslint-utils": "^3.0.0",
|
|
92
|
-
"lodash": "^4.17.21",
|
|
93
|
-
"postcss": "^8.4.6",
|
|
94
|
-
"postcss-safe-parser": "^6.0.0",
|
|
95
|
-
"postcss-scss": "^4.0.3",
|
|
96
|
-
"postcss-selector-parser": "^6.0.9",
|
|
97
|
-
"postcss-styl": "^0.9.0"
|
|
98
|
-
},
|
|
99
|
-
"peerDependencies": {
|
|
100
|
-
"eslint": ">=5.0.0",
|
|
101
|
-
"vue-eslint-parser": ">=7.1.0"
|
|
102
|
-
},
|
|
103
|
-
"nyc": {
|
|
104
|
-
"include": [
|
|
105
|
-
"lib/*.ts",
|
|
106
|
-
"lib/**/*.ts"
|
|
107
|
-
],
|
|
108
|
-
"extension": [
|
|
109
|
-
".ts"
|
|
110
|
-
],
|
|
111
|
-
"require": [
|
|
112
|
-
"ts-node/register"
|
|
113
|
-
],
|
|
114
|
-
"exclude": [
|
|
115
|
-
"**/*.spec.js",
|
|
116
|
-
"tests/**/*.js"
|
|
117
|
-
]
|
|
118
|
-
},
|
|
119
|
-
"engines": {
|
|
120
|
-
"node": "^12.22 || ^14.17 || >=16"
|
|
121
|
-
}
|
|
116
|
+
"require": [
|
|
117
|
+
"ts-node/register"
|
|
118
|
+
],
|
|
119
|
+
"exclude": [
|
|
120
|
+
"**/*.spec.js",
|
|
121
|
+
"tests/**/*.js"
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
"engines": {
|
|
125
|
+
"node": "^12.22 || ^14.17 || >=16"
|
|
126
|
+
},
|
|
127
|
+
"publishConfig": {
|
|
128
|
+
"access": "public"
|
|
129
|
+
}
|
|
122
130
|
}
|