Skip to content

Commit

Permalink
feat: implement first version of virtual addon
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Mar 20, 2018
1 parent 33186cd commit d3225e2
Showing 1 changed file with 93 additions and 0 deletions.
93 changes: 93 additions & 0 deletions addon/virtual.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use strict';

var createMemoizer = function (pfx) {
var offset = 10;
var msb = 35;
var power = 1;
var cache = {};

var self = {
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 = 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')('styled', renderer, ['putRaw']);
}

var memo = createMemoizer(renderer.pfx);

renderer.atomic = function (selectorTemplate, rawDecl, atrule) {
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 ((value instanceof Object) && !(value instanceof Array)) {
if (prop[0] === '@') {
renderer.putAt(selectorTemplate, value, prop);
} else {
renderer.virtual(renderer.selector(selectorTemplate, prop), value, atrule);
}
} else {
var rawDecl = renderer.decl(prop, value);

classNames += ' ' + renderer.atomic(selectorTemplate, rawDecl, atrule);
}
}

return classNames;
};
};

0 comments on commit d3225e2

Please sign in to comment.