mediaQueryListCommaWhitespaceChecker.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. 'use strict';
  2. const atRuleParamIndex = require('../utils/atRuleParamIndex');
  3. const report = require('../utils/report');
  4. const styleSearch = require('style-search');
  5. /**
  6. * @param {{
  7. * root: import('postcss').Root,
  8. * result: import('stylelint').PostcssResult,
  9. * locationChecker: (args: { source: string, index: number, err: (message: string) => void }) => void,
  10. * checkedRuleName: string,
  11. * fix?: ((atRule: import('postcss').AtRule, index: number) => boolean) | null | undefined,
  12. * allowTrailingComments?: boolean,
  13. * }} opts
  14. */
  15. module.exports = function mediaQueryListCommaWhitespaceChecker(opts) {
  16. opts.root.walkAtRules(/^media$/i, (atRule) => {
  17. const params = atRule.raws.params ? atRule.raws.params.raw : atRule.params;
  18. styleSearch({ source: params, target: ',' }, (match) => {
  19. let index = match.startIndex;
  20. if (opts.allowTrailingComments) {
  21. // if there is a comment on the same line at after the comma, check the space after the comment.
  22. let execResult;
  23. while ((execResult = /^[^\S\r\n]*\/\*([\s\S]*?)\*\//.exec(params.slice(index + 1)))) {
  24. index += execResult[0].length;
  25. }
  26. if ((execResult = /^([^\S\r\n]*\/\/[\s\S]*?)\r?\n/.exec(params.slice(index + 1)))) {
  27. index += execResult[1].length;
  28. }
  29. }
  30. checkComma(params, index, atRule);
  31. });
  32. });
  33. /**
  34. * @param {string} source
  35. * @param {number} index
  36. * @param {import('postcss').AtRule} node
  37. */
  38. function checkComma(source, index, node) {
  39. opts.locationChecker({
  40. source,
  41. index,
  42. err: (message) => {
  43. const commaIndex = index + atRuleParamIndex(node);
  44. if (opts.fix && opts.fix(node, commaIndex)) {
  45. return;
  46. }
  47. report({
  48. message,
  49. node,
  50. index: commaIndex,
  51. result: opts.result,
  52. ruleName: opts.checkedRuleName,
  53. });
  54. },
  55. });
  56. }
  57. };