Skip to content

Commit c5cc0ec

Browse files
committed
Try adding a new linter rule to prevent leaky selectors
1 parent 5a9af29 commit c5cc0ec

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

.stylelintrc.yml

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
extends:
22
- stylelint-config-css-modules
33
- stylelint-config-sass-guidelines
4+
plugins:
5+
- ./ember-osf-web-stylelint
46
rules:
57
indentation: 4
68
max-nesting-depth: 2
@@ -13,3 +15,4 @@ rules:
1315
- ignoreProperties:
1416
- composes
1517
- compose-with
18+
ember-osf-web-stylelint-plugin/no-unlocalized-selectors: true

ember-osf-web-stylelint.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// eslint-disable @typescript-eslin/no-var-requires
2+
const stylelint = require('stylelint');
3+
4+
/*
5+
* This rule prevents the use of bare element selectors in CSS
6+
* Bare element selectors are selectors that are not wrapped in or paired with a class or id
7+
*/
8+
9+
const ruleName = 'ember-osf-web-stylelint-plugin/no-unlocalized-selectors';
10+
const messages = stylelint.utils.ruleMessages(ruleName, {
11+
expected: selector => `Rule "${selector}" should be wrapped in or paired with a local-class or ID`,
12+
});
13+
14+
module.exports = stylelint.createPlugin(ruleName, _ =>
15+
(postcssRoot, postcssResult) => {
16+
postcssRoot.walkRules(rule => {
17+
const selector = rule.selector;
18+
const isChildRule = rule.parent.type === 'rule'; // top-level rules have rule.parent.type === 'root'
19+
const hasGlobal = selector.includes(':global');
20+
if (
21+
isChildRule ||
22+
(!hasGlobal && (selector.includes('.') || selector.includes('#'))) // has a local-class or local-id
23+
) {
24+
return;
25+
}
26+
27+
if (
28+
/^[a-z]+/.test(selector) || // starts with a letter
29+
/^:global\([a-z]+/.test(selector) // or starts with :global
30+
) {
31+
stylelint.utils.report({
32+
ruleName,
33+
result: postcssResult,
34+
message: messages.expected(selector),
35+
node: rule,
36+
});
37+
}
38+
});
39+
});
40+
41+
module.exports.ruleName = ruleName;
42+
module.exports.messages = messages;

0 commit comments

Comments
 (0)