UNPKG

2.76 kBJavaScriptView Raw
1// @ts-nocheck
2
3'use strict';
4
5const atRuleParamIndex = require('../../utils/atRuleParamIndex');
6const declarationValueIndex = require('../../utils/declarationValueIndex');
7const getUnitFromValueNode = require('../../utils/getUnitFromValueNode');
8const report = require('../../utils/report');
9const ruleMessages = require('../../utils/ruleMessages');
10const validateOptions = require('../../utils/validateOptions');
11const valueParser = require('postcss-value-parser');
12
13const ruleName = 'unit-case';
14
15const messages = ruleMessages(ruleName, {
16 expected: (actual, expected) => `Expected "${actual}" to be "${expected}"`,
17});
18
19function rule(expectation, options, context) {
20 return (root, result) => {
21 const validOptions = validateOptions(result, ruleName, {
22 actual: expectation,
23 possible: ['lower', 'upper'],
24 });
25
26 if (!validOptions) {
27 return;
28 }
29
30 function check(node, value, getIndex) {
31 const violations = [];
32
33 function processValue(valueNode) {
34 const unit = getUnitFromValueNode(valueNode);
35
36 if (!unit) {
37 return false;
38 }
39
40 const expectedUnit = expectation === 'lower' ? unit.toLowerCase() : unit.toUpperCase();
41
42 if (unit === expectedUnit) {
43 return false;
44 }
45
46 violations.push({
47 index: getIndex(node) + valueNode.sourceIndex,
48 message: messages.expected(unit, expectedUnit),
49 });
50
51 return true;
52 }
53
54 const parsedValue = valueParser(value).walk((valueNode) => {
55 // Ignore wrong units within `url` function
56 let needFix = false;
57 const value = valueNode.value;
58
59 if (valueNode.type === 'function' && value.toLowerCase() === 'url') {
60 return false;
61 }
62
63 if (value.includes('*')) {
64 value.split('*').some((val) => {
65 return processValue({
66 ...valueNode,
67 sourceIndex: value.indexOf(val) + val.length + 1,
68 value: val,
69 });
70 });
71 }
72
73 needFix = processValue(valueNode);
74
75 if (needFix && context.fix) {
76 valueNode.value = expectation === 'lower' ? value.toLowerCase() : value.toUpperCase();
77 }
78 });
79
80 if (violations.length) {
81 if (context.fix) {
82 if (node.name === 'media') {
83 node.params = parsedValue.toString();
84 } else {
85 node.value = parsedValue.toString();
86 }
87 } else {
88 violations.forEach((err) => {
89 report({
90 index: err.index,
91 message: err.message,
92 node,
93 result,
94 ruleName,
95 });
96 });
97 }
98 }
99 }
100
101 root.walkAtRules((atRule) => {
102 if (!/^media$/i.test(atRule.name) && !atRule.variable) {
103 return;
104 }
105
106 check(atRule, atRule.params, atRuleParamIndex);
107 });
108 root.walkDecls((decl) => check(decl, decl.value, declarationValueIndex));
109 };
110}
111
112rule.ruleName = ruleName;
113rule.messages = messages;
114module.exports = rule;