index.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. 'use strict';
  2. const isCustomProperty = require('../../utils/isCustomProperty');
  3. const isStandardSyntaxProperty = require('../../utils/isStandardSyntaxProperty');
  4. const report = require('../../utils/report');
  5. const ruleMessages = require('../../utils/ruleMessages');
  6. const validateOptions = require('../../utils/validateOptions');
  7. const optionsMatches = require('../../utils/optionsMatches');
  8. const { isRegExp, isString } = require('../../utils/validateTypes');
  9. const { isRule } = require('../../utils/typeGuards');
  10. const ruleName = 'property-case';
  11. const messages = ruleMessages(ruleName, {
  12. expected: (actual, expected) => `Expected "${actual}" to be "${expected}"`,
  13. });
  14. const meta = {
  15. url: 'https://stylelint.io/user-guide/rules/property-case',
  16. fixable: true,
  17. };
  18. /** @type {import('stylelint').Rule} */
  19. const rule = (primary, secondaryOptions, context) => {
  20. return (root, result) => {
  21. const validOptions = validateOptions(
  22. result,
  23. ruleName,
  24. {
  25. actual: primary,
  26. possible: ['lower', 'upper'],
  27. },
  28. {
  29. actual: secondaryOptions,
  30. possible: {
  31. ignoreSelectors: [isString, isRegExp],
  32. },
  33. optional: true,
  34. },
  35. );
  36. if (!validOptions) {
  37. return;
  38. }
  39. root.walkDecls((decl) => {
  40. const prop = decl.prop;
  41. if (!isStandardSyntaxProperty(prop)) {
  42. return;
  43. }
  44. if (isCustomProperty(prop)) {
  45. return;
  46. }
  47. const { parent } = decl;
  48. if (!parent) throw new Error('A parent node must be present');
  49. if (isRule(parent)) {
  50. const { selector } = parent;
  51. if (selector && optionsMatches(secondaryOptions, 'ignoreSelectors', selector)) {
  52. return;
  53. }
  54. }
  55. const expectedProp = primary === 'lower' ? prop.toLowerCase() : prop.toUpperCase();
  56. if (prop === expectedProp) {
  57. return;
  58. }
  59. if (context.fix) {
  60. decl.prop = expectedProp;
  61. return;
  62. }
  63. report({
  64. message: messages.expected(prop, expectedProp),
  65. word: prop,
  66. node: decl,
  67. ruleName,
  68. result,
  69. });
  70. });
  71. };
  72. };
  73. rule.ruleName = ruleName;
  74. rule.messages = messages;
  75. rule.meta = meta;
  76. module.exports = rule;