diff --git a/.changeset/modern-numbers-impress.md b/.changeset/modern-numbers-impress.md new file mode 100644 index 0000000000..73de26dadb --- /dev/null +++ b/.changeset/modern-numbers-impress.md @@ -0,0 +1,5 @@ +--- +"stylelint": patch +--- + +Fixed: `selector-anb-no-unmatchable` performance diff --git a/lib/rules/selector-anb-no-unmatchable/index.js b/lib/rules/selector-anb-no-unmatchable/index.js index 8299c91813..0a78998b4f 100644 --- a/lib/rules/selector-anb-no-unmatchable/index.js +++ b/lib/rules/selector-anb-no-unmatchable/index.js @@ -10,6 +10,7 @@ const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule'); const report = require('../../utils/report'); const ruleMessages = require('../../utils/ruleMessages'); const validateOptions = require('../../utils/validateOptions'); +const hasANPlusBNotationPseudoClasses = require('../../utils/hasANPlusBNotationPseudoClasses'); const ruleName = 'selector-anb-no-unmatchable'; @@ -50,6 +51,8 @@ const rule = (primary) => { } ruleNode.selectors.forEach((selector) => { + if (!hasANPlusBNotationPseudoClasses(selector)) return; + let cssTreeSelector; try { diff --git a/lib/utils/hasANPlusBNotationPseudoClasses.js b/lib/utils/hasANPlusBNotationPseudoClasses.js new file mode 100644 index 0000000000..41a367a59d --- /dev/null +++ b/lib/utils/hasANPlusBNotationPseudoClasses.js @@ -0,0 +1,22 @@ +'use strict'; + +const { + aNPlusBNotationPseudoClasses, + aNPlusBOfSNotationPseudoClasses, +} = require('../reference/selectors'); + +const classes = [ + ...aNPlusBNotationPseudoClasses.values(), + ...aNPlusBOfSNotationPseudoClasses.values(), +].join('|'); +const HAS_A_N_PLUS_B_NOTATION_PSEUDO_CLASSES = new RegExp(`\\b:(?:${classes})\\(`, 'i'); + +/** + * Check if a selector contains any pseudo class function that might contain an An+B notation + * + * @param {string} selector + * @returns {boolean} + */ +module.exports = function hasANPlusBNotationPseudoClasses(selector) { + return HAS_A_N_PLUS_B_NOTATION_PSEUDO_CLASSES.test(selector); +};