Comparing version 3.0.3 to 4.0.0
108
lib/babel.js
@@ -13,3 +13,31 @@ 'use strict'; | ||
visitor: { | ||
TaggedTemplateExpression: function TaggedTemplateExpression(path) { | ||
Program: { | ||
enter: function enter(path, state) { | ||
state.inline = path.hub.file.opts.filename === 'unknown' || state.opts.inline; | ||
state.staticRules = []; | ||
state.insertStaticRules = function (staticRules) { | ||
var _state$staticRules; | ||
(_state$staticRules = state.staticRules).push.apply(_state$staticRules, staticRules); | ||
}; | ||
}, | ||
exit: function exit(path, state) { | ||
if (state.staticRules.length !== 0) { | ||
var toWrite = state.staticRules.join('\n').trim(); | ||
var filenameArr = path.hub.file.opts.filename.split('.'); | ||
filenameArr.pop(); | ||
filenameArr.push('emotion', 'css'); | ||
var cssFilename = filenameArr.join('.'); | ||
var exists = _fs2.default.existsSync(cssFilename); | ||
path.node.body.unshift(t.importDeclaration([], t.stringLiteral('./' + (0, _path.basename)(cssFilename)))); | ||
if (exists ? _fs2.default.readFileSync(cssFilename, 'utf8') !== toWrite : true) { | ||
if (!exists) { | ||
(0, _touch.touchSync)(cssFilename); | ||
} | ||
_fs2.default.writeFileSync(cssFilename, toWrite); | ||
} | ||
} | ||
} | ||
}, | ||
TaggedTemplateExpression: function TaggedTemplateExpression(path, state) { | ||
// in: | ||
@@ -34,3 +62,3 @@ // styled.h1`color:${color};` | ||
var _inline = (0, _inline4.inline)(built, identifierName, 'css' | ||
var _inline = (0, _inline4.inline)(built, identifierName, 'css', state.inline | ||
@@ -41,3 +69,4 @@ // hash will be '0' when no styles are passed so we can just return the original tag | ||
rules = _inline.rules, | ||
name = _inline.name; | ||
name = _inline.name, | ||
isStatic = _inline.isStatic; | ||
@@ -47,10 +76,12 @@ if (hash === '0') { | ||
} | ||
var args = [tag, t.stringLiteral(name + '-' + hash), t.arrayExpression(built.expressions)]; | ||
if (isStatic) { | ||
state.insertStaticRules(rules); | ||
} else { | ||
var inlineContentExpr = t.functionExpression(t.identifier('createEmotionStyledRules'), built.expressions.map(function (x, i) { | ||
return t.identifier('x' + i); | ||
}), t.blockStatement([t.returnStatement(t.arrayExpression(parseDynamicValues(rules, t)))])); | ||
args.push(inlineContentExpr); | ||
} | ||
var arrayValues = parseDynamicValues(rules, t); | ||
var inlineContentExpr = t.functionExpression(t.identifier('createEmotionStyledRules'), built.expressions.map(function (x, i) { | ||
return t.identifier('x' + i); | ||
}), t.blockStatement([t.returnStatement(t.arrayExpression(arrayValues))])); | ||
var args = [tag, t.stringLiteral(name + '-' + hash), t.arrayExpression(built.expressions), inlineContentExpr]; | ||
return t.callExpression(identifier, args); | ||
@@ -68,26 +99,39 @@ } | ||
} else if (t.isIdentifier(path.node.tag) && path.node.tag.name === 'fragment') { | ||
var _inline2 = (0, _inline4.inline)(path.node.quasi, identifierName, 'frag'), | ||
hash = _inline2.hash, | ||
name = _inline2.name, | ||
var _inline2 = (0, _inline4.inline)(path.node.quasi, identifierName, 'frag', true), | ||
rules = _inline2.rules; | ||
path.replaceWith(t.callExpression(t.identifier('fragment'), [t.stringLiteral(name + '-' + hash), t.arrayExpression(path.node.quasi.expressions), t.functionExpression(t.identifier('createEmotionFragment'), path.node.quasi.expressions.map(function (x, i) { | ||
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); | ||
}); | ||
var dynamicRules = parseDynamicValues(rulesWithoutSelector, t); | ||
path.replaceWith(t.callExpression(t.identifier('fragment'), [t.arrayExpression(path.node.quasi.expressions), t.functionExpression(t.identifier('createEmotionFragment'), path.node.quasi.expressions.map(function (x, i) { | ||
return t.identifier('x' + i); | ||
}), t.blockStatement([t.returnStatement(t.arrayExpression(parseDynamicValues(rules, t)))]))])); | ||
}), t.blockStatement([t.returnStatement(dynamicRules[0])]))])); | ||
} else if (t.isIdentifier(path.node.tag) && path.node.tag.name === 'css') { | ||
var _inline3 = (0, _inline4.inline)(path.node.quasi, identifierName, 'css'), | ||
_hash = _inline3.hash, | ||
_name = _inline3.name, | ||
_rules = _inline3.rules; | ||
var _inline3 = (0, _inline4.inline)(path.node.quasi, identifierName, 'css', state.inline), | ||
hash = _inline3.hash, | ||
name = _inline3.name, | ||
_rules = _inline3.rules, | ||
isStatic = _inline3.isStatic; | ||
path.replaceWith(t.callExpression(t.identifier('css'), [t.stringLiteral(_name + '-' + _hash), t.arrayExpression(path.node.quasi.expressions), t.functionExpression(t.identifier('createEmotionRules'), path.node.quasi.expressions.map(function (x, i) { | ||
return t.identifier('x' + i); | ||
}), t.blockStatement([t.returnStatement(t.arrayExpression(parseDynamicValues(_rules, t)))]))])); | ||
var args = [t.stringLiteral(name + '-' + hash), t.arrayExpression(path.node.quasi.expressions)]; | ||
if (isStatic) { | ||
state.insertStaticRules(_rules); | ||
} else { | ||
var inlineContentExpr = t.functionExpression(t.identifier('createEmotionRules'), path.node.quasi.expressions.map(function (x, i) { | ||
return t.identifier('x' + i); | ||
}), t.blockStatement([t.returnStatement(t.arrayExpression(parseDynamicValues(_rules, t)))])); | ||
args.push(inlineContentExpr); | ||
} | ||
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'), | ||
_hash2 = _keyframes.hash, | ||
_name2 = _keyframes.name, | ||
_hash = _keyframes.hash, | ||
_name = _keyframes.name, | ||
_rules2 = _keyframes.rules; | ||
path.replaceWith(t.callExpression(t.identifier('keyframes'), [t.stringLiteral(_name2 + '-' + _hash2), t.arrayExpression(path.node.quasi.expressions), t.functionExpression(t.identifier('createEmotionKeyframe'), path.node.quasi.expressions.map(function (x, i) { | ||
path.replaceWith(t.callExpression(t.identifier('keyframes'), [t.stringLiteral(_name + '-' + _hash), t.arrayExpression(path.node.quasi.expressions), t.functionExpression(t.identifier('createEmotionKeyframe'), path.node.quasi.expressions.map(function (x, i) { | ||
return t.identifier('x' + i); | ||
@@ -99,7 +143,7 @@ }), t.blockStatement([t.returnStatement(t.arrayExpression(_rules2.map(function (r) { | ||
var _fontFace = (0, _inline4.fontFace)(path.node.quasi, identifierName, 'font-face'), | ||
_hash3 = _fontFace.hash, | ||
_name3 = _fontFace.name, | ||
_hash2 = _fontFace.hash, | ||
_name2 = _fontFace.name, | ||
_rules3 = _fontFace.rules; | ||
path.replaceWith(t.callExpression(t.identifier('fontFace'), [t.stringLiteral(_name3 + '-' + _hash3), t.arrayExpression(path.node.quasi.expressions), t.functionExpression(t.identifier('createEmotionFontFace'), path.node.quasi.expressions.map(function (x, i) { | ||
path.replaceWith(t.callExpression(t.identifier('fontFace'), [t.stringLiteral(_name2 + '-' + _hash2), t.arrayExpression(path.node.quasi.expressions), t.functionExpression(t.identifier('createEmotionFontFace'), path.node.quasi.expressions.map(function (x, i) { | ||
return t.identifier('x' + i); | ||
@@ -115,4 +159,10 @@ }), t.blockStatement([t.returnStatement(t.arrayExpression(_rules3.map(function (r) { | ||
var _parser = require('./parser'); | ||
var _fs = require('fs'); | ||
var _fs2 = _interopRequireDefault(_fs); | ||
var _path = require('path'); | ||
var _touch = require('touch'); | ||
var _inline4 = require('./inline'); | ||
@@ -119,0 +169,0 @@ |
@@ -5,2 +5,3 @@ 'use strict'; | ||
exports.default = hashArray; | ||
// murmurhash2 via https://gist.github.com/raycmorgan/588423 | ||
@@ -7,0 +8,0 @@ |
@@ -25,2 +25,17 @@ 'use strict'; | ||
function values(cls, vars) { | ||
var hash = (0, _hash2.default)([cls].concat(vars)); | ||
var varCls = 'vars-' + hash; | ||
if (inserted[hash]) { | ||
return varCls; | ||
} | ||
var src = vars.map(function (val, i) { | ||
return '--' + cls + '-' + i + ': ' + val; | ||
}).join('; '); | ||
sheet.insert('.' + varCls + ' {' + src + '}'); | ||
inserted[hash] = true; | ||
return varCls; | ||
} | ||
function flush() { | ||
@@ -33,37 +48,22 @@ sheet.flush(); | ||
function css(cls, vars, content) { | ||
// inline mode | ||
vars = vars.map(function (v) { | ||
return (/^frag-/.exec(v) ? fragments[v] : v | ||
); | ||
}); | ||
var src = content.apply(undefined, vars); | ||
var hash = (0, _hash2.default)(src); | ||
if (content) { | ||
// inline mode | ||
var src = content.apply(undefined, vars); // returns an array | ||
var hash = (0, _hash2.default)(src); | ||
if (!inserted[hash]) { | ||
inserted[hash] = true; | ||
src.map(function (r) { | ||
return r.replace(new RegExp(cls, 'gm'), cls + '-' + hash); | ||
}).forEach(function (r) { | ||
return sheet.insert(r); | ||
}); | ||
if (!inserted[hash]) { | ||
inserted[hash] = true; | ||
src.map(function (r) { | ||
return r.replace(new RegExp(cls, 'gm'), cls + '-' + hash); | ||
}).forEach(function (r) { | ||
return sheet.insert(r); | ||
}); | ||
} | ||
return cls + '-' + hash; | ||
} | ||
return cls + '-' + hash; | ||
return cls + (vars && vars.length > 0 ? ' ' + values(cls, vars) : ''); | ||
} | ||
var fragments = {}; | ||
function fragment(frag, vars, content) { | ||
vars = vars.map(function (v) { | ||
return (/^frag-/.exec(v) ? fragments[v] : v | ||
); | ||
}); | ||
var src = content.apply(undefined, vars); | ||
if (src.length > 1) { | ||
throw new Error('what up!'); | ||
} | ||
var hash = (0, _hash2.default)(src); | ||
src = src.join(''); | ||
fragments[frag + '-' + hash] = src.substring(src.indexOf('{') + 1, src.length - 1); | ||
return frag + '-' + hash; | ||
function fragment(vars, content) { | ||
return content.apply(undefined, vars); | ||
} | ||
@@ -70,0 +70,0 @@ |
@@ -35,3 +35,3 @@ 'use strict'; | ||
function inline(quasi, identifierName, prefix) { | ||
function inline(quasi, identifierName, prefix, inlineVars) { | ||
var strs = quasi.quasis.map(function (x) { | ||
@@ -42,3 +42,3 @@ return x.value.cooked; | ||
);var name = getName(extractNameFromProperty(strs.join('xxx')), identifierName, prefix); | ||
var hasApply = void 0; | ||
var src = strs.reduce(function (arr, str, i) { | ||
@@ -50,2 +50,3 @@ arr.push(str); | ||
if (applyMatch) { | ||
hasApply = true; | ||
arr.push('--' + name + '-' + hash + '-' + i); | ||
@@ -58,14 +59,18 @@ } else arr.push('var(--' + name + '-' + hash + '-' + i + ')'); | ||
var rules = (0, _parser.parseCSS)('.' + name + '-' + hash + ' { ' + src + ' }'); | ||
rules = rules.map(function (rule) { | ||
return rule.replace(/@apply\s+--[A-Za-z0-9-_]+-([0-9]+)/gm, function (match, p1) { | ||
return 'xxx' + p1 + 'xxx'; | ||
if (hasApply) { | ||
rules = rules.map(function (rule) { | ||
return rule.replace(/@apply\s+--[A-Za-z0-9-_]+-([0-9]+)/gm, function (match, p1) { | ||
return 'xxx' + p1 + 'xxx'; | ||
}); | ||
}); | ||
}); | ||
rules = rules.map(function (rule) { | ||
return rule.replace(/var\(--[A-Za-z0-9-_]+-([0-9]+)\)/gm, function (match, p1) { | ||
return 'xxx' + p1 + 'xxx'; | ||
} | ||
if (inlineVars || hasApply) { | ||
rules = rules.map(function (rule) { | ||
return rule.replace(/var\(--[A-Za-z0-9-_]+-([0-9]+)\)/gm, function (match, p1) { | ||
return 'xxx' + p1 + 'xxx'; | ||
}); | ||
}); | ||
}); | ||
} | ||
return { hash: hash, name: name, rules: rules }; | ||
return { hash: hash, name: name, rules: rules, isStatic: !hasApply && !inlineVars }; | ||
} | ||
@@ -96,4 +101,6 @@ | ||
name: name, | ||
rules: [(0, _parser.parseCSS)('@font-face {' + strs.join('').trim() + '}', { nested: false }).join('').trim()] | ||
rules: [(0, _parser.parseCSS)('@font-face {' + strs.join('').trim() + '}', { | ||
nested: false | ||
}).join('').trim()] | ||
}; | ||
} |
@@ -25,3 +25,5 @@ 'use strict'; | ||
function parseCSS(css) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { nested: true }; | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { | ||
nested: true | ||
}; | ||
@@ -33,2 +35,10 @@ // todo - handle errors | ||
root.walkDecls(function (decl) { | ||
if (decl.prop === 'name') decl.remove(); | ||
}); | ||
return stringifyCSSRoot(root); | ||
} | ||
function stringifyCSSRoot(root) { | ||
return root.nodes.map(function (node, i) { | ||
@@ -35,0 +45,0 @@ var str = ''; |
{ | ||
"name": "emotion", | ||
"version": "3.0.3", | ||
"description": "👩🎤 Glam + React", | ||
"version": "4.0.0", | ||
"description": "high performance css-in-js", | ||
"main": "lib/index.js", | ||
@@ -29,3 +29,4 @@ "files": [ | ||
"dependencies": { | ||
"styled-components": "2.0.0" | ||
"styled-components": "2.0.0", | ||
"touch": "^1.0.0" | ||
}, | ||
@@ -91,2 +92,8 @@ "devDependencies": { | ||
}, | ||
"jest": { | ||
"transform": { | ||
"\\.css$": "<rootDir>/test/styleTransform.js", | ||
"^.+\\.js?$": "babel-jest" | ||
} | ||
}, | ||
"bugs": { | ||
@@ -93,0 +100,0 @@ "url": "https://github.com/tkh44/emotion/issues" |
138
src/babel.js
@@ -1,2 +0,4 @@ | ||
import { parseKeyframes } from './parser' | ||
import fs from 'fs' | ||
import { basename } from 'path' | ||
import { touchSync } from 'touch' | ||
import { inline, keyframes, fontFace } from './inline' | ||
@@ -66,3 +68,37 @@ import findAndReplaceAttrs from './attrs' | ||
visitor: { | ||
TaggedTemplateExpression (path) { | ||
Program: { | ||
enter (path, state) { | ||
state.inline = | ||
path.hub.file.opts.filename === 'unknown' || state.opts.inline | ||
state.staticRules = [] | ||
state.insertStaticRules = function (staticRules) { | ||
state.staticRules.push(...staticRules) | ||
} | ||
}, | ||
exit (path, state) { | ||
if (state.staticRules.length !== 0) { | ||
const toWrite = state.staticRules.join('\n').trim() | ||
const filenameArr = path.hub.file.opts.filename.split('.') | ||
filenameArr.pop() | ||
filenameArr.push('emotion', 'css') | ||
const cssFilename = filenameArr.join('.') | ||
const exists = fs.existsSync(cssFilename) | ||
path.node.body.unshift( | ||
t.importDeclaration( | ||
[], | ||
t.stringLiteral('./' + basename(cssFilename)) | ||
) | ||
) | ||
if ( | ||
exists ? fs.readFileSync(cssFilename, 'utf8') !== toWrite : true | ||
) { | ||
if (!exists) { | ||
touchSync(cssFilename) | ||
} | ||
fs.writeFileSync(cssFilename, toWrite) | ||
} | ||
} | ||
} | ||
}, | ||
TaggedTemplateExpression (path, state) { | ||
// in: | ||
@@ -87,3 +123,8 @@ // styled.h1`color:${color};` | ||
let { hash, rules, name } = inline(built, identifierName, 'css') | ||
let { hash, rules, name, isStatic } = inline( | ||
built, | ||
identifierName, | ||
'css', | ||
state.inline | ||
) | ||
@@ -94,18 +135,21 @@ // hash will be '0' when no styles are passed so we can just return the original tag | ||
} | ||
let arrayValues = parseDynamicValues(rules, t) | ||
const inlineContentExpr = t.functionExpression( | ||
t.identifier('createEmotionStyledRules'), | ||
built.expressions.map((x, i) => t.identifier(`x${i}`)), | ||
t.blockStatement([ | ||
t.returnStatement(t.arrayExpression(arrayValues)) | ||
]) | ||
) | ||
const args = [ | ||
tag, | ||
t.stringLiteral(`${name}-${hash}`), | ||
t.arrayExpression(built.expressions), | ||
inlineContentExpr | ||
t.arrayExpression(built.expressions) | ||
] | ||
if (isStatic) { | ||
state.insertStaticRules(rules) | ||
} else { | ||
const inlineContentExpr = t.functionExpression( | ||
t.identifier('createEmotionStyledRules'), | ||
built.expressions.map((x, i) => t.identifier(`x${i}`)), | ||
t.blockStatement([ | ||
t.returnStatement( | ||
t.arrayExpression(parseDynamicValues(rules, t)) | ||
) | ||
]) | ||
) | ||
args.push(inlineContentExpr) | ||
} | ||
@@ -145,10 +189,19 @@ return t.callExpression(identifier, args) | ||
) { | ||
const { hash, name, rules } = inline( | ||
const { rules } = inline( | ||
path.node.quasi, | ||
identifierName, | ||
'frag' | ||
'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) | ||
) | ||
const dynamicRules = parseDynamicValues(rulesWithoutSelector, t) | ||
path.replaceWith( | ||
t.callExpression(t.identifier('fragment'), [ | ||
t.stringLiteral(`${name}-${hash}`), | ||
t.arrayExpression(path.node.quasi.expressions), | ||
@@ -160,7 +213,3 @@ t.functionExpression( | ||
), | ||
t.blockStatement([ | ||
t.returnStatement( | ||
t.arrayExpression(parseDynamicValues(rules, t)) | ||
) | ||
]) | ||
t.blockStatement([t.returnStatement(dynamicRules[0])]) | ||
) | ||
@@ -173,24 +222,27 @@ ]) | ||
) { | ||
const { hash, name, rules } = inline( | ||
const { hash, name, rules, isStatic } = inline( | ||
path.node.quasi, | ||
identifierName, | ||
'css' | ||
'css', | ||
state.inline | ||
) | ||
path.replaceWith( | ||
t.callExpression(t.identifier('css'), [ | ||
t.stringLiteral(`${name}-${hash}`), | ||
t.arrayExpression(path.node.quasi.expressions), | ||
t.functionExpression( | ||
t.identifier('createEmotionRules'), | ||
path.node.quasi.expressions.map((x, i) => | ||
t.identifier(`x${i}`) | ||
), | ||
t.blockStatement([ | ||
t.returnStatement( | ||
t.arrayExpression(parseDynamicValues(rules, t)) | ||
) | ||
]) | ||
) | ||
]) | ||
) | ||
const args = [ | ||
t.stringLiteral(`${name}-${hash}`), | ||
t.arrayExpression(path.node.quasi.expressions) | ||
] | ||
if (isStatic) { | ||
state.insertStaticRules(rules) | ||
} else { | ||
const inlineContentExpr = t.functionExpression( | ||
t.identifier('createEmotionRules'), | ||
path.node.quasi.expressions.map((x, i) => t.identifier(`x${i}`)), | ||
t.blockStatement([ | ||
t.returnStatement( | ||
t.arrayExpression(parseDynamicValues(rules, t)) | ||
) | ||
]) | ||
) | ||
args.push(inlineContentExpr) | ||
} | ||
path.replaceWith(t.callExpression(t.identifier('css'), args)) | ||
} else if ( | ||
@@ -227,3 +279,3 @@ t.isIdentifier(path.node.tag) && | ||
) { | ||
const {hash, name, rules} = fontFace( | ||
const { hash, name, rules } = fontFace( | ||
path.node.quasi, | ||
@@ -230,0 +282,0 @@ identifierName, |
@@ -0,4 +1,5 @@ | ||
// @flow | ||
// murmurhash2 via https://gist.github.com/raycmorgan/588423 | ||
export default function hashArray (arr) { | ||
export default function hashArray (arr: mixed[]): string { | ||
let str = arr.join(',') | ||
@@ -5,0 +6,0 @@ return murmur2(str, str.length).toString(36) |
@@ -0,1 +1,2 @@ | ||
// @flow | ||
import { StyleSheet } from './sheet' | ||
@@ -7,4 +8,23 @@ import hashArray from './hash' | ||
let inserted = {} | ||
let inserted: { [string]: boolean | void } = {} | ||
type inputVar = string | number | ||
type vars = Array<inputVar> | ||
function values (cls: string, vars: vars) { | ||
const hash = hashArray([cls, ...vars]) | ||
const varCls = `vars-${hash}` | ||
if (inserted[hash]) { | ||
return varCls | ||
} | ||
let src = vars | ||
.map((val: inputVar, i: number) => `--${cls}-${i}: ${val}`) | ||
.join('; ') | ||
sheet.insert(`.${varCls} {${src}}`) | ||
inserted[hash] = true | ||
return varCls | ||
} | ||
export function flush () { | ||
@@ -16,48 +36,24 @@ sheet.flush() | ||
export function css ( | ||
cls: string, | ||
vars: Array<string | number | (() => string | number)>, | ||
content: () => mixed[] | ||
) { | ||
// inline mode | ||
vars = vars.map(v => (/^frag-/.exec(v) ? fragments[v] : v)) | ||
let src = content(...vars) | ||
let hash = hashArray(src) | ||
export function css (cls: string, vars: vars, content: () => string[]) { | ||
if (content) { | ||
// inline mode | ||
let src = content(...vars) // returns an array | ||
let hash = hashArray(src) | ||
if (!inserted[hash]) { | ||
inserted[hash] = true | ||
src | ||
.map(r => r.replace(new RegExp(cls, 'gm'), `${cls}-${hash}`)) | ||
.forEach(r => sheet.insert(r)) | ||
if (!inserted[hash]) { | ||
inserted[hash] = true | ||
src | ||
.map(r => r.replace(new RegExp(cls, 'gm'), `${cls}-${hash}`)) | ||
.forEach(r => sheet.insert(r)) | ||
} | ||
return `${cls}-${hash}` | ||
} | ||
return `${cls}-${hash}` | ||
return cls + (vars && vars.length > 0 ? ' ' + values(cls, vars) : '') | ||
} | ||
const fragments = {} | ||
export function fragment ( | ||
frag: string, | ||
vars: Array<string | number | (() => string | number)>, | ||
content: () => mixed[] | ||
) { | ||
vars = vars.map(v => (/^frag-/.exec(v) ? fragments[v] : v)) | ||
let src = content(...vars) | ||
if (src.length > 1) { | ||
throw new Error('what up!') | ||
} | ||
let hash = hashArray(src) | ||
src = src.join('') | ||
fragments[`${frag}-${hash}`] = src.substring( | ||
src.indexOf('{') + 1, | ||
src.length - 1 | ||
) | ||
return `${frag}-${hash}` | ||
export function fragment (vars: vars, content: () => string[]) { | ||
return content(...vars) | ||
} | ||
export function keyframes ( | ||
kfm: string, | ||
vars: Array<string | number | (() => string | number)>, | ||
content: () => mixed[] | ||
) { | ||
export function keyframes (kfm: string, vars: vars, content: () => string[]) { | ||
let src = content(...vars) | ||
@@ -76,4 +72,4 @@ let hash = hashArray(src) | ||
fontRules: string, | ||
vars: Array<string | number | (() => string | number)>, | ||
content: () => mixed[] | ||
vars: vars, | ||
content: () => string[] | ||
) { | ||
@@ -91,4 +87,4 @@ let src = content(...vars) | ||
export function hydrate (ids) { | ||
export function hydrate (ids: string[]) { | ||
ids.forEach(id => (inserted[id] = true)) | ||
} |
@@ -0,5 +1,6 @@ | ||
// @flow | ||
import { parseCSS } from './parser' | ||
import hashArray from './hash' | ||
function extractNameFromProperty (str) { | ||
function extractNameFromProperty (str: string) { | ||
let regex = /name\s*:\s*([A-Za-z0-9\-_]+)\s*/gm | ||
@@ -12,3 +13,7 @@ let match = regex.exec(str) | ||
function getName (extracted, identifierName, prefix) { | ||
function getName ( | ||
extracted?: string, | ||
identifierName?: string, | ||
prefix: string | ||
): string { | ||
const parts = [] | ||
@@ -24,3 +29,8 @@ parts.push(prefix) | ||
export function inline (quasi, identifierName, prefix) { | ||
export function inline ( | ||
quasi: any, | ||
identifierName?: string, | ||
prefix: string, | ||
inlineVars: boolean | ||
): { hash: string, name: string, rules: string[], isStatic: boolean } { | ||
let strs = quasi.quasis.map(x => x.value.cooked) | ||
@@ -33,3 +43,3 @@ let hash = hashArray([...strs]) // todo - add current filename? | ||
) | ||
let hasApply | ||
let src = strs | ||
@@ -42,2 +52,3 @@ .reduce((arr, str, i) => { | ||
if (applyMatch) { | ||
hasApply = true | ||
arr.push(`--${name}-${hash}-${i}`) | ||
@@ -52,19 +63,27 @@ } else arr.push(`var(--${name}-${hash}-${i})`) | ||
let rules = parseCSS(`.${name}-${hash} { ${src} }`) | ||
rules = rules.map(rule => | ||
rule.replace( | ||
/@apply\s+--[A-Za-z0-9-_]+-([0-9]+)/gm, | ||
(match, p1) => `xxx${p1}xxx` | ||
if (hasApply) { | ||
rules = rules.map(rule => | ||
rule.replace( | ||
/@apply\s+--[A-Za-z0-9-_]+-([0-9]+)/gm, | ||
(match, p1) => `xxx${p1}xxx` | ||
) | ||
) | ||
) | ||
rules = rules.map(rule => | ||
rule.replace( | ||
/var\(--[A-Za-z0-9-_]+-([0-9]+)\)/gm, | ||
(match, p1) => `xxx${p1}xxx` | ||
} | ||
if (inlineVars || hasApply) { | ||
rules = rules.map(rule => | ||
rule.replace( | ||
/var\(--[A-Za-z0-9-_]+-([0-9]+)\)/gm, | ||
(match, p1) => `xxx${p1}xxx` | ||
) | ||
) | ||
) | ||
} | ||
return { hash, name, rules } | ||
return { hash, name, rules, isStatic: !hasApply && !inlineVars } | ||
} | ||
export function keyframes (quasi, identifierName, prefix) { | ||
export function keyframes ( | ||
quasi: any, | ||
identifierName?: string, | ||
prefix: string | ||
): { hash: string, name: string, rules: string[] } { | ||
let strs = quasi.quasis.map(x => x.value.cooked) | ||
@@ -85,3 +104,7 @@ let hash = hashArray([...strs]) | ||
export function fontFace (quasi, identifierName, prefix) { | ||
export function fontFace ( | ||
quasi: any, | ||
identifierName?: string, | ||
prefix: string | ||
): { hash: string, name: string, rules: string[] } { | ||
let strs = quasi.quasis.map(x => x.value.cooked) | ||
@@ -97,4 +120,10 @@ let hash = hashArray([...strs]) | ||
name, | ||
rules: [parseCSS(`@font-face {${strs.join('').trim()}}`, { nested: false }).join('').trim()] | ||
rules: [ | ||
parseCSS(`@font-face {${strs.join('').trim()}}`, { | ||
nested: false | ||
}) | ||
.join('') | ||
.trim() | ||
] | ||
} | ||
} |
@@ -7,3 +7,8 @@ // @flow | ||
export function parseCSS (css: string, options: { nested: boolean } = { nested: true }): string[] { | ||
export function parseCSS ( | ||
css: string, | ||
options: { nested: boolean } = { | ||
nested: true | ||
} | ||
): string[] { | ||
// todo - handle errors | ||
@@ -14,2 +19,10 @@ const root = parse(css) | ||
root.walkDecls(decl => { | ||
if (decl.prop === 'name') decl.remove() | ||
}) | ||
return stringifyCSSRoot(root) | ||
} | ||
function stringifyCSSRoot (root) { | ||
return root.nodes.map((node, i) => { | ||
@@ -16,0 +29,0 @@ let str = '' |
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
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
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
58227
1550
2
2
+ Addedtouch@^1.0.0
+ Addedabbrev@1.1.1(transitive)
+ Addednopt@1.0.10(transitive)
+ Addedtouch@1.0.0(transitive)