index.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports["default"] = rule;
  6. exports.ruleName = exports.meta = exports.messages = void 0;
  7. var _postcssSelectorParser = require("postcss-selector-parser");
  8. var _stylelint = require("stylelint");
  9. var _utils = require("../../utils");
  10. var ruleName = (0, _utils.namespace)("selector-no-union-class-name");
  11. exports.ruleName = ruleName;
  12. var messages = _stylelint.utils.ruleMessages(ruleName, {
  13. rejected: "Unexpected union class name with the parent selector (&)"
  14. });
  15. exports.messages = messages;
  16. var meta = {
  17. url: (0, _utils.ruleUrl)(ruleName)
  18. };
  19. exports.meta = meta;
  20. var validNestingTypes = [_postcssSelectorParser.isClassName, _postcssSelectorParser.isCombinator, _postcssSelectorParser.isAttribute, _postcssSelectorParser.isIdentifier, _postcssSelectorParser.isPseudoClass, _postcssSelectorParser.isPseudoElement];
  21. function rule(actual) {
  22. return function (root, result) {
  23. var validOptions = _stylelint.utils.validateOptions(result, ruleName, {
  24. actual: actual
  25. });
  26. if (!validOptions) {
  27. return;
  28. }
  29. root.walkRules(/&/, function (rule) {
  30. var parentNodes = [];
  31. var selector = getSelectorFromRule(rule.parent);
  32. if (selector) {
  33. (0, _utils.parseSelector)(selector, result, rule, function (fullSelector) {
  34. fullSelector.walk(function (node) {
  35. return parentNodes.push(node);
  36. });
  37. });
  38. }
  39. if (parentNodes.length === 0) return;
  40. var lastParentNode = parentNodes[parentNodes.length - 1];
  41. if (!(0, _postcssSelectorParser.isClassName)(lastParentNode)) return;
  42. (0, _utils.parseSelector)(rule.selector, result, rule, function (fullSelector) {
  43. fullSelector.walkNesting(function (node) {
  44. var next = node.next();
  45. if (!next) return;
  46. if (validNestingTypes.some(function (isType) {
  47. return isType(next);
  48. })) return;
  49. _stylelint.utils.report({
  50. ruleName: ruleName,
  51. result: result,
  52. node: rule,
  53. message: messages.rejected,
  54. index: node.sourceIndex
  55. });
  56. });
  57. });
  58. });
  59. };
  60. }
  61. rule.ruleName = ruleName;
  62. rule.messages = messages;
  63. rule.meta = meta;
  64. /**
  65. * Searches for the closest rule which
  66. * has a selector and returns the selector
  67. * @returns {string|undefined}
  68. */
  69. function getSelectorFromRule(rule) {
  70. // All non at-rules have their own selector
  71. if (rule.selector !== undefined) {
  72. return rule.selector;
  73. }
  74. // At-rules like @mixin don't have a selector themself
  75. // but their parents might have one
  76. if (rule.parent) {
  77. return getSelectorFromRule(rule.parent);
  78. }
  79. }