From 0e093a17b981fe1ac77f10c69564416f3e9c7478 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Thu, 13 Jul 2023 18:30:03 +0200 Subject: [PATCH 1/3] Fix `declaration-property-value-no-unknown` false negatives for nested declarations --- .../__tests__/index.mjs | 11 +++++++++++ .../declaration-property-value-no-unknown/index.js | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/rules/declaration-property-value-no-unknown/__tests__/index.mjs b/lib/rules/declaration-property-value-no-unknown/__tests__/index.mjs index 83dd0d19ea..6aeaaa9de6 100644 --- a/lib/rules/declaration-property-value-no-unknown/__tests__/index.mjs +++ b/lib/rules/declaration-property-value-no-unknown/__tests__/index.mjs @@ -9,6 +9,9 @@ testRule({ { code: 'a { top: 0; }', }, + { + code: 'a { @media screen { top: 0; } }', + }, { code: 'a { margin: auto 10em; }', }, @@ -66,6 +69,14 @@ testRule({ endLine: 1, endColumn: 17, }, + { + code: 'a { @media screen { top: unknown; } }', + message: messages.rejected('top', 'unknown'), + line: 1, + column: 26, + endLine: 1, + endColumn: 33, + }, { code: 'a { top: red; }', message: messages.rejected('top', 'red'), diff --git a/lib/rules/declaration-property-value-no-unknown/index.js b/lib/rules/declaration-property-value-no-unknown/index.js index 46153e6725..82d336749d 100644 --- a/lib/rules/declaration-property-value-no-unknown/index.js +++ b/lib/rules/declaration-property-value-no-unknown/index.js @@ -28,6 +28,8 @@ const meta = { url: 'https://stylelint.io/user-guide/rules/declaration-property-value-no-unknown', }; +const CONDITIONAL_RULES_ALLOWED_IN_NESTING = /^(?:media|supports|layer|scope|container)$/i; + /** @type {import('stylelint').Rule} */ const rule = (primary, secondaryOptions) => { return (root, result) => { @@ -111,7 +113,7 @@ const rule = (primary, secondaryOptions) => { } const { error } = - parent && isAtRule(parent) + parent && isAtRule(parent) && !CONDITIONAL_RULES_ALLOWED_IN_NESTING.test(parent.name) ? forkedLexer.matchAtruleDescriptor(parent.name, prop, cssTreeValueNode) : forkedLexer.matchProperty(prop, cssTreeValueNode); From 336db201e3f1220d30f4f7f9a16665679950c55c Mon Sep 17 00:00:00 2001 From: Romain Menke <11521496+romainmenke@users.noreply.github.com> Date: Thu, 13 Jul 2023 18:31:10 +0200 Subject: [PATCH 2/3] Create serious-pumas-march.md --- .changeset/serious-pumas-march.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/serious-pumas-march.md diff --git a/.changeset/serious-pumas-march.md b/.changeset/serious-pumas-march.md new file mode 100644 index 0000000000..e87b97cb35 --- /dev/null +++ b/.changeset/serious-pumas-march.md @@ -0,0 +1,5 @@ +--- +"stylelint": patch +--- + +Fixed: `declaration-property-value-no-unknown` false negatives for nested declarations From 59f81accdd007005793ec5ebe1ec352fa6cd3dd3 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Fri, 14 Jul 2023 10:42:54 +0200 Subject: [PATCH 3/3] apply suggestions from code review Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com> --- lib/reference/__tests__/atKeywords.test.mjs | 9 +++++++++ lib/reference/atKeywords.js | 5 +++++ lib/rules/declaration-property-value-no-unknown/index.js | 5 ++--- 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 lib/reference/__tests__/atKeywords.test.mjs diff --git a/lib/reference/__tests__/atKeywords.test.mjs b/lib/reference/__tests__/atKeywords.test.mjs new file mode 100644 index 0000000000..3c86e7ef86 --- /dev/null +++ b/lib/reference/__tests__/atKeywords.test.mjs @@ -0,0 +1,9 @@ +import { atKeywords, nestingSupportedAtKeywords } from '../atKeywords.js'; + +describe('atKeywords', () => { + it('nestingSupportedAtKeywords is a subset of all atKeywords', () => { + for (const keyword of nestingSupportedAtKeywords) { + expect(atKeywords).toContain(keyword); + } + }); +}); diff --git a/lib/reference/atKeywords.js b/lib/reference/atKeywords.js index 5773d14ea1..6934f883a3 100644 --- a/lib/reference/atKeywords.js +++ b/lib/reference/atKeywords.js @@ -2,6 +2,9 @@ const uniteSets = require('../utils/uniteSets.js'); +// https://www.w3.org/TR/css-nesting-1/#conditionals +const nestingSupportedAtKeywords = new Set(['container', 'layer', 'media', 'scope', 'supports']); + // https://www.w3.org/TR/css-page-3/#syntax-page-selector const pageMarginAtKeywords = new Set([ 'top-left-corner', @@ -45,6 +48,7 @@ const atKeywords = uniteSets(pageMarginAtKeywords, [ 'page', 'property', 'scroll-timeline', + 'scope', 'styleset', 'stylistic', 'supports', @@ -54,4 +58,5 @@ const atKeywords = uniteSets(pageMarginAtKeywords, [ module.exports = { atKeywords, + nestingSupportedAtKeywords, }; diff --git a/lib/rules/declaration-property-value-no-unknown/index.js b/lib/rules/declaration-property-value-no-unknown/index.js index 82d336749d..136b6ee803 100644 --- a/lib/rules/declaration-property-value-no-unknown/index.js +++ b/lib/rules/declaration-property-value-no-unknown/index.js @@ -15,6 +15,7 @@ const isStandardSyntaxProperty = require('../../utils/isStandardSyntaxProperty') const isStandardSyntaxDeclaration = require('../../utils/isStandardSyntaxDeclaration'); const { isAtRule } = require('../../utils/typeGuards'); const { isRegExp, isString } = require('../../utils/validateTypes'); +const { nestingSupportedAtKeywords } = require('../../reference/atKeywords'); const ruleName = 'declaration-property-value-no-unknown'; @@ -28,8 +29,6 @@ const meta = { url: 'https://stylelint.io/user-guide/rules/declaration-property-value-no-unknown', }; -const CONDITIONAL_RULES_ALLOWED_IN_NESTING = /^(?:media|supports|layer|scope|container)$/i; - /** @type {import('stylelint').Rule} */ const rule = (primary, secondaryOptions) => { return (root, result) => { @@ -113,7 +112,7 @@ const rule = (primary, secondaryOptions) => { } const { error } = - parent && isAtRule(parent) && !CONDITIONAL_RULES_ALLOWED_IN_NESTING.test(parent.name) + parent && isAtRule(parent) && !nestingSupportedAtKeywords.has(parent.name.toLowerCase()) ? forkedLexer.matchAtruleDescriptor(parent.name, prop, cssTreeValueNode) : forkedLexer.matchProperty(prop, cssTreeValueNode);