Skip to content

Commit d3225e2

Browse files
committed
feat: implement first version of virtual addon
1 parent 33186cd commit d3225e2

1 file changed

Lines changed: 93 additions & 0 deletions

File tree

addon/virtual.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
'use strict';
2+
3+
var createMemoizer = function (pfx) {
4+
var offset = 10;
5+
var msb = 35;
6+
var power = 1;
7+
var cache = {};
8+
9+
var self = {
10+
length: 0,
11+
12+
next: function () {
13+
var vcount = self.length + offset;
14+
15+
if (vcount === msb) {
16+
offset += (msb + 1) * 9;
17+
msb = Math.pow(36, ++power) - 1;
18+
}
19+
self.length++;
20+
21+
return vcount;
22+
},
23+
24+
get: function () {
25+
var curr = cache;
26+
var lastIndex = arguments.length - 1;
27+
var lastStep = arguments[lastIndex];
28+
29+
for (var i = 0; i < lastIndex; i++) {
30+
var step = arguments[i] || '_';
31+
32+
if (!curr[step]) curr[step] = {};
33+
curr = curr[step];
34+
}
35+
36+
if (!curr[lastStep]) curr[lastStep] = pfx + self.next().toString(36);
37+
38+
return curr[lastStep];
39+
},
40+
};
41+
42+
return self;
43+
};
44+
45+
exports.addon = function (renderer) {
46+
if (process.env.NODE_ENV !== 'production') {
47+
require('./__dev__/warnOnMissingDependencies')('styled', renderer, ['putRaw']);
48+
}
49+
50+
var memo = createMemoizer(renderer.pfx);
51+
52+
renderer.atomic = function (selectorTemplate, rawDecl, atrule) {
53+
var memoLength = memo.length;
54+
var className = memo.get(atrule, selectorTemplate, rawDecl);
55+
56+
if (memoLength < memo.length) {
57+
var selector = selectorTemplate.replace(/&/g, '.' + className);
58+
var str = selector + '{' + rawDecl + '}';
59+
60+
if (atrule) {
61+
str = atrule + '{' + str + '}';
62+
}
63+
64+
renderer.putRaw(str);
65+
}
66+
67+
return className;
68+
};
69+
70+
renderer.virtual = function (selectorTemplate, decls, atrule) {
71+
selectorTemplate = selectorTemplate || '&';
72+
73+
var classNames = '';
74+
75+
for (var prop in decls) {
76+
var value = decls[prop];
77+
78+
if ((value instanceof Object) && !(value instanceof Array)) {
79+
if (prop[0] === '@') {
80+
renderer.putAt(selectorTemplate, value, prop);
81+
} else {
82+
renderer.virtual(renderer.selector(selectorTemplate, prop), value, atrule);
83+
}
84+
} else {
85+
var rawDecl = renderer.decl(prop, value);
86+
87+
classNames += ' ' + renderer.atomic(selectorTemplate, rawDecl, atrule);
88+
}
89+
}
90+
91+
return classNames;
92+
};
93+
};

0 commit comments

Comments
 (0)