Skip to content

Commit

Permalink
Fix rule-selector-property-disallowed-list false positives for nest…
Browse files Browse the repository at this point in the history
…ing selectors (#7558)

Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>
  • Loading branch information
romainmenke and ybiquitous committed Mar 15, 2024
1 parent 5078666 commit 8a3f67e
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-roses-refuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"stylelint": patch
---

Fixed: `rule-selector-property-disallowed-list` false positives for nesting selectors
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ testRule({
{
code: 'a { background-color: red; }',
},
{
code: 'a { b { color: red; } }',
},
{
code: 'b { & a { color: red; } }',
},
{
code: 'a[href="#"] { color: red; }',
},
Expand Down Expand Up @@ -46,6 +52,14 @@ testRule({
endLine: 1,
endColumn: 27,
},
{
code: 'a { @media screen { color: red; } }',
message: messages.rejected('a', 'color'),
line: 1,
column: 21,
endLine: 1,
endColumn: 26,
},
{
code: 'a { margin-top: 0px; }',
message: messages.rejected('a', 'margin-top'),
Expand Down Expand Up @@ -89,6 +103,22 @@ testRule({
endLine: 1,
endColumn: 27,
},
{
code: 'b { a { color: red; } }',
message: messages.rejected('a', 'color'),
line: 1,
column: 9,
endLine: 1,
endColumn: 14,
},
{
code: 'a { b { width: 100% } color: red; }',
message: messages.rejected('a', 'color'),
line: 1,
column: 23,
endLine: 1,
endColumn: 28,
},
],
});

Expand All @@ -104,3 +134,49 @@ testRule({
},
],
});

testRule({
ruleName,
config: {
'/^((?!input).)*$/': 'color',
},

accept: [
{
code: '.foo input { color: red; }',
},
{
code: '.foo { & input { color: red; } }',
},
{
code: 'input .foo { color: red; }',
},
],

reject: [
{
code: '.foo form { color: red; }',
message: messages.rejected('.foo form', 'color'),
line: 1,
column: 13,
endLine: 1,
endColumn: 18,
},
{
code: '.search { & form { color: red; } }',
message: messages.rejected('& form', 'color'),
line: 1,
column: 20,
endLine: 1,
endColumn: 25,
},
{
code: 'input { & .foo { color: red; } }',
message: messages.rejected('& .foo', 'color'),
line: 1,
column: 18,
endLine: 1,
endColumn: 23,
},
],
});
23 changes: 23 additions & 0 deletions lib/rules/rule-selector-property-disallowed-list/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ const rule = (primary) => {
}

ruleNode.walkDecls((decl) => {
if (!declarationIsAChildOfRule(decl, ruleNode)) return;

const { prop } = decl;

if (matchesStringOrRegExp(prop, disallowedProperties)) {
Expand All @@ -75,4 +77,25 @@ rule.ruleName = ruleName;
rule.messages = messages;
rule.meta = meta;

/**
* Check that a given declaration is a child of this rule and not a nested rule
*
* @param {import('postcss').Declaration} decl
* @param {import('postcss').Rule} ruleNode
*/
function declarationIsAChildOfRule(decl, ruleNode) {
/** @type {import('postcss').Container['parent']} */
let parent = decl.parent;

while (parent) {
if (parent === ruleNode) return true;

if (parent.type === 'rule') return false;

parent = parent.parent;
}

return false;
}

module.exports = rule;
23 changes: 23 additions & 0 deletions lib/rules/rule-selector-property-disallowed-list/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ const rule = (primary) => {
}

ruleNode.walkDecls((decl) => {
if (!declarationIsAChildOfRule(decl, ruleNode)) return;

const { prop } = decl;

if (matchesStringOrRegExp(prop, disallowedProperties)) {
Expand All @@ -71,3 +73,24 @@ rule.ruleName = ruleName;
rule.messages = messages;
rule.meta = meta;
export default rule;

/**
* Check that a given declaration is a child of this rule and not a nested rule
*
* @param {import('postcss').Declaration} decl
* @param {import('postcss').Rule} ruleNode
*/
function declarationIsAChildOfRule(decl, ruleNode) {
/** @type {import('postcss').Container['parent']} */
let parent = decl.parent;

while (parent) {
if (parent === ruleNode) return true;

if (parent.type === 'rule') return false;

parent = parent.parent;
}

return false;
}

0 comments on commit 8a3f67e

Please sign in to comment.