-
-
Notifications
You must be signed in to change notification settings - Fork 930
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add selector-pseudo-element-*list rules (#3087)
- Loading branch information
Showing
12 changed files
with
541 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# selector-pseudo-element-blacklist | ||
|
||
Specify a blacklist of disallowed pseudo-element selectors. | ||
|
||
```css | ||
a::before {} | ||
/** ↑ | ||
* These pseudo-element selectors */ | ||
``` | ||
|
||
This rule ignores CSS2 pseudo-elements i.e. those prefixed with a single colon. | ||
|
||
This rule ignores selectors that use variable interpolation e.g. `::#{$variable} {}`. | ||
|
||
## Options | ||
|
||
`array|string|regex`: `["array", "of", "unprefixed", "pseudo-elements" or "regex"]|"pseudo-element"|/regex/` | ||
|
||
Given: | ||
|
||
```js | ||
["before", "/^my-/i"] | ||
``` | ||
|
||
The following patterns are considered violations: | ||
|
||
```css | ||
a::before {} | ||
``` | ||
|
||
```css | ||
a::my-pseudo-element {} | ||
``` | ||
|
||
```css | ||
a::MY-OTHER-pseudo-element {} | ||
``` | ||
|
||
|
||
The following patterns are *not* considered violations: | ||
|
||
```css | ||
a::after {} | ||
``` | ||
|
||
```css | ||
a::not-my-pseudo-element {} | ||
``` |
107 changes: 107 additions & 0 deletions
107
lib/rules/selector-pseudo-element-blacklist/__tests__/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
"use strict"; | ||
|
||
const messages = require("..").messages; | ||
const ruleName = require("..").ruleName; | ||
const rules = require("../../../rules"); | ||
|
||
const rule = rules[ruleName]; | ||
|
||
testRule(rule, { | ||
ruleName, | ||
config: ["before", "selection", /^my/i], | ||
skipBasicChecks: true, | ||
|
||
accept: [ | ||
{ | ||
code: "a {}" | ||
}, | ||
{ | ||
code: "a:hover {}" | ||
}, | ||
{ | ||
code: "a::BEFORE {}" | ||
}, | ||
{ | ||
code: "a::after {}" | ||
}, | ||
{ | ||
code: "::first-line {}" | ||
}, | ||
{ | ||
code: "::-webkit-first-line {}" | ||
}, | ||
{ | ||
code: "a:not(::first-line) {}" | ||
}, | ||
{ | ||
code: "a::their-pseudo-element {}" | ||
}, | ||
{ | ||
code: "a::THEIR-other-pseudo-element {}" | ||
} | ||
], | ||
|
||
reject: [ | ||
{ | ||
code: "a::before {}", | ||
message: messages.rejected("before"), | ||
line: 1, | ||
column: 2 | ||
}, | ||
{ | ||
code: "a,\nb::before {}", | ||
message: messages.rejected("before"), | ||
line: 2, | ||
column: 2 | ||
}, | ||
{ | ||
code: "::selection {}", | ||
message: messages.rejected("selection"), | ||
line: 1, | ||
column: 1 | ||
}, | ||
{ | ||
code: "::-webkit-selection {}", | ||
message: messages.rejected("-webkit-selection"), | ||
line: 1, | ||
column: 1 | ||
}, | ||
{ | ||
code: "a:not(::selection) {}", | ||
message: messages.rejected("selection"), | ||
line: 1, | ||
column: 7 | ||
}, | ||
{ | ||
code: "a::my-pseudo-element {}", | ||
message: messages.rejected("my-pseudo-element"), | ||
line: 1, | ||
column: 2 | ||
}, | ||
{ | ||
code: "a::MY-OTHER-pseudo-element {}", | ||
message: messages.rejected("MY-OTHER-pseudo-element"), | ||
line: 1, | ||
column: 2 | ||
} | ||
] | ||
}); | ||
|
||
testRule(rule, { | ||
ruleName, | ||
config: ["before"], | ||
skipBasicChecks: true, | ||
syntax: "scss", | ||
|
||
accept: [ | ||
{ | ||
code: "::#{$variable} {}" | ||
}, | ||
{ | ||
code: "::#{$VARIABLE} {}" | ||
}, | ||
{ | ||
code: "a::#{$variable} {}" | ||
} | ||
] | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
"use strict"; | ||
|
||
const _ = require("lodash"); | ||
const isStandardSyntaxRule = require("../../utils/isStandardSyntaxRule"); | ||
const isStandardSyntaxSelector = require("../../utils/isStandardSyntaxSelector"); | ||
const matchesStringOrRegExp = require("../../utils/matchesStringOrRegExp"); | ||
const parseSelector = require("../../utils/parseSelector"); | ||
const postcss = require("postcss"); | ||
const report = require("../../utils/report"); | ||
const ruleMessages = require("../../utils/ruleMessages"); | ||
const validateOptions = require("../../utils/validateOptions"); | ||
|
||
const ruleName = "selector-pseudo-element-blacklist"; | ||
|
||
const messages = ruleMessages(ruleName, { | ||
rejected: selector => `Unexpected pseudo-element "${selector}"` | ||
}); | ||
|
||
const rule = function(blacklist) { | ||
return (root, result) => { | ||
const validOptions = validateOptions(result, ruleName, { | ||
actual: blacklist, | ||
possible: [_.isString, _.isRegExp] | ||
}); | ||
if (!validOptions) { | ||
return; | ||
} | ||
|
||
root.walkRules(rule => { | ||
if (!isStandardSyntaxRule(rule)) { | ||
return; | ||
} | ||
|
||
const selector = rule.selector; | ||
|
||
if (!isStandardSyntaxSelector(selector)) { | ||
return; | ||
} | ||
|
||
if (selector.indexOf("::") === -1) { | ||
return; | ||
} | ||
|
||
parseSelector(selector, result, rule, selectorTree => { | ||
selectorTree.walkPseudos(pseudoNode => { | ||
const value = pseudoNode.value; | ||
|
||
// Ignore pseudo-classes | ||
if (value[1] !== ":") { | ||
return; | ||
} | ||
|
||
const name = value.slice(2); | ||
|
||
if ( | ||
!matchesStringOrRegExp(postcss.vendor.unprefixed(name), blacklist) | ||
) { | ||
return; | ||
} | ||
|
||
report({ | ||
index: pseudoNode.sourceIndex, | ||
message: messages.rejected(name), | ||
node: rule, | ||
result, | ||
ruleName | ||
}); | ||
}); | ||
}); | ||
}); | ||
}; | ||
}; | ||
|
||
rule.primaryOptionArray = true; | ||
|
||
rule.ruleName = ruleName; | ||
rule.messages = messages; | ||
module.exports = rule; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# selector-pseudo-element-whitelist | ||
|
||
Specify a whitelist of allowed pseudo-element selectors. | ||
|
||
```css | ||
a::before {} | ||
/** ↑ | ||
* These pseudo-element selectors */ | ||
``` | ||
|
||
This rule ignores CSS2 pseudo-elements i.e. those prefixed with a single colon. | ||
|
||
This rule ignores selectors that use variable interpolation e.g. `::#{$variable} {}`. | ||
|
||
## Options | ||
|
||
`array|string|regex`: `["array", "of", "unprefixed", "pseudo-elements" or "regex"]|"pseudo-element"|/regex/` | ||
|
||
Given: | ||
|
||
```js | ||
["before", "/^my-/i"] | ||
``` | ||
|
||
The following patterns are considered violations: | ||
|
||
```css | ||
a::after {} | ||
``` | ||
|
||
```css | ||
a::not-my-pseudo-element {} | ||
``` | ||
|
||
The following patterns are *not* considered violations: | ||
|
||
```css | ||
a::before {} | ||
``` | ||
|
||
```css | ||
a::my-pseudo-element {} | ||
``` | ||
|
||
```css | ||
a::MY-OTHER-pseudo-element {} | ||
``` |
Oops, something went wrong.