index.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports["default"] = rule;
  6. exports.ruleName = exports.meta = exports.messages = void 0;
  7. var _stylelint = require("stylelint");
  8. var _utils = require("../../utils");
  9. var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
  10. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
  11. var ruleName = (0, _utils.namespace)("dollar-variable-no-missing-interpolation");
  12. exports.ruleName = ruleName;
  13. var messages = _stylelint.utils.ruleMessages(ruleName, {
  14. rejected: function rejected(n, v) {
  15. return "Expected variable ".concat(v, " to be interpolated when using it with ").concat(n);
  16. }
  17. });
  18. exports.messages = messages;
  19. var meta = {
  20. url: (0, _utils.ruleUrl)(ruleName)
  21. };
  22. // https://developer.mozilla.org/en/docs/Web/CSS/custom-ident#Lists_of_excluded_values
  23. exports.meta = meta;
  24. var customIdentProps = ["animation", "animation-name", "counter-reset", "counter-increment", "list-style-type", "will-change"];
  25. // https://developer.mozilla.org/en/docs/Web/CSS/At-rule
  26. var customIdentAtRules = ["counter-style", "keyframes", "supports"];
  27. function isAtRule(type) {
  28. return type === "atrule";
  29. }
  30. function isCustomIdentAtRule(node) {
  31. return isAtRule(node.type) && customIdentAtRules.includes(node.name);
  32. }
  33. function isCustomIdentProp(node) {
  34. return customIdentProps.includes(node.prop);
  35. }
  36. function isAtSupports(node) {
  37. return isAtRule(node.type) && node.name === "supports";
  38. }
  39. function isSassVar(value) {
  40. return value[0] === "$";
  41. }
  42. function isStringVal(value) {
  43. return /^(["']).*(["'])$/.test(value);
  44. }
  45. function toRegex(arr) {
  46. return new RegExp("(".concat(arr.join("|"), ")"));
  47. }
  48. function rule(actual) {
  49. return function (root, result) {
  50. var validOptions = _stylelint.utils.validateOptions(result, ruleName, {
  51. actual: actual
  52. });
  53. if (!validOptions) {
  54. return;
  55. }
  56. var stringVars = [];
  57. var vars = [];
  58. function findVars(node) {
  59. node.walkDecls(function (decl) {
  60. var prop = decl.prop,
  61. value = decl.value;
  62. if (!isSassVar(prop) || vars.includes(prop)) {
  63. return;
  64. }
  65. if (isStringVal(value)) {
  66. stringVars.push(prop);
  67. }
  68. vars.push(prop);
  69. });
  70. }
  71. findVars(root);
  72. root.walkRules(findVars);
  73. if (!vars.length) {
  74. return;
  75. }
  76. function shouldReport(node, value) {
  77. if (isAtSupports(node) || isCustomIdentProp(node)) {
  78. return stringVars.includes(value);
  79. }
  80. if (isCustomIdentAtRule(node)) {
  81. return vars.includes(value);
  82. }
  83. return false;
  84. }
  85. function report(node, value) {
  86. var name = node.name,
  87. prop = node.prop,
  88. type = node.type;
  89. var nodeName = isAtRule(type) ? "@".concat(name) : prop;
  90. _stylelint.utils.report({
  91. ruleName: ruleName,
  92. result: result,
  93. node: node,
  94. message: messages.rejected(nodeName, value)
  95. });
  96. }
  97. function exitEarly(node) {
  98. return node.type !== "word" || !node.value;
  99. }
  100. function walkValues(node, value) {
  101. (0, _postcssValueParser["default"])(value).walk(function (valNode) {
  102. var value = valNode.value;
  103. if (exitEarly(valNode) || !shouldReport(node, value)) {
  104. return;
  105. }
  106. report(node, value);
  107. });
  108. }
  109. root.walkDecls(toRegex(customIdentProps), function (decl) {
  110. walkValues(decl, decl.value);
  111. });
  112. root.walkAtRules(toRegex(customIdentAtRules), function (atRule) {
  113. walkValues(atRule, atRule.params);
  114. });
  115. };
  116. }
  117. rule.ruleName = ruleName;
  118. rule.messages = messages;
  119. rule.meta = meta;