diff --git a/lib/rules/color-no-invalid-hex/__tests__/index.js b/lib/rules/color-no-invalid-hex/__tests__/index.js index 435d0ce51a..be797e0a06 100644 --- a/lib/rules/color-no-invalid-hex/__tests__/index.js +++ b/lib/rules/color-no-invalid-hex/__tests__/index.js @@ -30,14 +30,6 @@ testRule({ { code: 'a::before { content: "#ababa"; }', }, - { - code: 'a { border-#$side: 0; }', - description: 'ignore sass-like interpolation', - }, - { - code: 'a { box-sizing: #$type-box; }', - description: 'ignore sass-like interpolation', - }, { code: "a { background-image: svg-load('x.svg', fill=url(#a)); }", description: 'svg-load url with fill', @@ -91,6 +83,34 @@ testRule({ ], }); +testRule({ + ruleName, + config: [true], + customSyntax: 'postcss-less', + accept: [ + { + code: 'a { color: #colors[somecolor]; }', + description: 'Less map usage', + }, + ], +}); + +testRule({ + ruleName, + config: [true], + customSyntax: 'postcss-scss', + accept: [ + { + code: 'a { border-#$side: 0; }', + description: 'ignore sass-like interpolation', + }, + { + code: 'a { box-sizing: #$type-box; }', + description: 'ignore sass-like interpolation', + }, + ], +}); + testRule({ skip: true, ruleName, diff --git a/lib/rules/color-no-invalid-hex/index.js b/lib/rules/color-no-invalid-hex/index.js index 94fb9a2ad1..45db19fed7 100644 --- a/lib/rules/color-no-invalid-hex/index.js +++ b/lib/rules/color-no-invalid-hex/index.js @@ -1,6 +1,7 @@ 'use strict'; const declarationValueIndex = require('../../utils/declarationValueIndex'); +const isStandardSyntaxHexColor = require('../../utils/isStandardSyntaxHexColor'); const isValidHex = require('../../utils/isValidHex'); const report = require('../../utils/report'); const ruleMessages = require('../../utils/ruleMessages'); @@ -23,6 +24,10 @@ const rule = (primary) => { } root.walkDecls((decl) => { + if (!isStandardSyntaxHexColor(decl.value)) { + return; + } + valueParser(decl.value).walk(({ value, type, sourceIndex }) => { if (type === 'function' && value.endsWith('url')) return false; diff --git a/lib/utils/__tests__/isStandardSyntaxDeclaration.test.js b/lib/utils/__tests__/isStandardSyntaxDeclaration.test.js index 7cc6872745..fcce7bba53 100644 --- a/lib/utils/__tests__/isStandardSyntaxDeclaration.test.js +++ b/lib/utils/__tests__/isStandardSyntaxDeclaration.test.js @@ -139,6 +139,10 @@ describe('isStandardSyntaxDeclaration', () => { expect(isStandardSyntaxDeclaration(lessDecl('@map: { key: value; }'))).toBe(false); }); + it('less another map', () => { + expect(isStandardSyntaxDeclaration(lessDecl('#my-map() { key: value; }'))).toBe(false); + }); + it('scss map declaration', () => { expect(isStandardSyntaxDeclaration(scssDecl('$foo: (key: value, key2: value2)'))).toBe(false); }); diff --git a/lib/utils/__tests__/isStandardSyntaxHexColor.test.js b/lib/utils/__tests__/isStandardSyntaxHexColor.test.js new file mode 100644 index 0000000000..42520bd51c --- /dev/null +++ b/lib/utils/__tests__/isStandardSyntaxHexColor.test.js @@ -0,0 +1,12 @@ +'use strict'; + +const isStandardSyntaxHexColor = require('../isStandardSyntaxHexColor'); + +describe('isStandardSyntaxHexColor', () => { + it('default hex', () => { + expect(isStandardSyntaxHexColor('#000000')).toBe(true); + }); + it('less map usage', () => { + expect(isStandardSyntaxHexColor('#prop[someprop]')).toBe(false); + }); +}); diff --git a/lib/utils/isStandardSyntaxDeclaration.js b/lib/utils/isStandardSyntaxDeclaration.js index d917520c79..d8291befef 100644 --- a/lib/utils/isStandardSyntaxDeclaration.js +++ b/lib/utils/isStandardSyntaxDeclaration.js @@ -46,6 +46,17 @@ module.exports = function (decl) { return false; } + // Less map (e.g. #my-map() { myprop: red; }) + if ( + parent && + isRule(parent) && + parent.selector && + parent.selector.startsWith('#') && + parent.selector.endsWith('()') + ) { + return false; + } + // Sass nested properties (e.g. border: { style: solid; color: red; }) if ( parent && diff --git a/lib/utils/isStandardSyntaxHexColor.js b/lib/utils/isStandardSyntaxHexColor.js new file mode 100644 index 0000000000..71a7581a99 --- /dev/null +++ b/lib/utils/isStandardSyntaxHexColor.js @@ -0,0 +1,16 @@ +'use strict'; + +/** + * Check whether a hex color is standard + * + * @param {string} hex + * @returns {boolean} + */ +module.exports = function isStandardSyntaxHexColor(hex) { + // Less map usage (e.g. .myclass { color: #colors[somecolor]; }) + if (hex.includes('[')) { + return false; + } + + return true; +};