-
Notifications
You must be signed in to change notification settings - Fork 92
/
index.js
84 lines (68 loc) · 1.82 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
import valueParser from "postcss-value-parser";
import { utils } from "stylelint";
import { namespace } from "../../utils";
export const ruleName = namespace("map-keys-quotes");
export const messages = utils.ruleMessages(ruleName, {
expected: "Expected keys in map to be quoted."
});
function rule(primary) {
return (root, result) => {
const validOptions = utils.validateOptions(result, ruleName, {
actual: primary,
possible: ["always"]
});
if (!validOptions) {
return;
}
root.walkDecls(decl => {
if (decl.prop[0] !== "$") {
return;
}
valueParser(decl.value).walk(node => {
if (
node.type === "function" &&
node.value === "" &&
isMap(node.nodes)
) {
// Identify all of the map-keys and see if they're strings (not words).
const mapKeys = returnMapKeys(node.nodes);
mapKeys.forEach(map_key => {
if (map_key.type === "word" && isNaN(map_key.value)) {
utils.report({
message: messages.expected,
node: decl,
result,
ruleName
});
}
});
}
});
});
};
}
// Takes in a list of map nodes and identifies if they are a map.
// A map is identified by the pattern: [string/word colon(div) anything comma(div) ...]
function isMap(nodes) {
if (nodes.length < 4) {
return false;
}
if (nodes[0].type !== "word" && nodes[0].type !== "string") {
return false;
}
if (nodes[1].value !== ":") {
return false;
}
if (nodes[3].value !== ",") {
return false;
}
return true;
}
function returnMapKeys(array) {
const new_array = [];
for (let i = 0; i < array.length; i += 4) {
new_array.push(array[i]);
}
return new_array;
}
export default rule;