@mrhenry/stylelint-mrhenry-nesting 3.0.1 → 3.1.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/index.mjs +37 -0
- package/package.json +4 -3
package/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import stylelint from 'stylelint';
|
|
2
2
|
import selectorParser from 'postcss-selector-parser';
|
|
3
|
+
import { compare, selectorSpecificity } from '@csstools/selector-specificity';
|
|
3
4
|
|
|
4
5
|
const ruleName = "@mrhenry/stylelint-mrhenry-nesting";
|
|
5
6
|
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
@@ -18,6 +19,9 @@ const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
|
18
19
|
rejectedNestingSelectorIncorrectShape: () => {
|
|
19
20
|
return `Nested selectors must be compound selectors, starting with "&" and followed by a single pseudo selector.`;
|
|
20
21
|
},
|
|
22
|
+
rejectedMixedSpecificity: () => {
|
|
23
|
+
return `Each selector of a list in a nested context take the specificity of the most specific list item. This can lead to unexpected results.`;
|
|
24
|
+
},
|
|
21
25
|
});
|
|
22
26
|
|
|
23
27
|
const meta = {
|
|
@@ -101,6 +105,39 @@ const ruleFunction = (primaryOption, secondaryOption, context) => {
|
|
|
101
105
|
});
|
|
102
106
|
});
|
|
103
107
|
|
|
108
|
+
postcssRoot.walkRules((rule) => {
|
|
109
|
+
const containsBlocks = rule.nodes && rule.nodes.some((node) => node.type === 'rule' || node.type === 'atrule');
|
|
110
|
+
if (!containsBlocks) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const selectorAST = selectorParser().astSync(rule.selector);
|
|
115
|
+
if (selectorAST.nodes?.length < 2) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const specificities = selectorAST.nodes.map((node) => {
|
|
120
|
+
return selectorSpecificity(node);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const specificitiesAreEqual = specificities.every((specificity) => {
|
|
124
|
+
return compare(specificity, specificities[0]) === 0;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
if (specificitiesAreEqual) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
stylelint.utils.report({
|
|
132
|
+
message: messages.rejectedMixedSpecificity(),
|
|
133
|
+
node: rule,
|
|
134
|
+
index: 0,
|
|
135
|
+
endIndex: rule.selector.length,
|
|
136
|
+
result: postcssResult,
|
|
137
|
+
ruleName,
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
104
141
|
postcssRoot.walkRules((rule) => {
|
|
105
142
|
{
|
|
106
143
|
let rulesDepth = 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrhenry/stylelint-mrhenry-nesting",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Mr. Henry's preferred way of writing nested CSS",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -28,12 +28,13 @@
|
|
|
28
28
|
"stylelint-plugin"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"
|
|
31
|
+
"@csstools/selector-specificity": "^3.0.1",
|
|
32
|
+
"postcss-selector-parser": "^6.0.15"
|
|
32
33
|
},
|
|
33
34
|
"peerDependencies": {
|
|
34
35
|
"stylelint": "^16.0.0"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
|
-
"stylelint": "^16.0
|
|
38
|
+
"stylelint": "^16.1.0"
|
|
38
39
|
}
|
|
39
40
|
}
|