Skip to content

Commit

Permalink
Add support for x to unit-no-unknown (#4427)
Browse files Browse the repository at this point in the history
* Ignore `x` unit in some cases

* Complex @media case, update tests

* Complex decl case, update tests
  • Loading branch information
fanich37 authored and hudochenkov committed Nov 24, 2019
1 parent 68880e0 commit 1b43fca
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 2 deletions.
60 changes: 60 additions & 0 deletions lib/rules/unit-no-unknown/__tests__/index.js
Expand Up @@ -220,6 +220,22 @@ testRule(rule, {
code: "@import 'foo.css'",
description: 'ignore non-media and non-variable at-rule',
},
{
code: "a { background-image: image-set('img-1x.jpg' 1x, 'img-2x.jpg' 2x, 'img-3x.jpg' 3x) }",
description: 'ignore `x` unit in image-set',
},
{
code: '@media (resolution: 2x) {}',
description: 'ignore `x` unit in @media with `resolution`',
},
{
code: '@media ( resOLution: 2x) {}',
description: 'ignore `x` unit in @media with `resolution`',
},
{
code: 'a { image-resolution: 1x; }',
description: 'ignore `x` unit in image-resolution',
},
],

reject: [
Expand Down Expand Up @@ -356,6 +372,50 @@ testRule(rule, {
line: 1,
column: 13,
},
{
code: 'a { width: 400x; }',
message: messages.rejected('x'),
description: '`x` is not allowed for non-resolution props',
line: 1,
column: 12,
},
{
code: '@media (resolution: 2x) and (min-width: 200x) {}',
message: messages.rejected('x'),
description: '`x` rejected with inappropriate property',
line: 1,
column: 41,
},
{
code: '@media ( resolution: /* comment */ 2x ) and (min-width: 200x) {}',
message: messages.rejected('x'),
description: '`x` rejected with inappropriate property',
line: 1,
column: 44,
},
{
code:
"a { background: image-set('img1x.png' 1x, 'img2x.png' 2x) left 20x / 15% 60% repeat-x; }",
message: messages.rejected('x'),
description: '`x` rejected with inappropriate property',
line: 1,
column: 64,
},
{
code:
"a { background: /* comment */ image-set('img1x.png' 1x, 'img2x.png' 2x) left 20x / 15% 60% repeat-x; }",
message: messages.rejected('x'),
description: '`x` rejected with inappropriate property',
line: 1,
column: 78,
},
{
code: "a { background-image: image-set('img1x.png' 1pix, 'img2x.png' 2x); }",
message: messages.rejected('pix'),
description: '`pix` rejected with inappropriate property',
line: 1,
column: 45,
},
],
});

Expand Down
47 changes: 45 additions & 2 deletions lib/rules/unit-no-unknown/index.js
Expand Up @@ -5,6 +5,7 @@ const atRuleParamIndex = require('../../utils/atRuleParamIndex');
const declarationValueIndex = require('../../utils/declarationValueIndex');
const getUnitFromValueNode = require('../../utils/getUnitFromValueNode');
const keywordSets = require('../../reference/keywordSets');
const mediaParser = require('postcss-media-query-parser').default;
const optionsMatches = require('../../utils/optionsMatches');
const report = require('../../utils/report');
const ruleMessages = require('../../utils/ruleMessages');
Expand Down Expand Up @@ -41,7 +42,9 @@ const rule = function(actual, options) {
// make sure multiplication operations (*) are divided - not handled
// by postcss-value-parser
value = value.replace(/\*/g, ',');
valueParser(value).walk(function(valueNode) {
const parsedValue = valueParser(value);

parsedValue.walk(function(valueNode) {
// Ignore wrong units within `url` function
// and within functions listed in the `ignoreFunctions` option
if (
Expand All @@ -62,10 +65,50 @@ const rule = function(actual, options) {
return;
}

if (keywordSets.units.has(unit.toLowerCase())) {
if (keywordSets.units.has(unit.toLowerCase()) && unit.toLowerCase() !== 'x') {
return;
}

if (unit.toLowerCase() === 'x') {
if (
node.type === 'atrule' &&
node.name === 'media' &&
node.params.toLowerCase().includes('resolution')
) {
let ignoreUnit = false;

mediaParser(node.params).walk((mediaNode, i, mediaNodes) => {
if (
mediaNode.value.toLowerCase().includes('resolution') &&
_.last(mediaNodes).sourceIndex === valueNode.sourceIndex
) {
ignoreUnit = true;

return false;
}
});

if (ignoreUnit) {
return;
}
}

if (node.type === 'decl') {
if (node.prop.toLowerCase() === 'image-resolution') {
return;
}

if (/^image-set/i.test(value)) {
const imageSet = parsedValue.nodes.find((node) => node.value === 'image-set');
const imageSetValueLastIndex = _.last(imageSet.nodes).sourceIndex;

if (imageSetValueLastIndex >= valueNode.sourceIndex) {
return;
}
}
}
}

report({
index: getIndex(node) + valueNode.sourceIndex,
message: messages.rejected(unit),
Expand Down

0 comments on commit 1b43fca

Please sign in to comment.