index.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. 'use strict';
  2. const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule');
  3. const isStandardSyntaxSelector = require('../../utils/isStandardSyntaxSelector');
  4. const { levelOneAndTwoPseudoElements } = require('../../reference/selectors');
  5. const report = require('../../utils/report');
  6. const ruleMessages = require('../../utils/ruleMessages');
  7. const transformSelector = require('../../utils/transformSelector');
  8. const validateOptions = require('../../utils/validateOptions');
  9. const ruleName = 'selector-pseudo-element-case';
  10. const messages = ruleMessages(ruleName, {
  11. expected: (actual, expected) => `Expected "${actual}" to be "${expected}"`,
  12. });
  13. const meta = {
  14. url: 'https://stylelint.io/user-guide/rules/list/selector-pseudo-element-case',
  15. fixable: true,
  16. };
  17. /** @type {import('stylelint').Rule} */
  18. const rule = (primary, _secondaryOptions, context) => {
  19. return (root, result) => {
  20. const validOptions = validateOptions(result, ruleName, {
  21. actual: primary,
  22. possible: ['lower', 'upper'],
  23. });
  24. if (!validOptions) {
  25. return;
  26. }
  27. root.walkRules((ruleNode) => {
  28. if (!isStandardSyntaxRule(ruleNode)) {
  29. return;
  30. }
  31. const selector = ruleNode.selector;
  32. if (!selector.includes(':')) {
  33. return;
  34. }
  35. transformSelector(result, ruleNode, (selectorTree) => {
  36. selectorTree.walkPseudos((pseudoNode) => {
  37. const pseudoElement = pseudoNode.value;
  38. if (!isStandardSyntaxSelector(pseudoElement)) {
  39. return;
  40. }
  41. if (
  42. !pseudoElement.includes('::') &&
  43. !levelOneAndTwoPseudoElements.has(pseudoElement.toLowerCase().slice(1))
  44. ) {
  45. return;
  46. }
  47. const expectedPseudoElement =
  48. primary === 'lower' ? pseudoElement.toLowerCase() : pseudoElement.toUpperCase();
  49. if (pseudoElement === expectedPseudoElement) {
  50. return;
  51. }
  52. if (context.fix) {
  53. pseudoNode.value = expectedPseudoElement;
  54. return;
  55. }
  56. report({
  57. message: messages.expected(pseudoElement, expectedPseudoElement),
  58. node: ruleNode,
  59. index: pseudoNode.sourceIndex,
  60. ruleName,
  61. result,
  62. });
  63. });
  64. });
  65. });
  66. };
  67. };
  68. rule.ruleName = ruleName;
  69. rule.messages = messages;
  70. rule.meta = meta;
  71. module.exports = rule;