From 3c97e717a21208e83e8ba29c09df3a8167d46ade Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Mon, 1 Jun 2020 17:44:02 +0530 Subject: [PATCH 01/10] initial commit --- .../README.md | 96 +++++++++++++++++++ .../__tests__/index.js | 78 +++++++++++++++ .../index.js | 58 +++++++++++ 3 files changed, 232 insertions(+) create mode 100644 lib/rules/function-name-arguments-whitelist/README.md create mode 100644 lib/rules/function-name-arguments-whitelist/__tests__/index.js create mode 100644 lib/rules/function-name-arguments-whitelist/index.js diff --git a/lib/rules/function-name-arguments-whitelist/README.md b/lib/rules/function-name-arguments-whitelist/README.md new file mode 100644 index 0000000000..b1a081739c --- /dev/null +++ b/lib/rules/function-name-arguments-whitelist/README.md @@ -0,0 +1,96 @@ +# function-name-arguments-whitelist + +Specify a whitelist of allowed property and value pairs within declarations. + + +```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: + + +```css +a { whitespace: pre; } +``` + + +```css +a { transform: translate(1, 1); } +``` + + +```css +a { -webkit-transform: translate(1, 1); } +``` + + +```css +a { color: pink; } +``` + + +```css +a { background-color: pink; } +``` + +The following patterns are _not_ considered violations: + + +```css +a { color: pink; } +``` + + +```css +a { whitespace: nowrap; } +``` + + +```css +a { transform: scale(1, 1); } +``` + + +```css +a { -webkit-transform: scale(1, 1); } +``` + + +```css +a { color: green; } +``` + + +```css +a { background-color: green; } +``` + + +```css +a { background: pink; } +``` diff --git a/lib/rules/function-name-arguments-whitelist/__tests__/index.js b/lib/rules/function-name-arguments-whitelist/__tests__/index.js new file mode 100644 index 0000000000..a9bff2a2de --- /dev/null +++ b/lib/rules/function-name-arguments-whitelist/__tests__/index.js @@ -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', + }, + ], +}); diff --git a/lib/rules/function-name-arguments-whitelist/index.js b/lib/rules/function-name-arguments-whitelist/index.js new file mode 100644 index 0000000000..835858a200 --- /dev/null +++ b/lib/rules/function-name-arguments-whitelist/index.js @@ -0,0 +1,58 @@ +// @ts-nocheck + +'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; From a64ee6df302481607c83f76efed33386c91ea551 Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Tue, 2 Jun 2020 14:35:26 +0530 Subject: [PATCH 02/10] text case fix --- lib/rules/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/rules/index.js b/lib/rules/index.js index 241ce9fadf..af0f0a6435 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -145,6 +145,9 @@ const rules = { 'function-url-scheme-whitelist': importLazy(() => require('./function-url-scheme-whitelist'))(), 'function-whitelist': importLazy(() => require('./function-whitelist'))(), 'function-whitespace-after': importLazy(() => require('./function-whitespace-after'))(), + 'function-name-arguments-whitelist': importLazy(() => + require('./function-name-arguments-whitelist'), + )(), 'hue-degree-notation': importLazy(() => require('./hue-degree-notation'))(), 'keyframe-declaration-no-important': importLazy(() => require('./keyframe-declaration-no-important'), From 27c276e8a0c38905abd785945ac2c2f3e24ac75a Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Wed, 3 Jun 2020 11:41:36 +0530 Subject: [PATCH 03/10] function name argument functionality added --- .../README.md | 51 +++--------- .../__tests__/index.js | 77 +++++++++---------- .../index.js | 52 +++++++------ 3 files changed, 76 insertions(+), 104 deletions(-) diff --git a/lib/rules/function-name-arguments-whitelist/README.md b/lib/rules/function-name-arguments-whitelist/README.md index b1a081739c..00b7c6da84 100644 --- a/lib/rules/function-name-arguments-whitelist/README.md +++ b/lib/rules/function-name-arguments-whitelist/README.md @@ -4,7 +4,7 @@ Specify a whitelist of allowed property and value pairs within declarations. ```css -a { text-transform: uppercase; } +a { background-image: url('http://www.example.com/file.jpg'); } /** ↑ ↑ * These properties and these values */ ``` @@ -13,84 +13,57 @@ a { text-transform: uppercase; } `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/"] -} +["data", "/^http/"] ``` The following patterns are considered violations: ```css -a { whitespace: pre; } -``` - - -```css -a { transform: translate(1, 1); } -``` - - -```css -a { -webkit-transform: translate(1, 1); } +a { background-image: url('file://file.jpg'); } ``` - -```css -a { color: pink; } -``` +The following patterns are _not_ considered violations: ```css -a { background-color: pink; } +a { background-image: url('example.com/file.jpg'); } ``` -The following patterns are _not_ considered violations: - ```css -a { color: pink; } +a { background-image: url('/example.com/file.jpg'); } ``` ```css -a { whitespace: nowrap; } +a { background-image: url('//example.com/file.jpg'); } ``` ```css -a { transform: scale(1, 1); } +a { background-image: url('./path/to/file.jpg'); } ``` ```css -a { -webkit-transform: scale(1, 1); } +a { background-image: url('http://www.example.com/file.jpg'); } ``` ```css -a { color: green; } +a { background-image: url('https://www.example.com/file.jpg'); } ``` ```css -a { background-color: green; } +a { background-image: url('HTTPS://www.example.com/file.jpg'); } ``` ```css -a { background: pink; } +a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); } ``` diff --git a/lib/rules/function-name-arguments-whitelist/__tests__/index.js b/lib/rules/function-name-arguments-whitelist/__tests__/index.js index a9bff2a2de..6ddab75578 100644 --- a/lib/rules/function-name-arguments-whitelist/__tests__/index.js +++ b/lib/rules/function-name-arguments-whitelist/__tests__/index.js @@ -5,74 +5,67 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, - config: [ - { - transform: ['/scale/'], - whitespace: ['nowrap'], - '/color/': ['/^green/'], - }, - ], + config: [['/^http/']], accept: [ { - code: 'div { whitespace: nowrap; }', - }, - { - code: 'a { transform: scale(1, 1); }', - }, - { - code: 'a { -webkit-transform: scale(1, 1); }', + code: 'a { background: url(http://example.com/file.jpg); }', }, { - code: 'a { color: green; }', + code: 'a { background: url(HTTP://example.com/file.jpg); }', }, { - code: 'a { background-color: green; }', + code: 'a { background: url(https://example.com/file.jpg); }', }, ], reject: [ { - code: 'div { whitespace: pre; }', - message: messages.rejected('whitespace', 'pre'), + code: 'a { background: url(ftp://example.com/file.jpg); }', + message: messages.rejected('ftp'), line: 1, - column: 7, + column: 21, }, { - code: 'a { transform: translate(1, 1); }', - message: messages.rejected('transform', 'translate(1, 1)'), + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + message: messages.rejected('data'), line: 1, - column: 5, + column: 27, }, + ], +}); + +testRule({ + ruleName, + + config: [[/^http/]], + + accept: [ { - code: 'a { -webkit-transform: translate(1, 1); }', - message: messages.rejected('-webkit-transform', 'translate(1, 1)'), - line: 1, - column: 5, + code: 'a { background: url(http://example.com/file.jpg); }', }, { - code: 'a { color: pink; }', - message: messages.rejected('color', 'pink'), - line: 1, - column: 5, + code: 'a { background: url(HTTP://example.com/file.jpg); }', }, { - code: 'a { background-color: pink; }', - message: messages.rejected('background-color', 'pink'), - line: 1, - column: 5, + code: 'a { background: url(https://example.com/file.jpg); }', }, ], -}); -testRule({ - ruleName, - config: { position: ['static'] }, - skipBasicChecks: true, - accept: [ + reject: [ + { + code: 'a { background: url(ftp://example.com/file.jpg); }', + message: messages.rejected('ftp'), + line: 1, + column: 21, + }, { - code: 'a { font-size: 1em; }', - description: 'irrelevant CSS', + code: + "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", + message: messages.rejected('data'), + line: 1, + column: 27, }, ], }); diff --git a/lib/rules/function-name-arguments-whitelist/index.js b/lib/rules/function-name-arguments-whitelist/index.js index 835858a200..37c2672865 100644 --- a/lib/rules/function-name-arguments-whitelist/index.js +++ b/lib/rules/function-name-arguments-whitelist/index.js @@ -3,8 +3,10 @@ 'use strict'; const _ = require('lodash'); +const functionArgumentsSearch = require('../../utils/functionArgumentsSearch'); +const getSchemeFromUrl = require('../../utils/getSchemeFromUrl'); +const isStandardSyntaxUrl = require('../../utils/isStandardSyntaxUrl'); const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); -const postcss = require('postcss'); const report = require('../../utils/report'); const ruleMessages = require('../../utils/ruleMessages'); const validateOptions = require('../../utils/validateOptions'); @@ -19,7 +21,7 @@ function rule(whitelist) { return (root, result) => { const validOptions = validateOptions(result, ruleName, { actual: whitelist, - possible: [_.isObject], + possible: [_.isString, _.isRegExp], }); if (!validOptions) { @@ -27,27 +29,31 @@ function rule(whitelist) { } 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, + functionArgumentsSearch(decl.toString().toLowerCase(), 'url', (args, index) => { + const unspacedUrlString = _.trim(args, ' '); + + if (!isStandardSyntaxUrl(unspacedUrlString)) { + return; + } + + const urlString = _.trim(unspacedUrlString, '\'"'); + const scheme = getSchemeFromUrl(urlString); + + if (scheme === null) { + return; + } + + if (matchesStringOrRegExp(scheme, whitelist)) { + return; + } + + report({ + message: messages.rejected(scheme), + node: decl, + index, + result, + ruleName, + }); }); }); }; From 8d63a48c6bfd79b254e91d748a33c8a12325a23a Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Mon, 8 Jun 2020 15:33:44 +0530 Subject: [PATCH 04/10] Changed code logic based on declaration-propety-value-whitlist blueprint --- .../__tests__/index.js | 32 +++------------ .../index.js | 39 +++++++++++-------- 2 files changed, 27 insertions(+), 44 deletions(-) diff --git a/lib/rules/function-name-arguments-whitelist/__tests__/index.js b/lib/rules/function-name-arguments-whitelist/__tests__/index.js index 6ddab75578..8cb0300b6c 100644 --- a/lib/rules/function-name-arguments-whitelist/__tests__/index.js +++ b/lib/rules/function-name-arguments-whitelist/__tests__/index.js @@ -5,7 +5,7 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, - config: [['/^http/']], + config: [{ background: ['/^http/', '/^images/'] }], accept: [ { @@ -17,39 +17,17 @@ testRule({ { code: 'a { background: url(https://example.com/file.jpg); }', }, - ], - - reject: [ { - code: 'a { background: url(ftp://example.com/file.jpg); }', - message: messages.rejected('ftp'), - line: 1, - column: 21, + code: 'a { background: url(images/logo.png); }', }, { - code: - "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", - message: messages.rejected('data'), - line: 1, - column: 27, - }, - ], -}); - -testRule({ - ruleName, - - config: [[/^http/]], - - accept: [ - { - code: 'a { background: url(http://example.com/file.jpg); }', + code: 'a { background: url(/images/logo.png); }', }, { - code: 'a { background: url(HTTP://example.com/file.jpg); }', + code: 'a { background: url("images/logo.png"); }', }, { - code: 'a { background: url(https://example.com/file.jpg); }', + code: 'a { background: url("/images/logo.png"); }', }, ], diff --git a/lib/rules/function-name-arguments-whitelist/index.js b/lib/rules/function-name-arguments-whitelist/index.js index 37c2672865..f57f4d0336 100644 --- a/lib/rules/function-name-arguments-whitelist/index.js +++ b/lib/rules/function-name-arguments-whitelist/index.js @@ -3,25 +3,23 @@ 'use strict'; const _ = require('lodash'); -const functionArgumentsSearch = require('../../utils/functionArgumentsSearch'); -const getSchemeFromUrl = require('../../utils/getSchemeFromUrl'); -const isStandardSyntaxUrl = require('../../utils/isStandardSyntaxUrl'); 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 valueParser = require('postcss-value-parser'); const ruleName = 'function-name-arguments-whitelist'; const messages = ruleMessages(ruleName, { - rejected: (property, value) => `Unexpected arguments "${value}" for function "${property}"`, + rejected: (property, value) => `Unexpected value "${value}" for property "${property}"`, }); function rule(whitelist) { return (root, result) => { const validOptions = validateOptions(result, ruleName, { actual: whitelist, - possible: [_.isString, _.isRegExp], + possible: [_.isObject], }); if (!validOptions) { @@ -29,28 +27,35 @@ function rule(whitelist) { } root.walkDecls((decl) => { - functionArgumentsSearch(decl.toString().toLowerCase(), 'url', (args, index) => { - const unspacedUrlString = _.trim(args, ' '); + const prop = decl.prop; + const value = decl.value; - if (!isStandardSyntaxUrl(unspacedUrlString)) { - return; - } + const unprefixedProp = postcss.vendor.unprefixed(prop); + const propWhitelist = _.find(whitelist, (list, propIdentifier) => + matchesStringOrRegExp(unprefixedProp, propIdentifier), + ); - const urlString = _.trim(unspacedUrlString, '\'"'); - const scheme = getSchemeFromUrl(urlString); + if (_.isEmpty(propWhitelist)) { + return; + } + + valueParser(value).walk((node) => { + // Ignore wrong units within `url` function + if (node.type === 'function' && node.value.toLowerCase() === 'url') { + return false; + } - if (scheme === null) { + if (node.type === 'string') { return; } - if (matchesStringOrRegExp(scheme, whitelist)) { + if (matchesStringOrRegExp(value, propWhitelist)) { return; } report({ - message: messages.rejected(scheme), + message: messages.rejected(prop, value), node: decl, - index, result, ruleName, }); From 3b3de225e81f01f24174968d31a84361ccdcf90a Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Wed, 15 Jul 2020 16:05:26 +0530 Subject: [PATCH 05/10] fixed test case issue --- .../__tests__/index.js | 35 ++++++------------- .../index.js | 14 ++++---- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/lib/rules/function-name-arguments-whitelist/__tests__/index.js b/lib/rules/function-name-arguments-whitelist/__tests__/index.js index 8cb0300b6c..653dbe6969 100644 --- a/lib/rules/function-name-arguments-whitelist/__tests__/index.js +++ b/lib/rules/function-name-arguments-whitelist/__tests__/index.js @@ -5,45 +5,30 @@ const { messages, ruleName } = require('..'); testRule({ ruleName, - config: [{ background: ['/^http/', '/^images/'] }], - - accept: [ - { - code: 'a { background: url(http://example.com/file.jpg); }', - }, - { - code: 'a { background: url(HTTP://example.com/file.jpg); }', - }, - { - code: 'a { background: url(https://example.com/file.jpg); }', - }, + config: [ { - code: 'a { background: url(images/logo.png); }', + '/^background/': ['/^images/', '/^http/', '/^vendor/'], }, + ], + + accept: [ { - code: 'a { background: url(/images/logo.png); }', + code: 'a { background: url(images/x.jpg); }', }, { - code: 'a { background: url("images/logo.png"); }', + code: 'a { background: url(vendor/x.jpg); }', }, { - code: 'a { background: url("/images/logo.png"); }', + code: 'a { background: url(https://image/1.png); }', }, ], reject: [ { - code: 'a { background: url(ftp://example.com/file.jpg); }', - message: messages.rejected('ftp'), + code: 'a { background: url(data/x.jpg); }', + message: messages.rejected('background', 'data/x.jpg'), line: 1, column: 21, }, - { - code: - "a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); }", - message: messages.rejected('data'), - line: 1, - column: 27, - }, ], }); diff --git a/lib/rules/function-name-arguments-whitelist/index.js b/lib/rules/function-name-arguments-whitelist/index.js index f57f4d0336..74baeb5c4a 100644 --- a/lib/rules/function-name-arguments-whitelist/index.js +++ b/lib/rules/function-name-arguments-whitelist/index.js @@ -3,6 +3,7 @@ 'use strict'; const _ = require('lodash'); +const declarationValueIndex = require('../../utils/declarationValueIndex'); const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); const postcss = require('postcss'); const report = require('../../utils/report'); @@ -31,6 +32,7 @@ function rule(whitelist) { const value = decl.value; const unprefixedProp = postcss.vendor.unprefixed(prop); + const propWhitelist = _.find(whitelist, (list, propIdentifier) => matchesStringOrRegExp(unprefixedProp, propIdentifier), ); @@ -40,22 +42,18 @@ function rule(whitelist) { } valueParser(value).walk((node) => { - // Ignore wrong units within `url` function - if (node.type === 'function' && node.value.toLowerCase() === 'url') { - return false; - } - - if (node.type === 'string') { + if (node.type === 'function') { return; } - if (matchesStringOrRegExp(value, propWhitelist)) { + if (matchesStringOrRegExp(node.value, propWhitelist)) { return; } report({ - message: messages.rejected(prop, value), + message: messages.rejected(prop, node.value), node: decl, + index: declarationValueIndex(decl) + node.sourceIndex, result, ruleName, }); From 28b42132c8fa81ccb070ae0788dbce603d411eb9 Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Wed, 15 Jul 2020 16:48:25 +0530 Subject: [PATCH 06/10] added test cas fix --- lib/rules/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/rules/index.js b/lib/rules/index.js index 4846a04021..a4cd1958de 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -185,6 +185,9 @@ const rules = { 'function-whitespace-after': importLazy(() => require('./function-whitespace-after'))(), // Renamed to function-allowed-list 'function-whitelist': importLazy(() => require('./function-allowed-list'))(), + 'function-name-arguments-whitelist': importLazy(() => + require('./function-name-arguments-whitelist'), + )(), 'hue-degree-notation': importLazy(() => require('./hue-degree-notation'))(), 'keyframe-declaration-no-important': importLazy(() => require('./keyframe-declaration-no-important'), From 907513af5861f1fb56aceebcc35c8c56e9f679c2 Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Wed, 15 Jul 2020 17:14:07 +0530 Subject: [PATCH 07/10] changed name to function-name-arguments-allowed-list --- .../README.md | 2 +- .../__tests__/index.js | 0 .../index.js | 2 +- lib/rules/index.js | 4 ++-- 4 files changed, 4 insertions(+), 4 deletions(-) rename lib/rules/{function-name-arguments-whitelist => function-name-arguments-allowed-list}/README.md (97%) rename lib/rules/{function-name-arguments-whitelist => function-name-arguments-allowed-list}/__tests__/index.js (100%) rename lib/rules/{function-name-arguments-whitelist => function-name-arguments-allowed-list}/index.js (96%) diff --git a/lib/rules/function-name-arguments-whitelist/README.md b/lib/rules/function-name-arguments-allowed-list/README.md similarity index 97% rename from lib/rules/function-name-arguments-whitelist/README.md rename to lib/rules/function-name-arguments-allowed-list/README.md index 00b7c6da84..8a6d01bba9 100644 --- a/lib/rules/function-name-arguments-whitelist/README.md +++ b/lib/rules/function-name-arguments-allowed-list/README.md @@ -1,4 +1,4 @@ -# function-name-arguments-whitelist +# function-name-arguments-allowed-list Specify a whitelist of allowed property and value pairs within declarations. diff --git a/lib/rules/function-name-arguments-whitelist/__tests__/index.js b/lib/rules/function-name-arguments-allowed-list/__tests__/index.js similarity index 100% rename from lib/rules/function-name-arguments-whitelist/__tests__/index.js rename to lib/rules/function-name-arguments-allowed-list/__tests__/index.js diff --git a/lib/rules/function-name-arguments-whitelist/index.js b/lib/rules/function-name-arguments-allowed-list/index.js similarity index 96% rename from lib/rules/function-name-arguments-whitelist/index.js rename to lib/rules/function-name-arguments-allowed-list/index.js index 74baeb5c4a..bdd00f41f1 100644 --- a/lib/rules/function-name-arguments-whitelist/index.js +++ b/lib/rules/function-name-arguments-allowed-list/index.js @@ -10,7 +10,7 @@ const report = require('../../utils/report'); const ruleMessages = require('../../utils/ruleMessages'); const validateOptions = require('../../utils/validateOptions'); const valueParser = require('postcss-value-parser'); -const ruleName = 'function-name-arguments-whitelist'; +const ruleName = 'function-name-arguments-allowed-list'; const messages = ruleMessages(ruleName, { rejected: (property, value) => `Unexpected value "${value}" for property "${property}"`, diff --git a/lib/rules/index.js b/lib/rules/index.js index a4cd1958de..7e6987032d 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -185,8 +185,8 @@ const rules = { 'function-whitespace-after': importLazy(() => require('./function-whitespace-after'))(), // Renamed to function-allowed-list 'function-whitelist': importLazy(() => require('./function-allowed-list'))(), - 'function-name-arguments-whitelist': importLazy(() => - require('./function-name-arguments-whitelist'), + 'function-name-arguments-allowed-list': importLazy(() => + require('./function-name-arguments-allowed-list'), )(), 'hue-degree-notation': importLazy(() => require('./hue-degree-notation'))(), 'keyframe-declaration-no-important': importLazy(() => From 45afff9a04527193fc38d3655cacfbcbda6fef40 Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Thu, 16 Jul 2020 11:24:52 +0530 Subject: [PATCH 08/10] added test case and readme fix --- .../README.md | 29 ++++++++----------- .../__tests__/index.js | 6 +++- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/lib/rules/function-name-arguments-allowed-list/README.md b/lib/rules/function-name-arguments-allowed-list/README.md index 8a6d01bba9..36caa29f0c 100644 --- a/lib/rules/function-name-arguments-allowed-list/README.md +++ b/lib/rules/function-name-arguments-allowed-list/README.md @@ -4,66 +4,61 @@ Specify a whitelist of allowed property and value pairs within declarations. ```css -a { background-image: url('http://www.example.com/file.jpg'); } +a { background: url('http://www.example.com/file.jpg'); } /** ↑ ↑ * These properties and these values */ ``` ## Options -`object`: `{"unprefixed-function-name": ["string", "/regex/", /regex/] }` +`object`: `{"unprefixed-function-name": ["/regex/", /regex/] }` Given: ``` -["data", "/^http/"] +["/^images/", "/^http/"] ``` The following patterns are considered violations: ```css -a { background-image: url('file://file.jpg'); } +a { background-image: url('images/file.jpg'); } ``` -The following patterns are _not_ considered violations: - ```css -a { background-image: url('example.com/file.jpg'); } +a { background-image: url('http://www.example.com/file.jpg'); } ``` ```css -a { background-image: url('/example.com/file.jpg'); } +a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); } ``` - -```css -a { background-image: url('//example.com/file.jpg'); } -``` +The following patterns are _not_ considered violations: ```css -a { background-image: url('./path/to/file.jpg'); } +a { background-image: url('example.com/file.jpg'); } ``` ```css -a { background-image: url('http://www.example.com/file.jpg'); } +a { background-image: url('/example.com/file.jpg'); } ``` ```css -a { background-image: url('https://www.example.com/file.jpg'); } +a { background-image: url('//example.com/file.jpg'); } ``` ```css -a { background-image: url('HTTPS://www.example.com/file.jpg'); } +a { background-image: url('./path/to/file.jpg'); } ``` ```css -a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); } +a { background-image: url('vendor/file.jpg'); } ``` diff --git a/lib/rules/function-name-arguments-allowed-list/__tests__/index.js b/lib/rules/function-name-arguments-allowed-list/__tests__/index.js index 653dbe6969..bdd69b4bfb 100644 --- a/lib/rules/function-name-arguments-allowed-list/__tests__/index.js +++ b/lib/rules/function-name-arguments-allowed-list/__tests__/index.js @@ -7,7 +7,7 @@ testRule({ config: [ { - '/^background/': ['/^images/', '/^http/', '/^vendor/'], + '/^background/': ['/^data:/', '/^images/', '/^http/', '/^vendor/'], }, ], @@ -21,6 +21,10 @@ testRule({ { code: 'a { background: url(https://image/1.png); }', }, + { + code: + 'a { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=); }', + }, ], reject: [ From 2f06e7a47517db58b8c72b0c7cf75605068fd0a4 Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Sat, 18 Jul 2020 08:35:36 +0530 Subject: [PATCH 09/10] added review comments --- .../README.md | 31 ++++++++++++++----- .../__tests__/index.js | 27 +++++++++++++--- .../index.js | 12 ++++--- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/lib/rules/function-name-arguments-allowed-list/README.md b/lib/rules/function-name-arguments-allowed-list/README.md index 36caa29f0c..5027e73ff3 100644 --- a/lib/rules/function-name-arguments-allowed-list/README.md +++ b/lib/rules/function-name-arguments-allowed-list/README.md @@ -23,42 +23,57 @@ The following patterns are considered violations: ```css -a { background-image: url('images/file.jpg'); } +a { background-image: url(data/x.jpg); } ``` ```css -a { background-image: url('http://www.example.com/file.jpg'); } +a { background: url(#fff) } ``` ```css -a { background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='); } +a { background-image: url('//example.com/file.jpg'); } +``` + + +```css +a { background-image: url('./path/to/file.jpg'); } +``` + + +```css +a { background-image: url('vendor/file.jpg'); } ``` The following patterns are _not_ considered violations: ```css -a { background-image: url('example.com/file.jpg'); } +a { background: url(images/x.jpg); } ``` ```css -a { background-image: url('/example.com/file.jpg'); } +a { background-image: url(vendor/x.jpg); } ``` ```css -a { background-image: url('//example.com/file.jpg'); } +a { background: url(https://image/1.png); } ``` ```css -a { background-image: url('./path/to/file.jpg'); } +a { background-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=); } ``` ```css -a { background-image: url('vendor/file.jpg'); } +a { background-image: #fff url(images/select2.png) no-repeat 100% -22px } +``` + + +```css +a {background-image: url(images/select2.png) no-repeat 100% -22px, -moz-linear-gradient(bottom, #fff 85%, #eee 99%);} ``` diff --git a/lib/rules/function-name-arguments-allowed-list/__tests__/index.js b/lib/rules/function-name-arguments-allowed-list/__tests__/index.js index bdd69b4bfb..07b40c17ee 100644 --- a/lib/rules/function-name-arguments-allowed-list/__tests__/index.js +++ b/lib/rules/function-name-arguments-allowed-list/__tests__/index.js @@ -16,21 +16,40 @@ testRule({ code: 'a { background: url(images/x.jpg); }', }, { - code: 'a { background: url(vendor/x.jpg); }', + code: 'a { background-image: url(vendor/x.jpg); }', }, { code: 'a { background: url(https://image/1.png); }', }, { code: - 'a { background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=); }', + 'a { background-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=); }', + }, + { + code: 'a { background-image: #fff url(images/select2.png) no-repeat 100% -22px }', + }, + { + code: + 'a {background-image: url(images/select2.png) no-repeat 100% -22px, -moz-linear-gradient(bottom, #fff 85%, #eee 99%);}', }, ], reject: [ { - code: 'a { background: url(data/x.jpg); }', - message: messages.rejected('background', 'data/x.jpg'), + code: 'a { background-image: url(data/x.jpg); }', + message: messages.rejected('background-image', 'data/x.jpg'), + line: 1, + column: 27, + }, + { + code: 'a { background-image: #fff url(magic/select2.png) no-repeat 100% -22px }', + message: messages.rejected('background-image', 'magic/select2.png'), + line: 1, + column: 32, + }, + { + code: 'a { background: url(#fff) }', + message: messages.rejected('background', '#fff'), line: 1, column: 21, }, diff --git a/lib/rules/function-name-arguments-allowed-list/index.js b/lib/rules/function-name-arguments-allowed-list/index.js index bdd00f41f1..49eec48dd2 100644 --- a/lib/rules/function-name-arguments-allowed-list/index.js +++ b/lib/rules/function-name-arguments-allowed-list/index.js @@ -42,18 +42,22 @@ function rule(whitelist) { } valueParser(value).walk((node) => { - if (node.type === 'function') { + if (node.value !== 'url') { return; } - if (matchesStringOrRegExp(node.value, propWhitelist)) { + const nodes = node.nodes.length && node.nodes[0]; + + const { value, sourceIndex } = nodes; + + if (matchesStringOrRegExp(value, propWhitelist)) { return; } report({ - message: messages.rejected(prop, node.value), + message: messages.rejected(prop, value), node: decl, - index: declarationValueIndex(decl) + node.sourceIndex, + index: declarationValueIndex(decl) + sourceIndex, result, ruleName, }); From e74c8c14b7b994bac037e10c6cf95f9d4536bf04 Mon Sep 17 00:00:00 2001 From: mockey-jockey Date: Sat, 18 Jul 2020 08:37:32 +0530 Subject: [PATCH 10/10] added review comments --- .../function-name-arguments-allowed-list/README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/rules/function-name-arguments-allowed-list/README.md b/lib/rules/function-name-arguments-allowed-list/README.md index 5027e73ff3..805efe726f 100644 --- a/lib/rules/function-name-arguments-allowed-list/README.md +++ b/lib/rules/function-name-arguments-allowed-list/README.md @@ -1,6 +1,6 @@ # function-name-arguments-allowed-list -Specify a whitelist of allowed property and value pairs within declarations. +Specify an list of allowed property and value pairs within declarations. ```css @@ -9,6 +9,13 @@ a { background: url('http://www.example.com/file.jpg'); } * These properties and these values */ ``` + +```css +a { background-image: url('http://www.example.com/file.jpg'); } +/** ↑ ↑ + * These properties and these values */ +``` + ## Options `object`: `{"unprefixed-function-name": ["/regex/", /regex/] }` @@ -16,7 +23,7 @@ a { background: url('http://www.example.com/file.jpg'); } Given: ``` -["/^images/", "/^http/"] +['/^data:/', '/^images/', '/^http/', '/^vendor/'] ``` The following patterns are considered violations: