Spaces:
Sleeping
Sleeping
File size: 4,314 Bytes
56fda74 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
import { serializeStyles } from '@emotion/serialize'
import minify from './minify'
import { getLabelFromPath } from './label'
import { getSourceMap } from './source-maps'
import { simplifyObject } from './object-to-string'
import {
appendStringReturningExpressionToArguments,
joinStringLiterals
} from './strings'
import createNodeEnvConditional from './create-node-env-conditional'
const CSS_OBJECT_STRINGIFIED_ERROR =
"You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."
export let transformExpressionWithStyles = (
{ babel, state, path, shouldLabel, sourceMap = '' } /*: {
babel,
state,
path,
shouldLabel: boolean,
sourceMap?: string
} */
) => {
const autoLabel = state.opts.autoLabel || 'dev-only'
let t = babel.types
if (t.isTaggedTemplateExpression(path)) {
if (
!sourceMap &&
state.emotionSourceMap &&
path.node.quasi.loc !== undefined
) {
sourceMap = getSourceMap(path.node.quasi.loc.start, state)
}
minify(path, t)
}
if (t.isCallExpression(path)) {
const canAppendStrings = path.node.arguments.every(
arg => arg.type !== 'SpreadElement'
)
path.get('arguments').forEach(node => {
if (t.isObjectExpression(node)) {
node.replaceWith(simplifyObject(node.node, t))
}
})
path.node.arguments = joinStringLiterals(path.node.arguments, t)
if (
!sourceMap &&
canAppendStrings &&
state.emotionSourceMap &&
path.node.loc !== undefined
) {
sourceMap = getSourceMap(path.node.loc.start, state)
}
const label =
shouldLabel && autoLabel !== 'never'
? getLabelFromPath(path, state, t)
: null
if (
path.node.arguments.length === 1 &&
t.isStringLiteral(path.node.arguments[0])
) {
let cssString = path.node.arguments[0].value.replace(/;$/, '')
let res = serializeStyles([
`${cssString}${
label && autoLabel === 'always' ? `;label:${label};` : ''
}`
])
let prodNode = t.objectExpression([
t.objectProperty(t.identifier('name'), t.stringLiteral(res.name)),
t.objectProperty(t.identifier('styles'), t.stringLiteral(res.styles))
])
if (!state.emotionStringifiedCssId) {
const uid = state.file.scope.generateUidIdentifier(
'__EMOTION_STRINGIFIED_CSS_ERROR__'
)
state.emotionStringifiedCssId = uid
const cssObjectToString = t.functionDeclaration(
uid,
[],
t.blockStatement([
t.returnStatement(t.stringLiteral(CSS_OBJECT_STRINGIFIED_ERROR))
])
)
cssObjectToString._compact = true
state.file.path.unshiftContainer('body', [cssObjectToString])
}
if (label && autoLabel === 'dev-only') {
res = serializeStyles([`${cssString};label:${label};`])
}
let devNode = t.objectExpression(
[
t.objectProperty(t.identifier('name'), t.stringLiteral(res.name)),
t.objectProperty(
t.identifier('styles'),
t.stringLiteral(res.styles + sourceMap)
),
t.objectProperty(
t.identifier('toString'),
t.cloneNode(state.emotionStringifiedCssId)
)
].filter(Boolean)
)
return createNodeEnvConditional(t, prodNode, devNode)
}
if (canAppendStrings && label) {
const labelString = `;label:${label};`
switch (autoLabel) {
case 'dev-only': {
const labelConditional = createNodeEnvConditional(
t,
t.stringLiteral(''),
t.stringLiteral(labelString)
)
appendStringReturningExpressionToArguments(t, path, labelConditional)
break
}
case 'always':
appendStringReturningExpressionToArguments(t, path, labelString)
break
}
}
if (sourceMap) {
let sourceMapConditional = createNodeEnvConditional(
t,
t.stringLiteral(''),
t.stringLiteral(sourceMap)
)
appendStringReturningExpressionToArguments(t, path, sourceMapConditional)
}
}
}
|