glam
Version:
inline css for your jsx
151 lines (125 loc) • 4.23 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.simulations = simulations;
exports.default = generate;
var _CSSPropertyOperations = require('./CSSPropertyOperations');
var _plugins = require('./plugins');
var isBrowser = typeof window !== 'undefined';
// import type { AST } from './types';
// a flag to enable simulation meta tags on dom nodes
// defaults to true in dev mode. recommend *not* to
// toggle often.
var canSimulate = process.env.NODE_ENV !== 'production';
// we use these flags for issuing warnings when simulate is called
// in prod / in incorrect order
var warned1 = false,
warned2 = false;
// toggles simulation activity. shouldn't be needed in most cases
function simulations() {
var bool = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
canSimulate = !!bool;
}
// takes a string, converts to lowercase, strips out nonalphanumeric.
function simple(str) {
var replace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
return str.toLowerCase().replace(/[^a-z0-9]/g, replace);
}
// from https://github.com/j2css/j2c/blob/5d381c2d721d04b54fabe6a165d587247c3087cb/src/helpers.js#L28-L61
// "Tokenizes" the selectors into parts relevant for the next function.
// Strings and comments are matched, but ignored afterwards.
// This is not a full tokenizers. It only recognizes comas, parentheses,
// strings and comments.
// regexp generated by scripts/regexps.js then trimmed by hand
var selectorTokenizer = /[(),]|"(?:\\.|[^"\n])*"|'(?:\\.|[^'\n])*'|\/\*[\s\S]*?\*\//g;
/**
* This will split a coma-separated selector list into individual selectors,
* ignoring comas in strings, comments and in :pseudo-selectors(parameter, lists).
*
* @param {string} selector
* @return {string[]}
*/
function splitSelector(selector) {
if (selector.indexOf(',') === -1) {
return [selector];
}
var indices = [],
res = [],
inParen = 0,
o;
/*eslint-disable no-cond-assign*/
while (o = selectorTokenizer.exec(selector)) {
/*eslint-enable no-cond-assign*/
switch (o[0]) {
case '(':
inParen++;
break;
case ')':
inParen--;
break;
case ',':
if (inParen) break;
indices.push(o.index);
}
}
for (o = indices.length; o--;) {
res.unshift(selector.slice(indices[o] + 1));
selector = selector.slice(0, indices[o]);
}
res.unshift(selector);
return res;
}
function selector(id) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
if (!id && path) {
return path.replace(/\&/g, '');
}
if (id && !path) return '.' + id;
var x = splitSelector(path).map(function (x) {
return x.indexOf('&') >= 0 ? x.replace(/\&/gm, '.' + id) // todo - make sure each sub selector has an &
: '.' + id + x;
}).join(',');
if (canSimulate && /^\&\:/.exec(path) && !/\s/.exec(path)) {
x += ',.' + id + '[data-simulate-' + simple(path) + ']';
}
return x;
}
function toCSS(node) {
var result = (0, _plugins.prefixes)((0, _plugins.fallbacks)((0, _plugins.contentWrap)(node)));
return result.selector + '{' + (0, _CSSPropertyOperations.createMarkupForStyles)(result.style) + '}';
}
function toCSSArray(id, parsed) {
var css = [];
// plugins here
var plain = parsed.plain,
selects = parsed.selects,
medias = parsed.medias,
supports = parsed.supports;
// todo - :host?
if (plain) {
css.push(toCSS({ style: plain, selector: selector(id) }));
}
if (selects) {
Object.keys(selects).forEach(function (key) {
return css.push(toCSS({ style: selects[key], selector: selector(id, key) }));
});
}
if (medias) {
Object.keys(medias).forEach(function (key) {
return css.push(key + '{' + toCSSArray(id, medias[key]).join('') + '}');
});
}
if (supports) {
Object.keys(supports).forEach(function (key) {
return css.push(key + '{' + toCSSArray(id, supports[key]).join('') + '}');
});
}
return css;
}
// todo - if server side, then cache on classname
function generate(_ref) {
var className = _ref.className,
parsed = _ref.parsed;
return toCSSArray(className, parsed);
}