-
-
Notifications
You must be signed in to change notification settings - Fork 24
/
virtual.js
107 lines (81 loc) · 2.9 KB
/
virtual.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
'use strict';
var createMemoizer = function (pfx) {
var offset = 10;
var msb = 35;
var power = 1;
var self = {
cache: {},
length: 0,
next: function () {
var vcount = self.length + offset;
if (vcount === msb) {
offset += (msb + 1) * 9;
msb = Math.pow(36, ++power) - 1;
}
self.length++;
return vcount;
},
get: function () {
var curr = self.cache;
var lastIndex = arguments.length - 1;
var lastStep = arguments[lastIndex];
for (var i = 0; i < lastIndex; i++) {
var step = arguments[i] || '_';
if (!curr[step]) curr[step] = {};
curr = curr[step];
}
if (!curr[lastStep]) curr[lastStep] = pfx + self.next().toString(36);
return curr[lastStep];
}
};
return self;
};
exports.addon = function (renderer) {
if (process.env.NODE_ENV !== 'production') {
require('./__dev__/warnOnMissingDependencies')('virtual', renderer, ['rule', 'putRaw']);
}
renderer.memo = createMemoizer(renderer.pfx);
renderer.atomic = function (selectorTemplate, rawDecl, atrule) {
var memo = renderer.memo;
var memoLength = memo.length;
var className = memo.get(atrule, selectorTemplate, rawDecl);
if (memoLength < memo.length) {
var selector = selectorTemplate.replace(/&/g, '.' + className);
var str = selector + '{' + rawDecl + '}';
if (atrule) {
str = atrule + '{' + str + '}';
}
renderer.putRaw(str);
}
return className;
};
renderer.virtual = function (selectorTemplate, decls, atrule) {
selectorTemplate = selectorTemplate || '&';
var classNames = '';
for (var prop in decls) {
var value = decls[prop];
if (prop.indexOf('keyframes') > -1) {
renderer.putAt('', value, prop);
continue;
}
if ((value instanceof Object) && !(value instanceof Array)) {
if (prop[0] === '@') {
classNames += renderer.virtual(selectorTemplate, value, prop);
} else {
classNames += renderer.virtual(renderer.selector(selectorTemplate, prop), value, atrule);
}
} else {
var rawDecl = renderer.decl(prop, value);
var rawDecls = rawDecl.split(';');
for (var i = 0; i < rawDecls.length; i++) {
var d = rawDecls[i];
if (d) classNames += ' ' + renderer.atomic(selectorTemplate, d, atrule);
}
}
}
return classNames;
};
renderer.rule = function (decls) {
return renderer.virtual('&', decls);
};
};