declarationBangSpaceChecker.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. 'use strict';
  2. const declarationValueIndex = require('../utils/declarationValueIndex');
  3. const report = require('../utils/report');
  4. const styleSearch = require('style-search');
  5. /** @typedef {import('postcss').Declaration} Declaration */
  6. /** @typedef {(args: { source: string, index: number, err: (message: string) => void }) => void} LocationChecker */
  7. /**
  8. * @param {{
  9. * root: import('postcss').Root,
  10. * locationChecker: LocationChecker,
  11. * result: import('stylelint').PostcssResult,
  12. * checkedRuleName: string,
  13. * fix: ((decl: Declaration, index: number) => boolean) | null,
  14. * }} opts
  15. * @returns {void}
  16. */
  17. module.exports = function declarationBangSpaceChecker(opts) {
  18. opts.root.walkDecls((decl) => {
  19. const indexOffset = declarationValueIndex(decl);
  20. const declString = decl.toString();
  21. const valueString = decl.toString().slice(indexOffset);
  22. if (!valueString.includes('!')) {
  23. return;
  24. }
  25. styleSearch({ source: valueString, target: '!' }, (match) => {
  26. check(declString, match.startIndex + indexOffset, decl);
  27. });
  28. });
  29. /**
  30. * @param {string} source
  31. * @param {number} index
  32. * @param {Declaration} decl
  33. */
  34. function check(source, index, decl) {
  35. opts.locationChecker({
  36. source,
  37. index,
  38. err: (message) => {
  39. if (opts.fix && opts.fix(decl, index)) {
  40. return;
  41. }
  42. report({
  43. message,
  44. node: decl,
  45. index,
  46. result: opts.result,
  47. ruleName: opts.checkedRuleName,
  48. });
  49. },
  50. });
  51. }
  52. };