-
Notifications
You must be signed in to change notification settings - Fork 0
/
js-to-css.js
88 lines (76 loc) · 2.24 KB
/
js-to-css.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
var gen = require("gen-css-identifier");
var replaceVars = require("./replace-vars");
var map = function(obj, fn){
var r = [];
for(k in obj){
if(obj.hasOwnProperty(k)){
r.push(fn(obj[k], k));
}
}
return r;
};
var normalizeWhitespace = function(str){
return str.replace(/\s+/g, " ").replace(/^\s+/, "").replace(/\s+$/, "");
};
var renderProperties = function(properties){
return map(properties, function(val, key){
return normalizeWhitespace(key) + ":" + normalizeWhitespace(val + "");
}).join(";");
};
var renderRules = function(rules){
return map(rules, function(group_rules, group){
var group_css = map(group_rules, function(properties, key){
return normalizeWhitespace(key) + "{" + renderProperties(properties) + "}";
}).join("\n");
return group.length > 0
? group + "{" + group_css + "}"
: group_css;
}).join("\n");
};
var keyToRule = function(context, key){
return map(context.split(","), function(c){
return map(key.split(","), function(p){
p = normalizeWhitespace(p);
if(p[0] === ":"){
return c + p;
}else if(p[0] === "&"){
return c + p.substring(1);
}
return (c + " " + p).replace(/^\s+/, "");
}).join(",");
}).join(",");
};
module.exports = function(json){
var rules = {};
var var_cache = {};
var normalizeAndApplyVars = function(key){
return replaceVars(normalizeWhitespace(key), function(v){
if(!var_cache.hasOwnProperty(v)){
var_cache[v] = gen();
}
return var_cache[v];
});
};
var recurseRules = function(group, context, o){
map(o, function(val, key){
if(/^@/.test(key)){
recurseRules(keyToRule(context, normalizeAndApplyVars(key)), context, val);
}else if(Object.prototype.toString.call(val) === "[object Object]"){
recurseRules(group, keyToRule(context, normalizeAndApplyVars(key)), val);
}else{
if(!rules.hasOwnProperty(group)){
rules[group] = {};
}
if(!rules[group].hasOwnProperty(context)){
rules[group][context] = {};
}
rules[group][context][key] = normalizeAndApplyVars(val + "");
}
});
};
recurseRules("", "", json);
return {
css: renderRules(rules),
vars: var_cache
};
};