forked from stylelint-scss/stylelint-scss
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
124 lines (104 loc) · 2.49 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { utils } from "stylelint";
import { namespace } from "../../utils";
import valueParser from "postcss-value-parser";
export const ruleName = namespace("dimension-no-non-numeric-values");
export const messages = utils.ruleMessages(ruleName, {
rejected: unit =>
`Expected "$value * 1${unit}" instead of "#{value}${unit}". Consider writing "value" in terms of ${unit} originally.`
});
export const units = [
// Font-relative lengths:
// https://www.w3.org/TR/css-values-4/#font-relative-lengths
"em",
"ex",
"cap",
"ch",
"ic",
"rem",
"lh",
"rlh",
// Viewport-relative lengths:
// https://www.w3.org/TR/css-values-4/#viewport-relative-lengths
"vw",
"vh",
"vi",
"vb",
"vmin",
"vmax",
// Absolute lengths:
// https://www.w3.org/TR/css-values-4/#absolute-lengths
"cm",
"mm",
"Q",
"in",
"pc",
"pt",
"px",
// Angle units:
// https://www.w3.org/TR/css-values-4/#angles
"deg",
"grad",
"rad",
"turn",
// Duration units:
// https://www.w3.org/TR/css-values-4/#time
"s",
"ms",
// Frequency units:
// https://www.w3.org/TR/css-values-4/#frequency
"Hz",
"kHz",
// Resolution units:
// https://www.w3.org/TR/css-values-4/#resolution
"dpi",
"dpcm",
"dppx",
"x",
// Flexible lengths:
// https://www.w3.org/TR/css-grid-1/#fr-unit
"fr"
];
export default function rule(primary) {
return (root, result) => {
const validOptions = utils.validateOptions(result, ruleName, {
actual: primary
});
if (!validOptions) {
return;
}
root.walkDecls(decl => {
valueParser(decl.value).walk(node => {
// All words are non-quoted, while strings are quoted.
// If quoted, it's probably a deliberate non-numeric dimension.
if (node.type !== "word") {
return;
}
if (!isInterpolated(node.value)) {
return;
}
utils.report({
ruleName,
result,
message: messages.rejected,
node: decl
});
});
});
};
}
function isInterpolated(value) {
let boolean = false;
// ValueParser breaks up interpolation with math into multiple, fragmented
// segments (#{$value, +, 2}px). The easiest way to detect this is to look for a fragmented
// interpolated section.
if (value.match(/^#{\$[a-z]*$/)) {
return true;
}
units.forEach(unit => {
const regex = new RegExp("^#{[$a-z_0-9 +-]*}" + unit + ";?$");
if (value.match(regex)) {
boolean = true;
}
});
return boolean;
}