From 8efbef90dfbfeb18cb99c3649aa4bd639d641174 Mon Sep 17 00:00:00 2001 From: Drew Hays Date: Fri, 5 Mar 2021 21:09:07 -0800 Subject: [PATCH 1/2] Use postcss-value-parser for color-no-hex rule `style-search` returns false positives when used with `css-in-js` object notation. This change continues with the discussion in #4826 and moves another test away from using `style-search`. --- lib/rules/color-no-hex/__tests__/index.js | 78 +++++++++++++++++++++++ lib/rules/color-no-hex/index.js | 39 ++++++------ 2 files changed, 99 insertions(+), 18 deletions(-) diff --git a/lib/rules/color-no-hex/__tests__/index.js b/lib/rules/color-no-hex/__tests__/index.js index ee2625566e..41607f2785 100644 --- a/lib/rules/color-no-hex/__tests__/index.js +++ b/lib/rules/color-no-hex/__tests__/index.js @@ -94,3 +94,81 @@ testRule({ }, ], }); + +testRule({ + ruleName, + config: [true], + syntax: 'css-in-js', + + accept: [ + { + code: ` + export const s = styled.a({ + color: "pink", + }); + `, + }, + { + code: ` + export const s = styled.a({ + color: "rgba(0, 0, 0, 0)", + }); + `, + }, + { + code: ` + export const s = styled.a({ + content: '"#abcdef"', + }); + `, + }, + { + code: ` + export const s = styled.a({ + background: 'url("#aabbcc")', + }); + `, + }, + { + code: ` + export const s = styled.a({ + color: "red /* #ff0000 */", + }); + `, + }, + { + code: ` + export const s = styled.a({ + color: "linear-gradient(green, rgb(123, 123, 123), hsl(24, 70%, 80%))", + }); + `, + }, + ], + + reject: [ + { + code: ` + export const s = styled.a({ + color: "#abcdef", + }); + `, + + message: messages.rejected('#abcdef'), + line: 3, + column: 13, + }, + { + code: ` + export const s = styled.a({ + backgroundColor: "linear-gradient(#aaa, #ffff, #01234567)", + }); + `, + + warnings: [ + { message: messages.rejected('#aaa'), line: 3, column: 39 }, + { message: messages.rejected('#ffff'), line: 3, column: 45 }, + { message: messages.rejected('#01234567'), line: 3, column: 52 }, + ], + }, + ], +}); diff --git a/lib/rules/color-no-hex/index.js b/lib/rules/color-no-hex/index.js index fd154df024..5eba7f36c4 100644 --- a/lib/rules/color-no-hex/index.js +++ b/lib/rules/color-no-hex/index.js @@ -2,9 +2,12 @@ 'use strict'; +const valueParser = require('postcss-value-parser'); + +const declarationValueIndex = require('../../utils/declarationValueIndex'); +const getDeclarationValue = require('../../utils/getDeclarationValue'); const report = require('../../utils/report'); const ruleMessages = require('../../utils/ruleMessages'); -const styleSearch = require('style-search'); const validateOptions = require('../../utils/validateOptions'); const ruleName = 'color-no-hex'; @@ -13,6 +16,9 @@ const messages = ruleMessages(ruleName, { rejected: (hex) => `Unexpected hex color "${hex}"`, }); +const HEX = /^#[0-9A-Za-z]+/; +const IGNORED_FUNCTIONS = new Set(['url']); + function rule(actual) { return (root, result) => { const validOptions = validateOptions(result, ruleName, { actual }); @@ -22,28 +28,17 @@ function rule(actual) { } root.walkDecls((decl) => { - const declString = decl.toString(); - - styleSearch({ source: declString, target: '#' }, (match) => { - // If there's not a colon, comma, or whitespace character before, we'll assume this is - // not intended to be a hex color, but is instead something like the - // hash in a url() argument - if (!/[:,\s]/.test(declString[match.startIndex - 1])) { - return; - } - - const hexMatch = /^#[0-9A-Za-z]+/.exec(declString.substr(match.startIndex)); + const parsedValue = valueParser(getDeclarationValue(decl)); - if (!hexMatch) { - return; - } + parsedValue.walk((node) => { + if (isIgnoredFunction(node)) return false; - const hexValue = hexMatch[0]; + if (!isHexColor(node)) return; report({ - message: messages.rejected(hexValue), + message: messages.rejected(node.value), node: decl, - index: match.startIndex, + index: declarationValueIndex(decl) + node.sourceIndex, result, ruleName, }); @@ -52,6 +47,14 @@ function rule(actual) { }; } +function isIgnoredFunction({ type, value }) { + return type === 'function' && IGNORED_FUNCTIONS.has(value.toLowerCase()); +} + +function isHexColor({ type, value }) { + return type === 'word' && HEX.test(value); +} + rule.ruleName = ruleName; rule.messages = messages; module.exports = rule; From 97534f3f9fb6d905a306bc6c703fa03df1ed1873 Mon Sep 17 00:00:00 2001 From: Drew Hays Date: Fri, 5 Mar 2021 21:13:03 -0800 Subject: [PATCH 2/2] arguments to url shouldn't use quotes --- lib/rules/color-no-hex/__tests__/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/color-no-hex/__tests__/index.js b/lib/rules/color-no-hex/__tests__/index.js index 41607f2785..a01e7ad6fb 100644 --- a/lib/rules/color-no-hex/__tests__/index.js +++ b/lib/rules/color-no-hex/__tests__/index.js @@ -125,7 +125,7 @@ testRule({ { code: ` export const s = styled.a({ - background: 'url("#aabbcc")', + background: 'url(#aabbcc)', }); `, },