mediaQueryListCommaWhitespaceChecker.js 1.9 KB

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