UNPKG

glam

Version:

inline css for your jsx

151 lines (125 loc) 4.23 kB
'use strict'; 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); }