diff --git a/.changeset/shiny-toys-chew.md b/.changeset/shiny-toys-chew.md new file mode 100644 index 0000000000..5cc4639262 --- /dev/null +++ b/.changeset/shiny-toys-chew.md @@ -0,0 +1,5 @@ +--- +"stylelint": patch +--- + +Fixed: `unit-no-unknown` false positives for `unicode-range` descriptors diff --git a/lib/rules/unit-no-unknown/__tests__/index.js b/lib/rules/unit-no-unknown/__tests__/index.js index 7ce0aa5343..b98e0c6b27 100644 --- a/lib/rules/unit-no-unknown/__tests__/index.js +++ b/lib/rules/unit-no-unknown/__tests__/index.js @@ -254,6 +254,9 @@ testRule({ { code: 'a { width: 8ic; }', }, + { + code: '@font-face { unicode-range: U+0100-024F; }', + }, ], reject: [ @@ -484,6 +487,24 @@ testRule({ line: 1, column: 46, }, + { + code: '@font-face { color: U+0100-024F; }', + message: messages.rejected('F'), + description: 'Unicode range value in something other than `unicode-range`', + line: 1, + column: 31, + endLine: 1, + endColumn: 32, + }, + { + code: 'a { unicode-range: U+0100-024F; }', + message: messages.rejected('F'), + description: 'Unicode range value in something other than `@font-face`', + line: 1, + column: 30, + endLine: 1, + endColumn: 31, + }, ], }); diff --git a/lib/rules/unit-no-unknown/index.js b/lib/rules/unit-no-unknown/index.js index aa3530a02d..69f09fbe31 100644 --- a/lib/rules/unit-no-unknown/index.js +++ b/lib/rules/unit-no-unknown/index.js @@ -16,6 +16,7 @@ const getDeclarationValue = require('../../utils/getDeclarationValue'); const isStandardSyntaxAtRule = require('../../utils/isStandardSyntaxAtRule'); const isStandardSyntaxDeclaration = require('../../utils/isStandardSyntaxDeclaration'); const isStandardSyntaxValue = require('../../utils/isStandardSyntaxValue'); +const isUnicodeRangeDescriptor = require('../../utils/isUnicodeRangeDescriptor'); const optionsMatches = require('../../utils/optionsMatches'); const report = require('../../utils/report'); const ruleMessages = require('../../utils/ruleMessages'); @@ -167,6 +168,8 @@ const rule = (primary, secondaryOptions) => { root.walkDecls((decl) => { if (!isStandardSyntaxDeclaration(decl)) return; + if (isUnicodeRangeDescriptor(decl)) return; + const value = getDeclarationValue(decl); if (!isStandardSyntaxValue(value)) return; diff --git a/lib/utils/isUnicodeRangeDescriptor.js b/lib/utils/isUnicodeRangeDescriptor.js new file mode 100644 index 0000000000..8718a9c22b --- /dev/null +++ b/lib/utils/isUnicodeRangeDescriptor.js @@ -0,0 +1,26 @@ +'use strict'; + +const { isAtRule } = require('./typeGuards'); + +const IS_UNICODE_RANGE = /^unicode-range$/i; +const IS_AT_FONT_FACE = /^font-face$/i; + +/** + * Check whether a declaration is the `unicode-range` descriptor of an `@font-face` rule. + * + * @param {import('postcss').Declaration} decl + * @returns {boolean} + */ +module.exports = function isUnicodeRangeDescriptor(decl) { + if (!IS_UNICODE_RANGE.test(decl.prop)) { + return false; + } + + const parent = decl.parent; + + if (!parent || !isAtRule(parent)) { + return false; + } + + return IS_AT_FONT_FACE.test(parent.name); +};