index.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. 'use strict';
  2. const isStandardSyntaxRule = require('../../utils/isStandardSyntaxRule');
  3. const isStandardSyntaxSelector = require('../../utils/isStandardSyntaxSelector');
  4. const keywordSets = require('../../reference/keywordSets');
  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. };
  16. /** @type {import('stylelint').Rule} */
  17. const rule = (primary, _secondaryOptions, context) => {
  18. return (root, result) => {
  19. const validOptions = validateOptions(result, ruleName, {
  20. actual: primary,
  21. possible: ['lower', 'upper'],
  22. });
  23. if (!validOptions) {
  24. return;
  25. }
  26. root.walkRules((ruleNode) => {
  27. if (!isStandardSyntaxRule(ruleNode)) {
  28. return;
  29. }
  30. const selector = ruleNode.selector;
  31. if (!selector.includes(':')) {
  32. return;
  33. }
  34. transformSelector(result, ruleNode, (selectorTree) => {
  35. selectorTree.walkPseudos((pseudoNode) => {
  36. const pseudoElement = pseudoNode.value;
  37. if (!isStandardSyntaxSelector(pseudoElement)) {
  38. return;
  39. }
  40. if (
  41. !pseudoElement.includes('::') &&
  42. !keywordSets.levelOneAndTwoPseudoElements.has(pseudoElement.toLowerCase().slice(1))
  43. ) {
  44. return;
  45. }
  46. const expectedPseudoElement =
  47. primary === 'lower' ? pseudoElement.toLowerCase() : pseudoElement.toUpperCase();
  48. if (pseudoElement === expectedPseudoElement) {
  49. return;
  50. }
  51. if (context.fix) {
  52. pseudoNode.value = expectedPseudoElement;
  53. return;
  54. }
  55. report({
  56. message: messages.expected(pseudoElement, expectedPseudoElement),
  57. node: ruleNode,
  58. index: pseudoNode.sourceIndex,
  59. ruleName,
  60. result,
  61. });
  62. });
  63. });
  64. });
  65. };
  66. };
  67. rule.ruleName = ruleName;
  68. rule.messages = messages;
  69. rule.meta = meta;
  70. module.exports = rule;