Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #351 from rambleraptor/at-rule-no-parentheses
New rule: at-conditional-rule-no-parentheses
- Loading branch information
Showing
4 changed files
with
172 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# at-rule-conditional-no-parentheses | ||
|
||
Disallow parentheses in conditional @ rules (if, elsif, while) | ||
|
||
```css | ||
@if (true) {} | ||
/** ↑ ↑ | ||
* Get rid of parentheses like this. */ | ||
``` | ||
|
||
|
||
|
||
## Options | ||
|
||
### `true` | ||
|
||
The following patterns are considered warnings: | ||
|
||
```scss | ||
@if(true) | ||
``` | ||
|
||
```scss | ||
@else if(true) | ||
``` | ||
|
||
```scss | ||
@while(true) | ||
``` | ||
|
||
The following patterns are *not* considered warnings: | ||
|
||
```scss | ||
@if true | ||
``` | ||
|
||
```scss | ||
@else if true | ||
``` | ||
|
||
```scss | ||
@while true | ||
``` |
57 changes: 57 additions & 0 deletions
57
src/rules/at-rule-conditional-no-parentheses/__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,57 @@ | ||
import rule, { ruleName, messages } from ".."; | ||
|
||
testRule(rule, { | ||
ruleName, | ||
config: [true], | ||
syntax: "scss", | ||
fix: true, | ||
|
||
accept: [ | ||
{ | ||
code: "@if true {}", | ||
description: "accepts @if with no parentheses" | ||
}, | ||
{ | ||
code: "@if (1 + 1) == 2 {}", | ||
description: "accepts parentheses statement where () used for math" | ||
}, | ||
{ | ||
code: "@while true {}", | ||
description: "accepts @while with no parentheses" | ||
}, | ||
{ | ||
code: `@if true {} | ||
@else if true {}`, | ||
description: "accepts @else if with no parentheses" | ||
}, | ||
{ | ||
code: `@if true {} | ||
@else if true {} | ||
@else {}`, | ||
description: "accepts @else unconditionally" | ||
} | ||
], | ||
|
||
reject: [ | ||
{ | ||
code: "@if(true) {}", | ||
fixed: "@if true {}", | ||
message: messages.rejected, | ||
description: "does not accept @if with parentheses" | ||
}, | ||
{ | ||
code: "@while(true) {}", | ||
fixed: "@while true {}", | ||
message: messages.rejected, | ||
description: "does not accept @while with parentheses" | ||
}, | ||
{ | ||
code: `@if true {} | ||
@else if(true) {}`, | ||
fixed: `@if true {} | ||
@else if true {}`, | ||
message: messages.rejected, | ||
description: "does not accept @else if with parentheses" | ||
} | ||
] | ||
}); |
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,70 @@ | ||
import { utils } from "stylelint"; | ||
import { namespace } from "../../utils"; | ||
import _ from "lodash"; | ||
|
||
export const ruleName = namespace("at-rule-conditional-no-parentheses"); | ||
|
||
export const messages = utils.ruleMessages(ruleName, { | ||
rejected: "Unexpected () used to surround statements for @-rules" | ||
}); | ||
|
||
// postcss picks up else-if as else. | ||
const conditional_rules = ["if", "while", "else"]; | ||
|
||
function report(atrule, result) { | ||
utils.report({ | ||
message: messages.rejected, | ||
node: atrule, | ||
result, | ||
ruleName | ||
}); | ||
} | ||
|
||
function fix(atrule) { | ||
const regex = /(if)? ?\((.*)\)/; | ||
|
||
// 2 regex groups: 'if ' and cond. | ||
const groups = atrule.params.match(regex).slice(1); | ||
|
||
atrule.params = _.uniq(groups).join(" "); | ||
} | ||
|
||
export default function(primary, _unused, context) { | ||
return (root, result) => { | ||
const validOptions = utils.validateOptions(result, ruleName, { | ||
actual: primary | ||
}); | ||
|
||
if (!validOptions) { | ||
return; | ||
} | ||
|
||
root.walkAtRules(atrule => { | ||
// Check if this is a conditional rule. | ||
if (!_.includes(conditional_rules, atrule.name)) { | ||
return; | ||
} | ||
|
||
// Else uses a different regex | ||
// params are of format "`if (cond)` or `if cond` | ||
// instead of `(cond)` or `cond`" | ||
if (atrule.name === "else") { | ||
if (atrule.params.match(/ ?if ?\(.*\) ?$/)) { | ||
if (context.fix) { | ||
fix(atrule); | ||
} else { | ||
report(atrule, result); | ||
} | ||
} | ||
} else { | ||
if (atrule.params.match(/ ?\(.*\) ?$/)) { | ||
if (context.fix) { | ||
fix(atrule); | ||
} else { | ||
report(atrule, result); | ||
} | ||
} | ||
} | ||
}); | ||
}; | ||
} |
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