From 7ebf2661dcf06520f8748c4a71f4a966084fb5a3 Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Tue, 12 Oct 2021 11:13:02 -0400 Subject: [PATCH 01/12] add ignorePseudoClasses option --- lib/rules/max-nesting-depth/README.md | 58 +++++++++++++++++++ .../max-nesting-depth/__tests__/index.js | 25 ++++++++ lib/rules/max-nesting-depth/index.js | 23 +++++++- 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/lib/rules/max-nesting-depth/README.md b/lib/rules/max-nesting-depth/README.md index e0a1e8d8d0..24345c6ce9 100644 --- a/lib/rules/max-nesting-depth/README.md +++ b/lib/rules/max-nesting-depth/README.md @@ -353,3 +353,61 @@ a { } } ``` + +### `ignorePseudoClasses: ["string"]` + +Ignore the specified pseudo classes. + +For example, with `1` and given: + +```json +["hover", "active"] +``` + +The following patterns are _not_ considered problems: + + +```scss +.a { + &:hover { /* ignored */ + .b { /* 1 */ + top: 0; + } + } +} +``` + + +```scss +.a { + &:hover, &:active { /* ignored */ + .b { /* 1 */ + top: 0; + } + } +} +``` + +The following patterns are considered problems: + + +```scss +.a { + &:visited { /* 1 */ + .b { /* 2 */ + top: 0; + } + } +} +``` + + +```scss +.a { + &:hover, &:visited { /* 1 */ + .b { /* 2 */ + top: 0; + } + } +} +``` diff --git a/lib/rules/max-nesting-depth/__tests__/index.js b/lib/rules/max-nesting-depth/__tests__/index.js index 34a6ed9267..a078a42f2b 100644 --- a/lib/rules/max-nesting-depth/__tests__/index.js +++ b/lib/rules/max-nesting-depth/__tests__/index.js @@ -166,6 +166,31 @@ testRule({ ], }); +testRule({ + ruleName, + config: [1, { ignorePseudoClasses: ['hover', 'active'] }], + + accept: [ + { + code: '.a { &:hover { .b { top: 0; } } }', + }, + { + code: '.a { &:hover, &:active { .b { top: 0; } } }', + }, + ], + + reject: [ + { + code: '.a { &:visited { .b { top: 0; } } }', + message: messages.expected(1), + }, + { + code: '.a { &:hover, &:visited { .b { top: 0; } } }', + message: messages.expected(1), + }, + ], +}); + testRule({ ruleName, config: [1, { ignoreAtRules: ['media', '/^my-/'] }], diff --git a/lib/rules/max-nesting-depth/index.js b/lib/rules/max-nesting-depth/index.js index 0670c9aafa..b92cd7c440 100644 --- a/lib/rules/max-nesting-depth/index.js +++ b/lib/rules/max-nesting-depth/index.js @@ -16,7 +16,7 @@ const messages = ruleMessages(ruleName, { expected: (depth) => `Expected nesting depth to be no more than ${depth}`, }); -/** @type {import('stylelint').Rule} */ +/** @type {import('stylelint').StylelintRule} */ const rule = (primary, secondaryOptions) => { /** * @param {import('postcss').Node} node @@ -38,6 +38,7 @@ const rule = (primary, secondaryOptions) => { possible: { ignore: ['blockless-at-rules', 'pseudo-classes'], ignoreAtRules: [isString, isRegExp], + ignorePseudoClasses: [isString], }, }, ); @@ -108,13 +109,31 @@ const rule = (primary, secondaryOptions) => { return selectors.every((sel) => sel.startsWith('&:') && sel[2] !== ':'); } + /** + * @param {string[]} matches + * @param {string[]} selectors + * @returns {boolean} + */ + function containsIgnoredPseudoClassesOnly(matches, selectors) { + return selectors.every((selector) => { + const pseudoRule = selector.startsWith('&:') && selector[2] !== ':' && selector.substr(2); + + if (!pseudoRule) return false; + + return Boolean(matches.indexOf(pseudoRule) !== -1); + }); + } + if ( (optionsMatches(secondaryOptions, 'ignore', 'blockless-at-rules') && isAtRule(node) && node.every((child) => !isDeclaration(child))) || (optionsMatches(secondaryOptions, 'ignore', 'pseudo-classes') && isRule(node) && - containsPseudoClassesOnly(node.selector)) + containsPseudoClassesOnly(node.selector)) || + (isRule(node) && + secondaryOptions.ignorePseudoClasses && + containsIgnoredPseudoClassesOnly(secondaryOptions.ignorePseudoClasses, node.selectors)) ) { return nestingDepth(parent, level); } From 921cfdc656ab792148ce198bb4768d7c7c811a74 Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Tue, 12 Oct 2021 11:17:34 -0400 Subject: [PATCH 02/12] correct type after merge --- lib/rules/max-nesting-depth/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/max-nesting-depth/index.js b/lib/rules/max-nesting-depth/index.js index b92cd7c440..ecfbc995b7 100644 --- a/lib/rules/max-nesting-depth/index.js +++ b/lib/rules/max-nesting-depth/index.js @@ -16,7 +16,7 @@ const messages = ruleMessages(ruleName, { expected: (depth) => `Expected nesting depth to be no more than ${depth}`, }); -/** @type {import('stylelint').StylelintRule} */ +/** @type {import('stylelint').Rule} */ const rule = (primary, secondaryOptions) => { /** * @param {import('postcss').Node} node From bf47661dac609fc2b6c4c4922ba5a5447160642d Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Tue, 12 Oct 2021 11:21:37 -0400 Subject: [PATCH 03/12] convert code blocks to css in docs --- lib/rules/max-nesting-depth/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/rules/max-nesting-depth/README.md b/lib/rules/max-nesting-depth/README.md index 24345c6ce9..b237aa646d 100644 --- a/lib/rules/max-nesting-depth/README.md +++ b/lib/rules/max-nesting-depth/README.md @@ -367,7 +367,7 @@ For example, with `1` and given: The following patterns are _not_ considered problems: -```scss +```css .a { &:hover { /* ignored */ .b { /* 1 */ @@ -378,7 +378,7 @@ The following patterns are _not_ considered problems: ``` -```scss +```css .a { &:hover, &:active { /* ignored */ .b { /* 1 */ @@ -391,7 +391,7 @@ The following patterns are _not_ considered problems: The following patterns are considered problems: -```scss +```css .a { &:visited { /* 1 */ .b { /* 2 */ @@ -402,7 +402,7 @@ The following patterns are considered problems: ``` -```scss +```css .a { &:hover, &:visited { /* 1 */ .b { /* 2 */ From d9613150c6c32fe4720263d47bcb6f8866f02126 Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Tue, 12 Oct 2021 11:37:37 -0400 Subject: [PATCH 04/12] fix undefined options --- lib/rules/max-nesting-depth/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/rules/max-nesting-depth/index.js b/lib/rules/max-nesting-depth/index.js index ecfbc995b7..6247de6f98 100644 --- a/lib/rules/max-nesting-depth/index.js +++ b/lib/rules/max-nesting-depth/index.js @@ -132,6 +132,7 @@ const rule = (primary, secondaryOptions) => { isRule(node) && containsPseudoClassesOnly(node.selector)) || (isRule(node) && + secondaryOptions && secondaryOptions.ignorePseudoClasses && containsIgnoredPseudoClassesOnly(secondaryOptions.ignorePseudoClasses, node.selectors)) ) { From ef9fd440326d200fab83ce74e0043ee0ff4ccb1a Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Thu, 21 Oct 2021 12:35:52 -0400 Subject: [PATCH 05/12] update to support RegEx --- lib/rules/max-nesting-depth/README.md | 2 +- lib/rules/max-nesting-depth/__tests__/index.js | 13 ++++++++++--- lib/rules/max-nesting-depth/index.js | 13 +++++++------ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/rules/max-nesting-depth/README.md b/lib/rules/max-nesting-depth/README.md index b237aa646d..17765c6358 100644 --- a/lib/rules/max-nesting-depth/README.md +++ b/lib/rules/max-nesting-depth/README.md @@ -354,7 +354,7 @@ a { } ``` -### `ignorePseudoClasses: ["string"]` +### `ignorePseudoClasses: ["/regex/", /regex/, "string"]` Ignore the specified pseudo classes. diff --git a/lib/rules/max-nesting-depth/__tests__/index.js b/lib/rules/max-nesting-depth/__tests__/index.js index a078a42f2b..323694c3eb 100644 --- a/lib/rules/max-nesting-depth/__tests__/index.js +++ b/lib/rules/max-nesting-depth/__tests__/index.js @@ -168,14 +168,14 @@ testRule({ testRule({ ruleName, - config: [1, { ignorePseudoClasses: ['hover', 'active'] }], + config: [1, { ignorePseudoClasses: ['hover', '/^custom-.*$/'] }], accept: [ { code: '.a { &:hover { .b { top: 0; } } }', }, { - code: '.a { &:hover, &:active { .b { top: 0; } } }', + code: '.a { &:hover, &:custom-pseudo { .b { top: 0; } } }', }, ], @@ -183,10 +183,17 @@ testRule({ { code: '.a { &:visited { .b { top: 0; } } }', message: messages.expected(1), + description: 'pseudo-class not ignored', }, { - code: '.a { &:hover, &:visited { .b { top: 0; } } }', + code: '.a { &:custom-pseudo, &:visited { .b { top: 0; } } }', message: messages.expected(1), + description: 'ignored pseudo-class alongside pseudo-class', + }, + { + code: '.a { &:hover, .b { .c { top: 0; } } }', + message: messages.expected(1), + description: 'pseudo-class alongside class', }, ], }); diff --git a/lib/rules/max-nesting-depth/index.js b/lib/rules/max-nesting-depth/index.js index 6247de6f98..2b89eec9d7 100644 --- a/lib/rules/max-nesting-depth/index.js +++ b/lib/rules/max-nesting-depth/index.js @@ -25,7 +25,7 @@ const rule = (primary, secondaryOptions) => { isAtRule(node) && optionsMatches(secondaryOptions, 'ignoreAtRules', node.name); return (root, result) => { - validateOptions( + const validOptions = validateOptions( result, ruleName, { @@ -38,11 +38,13 @@ const rule = (primary, secondaryOptions) => { possible: { ignore: ['blockless-at-rules', 'pseudo-classes'], ignoreAtRules: [isString, isRegExp], - ignorePseudoClasses: [isString], + ignorePseudoClasses: [isString, isRegExp], }, }, ); + if (!validOptions) return; + root.walkRules(checkStatement); root.walkAtRules(checkStatement); @@ -110,17 +112,16 @@ const rule = (primary, secondaryOptions) => { } /** - * @param {string[]} matches * @param {string[]} selectors * @returns {boolean} */ - function containsIgnoredPseudoClassesOnly(matches, selectors) { + function containsIgnoredPseudoClassesOnly(selectors) { return selectors.every((selector) => { const pseudoRule = selector.startsWith('&:') && selector[2] !== ':' && selector.substr(2); if (!pseudoRule) return false; - return Boolean(matches.indexOf(pseudoRule) !== -1); + return optionsMatches(secondaryOptions, 'ignorePseudoClasses', pseudoRule); }); } @@ -134,7 +135,7 @@ const rule = (primary, secondaryOptions) => { (isRule(node) && secondaryOptions && secondaryOptions.ignorePseudoClasses && - containsIgnoredPseudoClassesOnly(secondaryOptions.ignorePseudoClasses, node.selectors)) + containsIgnoredPseudoClassesOnly(node.selectors)) ) { return nestingDepth(parent, level); } From d58853b63aaa5dc8c507387982081551e60f4877 Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Wed, 27 Oct 2021 10:18:56 -0400 Subject: [PATCH 06/12] unify selectors and naming in tests and docs --- lib/rules/max-nesting-depth/README.md | 64 +++++++++---------- .../max-nesting-depth/__tests__/index.js | 38 +++++------ 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/lib/rules/max-nesting-depth/README.md b/lib/rules/max-nesting-depth/README.md index 17765c6358..e1a0dc768e 100644 --- a/lib/rules/max-nesting-depth/README.md +++ b/lib/rules/max-nesting-depth/README.md @@ -17,7 +17,7 @@ a { & b { /* nesting depth 1 */ & .foo { /* nesting depth 2 */ @media print { /* nesting depth 3 */ - & .baz { /* nesting depth 4 */ + & baz { /* nesting depth 4 */ color: pink; } } @@ -60,7 +60,7 @@ The following patterns are considered problems: a { & .foo { /* 1 */ &__foo { /* 2 */ - & > .bar {} /* 3 */ + & > bar {} /* 3 */ } } } @@ -71,7 +71,7 @@ a { a { @media print { /* 1 */ & .foo { /* 2 */ - & .bar {} /* 3 */ + & bar {} /* 3 */ } } } @@ -87,7 +87,7 @@ a { } } -a .foo__foo .bar .baz {} +a .foo__foo bar baz {} ``` @@ -170,8 +170,8 @@ The following patterns are considered problems: ```css -.a { - .b { /* 1 */ +a { + b { /* 1 */ .c { /* 2 */ top: 0; } @@ -181,9 +181,9 @@ The following patterns are considered problems: ```css -.a { +a { &:hover { /* ignored */ - .b { /* 1 */ + b { /* 1 */ .c { /* 2 */ top: 0; } @@ -194,8 +194,8 @@ The following patterns are considered problems: ```css -.a { - .b { /* 1 */ +a { + b { /* 1 */ &::selection { /* 2 */ color: #64FFDA; } @@ -205,8 +205,8 @@ The following patterns are considered problems: ```css -.a { - .b { /* 1 */ +a { + b { /* 1 */ &:hover, .c { /* 2 */ top: 0; } @@ -216,12 +216,12 @@ The following patterns are considered problems: The following patterns are _not_ considered problems: -As all of the following pseudoclasses rules would have a nesting depth of just 1. +As all of the following pseudo-classes rules would have a nesting depth of just 1. ```css -.a { - .b { /* 1 */ +a { + b { /* 1 */ &:hover { /* ignored */ top: 0; } @@ -231,8 +231,8 @@ As all of the following pseudoclasses rules would have a nesting depth of just 1 ```css -.a { - .b { /* 1 */ +a { + b { /* 1 */ &:nest { &:nest-lvl2 { /* ignored */ top: 0; @@ -244,9 +244,9 @@ As all of the following pseudoclasses rules would have a nesting depth of just 1 ```css -.a { +a { &:hover { /* ignored */ - .b { /* 1 */ + b { /* 1 */ top: 0; } } @@ -255,11 +255,11 @@ As all of the following pseudoclasses rules would have a nesting depth of just 1 ```css -.a { +a { &:nest { /* ignored */ &:nest-lvl2 { /* ignored */ top: 0; - .b { /* 1 */ + b { /* 1 */ bottom: 0; } } @@ -269,8 +269,8 @@ As all of the following pseudoclasses rules would have a nesting depth of just 1 ```css -.a { - .b { /* 1 */ +a { + b { /* 1 */ &:hover, &:focus { /* ignored */ top: 0; } @@ -356,7 +356,7 @@ a { ### `ignorePseudoClasses: ["/regex/", /regex/, "string"]` -Ignore the specified pseudo classes. +Ignore the specified pseudo-classes. For example, with `1` and given: @@ -368,9 +368,9 @@ The following patterns are _not_ considered problems: ```css -.a { +a { &:hover { /* ignored */ - .b { /* 1 */ + b { /* 1 */ top: 0; } } @@ -379,9 +379,9 @@ The following patterns are _not_ considered problems: ```css -.a { +a { &:hover, &:active { /* ignored */ - .b { /* 1 */ + b { /* 1 */ top: 0; } } @@ -392,9 +392,9 @@ The following patterns are considered problems: ```css -.a { +a { &:visited { /* 1 */ - .b { /* 2 */ + b { /* 2 */ top: 0; } } @@ -403,9 +403,9 @@ The following patterns are considered problems: ```css -.a { +a { &:hover, &:visited { /* 1 */ - .b { /* 2 */ + b { /* 2 */ top: 0; } } diff --git a/lib/rules/max-nesting-depth/__tests__/index.js b/lib/rules/max-nesting-depth/__tests__/index.js index 323694c3eb..c9e772b59b 100644 --- a/lib/rules/max-nesting-depth/__tests__/index.js +++ b/lib/rules/max-nesting-depth/__tests__/index.js @@ -117,50 +117,50 @@ testRule({ accept: [ { - code: '.a { .b { top: 0; }}', + code: 'a { b { top: 0; }}', }, { - code: '.a { .b { &:hover { top: 0; }}}', + code: 'a { b { &:hover { top: 0; }}}', }, { - code: '.a { .b { &:nest { &:nest-lvl2 { top: 0; }}}}', + code: 'a { b { &:nest { &:nest-lvl2 { top: 0; }}}}', }, { - code: '.a { &:hover { .b { top: 0; }}}', + code: 'a { &:hover { b { top: 0; }}}', }, { - code: '.a { .b { &:hover { &:focus { &:otherone { top: 0; }}}}}', + code: 'a { b { &:hover { &:focus { &:otherone { top: 0; }}}}}', }, { - code: '.a { &:nest { &:nest-lvl2 { top: 0; .b { bottom: 0; }}}}', + code: 'a { &:nest { &:nest-lvl2 { top: 0; b { bottom: 0; }}}}', }, { - code: '.a { .b { &:hover .c { top: 0; }}}', + code: 'a { b { &:hover .c { top: 0; }}}', }, { - code: '.a { .b { &:hover, &:focus { top: 0; }}}', + code: 'a { b { &:hover, &:focus { top: 0; }}}', }, ], reject: [ { - code: '.a { .b { .c { top: 0; }}}', + code: 'a { b { .c { top: 0; }}}', message: messages.expected(1), }, { - code: '.a { &:hover { .b { .c { top: 0; }}}}', + code: 'a { &:hover { b { .c { top: 0; }}}}', message: messages.expected(1), }, { - code: '.a { .b { &:hover { &:focus { &:otherone { .c { top: 0; }}}}}}', + code: 'a { b { &:hover { &:focus { &:otherone { .c { top: 0; }}}}}}', message: messages.expected(1), }, { - code: '.a { .b { &::selection { color: #64FFDA; }}}', + code: 'a { b { &::selection { color: #64FFDA; }}}', message: messages.expected(1), }, { - code: '.a { .b { &:hover, .c { top: 0; }}}', + code: 'a { b { &:hover, .c { top: 0; }}}', message: messages.expected(1), }, ], @@ -172,26 +172,26 @@ testRule({ accept: [ { - code: '.a { &:hover { .b { top: 0; } } }', + code: 'a { &:hover { b { top: 0; } } }', }, { - code: '.a { &:hover, &:custom-pseudo { .b { top: 0; } } }', + code: 'a { &:hover, &:custom-pseudo { b { top: 0; } } }', }, ], reject: [ { - code: '.a { &:visited { .b { top: 0; } } }', + code: 'a { &:visited { b { top: 0; } } }', message: messages.expected(1), description: 'pseudo-class not ignored', }, { - code: '.a { &:custom-pseudo, &:visited { .b { top: 0; } } }', + code: 'a { &:custom-pseudo, &:visited { b { top: 0; } } }', message: messages.expected(1), description: 'ignored pseudo-class alongside pseudo-class', }, { - code: '.a { &:hover, .b { .c { top: 0; } } }', + code: 'a { &:hover, b { .c { top: 0; } } }', message: messages.expected(1), description: 'pseudo-class alongside class', }, @@ -259,7 +259,7 @@ testRule({ accept: [ { - code: '.foo { .bar { margin: { bottom: 0; } } }', + code: '.foo { bar { margin: { bottom: 0; } } }', description: 'SCSS nested properties', }, ], From 1c997d97a8086ca4c8396b30946becca1e86f1df Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Wed, 27 Oct 2021 10:20:30 -0400 Subject: [PATCH 07/12] add regex to example config --- lib/rules/max-nesting-depth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/max-nesting-depth/README.md b/lib/rules/max-nesting-depth/README.md index e1a0dc768e..3fe58818a2 100644 --- a/lib/rules/max-nesting-depth/README.md +++ b/lib/rules/max-nesting-depth/README.md @@ -361,7 +361,7 @@ Ignore the specified pseudo-classes. For example, with `1` and given: ```json -["hover", "active"] +["hover", "^focus-"] ``` The following patterns are _not_ considered problems: From 1062f51884620cf22fcc6829fe33fe07a04a204d Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Wed, 27 Oct 2021 11:14:19 -0400 Subject: [PATCH 08/12] update examples again --- lib/rules/max-nesting-depth/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/rules/max-nesting-depth/README.md b/lib/rules/max-nesting-depth/README.md index 3fe58818a2..b7df0379bc 100644 --- a/lib/rules/max-nesting-depth/README.md +++ b/lib/rules/max-nesting-depth/README.md @@ -17,7 +17,7 @@ a { & b { /* nesting depth 1 */ & .foo { /* nesting depth 2 */ @media print { /* nesting depth 3 */ - & baz { /* nesting depth 4 */ + & .baz { /* nesting depth 4 */ color: pink; } } @@ -60,7 +60,7 @@ The following patterns are considered problems: a { & .foo { /* 1 */ &__foo { /* 2 */ - & > bar {} /* 3 */ + & > .bar {} /* 3 */ } } } @@ -71,7 +71,7 @@ a { a { @media print { /* 1 */ & .foo { /* 2 */ - & bar {} /* 3 */ + & .bar {} /* 3 */ } } } @@ -87,7 +87,7 @@ a { } } -a .foo__foo bar baz {} +a .foo__foo .bar .baz {} ``` From d33758cb4424659d64e606bbf756505917c2713e Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Wed, 27 Oct 2021 11:16:02 -0400 Subject: [PATCH 09/12] updated test cases --- lib/rules/max-nesting-depth/__tests__/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/rules/max-nesting-depth/__tests__/index.js b/lib/rules/max-nesting-depth/__tests__/index.js index c9e772b59b..16b333fc14 100644 --- a/lib/rules/max-nesting-depth/__tests__/index.js +++ b/lib/rules/max-nesting-depth/__tests__/index.js @@ -135,7 +135,7 @@ testRule({ code: 'a { &:nest { &:nest-lvl2 { top: 0; b { bottom: 0; }}}}', }, { - code: 'a { b { &:hover .c { top: 0; }}}', + code: 'a { b { &:hover c { top: 0; }}}', }, { code: 'a { b { &:hover, &:focus { top: 0; }}}', @@ -144,15 +144,15 @@ testRule({ reject: [ { - code: 'a { b { .c { top: 0; }}}', + code: 'a { b { c { top: 0; }}}', message: messages.expected(1), }, { - code: 'a { &:hover { b { .c { top: 0; }}}}', + code: 'a { &:hover { b { c { top: 0; }}}}', message: messages.expected(1), }, { - code: 'a { b { &:hover { &:focus { &:otherone { .c { top: 0; }}}}}}', + code: 'a { b { &:hover { &:focus { &:otherone { c { top: 0; }}}}}}', message: messages.expected(1), }, { @@ -160,7 +160,7 @@ testRule({ message: messages.expected(1), }, { - code: 'a { b { &:hover, .c { top: 0; }}}', + code: 'a { b { &:hover, c { top: 0; }}}', message: messages.expected(1), }, ], @@ -191,7 +191,7 @@ testRule({ description: 'ignored pseudo-class alongside pseudo-class', }, { - code: 'a { &:hover, b { .c { top: 0; } } }', + code: 'a { &:hover, b { c { top: 0; } } }', message: messages.expected(1), description: 'pseudo-class alongside class', }, From 36c8158fa866bb98d220d313efaee4d37e438373 Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Wed, 27 Oct 2021 11:19:36 -0400 Subject: [PATCH 10/12] missed test change --- lib/rules/max-nesting-depth/__tests__/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/max-nesting-depth/__tests__/index.js b/lib/rules/max-nesting-depth/__tests__/index.js index 16b333fc14..406914462b 100644 --- a/lib/rules/max-nesting-depth/__tests__/index.js +++ b/lib/rules/max-nesting-depth/__tests__/index.js @@ -259,7 +259,7 @@ testRule({ accept: [ { - code: '.foo { bar { margin: { bottom: 0; } } }', + code: '.foo { .bar { margin: { bottom: 0; } } }', description: 'SCSS nested properties', }, ], From 6332c5fa72079955efed2d83acb7b38c5da49eb6 Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Wed, 27 Oct 2021 11:45:47 -0400 Subject: [PATCH 11/12] add suggestions from review --- lib/rules/max-nesting-depth/index.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/rules/max-nesting-depth/index.js b/lib/rules/max-nesting-depth/index.js index 2b89eec9d7..63f94ea390 100644 --- a/lib/rules/max-nesting-depth/index.js +++ b/lib/rules/max-nesting-depth/index.js @@ -108,7 +108,7 @@ const rule = (primary, secondaryOptions) => { const normalized = parser().processSync(selector, { lossless: false }); const selectors = normalized.split(','); - return selectors.every((sel) => sel.startsWith('&:') && sel[2] !== ':'); + return selectors.every((sel) => extractPseudoRule(sel)); } /** @@ -116,8 +116,10 @@ const rule = (primary, secondaryOptions) => { * @returns {boolean} */ function containsIgnoredPseudoClassesOnly(selectors) { + if (!(secondaryOptions && secondaryOptions.ignorePseudoClasses)) return false; + return selectors.every((selector) => { - const pseudoRule = selector.startsWith('&:') && selector[2] !== ':' && selector.substr(2); + const pseudoRule = extractPseudoRule(selector); if (!pseudoRule) return false; @@ -132,10 +134,7 @@ const rule = (primary, secondaryOptions) => { (optionsMatches(secondaryOptions, 'ignore', 'pseudo-classes') && isRule(node) && containsPseudoClassesOnly(node.selector)) || - (isRule(node) && - secondaryOptions && - secondaryOptions.ignorePseudoClasses && - containsIgnoredPseudoClassesOnly(node.selectors)) + (isRule(node) && containsIgnoredPseudoClassesOnly(node.selectors)) ) { return nestingDepth(parent, level); } @@ -148,6 +147,14 @@ const rule = (primary, secondaryOptions) => { } }; +/** + * @param {string} selector + * @returns {string | undefined} + */ +function extractPseudoRule(selector) { + return selector.startsWith('&:') && selector[2] !== ':' ? selector.substr(2) : undefined; +} + rule.ruleName = ruleName; rule.messages = messages; module.exports = rule; From c2c7813f40b2ecc4532d67f22e034949c39b1e0e Mon Sep 17 00:00:00 2001 From: Lachlan Heywood Date: Wed, 27 Oct 2021 15:02:06 -0400 Subject: [PATCH 12/12] Apply suggestions from code review Co-authored-by: Richard Hallows --- lib/rules/max-nesting-depth/__tests__/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/rules/max-nesting-depth/__tests__/index.js b/lib/rules/max-nesting-depth/__tests__/index.js index 406914462b..05ae869a85 100644 --- a/lib/rules/max-nesting-depth/__tests__/index.js +++ b/lib/rules/max-nesting-depth/__tests__/index.js @@ -168,14 +168,14 @@ testRule({ testRule({ ruleName, - config: [1, { ignorePseudoClasses: ['hover', '/^custom-.*$/'] }], + config: [1, { ignorePseudoClasses: ['hover', '/^--custom-.*$/'] }], accept: [ { code: 'a { &:hover { b { top: 0; } } }', }, { - code: 'a { &:hover, &:custom-pseudo { b { top: 0; } } }', + code: 'a { &:hover, &:--custom-pseudo { b { top: 0; } } }', }, ], @@ -186,7 +186,7 @@ testRule({ description: 'pseudo-class not ignored', }, { - code: 'a { &:custom-pseudo, &:visited { b { top: 0; } } }', + code: 'a { &:--custom-pseudo, &:visited { b { top: 0; } } }', message: messages.expected(1), description: 'ignored pseudo-class alongside pseudo-class', },