-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
72 lines (55 loc) · 2.23 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
const cosmiconfig = require('cosmiconfig');
const explorer = cosmiconfig('less-plugin-custom-properties');
const { config = { variables: {} } } = explorer.searchSync() || {};
module.exports = class CustomProperties {
install(
{
tree: { Call, Anonymous, Expression, Ruleset, Declaration, Selector, Element, Combinator },
visitors,
},
manager,
functions,
) {
const call = (name, ...args) => new Call(name, [new Expression(args)]);
class Visitor {
constructor() {
this.native = new visitors.Visitor(this);
this.isPreEvalVisitor = true;
this.isReplacing = true;
}
run(root) {
return this.native.visit(root);
}
visitOperation(node) {
return call('calc', node.operands[0], new Anonymous(node.op), node.operands[1]);
}
visitDeclaration(node) {
if (!(typeof node.name === 'string') || !node.name.match(/^@/)) {
return node;
}
const declaration = new Declaration(node.name.replace(/^@/, '--'), node.value);
if (node.parent.root || (node.parent.parent && node.parent.parent.type === 'Media' && node.parent.parent.parent.root)) {
return new Ruleset([new Selector([new Element(new Combinator(' '), ':root')], [])], [declaration]);
}
return declaration;
}
visitNegative(node) {
return call('calc', new Anonymous('-1'), new Anonymous('*'), node.value);
}
visitVariable(node) {
return call('var', new Anonymous(node.name.replace(/^@/, '--')));
}
}
manager.addVisitor(new Visitor());
functions.add('external', variable => {
if (variable.type !== 'Keyword') {
return call('var', variable);
}
const name = variable.value.replace(/^--/, '');
if (!(name in config.variables)) {
return call('var', variable);
}
return new Anonymous(String(config.variables[name]));
});
}
};