index.cjs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // NOTICE: This file is generated by Rollup. To modify it,
  2. // please instead edit the ESM counterpart and rebuild with Rollup (npm run build).
  3. 'use strict';
  4. const validateTypes = require('../../utils/validateTypes.cjs');
  5. const getRuleSelector = require('../../utils/getRuleSelector.cjs');
  6. const getStrippedSelectorSource = require('../../utils/getStrippedSelectorSource.cjs');
  7. const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule.cjs');
  8. const parseSelector = require('../../utils/parseSelector.cjs');
  9. const report = require('../../utils/report.cjs');
  10. const ruleMessages = require('../../utils/ruleMessages.cjs');
  11. const validateOptions = require('../../utils/validateOptions.cjs');
  12. /** @import { Rule } from 'postcss' */
  13. const ruleName = 'selector-nested-pattern';
  14. const messages = ruleMessages(ruleName, {
  15. expected: (selector, pattern) => `Expected "${selector}" to match pattern "${pattern}"`,
  16. });
  17. const meta = {
  18. url: 'https://stylelint.io/user-guide/rules/selector-nested-pattern',
  19. };
  20. /** @type {import('stylelint').CoreRules[ruleName]} */
  21. const rule = (primary, secondaryOptions) => {
  22. return (root, result) => {
  23. const validOptions = validateOptions(
  24. result,
  25. ruleName,
  26. {
  27. actual: primary,
  28. possible: [validateTypes.isRegExp, validateTypes.isString],
  29. },
  30. {
  31. actual: secondaryOptions,
  32. possible: {
  33. splitList: [validateTypes.isBoolean],
  34. },
  35. optional: true,
  36. },
  37. );
  38. if (!validOptions) {
  39. return;
  40. }
  41. const normalizedPattern = validateTypes.isString(primary) ? new RegExp(primary) : primary;
  42. const splitList = secondaryOptions && secondaryOptions.splitList;
  43. root.walkRules((ruleNode) => {
  44. if (ruleNode.parent && ruleNode.parent.type !== 'rule') {
  45. return;
  46. }
  47. if (!isStandardSyntaxRule(ruleNode)) {
  48. return;
  49. }
  50. const selectors = getRuleSelector(ruleNode);
  51. if (splitList) {
  52. parseSelector(selectors, result, ruleNode)?.each((selector) => {
  53. const { index, endIndex, selector: selectorStr } = getStrippedSelectorSource(selector);
  54. check(ruleNode, selectorStr, index, endIndex);
  55. });
  56. } else {
  57. check(ruleNode, selectors, 0, selectors.length);
  58. }
  59. });
  60. /**
  61. * @param {Rule} ruleNode
  62. * @param {string} selectorStr
  63. * @param {number} index
  64. * @param {number} endIndex
  65. */
  66. function check(ruleNode, selectorStr, index, endIndex) {
  67. if (normalizedPattern.test(selectorStr)) return;
  68. report({
  69. result,
  70. ruleName,
  71. message: messages.expected,
  72. messageArgs: [selectorStr, primary],
  73. node: ruleNode,
  74. index,
  75. endIndex,
  76. });
  77. }
  78. };
  79. };
  80. rule.ruleName = ruleName;
  81. rule.messages = messages;
  82. rule.meta = meta;
  83. module.exports = rule;