UNPKG

2.52 kBJavaScriptView Raw
1// @ts-nocheck
2
3'use strict';
4
5const _ = require('lodash');
6const atRuleParamIndex = require('../../utils/atRuleParamIndex');
7const declarationValueIndex = require('../../utils/declarationValueIndex');
8const getUnitFromValueNode = require('../../utils/getUnitFromValueNode');
9const optionsMatches = require('../../utils/optionsMatches');
10const report = require('../../utils/report');
11const ruleMessages = require('../../utils/ruleMessages');
12const validateObjectWithArrayProps = require('../../utils/validateObjectWithArrayProps');
13const validateOptions = require('../../utils/validateOptions');
14const valueParser = require('postcss-value-parser');
15
16const ruleName = 'unit-whitelist';
17
18const messages = ruleMessages(ruleName, {
19 rejected: (unit) => `Unexpected unit "${unit}"`,
20});
21
22function rule(listInput, options) {
23 const list = [].concat(listInput);
24
25 return (root, result) => {
26 const validOptions = validateOptions(
27 result,
28 ruleName,
29 {
30 actual: list,
31 possible: [_.isString],
32 },
33 {
34 optional: true,
35 actual: options,
36 possible: {
37 ignoreProperties: validateObjectWithArrayProps([_.isString, _.isRegExp]),
38 },
39 },
40 );
41
42 if (!validOptions) {
43 return;
44 }
45
46 result.warn(`'${ruleName}' has been deprecated. Instead use 'unit-allowed-list'.`, {
47 stylelintType: 'deprecation',
48 stylelintReference: `https://github.com/stylelint/stylelint/blob/13.7.0/lib/rules/${ruleName}/README.md`,
49 });
50
51 function check(node, value, getIndex) {
52 // make sure multiplication operations (*) are divided - not handled
53 // by postcss-value-parser
54 value = value.replace(/\*/g, ',');
55 valueParser(value).walk((valueNode) => {
56 // Ignore wrong units within `url` function
57 if (valueNode.type === 'function' && valueNode.value.toLowerCase() === 'url') {
58 return false;
59 }
60
61 const unit = getUnitFromValueNode(valueNode);
62
63 if (!unit || (unit && list.includes(unit.toLowerCase()))) {
64 return;
65 }
66
67 if (options && optionsMatches(options.ignoreProperties, unit.toLowerCase(), node.prop)) {
68 return;
69 }
70
71 report({
72 index: getIndex(node) + valueNode.sourceIndex,
73 message: messages.rejected(unit),
74 node,
75 result,
76 ruleName,
77 });
78 });
79 }
80
81 root.walkAtRules(/^media$/i, (atRule) => check(atRule, atRule.params, atRuleParamIndex));
82 root.walkDecls((decl) => check(decl, decl.value, declarationValueIndex));
83 };
84}
85
86rule.primaryOptionArray = true;
87
88rule.ruleName = ruleName;
89rule.messages = messages;
90module.exports = rule;