New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add function-name-arguments-allowed-list #4816
Changes from 1 commit
3c97e71
a64ee6d
27c276e
8d63a48
3b3de22
a118c99
28b4213
907513a
45afff9
2f06e7a
e74c8c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# function-name-arguments-whitelist | ||
|
||
Specify a whitelist of allowed property and value pairs within declarations. | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { text-transform: uppercase; } | ||
/** ↑ ↑ | ||
* These properties and these values */ | ||
``` | ||
|
||
## Options | ||
|
||
`object`: `{"unprefixed-function-name": ["string", "/regex/", /regex/] }` | ||
|
||
If a property name is found in the object, only its whitelisted property values are allowed. This rule complains about all non-matching values. (If the property name is not included in the object, anything goes.) | ||
|
||
If a property name is surrounded with `"/"` (e.g. `"/^animation/"`), it is interpreted as a regular expression. This allows, for example, easy targeting of shorthands: `/^animation/` will match `animation`, `animation-duration`, `animation-timing-function`, etc. | ||
|
||
The same goes for values. Keep in mind that a regular expression value is matched against the entire value of the declaration, not specific parts of it. For example, a value like `"10px solid rgba( 255 , 0 , 0 , 0.5 )"` will _not_ match `"/^solid/"` (notice beginning of the line boundary) but _will_ match `"/\\s+solid\\s+/"` or `"/\\bsolid\\b/"`. | ||
|
||
Be careful with regex matching not to accidentally consider quoted string values and `url()` arguments. For example, `"/red/"` will match value such as `"1px dotted red"` as well as `"\"red\""` and `"white url(/mysite.com/red.png)"`. | ||
|
||
Given: | ||
|
||
``` | ||
{ | ||
"transform": ["/scale/"], | ||
"whitespace": ["nowrap"], | ||
"/color/": ["/^green/"] | ||
} | ||
``` | ||
|
||
The following patterns are considered violations: | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { whitespace: pre; } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { transform: translate(1, 1); } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { -webkit-transform: translate(1, 1); } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { color: pink; } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { background-color: pink; } | ||
``` | ||
|
||
The following patterns are _not_ considered violations: | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { color: pink; } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { whitespace: nowrap; } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { transform: scale(1, 1); } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { -webkit-transform: scale(1, 1); } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { color: green; } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { background-color: green; } | ||
``` | ||
|
||
<!-- prettier-ignore --> | ||
```css | ||
a { background: pink; } | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
'use strict'; | ||
|
||
const { messages, ruleName } = require('..'); | ||
|
||
testRule({ | ||
ruleName, | ||
|
||
config: [ | ||
{ | ||
transform: ['/scale/'], | ||
whitespace: ['nowrap'], | ||
'/color/': ['/^green/'], | ||
}, | ||
], | ||
|
||
accept: [ | ||
{ | ||
code: 'div { whitespace: nowrap; }', | ||
}, | ||
{ | ||
code: 'a { transform: scale(1, 1); }', | ||
}, | ||
{ | ||
code: 'a { -webkit-transform: scale(1, 1); }', | ||
}, | ||
{ | ||
code: 'a { color: green; }', | ||
}, | ||
{ | ||
code: 'a { background-color: green; }', | ||
}, | ||
], | ||
|
||
reject: [ | ||
{ | ||
code: 'div { whitespace: pre; }', | ||
message: messages.rejected('whitespace', 'pre'), | ||
line: 1, | ||
column: 7, | ||
}, | ||
{ | ||
code: 'a { transform: translate(1, 1); }', | ||
message: messages.rejected('transform', 'translate(1, 1)'), | ||
line: 1, | ||
column: 5, | ||
}, | ||
{ | ||
code: 'a { -webkit-transform: translate(1, 1); }', | ||
message: messages.rejected('-webkit-transform', 'translate(1, 1)'), | ||
line: 1, | ||
column: 5, | ||
}, | ||
{ | ||
code: 'a { color: pink; }', | ||
message: messages.rejected('color', 'pink'), | ||
line: 1, | ||
column: 5, | ||
}, | ||
{ | ||
code: 'a { background-color: pink; }', | ||
message: messages.rejected('background-color', 'pink'), | ||
line: 1, | ||
column: 5, | ||
}, | ||
], | ||
}); | ||
|
||
testRule({ | ||
ruleName, | ||
config: { position: ['static'] }, | ||
skipBasicChecks: true, | ||
accept: [ | ||
{ | ||
code: 'a { font-size: 1em; }', | ||
description: 'irrelevant CSS', | ||
}, | ||
], | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// @ts-nocheck | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should use the {
"rules": {
"function-name-arguments-whitelist": {
"url": ["/^images/", "^fonts/"],
"blur": ["50%"]
}
}
}
The |
||
|
||
'use strict'; | ||
|
||
const _ = require('lodash'); | ||
const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); | ||
const postcss = require('postcss'); | ||
const report = require('../../utils/report'); | ||
const ruleMessages = require('../../utils/ruleMessages'); | ||
const validateOptions = require('../../utils/validateOptions'); | ||
|
||
const ruleName = 'function-name-arguments-whitelist'; | ||
|
||
const messages = ruleMessages(ruleName, { | ||
rejected: (property, value) => `Unexpected arguments "${value}" for function "${property}"`, | ||
}); | ||
|
||
function rule(whitelist) { | ||
return (root, result) => { | ||
const validOptions = validateOptions(result, ruleName, { | ||
actual: whitelist, | ||
possible: [_.isObject], | ||
}); | ||
|
||
if (!validOptions) { | ||
return; | ||
} | ||
|
||
root.walkDecls((decl) => { | ||
const prop = decl.prop; | ||
const value = decl.value; | ||
|
||
const unprefixedProp = postcss.vendor.unprefixed(prop); | ||
const propWhitelist = _.find(whitelist, (list, propIdentifier) => | ||
matchesStringOrRegExp(unprefixedProp, propIdentifier), | ||
); | ||
|
||
if (_.isEmpty(propWhitelist)) { | ||
return; | ||
} | ||
|
||
if (matchesStringOrRegExp(value, propWhitelist)) { | ||
return; | ||
} | ||
|
||
report({ | ||
message: messages.rejected(prop, value), | ||
node: decl, | ||
result, | ||
ruleName, | ||
}); | ||
}); | ||
}; | ||
} | ||
|
||
rule.ruleName = ruleName; | ||
rule.messages = messages; | ||
module.exports = rule; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your best next step is to change the tests so they align with the intended behaviour of the rule. I suggest starting with:
The config is saying:
brightness
function the parameters can only be50%
url
the parameters must start with eitherimages
orvendor
Then there are
accept
andreject
test cases for this config.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should validate against the background this contains either base64 string or URL function.
If URL present means have to validate starts with strings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rule isn't concerned with the type of arguments. It should always treat the arguments as a string for comparsion.