Comparing version 4.1.6 to 5.0.0
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t(e.emotion=e.emotion||{},e.React)}(this,function(e,t){function n(e){return e[e.length-1]}function r(e){if(e.sheet)return e.sheet;for(var t=0;t<document.styleSheets.length;t++)if(document.styleSheets[t].ownerNode===e)return document.styleSheets[t]}function i(){var e=document.createElement("style");return e.type="text/css",e.setAttribute("data-emotion",""),e.appendChild(document.createTextNode("")),(document.head||document.getElementsByTagName("head")[0]).appendChild(e),e}function s(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.speedy,n=void 0===t?!p&&!m:t,r=e.maxLength,i=void 0===r?l&&g?4e3:65e3:r;this.isSpeedy=n,this.sheet=void 0,this.tags=[],this.maxLength=i,this.ctr=0}function o(e){var t=e.join(",");return c(t,t.length).toString(36)}function c(e,t){for(var n=1540483477,r=t^e.length,i=e.length,s=0;i>=4;){var o=a(e,s);o=h(o,n),o=h(o^=o>>>24,n),r=h(r,n),r^=o,s+=4,i-=4}switch(i){case 3:r^=u(e,s),r=h(r^=e.charCodeAt(s+2)<<16,n);break;case 2:r=h(r^=u(e,s),n);break;case 1:r=h(r^=e.charCodeAt(s),n)}return r^=r>>>13,r=h(r,n),(r^=r>>>15)>>>0}function a(e,t){return e.charCodeAt(t++)+(e.charCodeAt(t++)<<8)+(e.charCodeAt(t++)<<16)+(e.charCodeAt(t)<<24)}function u(e,t){return e.charCodeAt(t++)+(e.charCodeAt(t++)<<8)}function h(e,t){return(65535&(e|=0))*(t|=0)+(((e>>>16)*t&65535)<<16)|0}function d(e,t){var n=o([e].concat(t)),r="vars-"+n;if(y[n])return r;var i=t.map(function(t,n){return"--"+e+"-"+n+": "+t}).join("; ");return v.insert("."+r+" {"+i+"}"),y[n]=!0,r}function f(e,t,n){if(n){var r=n.apply(void 0,t),i=o(r);return y[i]||(y[i]=!0,r.map(function(t){return t.replace(new RegExp(e,"gm"),e+"-"+i)}).forEach(function(e){return v.insert(e)})),e+"-"+i+" "+e}return e+(t&&t.length>0?" "+d(e,t):"")}t=t&&"default"in t?t.default:t;var l="undefined"!=typeof window,p="development"===process.env.NODE_ENV||!process.env.NODE_ENV,m="test"===process.env.NODE_ENV,g=function(){if(l){var e=document.createElement("div");return e.innerHTML="\x3c!--[if lt IE 10]><i></i><![endif]--\x3e",1===e.getElementsByTagName("i").length}}();Object.assign(s.prototype,{getSheet:function(){return r(n(this.tags))},inject:function(){var e=this;if(this.injected)throw new Error("already injected!");l?this.tags[0]=i():this.sheet={cssRules:[],insertRule:function(t){e.sheet.cssRules.push({cssText:t})}},this.injected=!0},speedy:function(e){if(0!==this.ctr)throw new Error("cannot change speedy now");this.isSpeedy=!!e},_insert:function(e){try{var t=this.getSheet();t.insertRule(e,-1!==e.indexOf("@import")?0:t.cssRules.length)}catch(t){p&&console.warn("illegal rule",e)}},insert:function(e){if(l)if(this.isSpeedy&&this.getSheet().insertRule)this._insert(e);else if(-1!==e.indexOf("@import")){var t=n(this.tags);t.insertBefore(document.createTextNode(e),t.firstChild)}else n(this.tags).appendChild(document.createTextNode(e));else this.sheet.insertRule(e,-1!==e.indexOf("@import")?0:this.sheet.cssRules.length);return this.ctr++,l&&this.ctr%this.maxLength==0&&this.tags.push(i()),this.ctr-1},delete:function(e){return this.replace(e,"")},flush:function(){l?(this.tags.forEach(function(e){return e.parentNode.removeChild(e)}),this.tags=[],this.sheet=null,this.ctr=0):this.sheet.cssRules=[],this.injected=!1},rules:function(){if(!l)return this.sheet.cssRules;var e=[];return this.tags.forEach(function(t){return e.splice.apply(e,[e.length,0].concat(Array.from(r(t).cssRules)))}),e}});var v=new s;v.inject();var y={};e.default=function(e,n){function r(r){var o=f(n,i.map(function(e){return e&&"function"==typeof e?e.cls||e(r):e}),s);return t.createElement(e,Object.assign({},r,{ref:r.innerRef,className:r.className?o+" "+r.className:o}))}var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],s=arguments[3];if(!e)throw new Error("You are trying to create a styled element with an undefined component.\nYou may have forgotten to import it.");var o=n.split("-")[0],c="css"===o?"":"."+o,a=e.displayName||e.name||"Component";return r.displayName="styled("+a+c+")",r.cls="."+n,r},Object.defineProperty(e,"__esModule",{value:!0})}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t(e.emotion=e.emotion||{},e.React)}(this,function(e,t){function n(e){return e[e.length-1]}function r(e){if(e.sheet)return e.sheet;for(var t=0;t<document.styleSheets.length;t++)if(document.styleSheets[t].ownerNode===e)return document.styleSheets[t]}function i(){var e=document.createElement("style");return e.type="text/css",e.setAttribute("data-emotion",""),e.appendChild(document.createTextNode("")),(document.head||document.getElementsByTagName("head")[0]).appendChild(e),e}function s(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.speedy,n=void 0===t?!p&&!m:t,r=e.maxLength,i=void 0===r?l&&g?4e3:65e3:r;this.isSpeedy=n,this.sheet=void 0,this.tags=[],this.maxLength=i,this.ctr=0}function o(e){var t=e.join(",");return c(t,t.length).toString(36)}function c(e,t){for(var n=1540483477,r=t^e.length,i=e.length,s=0;i>=4;){var o=a(e,s);o=h(o,n),o=h(o^=o>>>24,n),r=h(r,n),r^=o,s+=4,i-=4}switch(i){case 3:r^=u(e,s),r=h(r^=e.charCodeAt(s+2)<<16,n);break;case 2:r=h(r^=u(e,s),n);break;case 1:r=h(r^=e.charCodeAt(s),n)}return r^=r>>>13,r=h(r,n),(r^=r>>>15)>>>0}function a(e,t){return e.charCodeAt(t++)+(e.charCodeAt(t++)<<8)+(e.charCodeAt(t++)<<16)+(e.charCodeAt(t)<<24)}function u(e,t){return e.charCodeAt(t++)+(e.charCodeAt(t++)<<8)}function h(e,t){return(65535&(e|=0))*(t|=0)+(((e>>>16)*t&65535)<<16)|0}function d(e,t){var n=o([e].concat(t)),r="vars-"+n;if(y[n])return r;var i=t.map(function(t,n){return"--"+e+"-"+n+": "+t}).join("; ");return v.insert("."+r+" {"+i+"}"),y[n]=!0,r}function f(e,t,n){if(n){var r=n.apply(void 0,t),i=o(r);return y[i]||(y[i]=!0,r.map(function(t){return t.replace(new RegExp(e[0],"gm"),e[0]+"-"+i)}).forEach(function(e){return v.insert(e)})),e[0]+"-"+i+" "+e.join(" ")}return e.join(" ")+(t&&t.length>0?" "+d(e[0],t):"")}t=t&&"default"in t?t.default:t;var l="undefined"!=typeof window,p="development"===process.env.NODE_ENV||!process.env.NODE_ENV,m="test"===process.env.NODE_ENV,g=function(){if(l){var e=document.createElement("div");return e.innerHTML="\x3c!--[if lt IE 10]><i></i><![endif]--\x3e",1===e.getElementsByTagName("i").length}}();Object.assign(s.prototype,{getSheet:function(){return r(n(this.tags))},inject:function(){var e=this;if(this.injected)throw new Error("already injected!");l?this.tags[0]=i():this.sheet={cssRules:[],insertRule:function(t){e.sheet.cssRules.push({cssText:t})}},this.injected=!0},speedy:function(e){if(0!==this.ctr)throw new Error("cannot change speedy now");this.isSpeedy=!!e},_insert:function(e){try{var t=this.getSheet();t.insertRule(e,-1!==e.indexOf("@import")?0:t.cssRules.length)}catch(t){p&&console.warn("illegal rule",e)}},insert:function(e){if(l)if(this.isSpeedy&&this.getSheet().insertRule)this._insert(e);else if(-1!==e.indexOf("@import")){var t=n(this.tags);t.insertBefore(document.createTextNode(e),t.firstChild)}else n(this.tags).appendChild(document.createTextNode(e));else this.sheet.insertRule(e,-1!==e.indexOf("@import")?0:this.sheet.cssRules.length);return this.ctr++,l&&this.ctr%this.maxLength==0&&this.tags.push(i()),this.ctr-1},delete:function(e){return this.replace(e,"")},flush:function(){l?(this.tags.forEach(function(e){return e.parentNode.removeChild(e)}),this.tags=[],this.sheet=null,this.ctr=0):this.sheet.cssRules=[],this.injected=!1},rules:function(){if(!l)return this.sheet.cssRules;var e=[];return this.tags.forEach(function(t){return e.splice.apply(e,[e.length,0].concat(Array.from(r(t).cssRules)))}),e}});var v=new s;v.inject();var y={};e.default=function(e,n){function r(r){var o=f(n,i.map(function(e){return e&&"function"==typeof e?e.cls||e(r):e}),s);return t.createElement(e,Object.assign({},r,{ref:r.innerRef,className:r.className?o+" "+r.className:o}))}var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],s=arguments[3];if(!e)throw new Error("You are trying to create a styled element with an undefined component.\nYou may have forgotten to import it.");var o=n[0].split("-")[1],c=e.displayName||e.name||"Component";return r.displayName="styled("+c+o+")",r.cls="."+n,r},Object.defineProperty(e,"__esModule",{value:!0})}); | ||
//# sourceMappingURL=DO-NOT-USE.min.js.map |
116
lib/babel.js
@@ -64,3 +64,3 @@ 'use strict'; | ||
var _inline = (0, _inline4.inline)(built, identifierName, 'css', state.inline | ||
var _inline = (0, _inline3.inline)(built, identifierName, 'css', state.inline | ||
@@ -73,3 +73,3 @@ // hash will be '0' when no styles are passed so we can just return the original tag | ||
hasOtherMatch = _inline.hasOtherMatch, | ||
hasApply = _inline.hasApply; | ||
composes = _inline.composes; | ||
@@ -79,4 +79,8 @@ if (hash === '0') { | ||
} | ||
var args = [tag, t.stringLiteral(name + '-' + hash), t.arrayExpression(built.expressions)]; | ||
if (!hasApply && !hasOtherMatch && !state.inline) { | ||
var inputClasses = [t.stringLiteral(name + '-' + hash)]; | ||
for (var i = 0; i < composes; i++) { | ||
inputClasses.push(path.node.quasi.expressions.shift()); | ||
} | ||
var args = [tag, t.arrayExpression(inputClasses), t.arrayExpression(built.expressions)]; | ||
if (!hasOtherMatch && !state.inline) { | ||
state.insertStaticRules(rules); | ||
@@ -87,3 +91,3 @@ } else { | ||
}); | ||
var inlineContentExpr = t.functionExpression(t.identifier('createEmotionStyledRules'), expressions, t.blockStatement([t.returnStatement(t.arrayExpression(parseDynamicValues(rules, t, expressions)))])); | ||
var inlineContentExpr = t.functionExpression(t.identifier('createEmotionStyledRules'), expressions, t.blockStatement([t.returnStatement(t.arrayExpression(parseDynamicValues(rules, t, expressions, composes)))])); | ||
args.push(inlineContentExpr); | ||
@@ -103,42 +107,38 @@ } | ||
path.replaceWith(buildCallExpression(path.node.tag.callee, path.node.tag.arguments[0], path)); | ||
} else if (t.isIdentifier(path.node.tag) && path.node.tag.name === 'fragment') { | ||
var _inline2 = (0, _inline4.inline)(path.node.quasi, identifierName, 'frag', true), | ||
rules = _inline2.rules; | ||
if (rules.length > 1) { | ||
throw path.buildCodeFrameError('Fragments cannot have multiple selectors.'); | ||
} | ||
var rulesWithoutSelector = rules.map(function (rule) { | ||
return rule.substring(rule.indexOf('{') + 1, rule.length - 1).trim(); | ||
}); | ||
path.replaceWith(parseDynamicValues(rulesWithoutSelector, t, path.node.quasi.expressions)[0]); | ||
} else if (t.isIdentifier(path.node.tag) && path.node.tag.name === 'css') { | ||
var _inline3 = (0, _inline4.inline)(path.node.quasi, identifierName, 'css', state.inline), | ||
hash = _inline3.hash, | ||
name = _inline3.name, | ||
_rules = _inline3.rules, | ||
hasApply = _inline3.hasApply, | ||
hasVar = _inline3.hasVar, | ||
hasOtherMatch = _inline3.hasOtherMatch; | ||
try { | ||
var _inline2 = (0, _inline3.inline)(path.node.quasi, identifierName, 'css', state.inline), | ||
hash = _inline2.hash, | ||
name = _inline2.name, | ||
rules = _inline2.rules, | ||
hasVar = _inline2.hasVar, | ||
composes = _inline2.composes, | ||
hasOtherMatch = _inline2.hasOtherMatch; | ||
var classNameStringLiteral = t.stringLiteral(name + '-' + hash); | ||
var args = [classNameStringLiteral, t.arrayExpression(path.node.quasi.expressions)]; | ||
if (!hasApply && !hasOtherMatch && !state.inline) { | ||
state.insertStaticRules(_rules); | ||
if (!hasVar) { | ||
return path.replaceWith(classNameStringLiteral); | ||
var inputClasses = [t.stringLiteral(name + '-' + hash)]; | ||
for (var i = 0; i < composes; i++) { | ||
inputClasses.push(path.node.quasi.expressions.shift()); | ||
} | ||
} else { | ||
var expressions = path.node.quasi.expressions.map(function (x, i) { | ||
return t.identifier('x' + i); | ||
}); | ||
var inlineContentExpr = t.functionExpression(t.identifier('createEmotionRules'), expressions, t.blockStatement([t.returnStatement(t.arrayExpression(parseDynamicValues(_rules, t, expressions)))])); | ||
args.push(inlineContentExpr); | ||
var args = [t.arrayExpression(inputClasses), t.arrayExpression(path.node.quasi.expressions)]; | ||
if (!hasOtherMatch && !state.inline) { | ||
state.insertStaticRules(rules); | ||
if (!hasVar) { | ||
return path.replaceWith(joinExpressionsWithSpaces(inputClasses, t)); | ||
} | ||
} else { | ||
var expressions = path.node.quasi.expressions.map(function (x, i) { | ||
return t.identifier('x' + i); | ||
}); | ||
var inlineContentExpr = t.functionExpression(t.identifier('createEmotionRules'), expressions, t.blockStatement([t.returnStatement(t.arrayExpression(parseDynamicValues(rules, t, expressions, composes)))])); | ||
args.push(inlineContentExpr); | ||
} | ||
path.replaceWith(t.callExpression(t.identifier('css'), args)); | ||
} catch (e) { | ||
throw path.buildCodeFrameError(e); | ||
} | ||
path.replaceWith(t.callExpression(t.identifier('css'), args)); | ||
} else if (t.isIdentifier(path.node.tag) && path.node.tag.name === 'keyframes') { | ||
var _keyframes = (0, _inline4.keyframes)(path.node.quasi, identifierName, 'animation'), | ||
var _keyframes = (0, _inline3.keyframes)(path.node.quasi, identifierName, 'animation'), | ||
_hash = _keyframes.hash, | ||
_name = _keyframes.name, | ||
_rules2 = _keyframes.rules, | ||
_rules = _keyframes.rules, | ||
hasInterpolation = _keyframes.hasInterpolation; | ||
@@ -148,14 +148,14 @@ | ||
if (!hasInterpolation && !state.inline) { | ||
state.insertStaticRules(['@keyframes ' + animationName + ' ' + _rules2.join('')]); | ||
state.insertStaticRules(['@keyframes ' + animationName + ' ' + _rules.join('')]); | ||
path.replaceWith(t.stringLiteral(animationName)); | ||
} else { | ||
path.replaceWith(t.callExpression(t.identifier('keyframes'), [t.stringLiteral(animationName), t.arrayExpression(parseDynamicValues(_rules2, t, path.node.quasi.expressions))])); | ||
path.replaceWith(t.callExpression(t.identifier('keyframes'), [t.stringLiteral(animationName), t.arrayExpression(parseDynamicValues(_rules, t, path.node.quasi.expressions))])); | ||
} | ||
} else if (t.isIdentifier(path.node.tag) && path.node.tag.name === 'fontFace') { | ||
var _fontFace = (0, _inline4.fontFace)(path.node.quasi, state.inline), | ||
_rules3 = _fontFace.rules, | ||
var _fontFace = (0, _inline3.fontFace)(path.node.quasi, state.inline), | ||
_rules2 = _fontFace.rules, | ||
_hasInterpolation = _fontFace.hasInterpolation; | ||
if (!_hasInterpolation && !state.inline) { | ||
state.insertStaticRules(_rules3); | ||
state.insertStaticRules(_rules2); | ||
if (t.isExpressionStatement(path.parent)) { | ||
@@ -167,11 +167,11 @@ path.parentPath.remove(); | ||
} else { | ||
path.replaceWith(t.callExpression(t.identifier('fontFace'), [t.arrayExpression(parseDynamicValues(_rules3, t, path.node.quasi.expressions))])); | ||
path.replaceWith(t.callExpression(t.identifier('fontFace'), [t.arrayExpression(parseDynamicValues(_rules2, t, path.node.quasi.expressions))])); | ||
} | ||
} else if (t.isIdentifier(path.node.tag) && path.node.tag.name === 'injectGlobal' && t.isTemplateLiteral(path.node.quasi)) { | ||
var _injectGlobal = (0, _inline4.injectGlobal)(path.node.quasi), | ||
_rules4 = _injectGlobal.rules, | ||
var _injectGlobal = (0, _inline3.injectGlobal)(path.node.quasi), | ||
_rules3 = _injectGlobal.rules, | ||
_hasInterpolation2 = _injectGlobal.hasInterpolation; | ||
if (!_hasInterpolation2 && !state.inline) { | ||
state.insertStaticRules(_rules4); | ||
state.insertStaticRules(_rules3); | ||
if (t.isExpressionStatement(path.parent)) { | ||
@@ -183,3 +183,3 @@ path.parentPath.remove(); | ||
} else { | ||
path.replaceWith(t.callExpression(t.identifier('injectGlobal'), [t.arrayExpression(parseDynamicValues(_rules4, t, path.node.quasi.expressions))])); | ||
path.replaceWith(t.callExpression(t.identifier('injectGlobal'), [t.arrayExpression(parseDynamicValues(_rules3, t, path.node.quasi.expressions))])); | ||
} | ||
@@ -200,3 +200,3 @@ } | ||
var _inline4 = require('./inline'); | ||
var _inline3 = require('./inline'); | ||
@@ -213,7 +213,22 @@ var _attrs = require('./attrs'); | ||
function joinExpressionsWithSpaces(expressions, t) { | ||
var quasis = [t.templateElement({ cooked: '', raw: '' }, true)]; | ||
expressions.forEach(function (x, i) { | ||
if (i === expressions.length - 1) { | ||
return quasis.push(t.templateElement({ cooked: '', raw: '' }, true)); | ||
} | ||
quasis.push(t.templateElement({ cooked: ' ', raw: ' ' }, true)); | ||
}); | ||
return t.templateLiteral(quasis, expressions); | ||
} | ||
function parseDynamicValues(rules, t, inputExpressions) { | ||
var composes = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; | ||
return rules.map(function (rule) { | ||
var re = /xxx(\S)xxx/gm; | ||
var varMatch = void 0; | ||
var matches = []; | ||
while ((varMatch = re.exec(rule)) !== null) { | ||
@@ -241,5 +256,4 @@ matches.push({ | ||
} | ||
expressions.push(inputExpressions[p1 - composes]); | ||
expressions.push(inputExpressions[p1]); | ||
if (i === matches.length - 1 && cursor <= rule.length) { | ||
@@ -246,0 +260,0 @@ var postMatch = rule.substring(cursor); |
@@ -7,3 +7,2 @@ 'use strict'; | ||
exports.css = css; | ||
exports.fragment = fragment; | ||
exports.injectGlobal = injectGlobal; | ||
@@ -47,3 +46,3 @@ exports.keyframes = keyframes; | ||
function css(cls, vars, content) { | ||
function css(classes, vars, content) { | ||
if (content) { | ||
@@ -57,3 +56,3 @@ // inline mode | ||
src.map(function (r) { | ||
return r.replace(new RegExp(cls, 'gm'), cls + '-' + hash); | ||
return r.replace(new RegExp(classes[0], 'gm'), classes[0] + '-' + hash); | ||
}).forEach(function (r) { | ||
@@ -63,9 +62,7 @@ return sheet.insert(r); | ||
} | ||
return cls + '-' + hash + ' ' + cls; | ||
return classes[0] + '-' + hash + ' ' + classes.join(' '); | ||
} | ||
return cls + (vars && vars.length > 0 ? ' ' + values(cls, vars) : ''); | ||
return classes.join(' ') + (vars && vars.length > 0 ? ' ' + values(classes[0], vars) : ''); | ||
} | ||
function fragment() {} | ||
function injectGlobal(src) { | ||
@@ -72,0 +69,0 @@ var hash = (0, _hash2.default)(src); |
@@ -36,29 +36,13 @@ 'use strict'; | ||
function replaceApplyWithPlaceholders(rules) { | ||
return rules.map(function (rule) { | ||
return rule.replace(/@apply\s+--[A-Za-z0-9-_]+-([0-9]+)/gm, function (match, p1) { | ||
return 'xxx' + p1 + 'xxx'; | ||
}); | ||
}); | ||
} | ||
function createSrc(strs, name, hash) { | ||
var hasApply = false; | ||
var otherMatches = 0; | ||
var matches = 0; | ||
var src = strs.reduce(function (arr, str, i) { | ||
arr.push(str); | ||
if (i !== strs.length - 1) { | ||
// todo - test for preceding @apply | ||
var applyMatch = /@apply\s*$/gm.exec(str); | ||
if (applyMatch) { | ||
hasApply = true; | ||
arr.push('--' + name + '-' + hash + '-' + i); | ||
} else { | ||
otherMatches++; | ||
arr.push('xxx' + i + 'xxx'); | ||
} | ||
matches++; | ||
arr.push('xxx' + i + 'xxx'); | ||
} | ||
return arr; | ||
}, []).join('').trim(); | ||
return { src: src, hasApply: hasApply, otherMatches: otherMatches }; | ||
return { src: src, matches: matches }; | ||
} | ||
@@ -75,19 +59,17 @@ | ||
src = _createSrc.src, | ||
hasApply = _createSrc.hasApply, | ||
otherMatches = _createSrc.otherMatches; | ||
matches = _createSrc.matches; | ||
var _parseCSS = (0, _parser.parseCSS)('.' + name + '-' + hash + ' { ' + src + ' }', { | ||
inlineMode: inlineMode || hasApply, | ||
otherMatches: otherMatches, | ||
inlineMode: inlineMode, | ||
matches: matches, | ||
name: name, | ||
hash: hash | ||
hash: hash, | ||
canCompose: true | ||
}), | ||
rules = _parseCSS.rules, | ||
hasVar = _parseCSS.hasVar, | ||
hasOtherMatch = _parseCSS.hasOtherMatch; | ||
hasOtherMatch = _parseCSS.hasOtherMatch, | ||
composes = _parseCSS.composes; | ||
if (hasApply) { | ||
rules = replaceApplyWithPlaceholders(rules); | ||
} | ||
return { hash: hash, name: name, rules: rules, hasApply: hasApply, hasVar: hasVar, hasOtherMatch: hasOtherMatch }; | ||
return { hash: hash, name: name, rules: rules, hasVar: hasVar, hasOtherMatch: hasOtherMatch, composes: composes }; | ||
} | ||
@@ -104,4 +86,3 @@ | ||
src = _createSrc2.src, | ||
hasApply = _createSrc2.hasApply, | ||
otherMatches = _createSrc2.otherMatches; | ||
matches = _createSrc2.matches; | ||
@@ -111,3 +92,3 @@ var _parseCSS2 = (0, _parser.parseCSS)('{ ' + src + ' }', { | ||
inlineMode: true, | ||
otherMatches: otherMatches, | ||
matches: matches, | ||
name: name, | ||
@@ -120,6 +101,3 @@ hash: hash | ||
if (hasApply) { | ||
rules = replaceApplyWithPlaceholders(rules); | ||
} | ||
return { hash: hash, name: name, rules: rules, hasInterpolation: hasVar || hasApply || hasOtherMatch }; | ||
return { hash: hash, name: name, rules: rules, hasInterpolation: hasVar || hasOtherMatch }; | ||
} | ||
@@ -134,6 +112,5 @@ | ||
src = _createSrc3.src, | ||
hasApply = _createSrc3.hasApply, | ||
otherMatches = _createSrc3.otherMatches; | ||
matches = _createSrc3.matches; | ||
var _parseCSS3 = (0, _parser.parseCSS)('@font-face {' + src + '}', { otherMatches: otherMatches, inlineMode: true, name: 'name', hash: 'hash' }), | ||
var _parseCSS3 = (0, _parser.parseCSS)('@font-face {' + src + '}', { matches: matches, inlineMode: true, name: 'name', hash: 'hash' }), | ||
rules = _parseCSS3.rules, | ||
@@ -143,6 +120,3 @@ hasVar = _parseCSS3.hasVar, | ||
if (hasApply) { | ||
rules = replaceApplyWithPlaceholders(rules); | ||
} | ||
return { rules: rules, hasInterpolation: hasVar || hasApply || hasOtherMatch }; | ||
return { rules: rules, hasInterpolation: hasVar || hasOtherMatch }; | ||
} | ||
@@ -157,6 +131,5 @@ | ||
src = _createSrc4.src, | ||
otherMatches = _createSrc4.otherMatches, | ||
hasApply = _createSrc4.hasApply; | ||
matches = _createSrc4.matches; | ||
var _parseCSS4 = (0, _parser.parseCSS)(src, { otherMatches: otherMatches, inlineMode: true, name: 'name', hash: 'hash' }), | ||
var _parseCSS4 = (0, _parser.parseCSS)(src, { matches: matches, inlineMode: true, name: 'name', hash: 'hash' }), | ||
rules = _parseCSS4.rules, | ||
@@ -166,6 +139,3 @@ hasVar = _parseCSS4.hasVar, | ||
if (hasApply) { | ||
rules = replaceApplyWithPlaceholders(rules); | ||
} | ||
return { rules: rules, hasInterpolation: hasVar || hasApply || hasOtherMatch }; | ||
return { rules: rules, hasInterpolation: hasVar || hasOtherMatch }; | ||
} |
@@ -28,5 +28,6 @@ 'use strict'; | ||
inlineMode: true, | ||
otherMatches: 0, | ||
matches: 0, | ||
name: 'name', | ||
hash: 'hash' | ||
hash: 'hash', | ||
canCompose: false | ||
}; | ||
@@ -39,21 +40,43 @@ | ||
var vars = 0; | ||
var composes = 0; | ||
root.walkDecls(function (decl) { | ||
if (decl.prop === 'name') decl.remove(); | ||
if (options.canCompose) { | ||
if (decl.prop === 'composes') { | ||
if (decl.parent.selector !== '.' + options.name + '-' + options.hash) { | ||
throw new Error('composes cannot be on nested selectors'); | ||
} | ||
if (!/xxx(\S)xxx/gm.exec(decl.value)) { | ||
throw new Error('composes must be a interpolation'); | ||
} | ||
if (decl.parent.nodes[0] !== decl) { | ||
throw new Error('composes must be the first rule'); | ||
} | ||
var numOfComposes = decl.value.match(/xxx(\S)xxx/gm).length; | ||
composes += numOfComposes; | ||
vars += numOfComposes; | ||
return decl.remove(); | ||
} | ||
} | ||
if (!options.inlineMode) { | ||
var re = /xxx(\S)xxx/gm; | ||
var match = re.exec(decl.value); | ||
var match = /xxx(\S)xxx/gm.exec(decl.value); | ||
if (match) { | ||
vars++; | ||
decl.value = decl.value.replace(match[0], 'var(--' + options.name + '-' + options.hash + '-' + match[1] + ')'); | ||
} | ||
} | ||
}); | ||
if (!options.inlineMode && vars === options.matches) { | ||
root.walkDecls(function (decl) { | ||
decl.value = decl.value.replace(/xxx(\S)xxx/gm, function (match, p1) { | ||
return 'var(--' + options.name + '-' + options.hash + '-' + p1 + ')'; | ||
}); | ||
}); | ||
} | ||
(0, _autoprefix2.default)(root); | ||
return { | ||
rules: stringifyCSSRoot(root), | ||
hasOtherMatch: vars !== options.otherMatches, | ||
hasVar: !!vars || !!(options.inlineMode && options.otherMatches) | ||
hasOtherMatch: vars !== options.matches, | ||
hasVar: !!vars && vars !== composes || !!(options.inlineMode && options.matches), | ||
composes: composes | ||
}; | ||
@@ -60,0 +83,0 @@ } |
@@ -24,8 +24,5 @@ 'use strict'; | ||
var _cls$split = cls.split('-'), | ||
name = _cls$split[0]; | ||
var debugName = name === 'css' ? '' : '.' + name; | ||
var name = cls[0].split('-')[1]; | ||
var componentTag = tag.displayName || tag.name || 'Component'; | ||
Styled.displayName = 'styled(' + componentTag + debugName + ')'; | ||
Styled.displayName = 'styled(' + componentTag + name + ')'; | ||
Styled.cls = '.' + cls; | ||
@@ -32,0 +29,0 @@ return Styled; |
'use strict'; | ||
exports.__esModule = true; | ||
exports.renderStatic = renderStatic; | ||
exports.renderStaticOptimized = renderStaticOptimized; | ||
exports.extractCritical = extractCritical; | ||
var _index = require('./index'); | ||
/** ** serverside stuff ****/ | ||
// the api's copied from aphrodite, with 1 key difference | ||
// we include *all* the css generated by the app | ||
// to optimize to only include generated styles on the pages | ||
// use renderStaticOptimized | ||
function renderStatic(fn) { | ||
var html = fn(); | ||
if (html === undefined) { | ||
throw new Error('did you forget to return from renderToString?'); | ||
} | ||
var rules = _index.sheet.sheet.cssRules; | ||
var css = rules.map(function (r) { | ||
return r.cssText; | ||
}).join(''); | ||
return { html: html, ids: Object.keys(_index.inserted), css: css, rules: rules }; | ||
} | ||
function renderStaticOptimized(fn) { | ||
function extractCritical(html) { | ||
// parse out ids from html | ||
// reconstruct css/rules/cache to pass | ||
var html = fn(); | ||
if (html === undefined) { | ||
throw new Error('did you forget to return from renderToString?'); | ||
} | ||
var o = { html: html, ids: [], css: '', rules: [] }; | ||
@@ -35,0 +12,0 @@ var regex = /css-([a-zA-Z0-9]+)/gm; |
{ | ||
"name": "emotion", | ||
"version": "4.1.6", | ||
"version": "5.0.0", | ||
"description": "high performance css-in-js", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
102
README.md
@@ -19,4 +19,5 @@ <h1 align="center" style="color: #343a40"> | ||
- [Install](#install) | ||
- [Example Project](https://github.com/tkh44/emotion/tree/master/example) | ||
- [Install](#install) | ||
- [Example Project](https://github.com/tkh44/emotion/tree/master/example) | ||
- [Benchmarks](https://github.com/tkh44/emotion/tree/master/docs/benchmarks.md) | ||
@@ -74,4 +75,23 @@ ## Install | ||
Inline mode does **not** extract css into external files. | ||
- ~~Only extracts styles **without** dynamic values.~~ (we're working on this) | ||
- No css var requirement | ||
- Same speed as default mode in benchmarks | ||
- Works with SSR | ||
Extracted: | ||
```jsx | ||
const H1 = styled('h1')` | ||
color: #ffd43b; | ||
` | ||
``` | ||
**Not** extracted | ||
```jsx | ||
const H1 = styled('h1')` | ||
color: ${props => props.color}; | ||
` | ||
``` | ||
Configure babel | ||
**.babelrc** | ||
@@ -92,3 +112,3 @@ ```json | ||
const H1 = styled('h1')` | ||
color: #ffd43b; | ||
color: ${props => props.color}; | ||
` | ||
@@ -103,4 +123,4 @@ ``` | ||
const H1 = styled('h1', 'css-H1-duiy4a', [], function createEmotionStyles() { | ||
return ['.css-H1-duiy4a {color:blue}'] | ||
const H1 = styled('h1', 'css-H1-duiy4a', [props => props.color], function createEmotionStyles(x0) { | ||
return [`.css-H1-duiy4a { color:${x0} }`] | ||
}) | ||
@@ -193,4 +213,6 @@ ``` | ||
### fragment | ||
### composes property | ||
The composes property is based on [css modules' composes property](https://github.com/css-modules/css-modules#composition). | ||
```jsx | ||
@@ -200,4 +222,4 @@ import { fragment, css } from 'emotion' | ||
// You can define fragments which can be reused anywhere | ||
const flexCenter = fragment` | ||
// Define a class | ||
const flexCenter = css` | ||
display: flex; | ||
@@ -208,14 +230,41 @@ justify-content: center; | ||
// You can use them with @apply | ||
// You can use compose them with the composes property | ||
const flexCenterClass = css` | ||
@apply ${flexCenter}; | ||
composes: ${flexCenter}; | ||
flex-direction: column; | ||
` | ||
// You can use them with all of emotion's apis like styled | ||
// You can also use them in styled.* and the css prop | ||
const FlexCenterComponent = styled.div` | ||
@apply ${flexCenter} | ||
composes: ${flexCenter}; | ||
` | ||
const flexWrap = css` | ||
flex-wrap: wrap; | ||
` | ||
// You can compose with use multiple classes | ||
const ColumnCenteredComponent = styled.div` | ||
composes: ${flexCenter} ${flexWrap}; | ||
` | ||
// You can also use composes with regular classes or classes from a css module | ||
const CssModuleComponent = styled.h1` | ||
composes: ${'some-class'} ${styles.header}; | ||
` | ||
// composes MUST be the first rule, e.g. this doesn't work | ||
const cls = css` | ||
font-size: 20px; | ||
composes: ${flexCenter} | ||
` | ||
// composes also does not work in nested selectors, e.g. this doesn't work | ||
const cls = css` | ||
& .flex { | ||
composes: ${flexCenter} | ||
} | ||
` | ||
``` | ||
@@ -265,32 +314,19 @@ | ||
Server-Side Rendering in emotion currently only works in inline mode. It's based on [glamor's api](https://github.com/threepointone/glamor/blob/master/docs/server.md). For an example of emotion and next.js checkout the [with-emotion example in the next.js repo](https://github.com/zeit/next.js/tree/master/examples/with-emotion). | ||
Server-Side Rendering in emotion currently only works in inline mode. It's similar to [glamor's api](https://github.com/threepointone/glamor/blob/master/docs/server.md). For an example of emotion and next.js checkout the [with-emotion example in the next.js repo](https://github.com/zeit/next.js/tree/master/examples/with-emotion). | ||
#### renderStatic | ||
This returns an object with the properties `html`, `ids` and `css`. | ||
#### extractCritical | ||
This returns an object with the properties `html`, `ids` and `css`. It removes unused rules that were created with emotion(it still includes rules that were inserted with `injectGlobal`). | ||
```jsx | ||
import { renderToString } from 'react-dom/server' | ||
import { renderStatic } from 'emotion/server' | ||
import { extractCritical } from 'emotion/server' | ||
import App from './App' | ||
const { html, ids, css } = renderStatic(() => renderToString(<App/>)) | ||
const { html, ids, css } = extractCritical(renderToString(<App/>)) | ||
``` | ||
#### renderStatic | ||
This returns an object with the properties `html`, `ids` and `css` just like `renderStatic` but it remove unused rules that were created with emotion(it still includes rules that were inserted with `injectGlobal`). | ||
```jsx | ||
import { renderToString } from 'react-dom/server' | ||
import { renderStaticOptimized } from 'emotion/server' | ||
import App from './App' | ||
const { html, ids, css } = renderStaticOptimized(() => renderToString(<App/>)) | ||
``` | ||
#### hydrate | ||
`hydrate` should be called on the client with the `ids` that `renderStatic` and `renderStaticOptimized` return. If you don't call it then emotion will reinsert all the rules. | ||
`hydrate` should be called on the client with the `ids` that `extractCritical` returns. If you don't call it then emotion will reinsert all the rules. | ||
@@ -297,0 +333,0 @@ ```jsx |
131
src/babel.js
@@ -8,7 +8,23 @@ import fs from 'fs' | ||
function parseDynamicValues (rules, t, inputExpressions) { | ||
function joinExpressionsWithSpaces (expressions, t) { | ||
const quasis = [t.templateElement({ cooked: '', raw: '' }, true)] | ||
expressions.forEach((x, i) => { | ||
if (i === expressions.length - 1) { | ||
return quasis.push(t.templateElement({ cooked: '', raw: '' }, true)) | ||
} | ||
quasis.push(t.templateElement({ cooked: ' ', raw: ' ' }, true)) | ||
}) | ||
return t.templateLiteral( | ||
quasis, | ||
expressions | ||
) | ||
} | ||
function parseDynamicValues (rules, t, inputExpressions, composes = 0) { | ||
return rules.map(rule => { | ||
const re = /xxx(\S)xxx/gm | ||
let varMatch | ||
let matches = [] | ||
while ((varMatch = re.exec(rule)) !== null) { | ||
@@ -31,5 +47,4 @@ matches.push({ | ||
} | ||
expressions.push(inputExpressions[p1 - composes]) | ||
expressions.push(inputExpressions[p1]) | ||
if (i === matches.length - 1 && cursor <= rule.length) { | ||
@@ -127,3 +142,3 @@ const postMatch = rule.substring(cursor) | ||
let { hash, rules, name, hasOtherMatch, hasApply } = inline( | ||
let { hash, rules, name, hasOtherMatch, composes } = inline( | ||
built, | ||
@@ -139,8 +154,12 @@ identifierName, | ||
} | ||
const inputClasses = [t.stringLiteral(`${name}-${hash}`)] | ||
for (var i = 0; i < composes; i++) { | ||
inputClasses.push(path.node.quasi.expressions.shift()) | ||
} | ||
const args = [ | ||
tag, | ||
t.stringLiteral(`${name}-${hash}`), | ||
t.arrayExpression(inputClasses), | ||
t.arrayExpression(built.expressions) | ||
] | ||
if (!hasApply && !hasOtherMatch && !state.inline) { | ||
if (!hasOtherMatch && !state.inline) { | ||
state.insertStaticRules(rules) | ||
@@ -156,3 +175,5 @@ } else { | ||
t.returnStatement( | ||
t.arrayExpression(parseDynamicValues(rules, t, expressions)) | ||
t.arrayExpression( | ||
parseDynamicValues(rules, t, expressions, composes) | ||
) | ||
) | ||
@@ -195,61 +216,49 @@ ]) | ||
t.isIdentifier(path.node.tag) && | ||
path.node.tag.name === 'fragment' | ||
) { | ||
const { rules } = inline( | ||
path.node.quasi, | ||
identifierName, | ||
'frag', | ||
true | ||
) | ||
if (rules.length > 1) { | ||
throw path.buildCodeFrameError( | ||
'Fragments cannot have multiple selectors.' | ||
) | ||
} | ||
const rulesWithoutSelector = rules.map(rule => | ||
rule.substring(rule.indexOf('{') + 1, rule.length - 1).trim() | ||
) | ||
path.replaceWith( | ||
parseDynamicValues( | ||
rulesWithoutSelector, | ||
t, | ||
path.node.quasi.expressions | ||
)[0] | ||
) | ||
} else if ( | ||
t.isIdentifier(path.node.tag) && | ||
path.node.tag.name === 'css' | ||
) { | ||
const { hash, name, rules, hasApply, hasVar, hasOtherMatch } = inline( | ||
path.node.quasi, | ||
identifierName, | ||
'css', | ||
state.inline | ||
) | ||
const classNameStringLiteral = t.stringLiteral(`${name}-${hash}`) | ||
const args = [ | ||
classNameStringLiteral, | ||
t.arrayExpression(path.node.quasi.expressions) | ||
] | ||
if (!hasApply && !hasOtherMatch && !state.inline) { | ||
state.insertStaticRules(rules) | ||
if (!hasVar) { | ||
return path.replaceWith(classNameStringLiteral) | ||
try { | ||
const { | ||
hash, | ||
name, | ||
rules, | ||
hasVar, | ||
composes, | ||
hasOtherMatch | ||
} = inline(path.node.quasi, identifierName, 'css', state.inline) | ||
const inputClasses = [t.stringLiteral(`${name}-${hash}`)] | ||
for (var i = 0; i < composes; i++) { | ||
inputClasses.push(path.node.quasi.expressions.shift()) | ||
} | ||
} else { | ||
const expressions = path.node.quasi.expressions.map((x, i) => | ||
t.identifier(`x${i}`) | ||
) | ||
const inlineContentExpr = t.functionExpression( | ||
t.identifier('createEmotionRules'), | ||
expressions, | ||
t.blockStatement([ | ||
t.returnStatement( | ||
t.arrayExpression(parseDynamicValues(rules, t, expressions)) | ||
const args = [ | ||
t.arrayExpression(inputClasses), | ||
t.arrayExpression(path.node.quasi.expressions) | ||
] | ||
if (!hasOtherMatch && !state.inline) { | ||
state.insertStaticRules(rules) | ||
if (!hasVar) { | ||
return path.replaceWith( | ||
joinExpressionsWithSpaces(inputClasses, t) | ||
) | ||
]) | ||
) | ||
args.push(inlineContentExpr) | ||
} | ||
} else { | ||
const expressions = path.node.quasi.expressions.map((x, i) => | ||
t.identifier(`x${i}`) | ||
) | ||
const inlineContentExpr = t.functionExpression( | ||
t.identifier('createEmotionRules'), | ||
expressions, | ||
t.blockStatement([ | ||
t.returnStatement( | ||
t.arrayExpression( | ||
parseDynamicValues(rules, t, expressions, composes) | ||
) | ||
) | ||
]) | ||
) | ||
args.push(inlineContentExpr) | ||
} | ||
path.replaceWith(t.callExpression(t.identifier('css'), args)) | ||
} catch (e) { | ||
throw path.buildCodeFrameError(e) | ||
} | ||
path.replaceWith(t.callExpression(t.identifier('css'), args)) | ||
} else if ( | ||
@@ -256,0 +265,0 @@ t.isIdentifier(path.node.tag) && |
@@ -35,3 +35,3 @@ // @flow | ||
export function css (cls: string, vars: vars, content: () => string[]) { | ||
export function css (classes: string[], vars: vars, content: () => string[]) { | ||
if (content) { | ||
@@ -45,12 +45,10 @@ // inline mode | ||
src | ||
.map(r => r.replace(new RegExp(cls, 'gm'), `${cls}-${hash}`)) | ||
.map(r => r.replace(new RegExp(classes[0], 'gm'), `${classes[0]}-${hash}`)) | ||
.forEach(r => sheet.insert(r)) | ||
} | ||
return `${cls}-${hash} ${cls}` | ||
return `${classes[0]}-${hash} ${classes.join(' ')}` | ||
} | ||
return cls + (vars && vars.length > 0 ? ' ' + values(cls, vars) : '') | ||
return classes.join(' ') + (vars && vars.length > 0 ? ' ' + values(classes[0], vars) : '') | ||
} | ||
export function fragment () {} | ||
export function injectGlobal (src: string[]) { | ||
@@ -57,0 +55,0 @@ const hash = hashArray(src) |
@@ -28,11 +28,2 @@ // @flow | ||
function replaceApplyWithPlaceholders (rules: string[]): string[] { | ||
return rules.map(rule => | ||
rule.replace( | ||
/@apply\s+--[A-Za-z0-9-_]+-([0-9]+)/gm, | ||
(match, p1) => `xxx${p1}xxx` | ||
) | ||
) | ||
} | ||
function createSrc ( | ||
@@ -42,5 +33,4 @@ strs: string[], | ||
hash: string | ||
): { src: string, hasApply: boolean, otherMatches: number } { | ||
let hasApply = false | ||
let otherMatches = 0 | ||
): { src: string, matches: number } { | ||
let matches = 0 | ||
const src = strs | ||
@@ -50,11 +40,4 @@ .reduce((arr, str, i) => { | ||
if (i !== strs.length - 1) { | ||
// todo - test for preceding @apply | ||
let applyMatch = /@apply\s*$/gm.exec(str) | ||
if (applyMatch) { | ||
hasApply = true | ||
arr.push(`--${name}-${hash}-${i}`) | ||
} else { | ||
otherMatches++ | ||
arr.push(`xxx${i}xxx`) | ||
} | ||
matches++ | ||
arr.push(`xxx${i}xxx`) | ||
} | ||
@@ -65,3 +48,3 @@ return arr | ||
.trim() | ||
return { src, hasApply, otherMatches } | ||
return { src, matches } | ||
} | ||
@@ -78,5 +61,5 @@ | ||
rules: string[], | ||
hasApply: boolean, | ||
hasVar: boolean, | ||
hasOtherMatch: boolean | ||
hasOtherMatch: boolean, | ||
composes: number | ||
} { | ||
@@ -90,15 +73,11 @@ let strs = quasi.quasis.map(x => x.value.cooked) | ||
) | ||
let { src, hasApply, otherMatches } = createSrc(strs, name, hash) | ||
let { rules, hasVar, hasOtherMatch } = parseCSS(`.${name}-${hash} { ${src} }`, { | ||
inlineMode: inlineMode || hasApply, | ||
otherMatches, | ||
let { src, matches } = createSrc(strs, name, hash) | ||
let { rules, hasVar, hasOtherMatch, composes } = parseCSS(`.${name}-${hash} { ${src} }`, { | ||
inlineMode: inlineMode, | ||
matches, | ||
name, | ||
hash | ||
hash, | ||
canCompose: true | ||
}) | ||
if (hasApply) { | ||
rules = replaceApplyWithPlaceholders(rules) | ||
} | ||
return { hash, name, rules, hasApply, hasVar, hasOtherMatch } | ||
return { hash, name, rules, hasVar, hasOtherMatch, composes } | ||
} | ||
@@ -123,14 +102,11 @@ | ||
) | ||
const { src, hasApply, otherMatches } = createSrc(strs, name, hash) | ||
const { src, matches } = createSrc(strs, name, hash) | ||
let { rules, hasVar, hasOtherMatch } = parseCSS(`{ ${src} }`, { | ||
nested: false, | ||
inlineMode: true, | ||
otherMatches, | ||
matches, | ||
name, | ||
hash | ||
}) | ||
if (hasApply) { | ||
rules = replaceApplyWithPlaceholders(rules) | ||
} | ||
return { hash, name, rules, hasInterpolation: hasVar || hasApply || hasOtherMatch } | ||
return { hash, name, rules, hasInterpolation: hasVar || hasOtherMatch } | ||
} | ||
@@ -142,8 +118,5 @@ | ||
let strs = quasi.quasis.map(x => x.value.cooked) | ||
const { src, hasApply, otherMatches } = createSrc(strs, 'name', 'hash') | ||
let { rules, hasVar, hasOtherMatch } = parseCSS(`@font-face {${src}}`, { otherMatches, inlineMode: true, name: 'name', hash: 'hash' }) | ||
if (hasApply) { | ||
rules = replaceApplyWithPlaceholders(rules) | ||
} | ||
return { rules, hasInterpolation: hasVar || hasApply || hasOtherMatch } | ||
const { src, matches } = createSrc(strs, 'name', 'hash') | ||
let { rules, hasVar, hasOtherMatch } = parseCSS(`@font-face {${src}}`, { matches, inlineMode: true, name: 'name', hash: 'hash' }) | ||
return { rules, hasInterpolation: hasVar || hasOtherMatch } | ||
} | ||
@@ -155,8 +128,5 @@ | ||
let strs = quasi.quasis.map(x => x.value.cooked) | ||
const { src, otherMatches, hasApply } = createSrc(strs, 'name', 'hash') | ||
let { rules, hasVar, hasOtherMatch } = parseCSS(src, { otherMatches, inlineMode: true, name: 'name', hash: 'hash' }) | ||
if (hasApply) { | ||
rules = replaceApplyWithPlaceholders(rules) | ||
} | ||
return { rules, hasInterpolation: hasVar || hasApply || hasOtherMatch } | ||
const { src, matches } = createSrc(strs, 'name', 'hash') | ||
let { rules, hasVar, hasOtherMatch } = parseCSS(src, { matches, inlineMode: true, name: 'name', hash: 'hash' }) | ||
return { rules, hasInterpolation: hasVar || hasOtherMatch } | ||
} |
@@ -12,13 +12,15 @@ // @flow | ||
inlineMode: boolean, | ||
otherMatches: number, | ||
matches: number, | ||
name: string, | ||
hash: string | ||
hash: string, | ||
canCompose?: boolean | ||
} = { | ||
nested: true, | ||
inlineMode: true, | ||
otherMatches: 0, | ||
matches: 0, | ||
name: 'name', | ||
hash: 'hash' | ||
hash: 'hash', | ||
canCompose: false | ||
} | ||
): { rules: string[], hasOtherMatch: boolean, hasVar: boolean } { | ||
): { rules: string[], hasOtherMatch: boolean, hasVar: boolean, composes: number } { | ||
// todo - handle errors | ||
@@ -29,21 +31,43 @@ const root = parse(css) | ||
let vars = 0 | ||
let composes = 0 | ||
root.walkDecls(decl => { | ||
if (decl.prop === 'name') decl.remove() | ||
if (options.canCompose) { | ||
if (decl.prop === 'composes') { | ||
if (decl.parent.selector !== `.${options.name}-${options.hash}`) { | ||
throw new Error('composes cannot be on nested selectors') | ||
} | ||
if (!/xxx(\S)xxx/gm.exec(decl.value)) { | ||
throw new Error('composes must be a interpolation') | ||
} | ||
if (decl.parent.nodes[0] !== decl) { | ||
throw new Error('composes must be the first rule') | ||
} | ||
const numOfComposes = decl.value.match(/xxx(\S)xxx/gm).length | ||
composes += numOfComposes | ||
vars += numOfComposes | ||
return decl.remove() | ||
} | ||
} | ||
if (!options.inlineMode) { | ||
const re = /xxx(\S)xxx/gm | ||
const match = re.exec(decl.value) | ||
const match = /xxx(\S)xxx/gm.exec(decl.value) | ||
if (match) { | ||
vars++ | ||
decl.value = decl.value.replace(match[0], `var(--${options.name}-${options.hash}-${match[1]})`) | ||
} | ||
} | ||
}) | ||
if (!options.inlineMode && vars === options.matches) { | ||
root.walkDecls((decl) => { | ||
decl.value = decl.value.replace(/xxx(\S)xxx/gm, (match, p1) => { | ||
return `var(--${options.name}-${options.hash}-${p1})` | ||
}) | ||
}) | ||
} | ||
autoprefix(root) | ||
return { | ||
rules: stringifyCSSRoot(root), | ||
hasOtherMatch: vars !== options.otherMatches, | ||
hasVar: !!vars || !!(options.inlineMode && options.otherMatches) | ||
hasOtherMatch: vars !== options.matches, | ||
hasVar: (!!vars && vars !== composes) || !!(options.inlineMode && options.matches), | ||
composes | ||
} | ||
@@ -50,0 +74,0 @@ } |
@@ -29,8 +29,7 @@ import React from 'react' | ||
const [name] = cls.split('-') | ||
const debugName = name === 'css' ? '' : `.${name}` | ||
const name = cls[0].split('-')[1] | ||
const componentTag = tag.displayName || tag.name || 'Component' | ||
Styled.displayName = `styled(${componentTag}${debugName})` | ||
Styled.displayName = `styled(${componentTag}${name})` | ||
Styled.cls = '.' + cls | ||
return Styled | ||
} |
import { sheet, inserted } from './index' | ||
/** ** serverside stuff ****/ | ||
// the api's copied from aphrodite, with 1 key difference | ||
// we include *all* the css generated by the app | ||
// to optimize to only include generated styles on the pages | ||
// use renderStaticOptimized | ||
export function renderStatic (fn) { | ||
let html = fn() | ||
if (html === undefined) { | ||
throw new Error('did you forget to return from renderToString?') | ||
} | ||
let rules = sheet.sheet.cssRules | ||
let css = rules.map(r => r.cssText).join('') | ||
return { html, ids: Object.keys(inserted), css, rules } | ||
} | ||
export function renderStaticOptimized (fn) { | ||
export function extractCritical (html) { | ||
// parse out ids from html | ||
// reconstruct css/rules/cache to pass | ||
let html = fn() | ||
if (html === undefined) { | ||
throw new Error('did you forget to return from renderToString?') | ||
} | ||
let o = { html, ids: [], css: '', rules: [] } | ||
@@ -27,0 +7,0 @@ let regex = /css-([a-zA-Z0-9]+)/gm |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
409
98166
2013