-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
scss/function-no-unknown
rule (#591)
* Add `scss/function-no-unknown` rule * Update functions list * Update functions list * npm i github:stylelint/stylelint#bump-css-functions-list * git+https * Revert "git+https" This reverts commit f70c826. * Revert "npm i github:stylelint/stylelint#bump-css-functions-list" This reverts commit a38124c. * Update lockfile * Bump stylelint to 14.5.1 * Add reject case for unknown SCSS function * Add more accept cases
- Loading branch information
1 parent
2c4285e
commit 03af755
Showing
8 changed files
with
654 additions
and
134 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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,64 @@ | ||
# function-no-unknown | ||
|
||
Disallow unknown functions. Should be used **instead of** Stylelint's [function-no-unknown](https://stylelint.io/user-guide/rules/list/at-rule-no-unknown). | ||
|
||
```css | ||
a { color: unknown(1); } | ||
/** ↑ | ||
* Functions like this */ | ||
``` | ||
|
||
This rule is basically a wrapper around the mentioned core rule. You must disable Stylelint's core rule to make this rule work: | ||
|
||
```json | ||
{ | ||
"rules": { | ||
"function-no-unknown": null, | ||
"scss/function-no-unknown": true | ||
} | ||
} | ||
``` | ||
|
||
## Options | ||
|
||
### `true` | ||
|
||
The following patterns are considered warnings: | ||
|
||
```css | ||
a { color: unknown(1); } | ||
``` | ||
|
||
The following patterns are *not* considered warnings: | ||
|
||
```css | ||
a { color: hsl(240 100% 50%); } | ||
``` | ||
|
||
```css | ||
a { color: if(true, green, red); } | ||
``` | ||
|
||
## Optional secondary options | ||
|
||
### `ignoreFunctions: ["/regex/", /regex/, "non-regex"]` | ||
|
||
Given: | ||
|
||
```json | ||
["/^my-/i", "foo"] | ||
``` | ||
|
||
The following patterns are *not* considered warnings: | ||
|
||
```css | ||
a { color: my-func(1); } | ||
``` | ||
|
||
```css | ||
a { color: MY-FUNC(1); } | ||
``` | ||
|
||
```css | ||
a { color: foo(1); } | ||
``` |
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,85 @@ | ||
import { ruleName, messages } from ".."; | ||
|
||
testRule({ | ||
ruleName, | ||
config: [true], | ||
customSyntax: "postcss-scss", | ||
|
||
accept: [ | ||
{ | ||
code: "a { color: hwb(240 100% 50%); }", | ||
description: "Normal CSS function" | ||
}, | ||
{ | ||
code: "a { color: hsl(240 100% 50%); }", | ||
description: "Function both in CSS and SCSS" | ||
}, | ||
{ | ||
code: "a { color: if(true, green, red); }", | ||
description: "SCSS function" | ||
}, | ||
{ | ||
code: "a { color: adjust-color(#6b717f, $red: 15); }" | ||
}, | ||
{ | ||
code: "a { color: color.adjust(#6b717f, $red: 15); }" | ||
} | ||
], | ||
|
||
reject: [ | ||
{ | ||
code: "a { color: unknown(1); }", | ||
message: messages.rejected("unknown"), | ||
line: 1, | ||
column: 12 | ||
}, | ||
{ | ||
code: "a { color: color.unknown(#6b717f, $red: 15); }", | ||
message: messages.rejected("color.unknown"), | ||
line: 1, | ||
column: 12 | ||
} | ||
] | ||
}); | ||
|
||
testRule({ | ||
ruleName, | ||
config: [true, { ignoreFunctions: ["/^my-/i", /foo$/, "bar"] }], | ||
customSyntax: "postcss-scss", | ||
|
||
accept: [ | ||
{ | ||
code: "a { color: my-func(1); }" | ||
}, | ||
{ | ||
code: "a { color: MY-FUNC(1); }" | ||
}, | ||
{ | ||
code: "a { color: func-foo(1); }" | ||
}, | ||
{ | ||
code: "a { color: bar(1); }" | ||
} | ||
], | ||
|
||
reject: [ | ||
{ | ||
code: "a { color: my(1); }", | ||
message: messages.rejected("my"), | ||
line: 1, | ||
column: 12 | ||
}, | ||
{ | ||
code: "a { color: foo-func(1); }", | ||
message: messages.rejected("foo-func"), | ||
line: 1, | ||
column: 12 | ||
}, | ||
{ | ||
code: "a { color: barrr(1); }", | ||
message: messages.rejected("barrr"), | ||
line: 1, | ||
column: 12 | ||
} | ||
] | ||
}); |
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,77 @@ | ||
import { isRegExp, isString } from "lodash"; | ||
import { rules, utils } from "stylelint"; | ||
import valueParser from "postcss-value-parser"; | ||
import { namespace, ALL_FUNCTIONS } from "../../utils"; | ||
|
||
const ruleToCheckAgainst = "function-no-unknown"; | ||
|
||
export const ruleName = namespace(ruleToCheckAgainst); | ||
|
||
export const messages = utils.ruleMessages(ruleName, { | ||
rejected: (...args) => { | ||
return rules[ruleToCheckAgainst].messages | ||
.rejected(...args) | ||
.replace(` (${ruleToCheckAgainst})`, ""); | ||
} | ||
}); | ||
|
||
export default function rule(primaryOption, secondaryOptions) { | ||
return (root, result) => { | ||
const validOptions = utils.validateOptions( | ||
result, | ||
ruleName, | ||
{ | ||
actual: primaryOption | ||
}, | ||
{ | ||
actual: secondaryOptions, | ||
possible: { | ||
ignoreFunctions: [isString, isRegExp] | ||
}, | ||
optional: true | ||
} | ||
); | ||
|
||
if (!validOptions) { | ||
return; | ||
} | ||
|
||
const optionsFunctions = | ||
(secondaryOptions && secondaryOptions.ignoreFunctions) || []; | ||
const ignoreFunctions = ALL_FUNCTIONS.concat(optionsFunctions); | ||
const ignoreFunctionsAsSet = new Set(ignoreFunctions); | ||
const newSecondaryOptions = Object.assign({}, secondaryOptions, { | ||
ignoreFunctions | ||
}); | ||
|
||
utils.checkAgainstRule( | ||
{ | ||
ruleName: ruleToCheckAgainst, | ||
ruleSettings: [primaryOption, newSecondaryOptions], | ||
root | ||
}, | ||
warning => { | ||
const { node, index } = warning; | ||
|
||
// NOTE: Using `valueParser` is necessary for extracting a function name. This may be a performance waste. | ||
valueParser(node.value).walk(valueNode => { | ||
const { type, value: funcName } = valueNode; | ||
|
||
if (type !== "function") { | ||
return; | ||
} | ||
|
||
if (!ignoreFunctionsAsSet.has(funcName)) { | ||
utils.report({ | ||
message: messages.rejected(funcName), | ||
ruleName, | ||
result, | ||
node, | ||
index | ||
}); | ||
} | ||
}); | ||
} | ||
); | ||
}; | ||
} |
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
Oops, something went wrong.