From 7a68da1af527b316c527a13d7526ebdc159684d4 Mon Sep 17 00:00:00 2001 From: Alex Bea Date: Tue, 20 Apr 2021 07:02:19 -0500 Subject: [PATCH] Add ignore: ["inside-function"] to declaration-property-unit-allowed-list (#5194) --- lib/rules/color-named/index.js | 2 +- .../README.md | 34 +++++++++++ .../__tests__/index.js | 59 +++++++++++++++++++ .../index.js | 32 +++++++--- 4 files changed, 119 insertions(+), 8 deletions(-) diff --git a/lib/rules/color-named/index.js b/lib/rules/color-named/index.js index 2cc49f7dfd..23dba11c0e 100644 --- a/lib/rules/color-named/index.js +++ b/lib/rules/color-named/index.js @@ -24,7 +24,7 @@ const messages = ruleMessages(ruleName, { rejected: (named) => `Unexpected named color "${named}"`, }); -// Todo tested on case insensivity +// Todo tested on case insensitivity const NODE_TYPES = new Set(['word', 'function']); function rule(expectation, options) { diff --git a/lib/rules/declaration-property-unit-allowed-list/README.md b/lib/rules/declaration-property-unit-allowed-list/README.md index 48a95c973d..d67ead027d 100644 --- a/lib/rules/declaration-property-unit-allowed-list/README.md +++ b/lib/rules/declaration-property-unit-allowed-list/README.md @@ -83,3 +83,37 @@ a { animation-duration: 5s; } ```css a { line-height: 1; } ``` + +## Optional secondary options + +### `ignore: ["inside-function"]` + +Ignore units that are inside a function. + +For example, given: + +``` +{ + "/^border/": ["px"], + "/^background/": ["%"], +}, +{ + "ignore": ["inside-function"], +}, +``` + +The following patterns are _not_ considered violations: + + +```css +a { + border: 1px solid hsla(162deg, 51%, 35%, 0.8); +} +``` + + +```css +a { + background-image: linear-gradient(hsla(162deg, 51%, 35%, 0.8), hsla(62deg, 51%, 35%, 0.8)); +} +``` diff --git a/lib/rules/declaration-property-unit-allowed-list/__tests__/index.js b/lib/rules/declaration-property-unit-allowed-list/__tests__/index.js index fcb8dfc4f7..ccf613b065 100644 --- a/lib/rules/declaration-property-unit-allowed-list/__tests__/index.js +++ b/lib/rules/declaration-property-unit-allowed-list/__tests__/index.js @@ -154,6 +154,10 @@ testRule({ { code: 'a { -webkit-animation-duration: 300ms; }', }, + { + code: + 'a { animation: 3ms cubic-bezier(.17,.67,.83,.67) 1ms infinite alternate none running slidein; }', + }, ], reject: [ @@ -175,3 +179,58 @@ testRule({ }, ], }); + +testRule({ + ruleName, + + config: [ + { + '/^border/': ['px'], + '/^background/': ['%'], + }, + { + ignore: ['inside-function'], + }, + ], + + skipBasicChecks: true, + + accept: [ + { + code: 'a { border-color: hsla(162deg, 51%, 35%, 0.8); }', + }, + { + code: 'a { border: 1px solid hsla(162deg, 51%, 35%, 0.8); }', + }, + { + code: + 'a { background-image: linear-gradient(hsla(162deg, 51%, 35%, 0.8), hsla(62deg, 51%, 35%, 0.8)); }', + }, + { + code: 'a { background-image: url("https://example.com/img.png"); }', + }, + { + code: + 'a { background: center center / 50% 50% linear-gradient(hsla(162deg, 51%, 35%, 0.8), hsla(62deg, 51%, 35%, 0.8)); }', + }, + { + code: 'a { background-color: var(--bg-color); }', + }, + ], + + reject: [ + { + code: 'a { border: 1rem solid hsla(162deg, 51%, 35%, 0.8); }', + message: messages.rejected('border', 'rem'), + }, + { + code: 'a { background-position: 5rem 45%; }', + message: messages.rejected('background-position', 'rem'), + }, + { + code: + 'a { background: center center / 50px 10% linear-gradient(hsla(162deg, 51%, 35%, 0.8), hsla(62deg, 51%, 35%, 0.8)); }', + message: messages.rejected('background', 'px'), + }, + ], +}); diff --git a/lib/rules/declaration-property-unit-allowed-list/index.js b/lib/rules/declaration-property-unit-allowed-list/index.js index 9cec92b445..a1df3bf6dd 100644 --- a/lib/rules/declaration-property-unit-allowed-list/index.js +++ b/lib/rules/declaration-property-unit-allowed-list/index.js @@ -6,6 +6,7 @@ const _ = require('lodash'); const declarationValueIndex = require('../../utils/declarationValueIndex'); const getUnitFromValueNode = require('../../utils/getUnitFromValueNode'); const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp'); +const optionsMatches = require('../../utils/optionsMatches'); const report = require('../../utils/report'); const ruleMessages = require('../../utils/ruleMessages'); const validateOptions = require('../../utils/validateOptions'); @@ -18,12 +19,23 @@ const messages = ruleMessages(ruleName, { rejected: (property, unit) => `Unexpected unit "${unit}" for property "${property}"`, }); -function rule(list) { +function rule(list, options) { return (root, result) => { - const validOptions = validateOptions(result, ruleName, { - actual: list, - possible: [_.isObject], - }); + const validOptions = validateOptions( + result, + ruleName, + { + actual: list, + possible: [_.isObject], + }, + { + actual: options, + possible: { + ignore: ['inside-function'], + }, + optional: true, + }, + ); if (!validOptions) { return; @@ -45,8 +57,14 @@ function rule(list) { valueParser(value).walk((node) => { // Ignore wrong units within `url` function - if (node.type === 'function' && node.value.toLowerCase() === 'url') { - return false; + if (node.type === 'function') { + if (node.value.toLowerCase() === 'url') { + return false; + } + + if (optionsMatches(options, 'ignore', 'inside-function')) { + return false; + } } if (node.type === 'string') {