valueListCommaWhitespaceChecker.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. 'use strict';
  2. const isStandardSyntaxDeclaration = require('../utils/isStandardSyntaxDeclaration');
  3. const isStandardSyntaxProperty = require('../utils/isStandardSyntaxProperty');
  4. const report = require('../utils/report');
  5. const styleSearch = require('style-search');
  6. /**
  7. * @param {{
  8. * root: import('postcss').Root,
  9. * result: import('stylelint').PostcssResult,
  10. * locationChecker: (opts: { source: string, index: number, err: (msg: string) => void }) => void,
  11. * checkedRuleName: string,
  12. * fix?: ((node: import('postcss').Declaration, index: number) => void) | null,
  13. * determineIndex?: (declString: string, match: import('style-search').StyleSearchMatch) => number | false,
  14. * }} opts
  15. */
  16. module.exports = function valueListCommaWhitespaceChecker(opts) {
  17. opts.root.walkDecls((decl) => {
  18. if (!isStandardSyntaxDeclaration(decl) || !isStandardSyntaxProperty(decl.prop)) {
  19. return;
  20. }
  21. const declString = decl.toString();
  22. styleSearch(
  23. {
  24. source: declString,
  25. target: ',',
  26. functionArguments: 'skip',
  27. },
  28. (match) => {
  29. const indexToCheckAfter = opts.determineIndex
  30. ? opts.determineIndex(declString, match)
  31. : match.startIndex;
  32. if (indexToCheckAfter === false) {
  33. return;
  34. }
  35. checkComma(declString, indexToCheckAfter, decl);
  36. },
  37. );
  38. });
  39. /**
  40. * @param {string} source
  41. * @param {number} index
  42. * @param {import('postcss').Declaration} node
  43. * @returns {void}
  44. */
  45. function checkComma(source, index, node) {
  46. opts.locationChecker({
  47. source,
  48. index,
  49. err: (message) => {
  50. if (opts.fix && opts.fix(node, index)) {
  51. return;
  52. }
  53. report({
  54. message,
  55. node,
  56. index,
  57. result: opts.result,
  58. ruleName: opts.checkedRuleName,
  59. });
  60. },
  61. });
  62. }
  63. };