mirror of
https://github.com/idanoo/GoScrobble
synced 2025-07-04 07:02:18 +00:00
0.2.0 - Mid migration
This commit is contained in:
parent
139e6a915e
commit
7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions
62
web/node_modules/babel-plugin-emotion/src/css-macro.js
generated
vendored
Normal file
62
web/node_modules/babel-plugin-emotion/src/css-macro.js
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
// @flow
|
||||
import { createMacro } from 'babel-plugin-macros'
|
||||
import { addDefault, addNamed } from '@babel/helper-module-imports'
|
||||
import { transformExpressionWithStyles } from './utils'
|
||||
|
||||
export const transformCssCallExpression = ({
|
||||
babel,
|
||||
state,
|
||||
path,
|
||||
sourceMap
|
||||
}: {
|
||||
babel: *,
|
||||
state: *,
|
||||
path: *,
|
||||
sourceMap?: string
|
||||
}) => {
|
||||
let node = transformExpressionWithStyles({
|
||||
babel,
|
||||
state,
|
||||
path,
|
||||
shouldLabel: true,
|
||||
sourceMap
|
||||
})
|
||||
if (node) {
|
||||
path.replaceWith(node)
|
||||
path.hoist()
|
||||
} else if (path.isCallExpression()) {
|
||||
path.addComment('leading', '#__PURE__')
|
||||
}
|
||||
}
|
||||
|
||||
export default createMacro(({ references, state, babel, isEmotionCall }) => {
|
||||
if (!isEmotionCall) {
|
||||
state.emotionSourceMap = true
|
||||
}
|
||||
const t = babel.types
|
||||
if (references.default && references.default.length) {
|
||||
references.default.reverse().forEach(reference => {
|
||||
if (!state.cssIdentifier) {
|
||||
state.cssIdentifier = addDefault(reference, '@emotion/css', {
|
||||
nameHint: 'css'
|
||||
})
|
||||
}
|
||||
reference.replaceWith(t.cloneDeep(state.cssIdentifier))
|
||||
transformCssCallExpression({ babel, state, path: reference.parentPath })
|
||||
})
|
||||
}
|
||||
Object.keys(references)
|
||||
.filter(x => x !== 'default')
|
||||
.forEach(referenceKey => {
|
||||
let runtimeNode = addNamed(
|
||||
state.file.path,
|
||||
referenceKey,
|
||||
'@emotion/css',
|
||||
{ nameHint: referenceKey }
|
||||
)
|
||||
|
||||
references[referenceKey].reverse().forEach(reference => {
|
||||
reference.replaceWith(t.cloneDeep(runtimeNode))
|
||||
})
|
||||
})
|
||||
})
|
50
web/node_modules/babel-plugin-emotion/src/emotion-macro.js
generated
vendored
Normal file
50
web/node_modules/babel-plugin-emotion/src/emotion-macro.js
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
// @flow
|
||||
import { transformExpressionWithStyles } from './utils'
|
||||
import { addNamed } from '@babel/helper-module-imports'
|
||||
import { createMacro } from 'babel-plugin-macros'
|
||||
|
||||
export let createEmotionMacro = (instancePath: string) =>
|
||||
createMacro(function macro({ references, state, babel, isEmotionCall }) {
|
||||
if (!isEmotionCall) {
|
||||
state.emotionSourceMap = true
|
||||
}
|
||||
|
||||
let t = babel.types
|
||||
Object.keys(references).forEach(referenceKey => {
|
||||
let isPure = true
|
||||
let runtimeNode = addNamed(state.file.path, referenceKey, instancePath)
|
||||
|
||||
switch (referenceKey) {
|
||||
case 'injectGlobal': {
|
||||
isPure = false
|
||||
}
|
||||
// eslint-disable-next-line no-fallthrough
|
||||
case 'css':
|
||||
case 'keyframes': {
|
||||
references[referenceKey].reverse().forEach(reference => {
|
||||
const path = reference.parentPath
|
||||
|
||||
reference.replaceWith(t.cloneDeep(runtimeNode))
|
||||
if (isPure) {
|
||||
path.addComment('leading', '#__PURE__')
|
||||
}
|
||||
let node = transformExpressionWithStyles({
|
||||
babel,
|
||||
state,
|
||||
path,
|
||||
shouldLabel: true
|
||||
})
|
||||
if (node) {
|
||||
path.node.arguments[0] = node
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
default: {
|
||||
references[referenceKey].reverse().forEach(reference => {
|
||||
reference.replaceWith(t.cloneDeep(runtimeNode))
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
242
web/node_modules/babel-plugin-emotion/src/index.js
generated
vendored
Normal file
242
web/node_modules/babel-plugin-emotion/src/index.js
generated
vendored
Normal file
|
@ -0,0 +1,242 @@
|
|||
// @flow
|
||||
import { createEmotionMacro } from './emotion-macro'
|
||||
import { createStyledMacro } from './styled-macro'
|
||||
import cssMacro, { transformCssCallExpression } from './css-macro'
|
||||
import { addNamed } from '@babel/helper-module-imports'
|
||||
import nodePath from 'path'
|
||||
import { getSourceMap, getStyledOptions } from './utils'
|
||||
|
||||
let webStyledMacro = createStyledMacro({
|
||||
importPath: '@emotion/styled-base',
|
||||
originalImportPath: '@emotion/styled',
|
||||
isWeb: true
|
||||
})
|
||||
let nativeStyledMacro = createStyledMacro({
|
||||
importPath: '@emotion/native',
|
||||
originalImportPath: '@emotion/native',
|
||||
isWeb: false
|
||||
})
|
||||
let primitivesStyledMacro = createStyledMacro({
|
||||
importPath: '@emotion/primitives',
|
||||
originalImportPath: '@emotion/primitives',
|
||||
isWeb: false
|
||||
})
|
||||
|
||||
export const macros = {
|
||||
createEmotionMacro,
|
||||
css: cssMacro,
|
||||
createStyledMacro
|
||||
}
|
||||
|
||||
export type BabelPath = any
|
||||
|
||||
export type EmotionBabelPluginPass = any
|
||||
|
||||
let emotionCoreMacroThatsNotARealMacro = ({ references, state, babel }) => {
|
||||
Object.keys(references).forEach(refKey => {
|
||||
if (refKey === 'css') {
|
||||
references[refKey].forEach(path => {
|
||||
transformCssCallExpression({ babel, state, path: path.parentPath })
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
emotionCoreMacroThatsNotARealMacro.keepImport = true
|
||||
|
||||
function getAbsolutePath(instancePath: string, rootPath: string) {
|
||||
if (instancePath.charAt(0) === '.') {
|
||||
let absoluteInstancePath = nodePath.resolve(rootPath, instancePath)
|
||||
return absoluteInstancePath
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function getInstancePathToCompare(instancePath: string, rootPath: string) {
|
||||
let absolutePath = getAbsolutePath(instancePath, rootPath)
|
||||
if (absolutePath === false) {
|
||||
return instancePath
|
||||
}
|
||||
return absolutePath
|
||||
}
|
||||
|
||||
export default function(babel: *) {
|
||||
let t = babel.types
|
||||
return {
|
||||
name: 'emotion',
|
||||
inherits: require('babel-plugin-syntax-jsx'),
|
||||
visitor: {
|
||||
ImportDeclaration(path: *, state: *) {
|
||||
const hasFilepath =
|
||||
path.hub.file.opts.filename &&
|
||||
path.hub.file.opts.filename !== 'unknown'
|
||||
let dirname = hasFilepath
|
||||
? nodePath.dirname(path.hub.file.opts.filename)
|
||||
: ''
|
||||
|
||||
if (
|
||||
!state.pluginMacros[path.node.source.value] &&
|
||||
state.emotionInstancePaths.indexOf(
|
||||
getInstancePathToCompare(path.node.source.value, dirname)
|
||||
) !== -1
|
||||
) {
|
||||
state.pluginMacros[path.node.source.value] = createEmotionMacro(
|
||||
path.node.source.value
|
||||
)
|
||||
}
|
||||
let pluginMacros = state.pluginMacros
|
||||
// most of this is from https://github.com/kentcdodds/babel-plugin-macros/blob/master/src/index.js
|
||||
if (pluginMacros[path.node.source.value] === undefined) {
|
||||
return
|
||||
}
|
||||
if (t.isImportNamespaceSpecifier(path.node.specifiers[0])) {
|
||||
return
|
||||
}
|
||||
const imports = path.node.specifiers.map(s => ({
|
||||
localName: s.local.name,
|
||||
importedName:
|
||||
s.type === 'ImportDefaultSpecifier' ? 'default' : s.imported.name
|
||||
}))
|
||||
let shouldExit = false
|
||||
let hasReferences = false
|
||||
const referencePathsByImportName = imports.reduce(
|
||||
(byName, { importedName, localName }) => {
|
||||
let binding = path.scope.getBinding(localName)
|
||||
if (!binding) {
|
||||
shouldExit = true
|
||||
return byName
|
||||
}
|
||||
byName[importedName] = binding.referencePaths
|
||||
hasReferences =
|
||||
hasReferences || Boolean(byName[importedName].length)
|
||||
return byName
|
||||
},
|
||||
{}
|
||||
)
|
||||
if (!hasReferences || shouldExit) {
|
||||
return
|
||||
}
|
||||
/**
|
||||
* Other plugins that run before babel-plugin-macros might use path.replace, where a path is
|
||||
* put into its own replacement. Apparently babel does not update the scope after such
|
||||
* an operation. As a remedy, the whole scope is traversed again with an empty "Identifier"
|
||||
* visitor - this makes the problem go away.
|
||||
*
|
||||
* See: https://github.com/kentcdodds/import-all.macro/issues/7
|
||||
*/
|
||||
state.file.scope.path.traverse({
|
||||
Identifier() {}
|
||||
})
|
||||
|
||||
pluginMacros[path.node.source.value]({
|
||||
references: referencePathsByImportName,
|
||||
state,
|
||||
babel,
|
||||
isBabelMacrosCall: true,
|
||||
isEmotionCall: true
|
||||
})
|
||||
if (!pluginMacros[path.node.source.value].keepImport) {
|
||||
path.remove()
|
||||
}
|
||||
},
|
||||
Program(path: *, state: *) {
|
||||
state.emotionInstancePaths = (state.opts.instances || []).map(
|
||||
instancePath => getInstancePathToCompare(instancePath, process.cwd())
|
||||
)
|
||||
state.pluginMacros = {
|
||||
'@emotion/css': cssMacro,
|
||||
'@emotion/styled': webStyledMacro,
|
||||
'@emotion/core': emotionCoreMacroThatsNotARealMacro,
|
||||
'@emotion/primitives': primitivesStyledMacro,
|
||||
'@emotion/native': nativeStyledMacro,
|
||||
emotion: createEmotionMacro('emotion')
|
||||
}
|
||||
if (state.opts.cssPropOptimization === undefined) {
|
||||
for (const node of path.node.body) {
|
||||
if (
|
||||
t.isImportDeclaration(node) &&
|
||||
node.source.value === '@emotion/core' &&
|
||||
node.specifiers.some(
|
||||
x => t.isImportSpecifier(x) && x.imported.name === 'jsx'
|
||||
)
|
||||
) {
|
||||
state.transformCssProp = true
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
state.transformCssProp = state.opts.cssPropOptimization
|
||||
}
|
||||
|
||||
if (state.opts.sourceMap === false) {
|
||||
state.emotionSourceMap = false
|
||||
} else {
|
||||
state.emotionSourceMap = true
|
||||
}
|
||||
},
|
||||
JSXAttribute(path: *, state: *) {
|
||||
if (path.node.name.name !== 'css' || !state.transformCssProp) {
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
t.isJSXExpressionContainer(path.node.value) &&
|
||||
(t.isObjectExpression(path.node.value.expression) ||
|
||||
t.isArrayExpression(path.node.value.expression))
|
||||
) {
|
||||
let expressionPath = path.get('value.expression')
|
||||
let sourceMap =
|
||||
state.emotionSourceMap && path.node.loc !== undefined
|
||||
? getSourceMap(path.node.loc.start, state)
|
||||
: ''
|
||||
|
||||
expressionPath.replaceWith(
|
||||
t.callExpression(
|
||||
// the name of this identifier doesn't really matter at all
|
||||
// it'll never appear in generated code
|
||||
t.identifier('___shouldNeverAppearCSS'),
|
||||
[path.node.value.expression]
|
||||
)
|
||||
)
|
||||
|
||||
transformCssCallExpression({
|
||||
babel,
|
||||
state,
|
||||
path: expressionPath,
|
||||
sourceMap
|
||||
})
|
||||
if (t.isCallExpression(expressionPath)) {
|
||||
if (!state.cssIdentifier) {
|
||||
state.cssIdentifier = addNamed(path, 'css', '@emotion/core', {
|
||||
nameHint: 'css'
|
||||
})
|
||||
}
|
||||
|
||||
expressionPath
|
||||
.get('callee')
|
||||
.replaceWith(t.cloneDeep(state.cssIdentifier))
|
||||
}
|
||||
}
|
||||
},
|
||||
CallExpression: {
|
||||
exit(path: BabelPath, state: EmotionBabelPluginPass) {
|
||||
try {
|
||||
if (
|
||||
path.node.callee &&
|
||||
path.node.callee.property &&
|
||||
path.node.callee.property.name === 'withComponent'
|
||||
) {
|
||||
switch (path.node.arguments.length) {
|
||||
case 1:
|
||||
case 2: {
|
||||
path.node.arguments[1] = getStyledOptions(t, path, state)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw path.buildCodeFrameError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
113
web/node_modules/babel-plugin-emotion/src/styled-macro.js
generated
vendored
Normal file
113
web/node_modules/babel-plugin-emotion/src/styled-macro.js
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
// @flow
|
||||
import { createMacro } from 'babel-plugin-macros'
|
||||
import { addDefault, addNamed } from '@babel/helper-module-imports'
|
||||
import { transformExpressionWithStyles, getStyledOptions } from './utils'
|
||||
|
||||
export let createStyledMacro = ({
|
||||
importPath,
|
||||
originalImportPath = importPath,
|
||||
isWeb
|
||||
}: {
|
||||
importPath: string,
|
||||
originalImportPath?: string,
|
||||
isWeb: boolean
|
||||
}) =>
|
||||
createMacro(({ references, state, babel, isEmotionCall }) => {
|
||||
if (!isEmotionCall) {
|
||||
state.emotionSourceMap = true
|
||||
}
|
||||
const t = babel.types
|
||||
if (references.default && references.default.length) {
|
||||
let _styledIdentifier
|
||||
let getStyledIdentifier = () => {
|
||||
if (_styledIdentifier === undefined) {
|
||||
_styledIdentifier = addDefault(state.file.path, importPath, {
|
||||
nameHint: 'styled'
|
||||
})
|
||||
}
|
||||
return t.cloneDeep(_styledIdentifier)
|
||||
}
|
||||
let originalImportPathStyledIdentifier
|
||||
let getOriginalImportPathStyledIdentifier = () => {
|
||||
if (originalImportPathStyledIdentifier === undefined) {
|
||||
originalImportPathStyledIdentifier = addDefault(
|
||||
state.file.path,
|
||||
originalImportPath,
|
||||
{
|
||||
nameHint: 'styled'
|
||||
}
|
||||
)
|
||||
}
|
||||
return t.cloneDeep(originalImportPathStyledIdentifier)
|
||||
}
|
||||
if (importPath === originalImportPath) {
|
||||
getOriginalImportPathStyledIdentifier = getStyledIdentifier
|
||||
}
|
||||
references.default.forEach(reference => {
|
||||
let isCall = false
|
||||
if (
|
||||
t.isMemberExpression(reference.parent) &&
|
||||
reference.parent.computed === false
|
||||
) {
|
||||
isCall = true
|
||||
if (
|
||||
// checks if the first character is lowercase
|
||||
// becasue we don't want to transform the member expression if
|
||||
// it's in primitives/native
|
||||
reference.parent.property.name.charCodeAt(0) > 96
|
||||
) {
|
||||
reference.parentPath.replaceWith(
|
||||
t.callExpression(getStyledIdentifier(), [
|
||||
t.stringLiteral(reference.parent.property.name)
|
||||
])
|
||||
)
|
||||
} else {
|
||||
reference.replaceWith(getStyledIdentifier())
|
||||
}
|
||||
} else if (
|
||||
reference.parentPath &&
|
||||
reference.parentPath.parentPath &&
|
||||
t.isCallExpression(reference.parentPath) &&
|
||||
reference.parent.callee === reference.node
|
||||
) {
|
||||
isCall = true
|
||||
reference.replaceWith(getStyledIdentifier())
|
||||
} else {
|
||||
reference.replaceWith(getOriginalImportPathStyledIdentifier())
|
||||
}
|
||||
if (reference.parentPath && reference.parentPath.parentPath) {
|
||||
const styledCallPath = reference.parentPath.parentPath
|
||||
let node = transformExpressionWithStyles({
|
||||
path: styledCallPath,
|
||||
state,
|
||||
babel,
|
||||
shouldLabel: false
|
||||
})
|
||||
if (node && isWeb) {
|
||||
// we know the argument length will be 1 since that's the only time we will have a node since it will be static
|
||||
styledCallPath.node.arguments[0] = node
|
||||
}
|
||||
}
|
||||
|
||||
if (isCall) {
|
||||
reference.addComment('leading', '#__PURE__')
|
||||
if (isWeb) {
|
||||
reference.parentPath.node.arguments[1] = getStyledOptions(
|
||||
t,
|
||||
reference.parentPath,
|
||||
state
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
Object.keys(references)
|
||||
.filter(x => x !== 'default')
|
||||
.forEach(referenceKey => {
|
||||
let runtimeNode = addNamed(state.file.path, referenceKey, importPath)
|
||||
|
||||
references[referenceKey].reverse().forEach(reference => {
|
||||
reference.replaceWith(t.cloneDeep(runtimeNode))
|
||||
})
|
||||
})
|
||||
})
|
54
web/node_modules/babel-plugin-emotion/src/utils/get-styled-options.js
generated
vendored
Normal file
54
web/node_modules/babel-plugin-emotion/src/utils/get-styled-options.js
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
// @flow
|
||||
import { getLabelFromPath } from './label'
|
||||
import { getTargetClassName } from './get-target-class-name'
|
||||
|
||||
const getKnownProperties = (t: *, node: *) =>
|
||||
new Set(
|
||||
node.properties
|
||||
.filter(n => t.isObjectProperty(n) && !n.computed)
|
||||
.map(n => (t.isIdentifier(n.key) ? n.key.name : n.key.value))
|
||||
)
|
||||
|
||||
export let getStyledOptions = (t: *, path: *, state: *) => {
|
||||
let args = path.node.arguments
|
||||
let optionsArgument = args.length >= 2 ? args[1] : null
|
||||
|
||||
let properties = []
|
||||
let knownProperties =
|
||||
optionsArgument && t.isObjectExpression(optionsArgument)
|
||||
? getKnownProperties(t, optionsArgument)
|
||||
: new Set()
|
||||
|
||||
if (!knownProperties.has('target')) {
|
||||
properties.push(
|
||||
t.objectProperty(
|
||||
t.identifier('target'),
|
||||
t.stringLiteral(getTargetClassName(state, t))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
let label = getLabelFromPath(path, state, t)
|
||||
if (label && !knownProperties.has('label')) {
|
||||
properties.push(
|
||||
t.objectProperty(t.identifier('label'), t.stringLiteral(label))
|
||||
)
|
||||
}
|
||||
|
||||
if (optionsArgument) {
|
||||
if (!t.isObjectExpression(optionsArgument)) {
|
||||
return t.callExpression(state.file.addHelper('extends'), [
|
||||
t.objectExpression([]),
|
||||
t.objectExpression(properties),
|
||||
optionsArgument
|
||||
])
|
||||
}
|
||||
|
||||
properties.unshift(...optionsArgument.properties)
|
||||
}
|
||||
|
||||
return t.objectExpression(
|
||||
// $FlowFixMe
|
||||
properties
|
||||
)
|
||||
}
|
52
web/node_modules/babel-plugin-emotion/src/utils/get-target-class-name.js
generated
vendored
Normal file
52
web/node_modules/babel-plugin-emotion/src/utils/get-target-class-name.js
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
// @flow
|
||||
import findRoot from 'find-root'
|
||||
import memoize from '@emotion/memoize'
|
||||
import nodePath from 'path'
|
||||
import hashString from '@emotion/hash'
|
||||
import escapeRegexp from 'escape-string-regexp'
|
||||
|
||||
let hashArray = (arr: Array<string>) => hashString(arr.join(''))
|
||||
|
||||
const unsafeRequire = require
|
||||
|
||||
const getPackageRootPath = memoize(filename => findRoot(filename))
|
||||
|
||||
const separator = new RegExp(escapeRegexp(nodePath.sep), 'g')
|
||||
|
||||
const normalizePath = path => nodePath.normalize(path).replace(separator, '/')
|
||||
|
||||
export function getTargetClassName(state: *, t: *) {
|
||||
if (state.emotionTargetClassNameCount === undefined) {
|
||||
state.emotionTargetClassNameCount = 0
|
||||
}
|
||||
|
||||
const hasFilepath =
|
||||
state.file.opts.filename && state.file.opts.filename !== 'unknown'
|
||||
const filename = hasFilepath ? state.file.opts.filename : ''
|
||||
// normalize the file path to ignore folder structure
|
||||
// outside the current node project and arch-specific delimiters
|
||||
let moduleName = ''
|
||||
let rootPath = filename
|
||||
|
||||
try {
|
||||
rootPath = getPackageRootPath(filename)
|
||||
moduleName = unsafeRequire(rootPath + '/package.json').name
|
||||
} catch (err) {}
|
||||
|
||||
const finalPath =
|
||||
filename === rootPath ? 'root' : filename.slice(rootPath.length)
|
||||
|
||||
const positionInFile = state.emotionTargetClassNameCount++
|
||||
|
||||
const stuffToHash = [moduleName]
|
||||
|
||||
if (finalPath) {
|
||||
stuffToHash.push(normalizePath(finalPath))
|
||||
} else {
|
||||
stuffToHash.push(state.file.code)
|
||||
}
|
||||
|
||||
const stableClassName = `e${hashArray(stuffToHash)}${positionInFile}`
|
||||
|
||||
return stableClassName
|
||||
}
|
11
web/node_modules/babel-plugin-emotion/src/utils/index.js
generated
vendored
Normal file
11
web/node_modules/babel-plugin-emotion/src/utils/index.js
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
// @flow
|
||||
export { getExpressionsFromTemplateLiteral } from './minify'
|
||||
export { getLabelFromPath } from './label'
|
||||
export { getSourceMap } from './source-maps'
|
||||
export { getTargetClassName } from './get-target-class-name'
|
||||
export { simplifyObject } from './object-to-string'
|
||||
export {
|
||||
transformExpressionWithStyles
|
||||
} from './transform-expression-with-styles'
|
||||
export { getStyledOptions } from './get-styled-options'
|
||||
export { appendStringToArguments, joinStringLiterals } from './strings'
|
135
web/node_modules/babel-plugin-emotion/src/utils/label.js
generated
vendored
Normal file
135
web/node_modules/babel-plugin-emotion/src/utils/label.js
generated
vendored
Normal file
|
@ -0,0 +1,135 @@
|
|||
// @flow
|
||||
import nodePath from 'path'
|
||||
|
||||
const invalidClassNameCharacters = /[!"#$%&'()*+,./:;<=>?@[\]^`|}~{]/g
|
||||
|
||||
const sanitizeLabelPart = (labelPart: string) =>
|
||||
labelPart.trim().replace(invalidClassNameCharacters, '-')
|
||||
|
||||
function getLabel(
|
||||
identifierName?: string,
|
||||
autoLabel: boolean,
|
||||
labelFormat?: string,
|
||||
filename: string
|
||||
) {
|
||||
if (!identifierName || !autoLabel) return null
|
||||
if (!labelFormat) return sanitizeLabelPart(identifierName)
|
||||
|
||||
const parsedPath = nodePath.parse(filename)
|
||||
let localDirname = nodePath.basename(parsedPath.dir)
|
||||
let localFilename = parsedPath.name
|
||||
|
||||
if (localFilename === 'index') {
|
||||
localFilename = localDirname
|
||||
}
|
||||
|
||||
return labelFormat
|
||||
.replace(/\[local\]/gi, sanitizeLabelPart(identifierName))
|
||||
.replace(/\[filename\]/gi, sanitizeLabelPart(localFilename))
|
||||
.replace(/\[dirname\]/gi, sanitizeLabelPart(localDirname))
|
||||
}
|
||||
|
||||
export function getLabelFromPath(path: *, state: *, t: *) {
|
||||
return getLabel(
|
||||
getIdentifierName(path, t),
|
||||
state.opts.autoLabel === undefined
|
||||
? process.env.NODE_ENV !== 'production'
|
||||
: state.opts.autoLabel,
|
||||
state.opts.labelFormat,
|
||||
state.file.opts.filename
|
||||
)
|
||||
}
|
||||
|
||||
let pascalCaseRegex = /^[A-Z][A-Za-z]+/
|
||||
|
||||
function getDeclaratorName(path, t) {
|
||||
// $FlowFixMe
|
||||
const parent = path.findParent(
|
||||
p =>
|
||||
p.isVariableDeclarator() ||
|
||||
p.isFunctionDeclaration() ||
|
||||
p.isFunctionExpression() ||
|
||||
p.isArrowFunctionExpression() ||
|
||||
p.isObjectProperty()
|
||||
)
|
||||
if (!parent) {
|
||||
return ''
|
||||
}
|
||||
|
||||
// we probably have a css call assigned to a variable
|
||||
// so we'll just return the variable name
|
||||
if (parent.isVariableDeclarator()) {
|
||||
if (t.isIdentifier(parent.node.id)) {
|
||||
return parent.node.id.name
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
// we probably have an inline css prop usage
|
||||
if (parent.isFunctionDeclaration()) {
|
||||
let { name } = parent.node.id
|
||||
if (pascalCaseRegex.test(name)) {
|
||||
return name
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
// we could also have an object property
|
||||
if (parent.isObjectProperty() && !parent.node.computed) {
|
||||
return parent.node.key.name
|
||||
}
|
||||
|
||||
let variableDeclarator = path.findParent(p => p.isVariableDeclarator())
|
||||
if (!variableDeclarator) {
|
||||
return ''
|
||||
}
|
||||
let { name } = variableDeclarator.node.id
|
||||
if (pascalCaseRegex.test(name)) {
|
||||
return name
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function getIdentifierName(path: *, t: *) {
|
||||
let classOrClassPropertyParent
|
||||
|
||||
if (
|
||||
t.isObjectProperty(path.parentPath) &&
|
||||
path.parentPath.node.computed === false &&
|
||||
(t.isIdentifier(path.parentPath.node.key) ||
|
||||
t.isStringLiteral(path.parentPath.node.key))
|
||||
) {
|
||||
return path.parentPath.node.key.name || path.parentPath.node.key.value
|
||||
}
|
||||
|
||||
if (path) {
|
||||
// $FlowFixMe
|
||||
classOrClassPropertyParent = path.findParent(
|
||||
p => t.isClassProperty(p) || t.isClass(p)
|
||||
)
|
||||
}
|
||||
if (classOrClassPropertyParent) {
|
||||
if (
|
||||
t.isClassProperty(classOrClassPropertyParent) &&
|
||||
classOrClassPropertyParent.node.computed === false &&
|
||||
t.isIdentifier(classOrClassPropertyParent.node.key)
|
||||
) {
|
||||
return classOrClassPropertyParent.node.key.name
|
||||
}
|
||||
if (
|
||||
t.isClass(classOrClassPropertyParent) &&
|
||||
classOrClassPropertyParent.node.id
|
||||
) {
|
||||
return t.isIdentifier(classOrClassPropertyParent.node.id)
|
||||
? classOrClassPropertyParent.node.id.name
|
||||
: ''
|
||||
}
|
||||
}
|
||||
|
||||
let declaratorName = getDeclaratorName(path, t)
|
||||
// if the name starts with _ it was probably generated by babel so we should ignore it
|
||||
if (declaratorName.charAt(0) === '_') {
|
||||
return ''
|
||||
}
|
||||
return declaratorName
|
||||
}
|
96
web/node_modules/babel-plugin-emotion/src/utils/minify-utils.js
generated
vendored
Normal file
96
web/node_modules/babel-plugin-emotion/src/utils/minify-utils.js
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
// @flow
|
||||
// babel-plugin-styled-components
|
||||
// https://github.com/styled-components/babel-plugin-styled-components/blob/8d44acc36f067d60d4e09f9c22ff89695bc332d2/src/minify/index.js
|
||||
|
||||
const multilineCommentRegex = /\/\*[^!](.|[\r\n])*?\*\//g
|
||||
const lineCommentStart = /\/\//g
|
||||
const symbolRegex = /(\s*[;:{},]\s*)/g
|
||||
|
||||
// Counts occurences of substr inside str
|
||||
const countOccurences = (str, substr) => str.split(substr).length - 1
|
||||
|
||||
// Joins substrings until predicate returns true
|
||||
const reduceSubstr = (substrs, join, predicate) => {
|
||||
const length = substrs.length
|
||||
let res = substrs[0]
|
||||
|
||||
if (length === 1) {
|
||||
return res
|
||||
}
|
||||
|
||||
for (let i = 1; i < length; i++) {
|
||||
if (predicate(res)) {
|
||||
break
|
||||
}
|
||||
|
||||
res += join + substrs[i]
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// Joins at comment starts when it's inside a string or parantheses
|
||||
// effectively removing line comments
|
||||
export const stripLineComment = (line: string) =>
|
||||
reduceSubstr(
|
||||
line.split(lineCommentStart),
|
||||
'//',
|
||||
str =>
|
||||
!str.endsWith(':') && // NOTE: This is another guard against urls, if they're not inside strings or parantheses.
|
||||
countOccurences(str, "'") % 2 === 0 &&
|
||||
countOccurences(str, '"') % 2 === 0 &&
|
||||
countOccurences(str, '(') === countOccurences(str, ')')
|
||||
)
|
||||
|
||||
export const compressSymbols = (code: string) =>
|
||||
code.split(symbolRegex).reduce((str, fragment, index) => {
|
||||
// Even-indices are non-symbol fragments
|
||||
if (index % 2 === 0) {
|
||||
return str + fragment
|
||||
}
|
||||
|
||||
// Only manipulate symbols outside of strings
|
||||
if (
|
||||
countOccurences(str, "'") % 2 === 0 &&
|
||||
countOccurences(str, '"') % 2 === 0
|
||||
) {
|
||||
return str + fragment.trim()
|
||||
}
|
||||
|
||||
return str + fragment
|
||||
}, '')
|
||||
|
||||
// Detects lines that are exclusively line comments
|
||||
const isLineComment = line => line.trim().startsWith('//')
|
||||
const linebreakRegex = /[\r\n]\s*/g
|
||||
const spacesAndLinebreakRegex = /\s+|\n+/g
|
||||
|
||||
function multilineReplacer(match: string) {
|
||||
// When we encounter a standard multi-line CSS comment and it contains a '@'
|
||||
// character, we keep the comment but optimize it into a single line. Some
|
||||
// Stylis plugins, such as the stylis-rtl via the cssjanus plugin, use this
|
||||
// special comment syntax to control behavior (such as: /* @noflip */).
|
||||
// We can do this with standard CSS comments because they will work with
|
||||
// compression, as opposed to non-standard single-line comments that will
|
||||
// break compressed CSS. If the comment doesn't contain '@', then we replace
|
||||
// it with a line break, which effectively removes it from the output.
|
||||
|
||||
const keepComment = match.indexOf('@') > -1
|
||||
|
||||
if (keepComment) {
|
||||
return match.replace(spacesAndLinebreakRegex, ' ').trim()
|
||||
}
|
||||
|
||||
return '\n'
|
||||
}
|
||||
|
||||
export const minify = (code: string) => {
|
||||
const newCode = code
|
||||
.replace(multilineCommentRegex, multilineReplacer) // If allowed, remove line breaks and extra space from multi-line comments so they appear on one line
|
||||
.split(linebreakRegex) // Split at newlines
|
||||
.filter(line => line.length > 0 && !isLineComment(line)) // Removes lines containing only line comments
|
||||
.map(stripLineComment) // Remove line comments inside text
|
||||
.join(' ') // Rejoin all lines
|
||||
|
||||
return compressSymbols(newCode)
|
||||
}
|
88
web/node_modules/babel-plugin-emotion/src/utils/minify.js
generated
vendored
Normal file
88
web/node_modules/babel-plugin-emotion/src/utils/minify.js
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
// @flow
|
||||
import { minify } from './minify-utils'
|
||||
|
||||
export function getExpressionsFromTemplateLiteral(node: *, t: *): Array<*> {
|
||||
const raw = createRawStringFromTemplateLiteral(node)
|
||||
const minified = minify(raw)
|
||||
return replacePlaceholdersWithExpressions(minified, node.expressions || [], t)
|
||||
}
|
||||
|
||||
const interleave = (strings: Array<*>, interpolations: Array<*>) =>
|
||||
interpolations.reduce(
|
||||
(array, interp, i) => array.concat([interp], strings[i + 1]),
|
||||
[strings[0]]
|
||||
)
|
||||
|
||||
function getDynamicMatches(str: string) {
|
||||
const re = /xxx(\d+)xxx/gm
|
||||
let match
|
||||
const matches = []
|
||||
while ((match = re.exec(str)) !== null) {
|
||||
// so that flow doesn't complain
|
||||
if (match !== null) {
|
||||
matches.push({
|
||||
value: match[0],
|
||||
p1: parseInt(match[1], 10),
|
||||
index: match.index
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return matches
|
||||
}
|
||||
|
||||
function replacePlaceholdersWithExpressions(
|
||||
str: string,
|
||||
expressions: Array<*>,
|
||||
t: *
|
||||
) {
|
||||
const matches = getDynamicMatches(str)
|
||||
if (matches.length === 0) {
|
||||
if (str === '') {
|
||||
return []
|
||||
}
|
||||
return [t.stringLiteral(str)]
|
||||
}
|
||||
const strings = []
|
||||
const finalExpressions = []
|
||||
let cursor = 0
|
||||
|
||||
matches.forEach(({ value, p1, index }, i) => {
|
||||
const preMatch = str.substring(cursor, index)
|
||||
cursor = cursor + preMatch.length + value.length
|
||||
if (preMatch) {
|
||||
strings.push(t.stringLiteral(preMatch))
|
||||
} else if (i === 0) {
|
||||
strings.push(t.stringLiteral(''))
|
||||
}
|
||||
|
||||
finalExpressions.push(expressions[p1])
|
||||
if (i === matches.length - 1) {
|
||||
strings.push(t.stringLiteral(str.substring(index + value.length)))
|
||||
}
|
||||
})
|
||||
|
||||
return interleave(strings, finalExpressions).filter(
|
||||
(node: { value: string }) => {
|
||||
return node.value !== ''
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function createRawStringFromTemplateLiteral(quasi: {
|
||||
quasis: Array<{ value: { cooked: string } }>
|
||||
}) {
|
||||
let strs = quasi.quasis.map(x => x.value.cooked)
|
||||
|
||||
const src = strs
|
||||
.reduce((arr, str, i) => {
|
||||
arr.push(str)
|
||||
if (i !== strs.length - 1) {
|
||||
arr.push(`xxx${i}xxx`)
|
||||
}
|
||||
return arr
|
||||
}, [])
|
||||
.join('')
|
||||
.trim()
|
||||
return src
|
||||
}
|
40
web/node_modules/babel-plugin-emotion/src/utils/object-to-string.js
generated
vendored
Normal file
40
web/node_modules/babel-plugin-emotion/src/utils/object-to-string.js
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
// @flow
|
||||
import { serializeStyles } from '@emotion/serialize'
|
||||
|
||||
// to anyone looking at this, this isn't intended to simplify every single case
|
||||
// it's meant to simplify the most common cases so i don't want to make it especially complex
|
||||
// also, this will be unnecessary when prepack is ready
|
||||
export function simplifyObject(node: *, t: Object) {
|
||||
let finalString = ''
|
||||
for (let i = 0; i < node.properties.length; i++) {
|
||||
let property = node.properties[i]
|
||||
|
||||
if (
|
||||
!t.isObjectProperty(property) ||
|
||||
property.computed ||
|
||||
(!t.isIdentifier(property.key) && !t.isStringLiteral(property.key)) ||
|
||||
(!t.isStringLiteral(property.value) &&
|
||||
!t.isNumericLiteral(property.value) &&
|
||||
!t.isObjectExpression(property.value))
|
||||
) {
|
||||
return node
|
||||
}
|
||||
|
||||
let key = property.key.name || property.key.value
|
||||
if (key === 'styles') {
|
||||
return node
|
||||
}
|
||||
if (t.isObjectExpression(property.value)) {
|
||||
let simplifiedChild = simplifyObject(property.value, t)
|
||||
if (!t.isStringLiteral(simplifiedChild)) {
|
||||
return node
|
||||
}
|
||||
finalString += `${key}{${simplifiedChild.value}}`
|
||||
continue
|
||||
}
|
||||
let value = property.value.value
|
||||
|
||||
finalString += serializeStyles([{ [key]: value }]).styles
|
||||
}
|
||||
return t.stringLiteral(finalString)
|
||||
}
|
45
web/node_modules/babel-plugin-emotion/src/utils/source-maps.js
generated
vendored
Normal file
45
web/node_modules/babel-plugin-emotion/src/utils/source-maps.js
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
// @flow
|
||||
import { SourceMapGenerator } from 'source-map'
|
||||
import convert from 'convert-source-map'
|
||||
|
||||
function getGeneratorOpts(file) {
|
||||
return file.opts.generatorOpts ? file.opts.generatorOpts : file.opts
|
||||
}
|
||||
|
||||
export function makeSourceMapGenerator(file: *) {
|
||||
const generatorOpts = getGeneratorOpts(file)
|
||||
const filename = generatorOpts.sourceFileName
|
||||
const generator = new SourceMapGenerator({
|
||||
file: filename,
|
||||
sourceRoot: generatorOpts.sourceRoot
|
||||
})
|
||||
|
||||
generator.setSourceContent(filename, file.code)
|
||||
return generator
|
||||
}
|
||||
|
||||
export function getSourceMap(
|
||||
offset: {
|
||||
line: number,
|
||||
column: number
|
||||
},
|
||||
state: *
|
||||
): string {
|
||||
const generator = makeSourceMapGenerator(state.file)
|
||||
const generatorOpts = getGeneratorOpts(state.file)
|
||||
if (
|
||||
generatorOpts.sourceFileName &&
|
||||
generatorOpts.sourceFileName !== 'unknown'
|
||||
) {
|
||||
generator.addMapping({
|
||||
generated: {
|
||||
line: 1,
|
||||
column: 0
|
||||
},
|
||||
source: generatorOpts.sourceFileName,
|
||||
original: offset
|
||||
})
|
||||
return convert.fromObject(generator).toComment({ multiline: true })
|
||||
}
|
||||
return ''
|
||||
}
|
45
web/node_modules/babel-plugin-emotion/src/utils/strings.js
generated
vendored
Normal file
45
web/node_modules/babel-plugin-emotion/src/utils/strings.js
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
// @flow
|
||||
import {
|
||||
getTypeScriptMakeTemplateObjectPath,
|
||||
isTaggedTemplateTranspiledByBabel
|
||||
} from './transpiled-output-utils'
|
||||
|
||||
export const appendStringToArguments = (path: *, string: string, t: *) => {
|
||||
if (!string) {
|
||||
return
|
||||
}
|
||||
const args = path.node.arguments
|
||||
if (t.isStringLiteral(args[args.length - 1])) {
|
||||
args[args.length - 1].value += string
|
||||
} else {
|
||||
const makeTemplateObjectCallPath = getTypeScriptMakeTemplateObjectPath(path)
|
||||
|
||||
if (makeTemplateObjectCallPath) {
|
||||
makeTemplateObjectCallPath.get('arguments').forEach(argPath => {
|
||||
const elements = argPath.get('elements')
|
||||
const lastElement = elements[elements.length - 1]
|
||||
lastElement.replaceWith(
|
||||
t.stringLiteral(lastElement.node.value + string)
|
||||
)
|
||||
})
|
||||
} else if (!isTaggedTemplateTranspiledByBabel(path)) {
|
||||
args.push(t.stringLiteral(string))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const joinStringLiterals = (expressions: Array<*>, t: *) => {
|
||||
return expressions.reduce((finalExpressions, currentExpression, i) => {
|
||||
if (!t.isStringLiteral(currentExpression)) {
|
||||
finalExpressions.push(currentExpression)
|
||||
} else if (
|
||||
t.isStringLiteral(finalExpressions[finalExpressions.length - 1])
|
||||
) {
|
||||
finalExpressions[finalExpressions.length - 1].value +=
|
||||
currentExpression.value
|
||||
} else {
|
||||
finalExpressions.push(currentExpression)
|
||||
}
|
||||
return finalExpressions
|
||||
}, [])
|
||||
}
|
174
web/node_modules/babel-plugin-emotion/src/utils/transform-expression-with-styles.js
generated
vendored
Normal file
174
web/node_modules/babel-plugin-emotion/src/utils/transform-expression-with-styles.js
generated
vendored
Normal file
|
@ -0,0 +1,174 @@
|
|||
// @flow
|
||||
|
||||
import { serializeStyles } from '@emotion/serialize'
|
||||
import { getExpressionsFromTemplateLiteral } from './minify'
|
||||
import { getLabelFromPath } from './label'
|
||||
import { getSourceMap } from './source-maps'
|
||||
import { simplifyObject } from './object-to-string'
|
||||
import { appendStringToArguments, joinStringLiterals } from './strings'
|
||||
import {
|
||||
getTypeScriptMakeTemplateObjectPath,
|
||||
isTaggedTemplateTranspiledByBabel
|
||||
} from './transpiled-output-utils'
|
||||
|
||||
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)."
|
||||
|
||||
// with babel@6 fallback
|
||||
const cloneNode = (t, node) =>
|
||||
typeof t.cloneNode === 'function' ? t.cloneNode(node) : t.cloneDeep(node)
|
||||
|
||||
function createSourceMapConditional(t, production, development) {
|
||||
return t.conditionalExpression(
|
||||
t.binaryExpression(
|
||||
'===',
|
||||
t.memberExpression(
|
||||
t.memberExpression(t.identifier('process'), t.identifier('env')),
|
||||
t.identifier('NODE_ENV')
|
||||
),
|
||||
t.stringLiteral('production')
|
||||
),
|
||||
production,
|
||||
development
|
||||
)
|
||||
}
|
||||
|
||||
export let transformExpressionWithStyles = ({
|
||||
babel,
|
||||
state,
|
||||
path,
|
||||
shouldLabel,
|
||||
sourceMap = ''
|
||||
}: {
|
||||
babel: *,
|
||||
state: *,
|
||||
path: *,
|
||||
shouldLabel: boolean,
|
||||
sourceMap?: string
|
||||
}): * => {
|
||||
let t = babel.types
|
||||
if (t.isTaggedTemplateExpression(path)) {
|
||||
const expressions = getExpressionsFromTemplateLiteral(path.node.quasi, t)
|
||||
if (state.emotionSourceMap && path.node.quasi.loc !== undefined) {
|
||||
sourceMap = getSourceMap(path.node.quasi.loc.start, state)
|
||||
}
|
||||
path.replaceWith(t.callExpression(path.node.tag, expressions))
|
||||
}
|
||||
|
||||
if (t.isCallExpression(path)) {
|
||||
const canAppendStrings = path.node.arguments.every(
|
||||
arg => arg.type !== 'SpreadElement'
|
||||
)
|
||||
|
||||
if (canAppendStrings && shouldLabel) {
|
||||
const label = getLabelFromPath(path, state, t)
|
||||
if (label) {
|
||||
appendStringToArguments(path, `;label:${label};`, t)
|
||||
}
|
||||
}
|
||||
|
||||
path.get('arguments').forEach(node => {
|
||||
if (t.isObjectExpression(node)) {
|
||||
node.replaceWith(simplifyObject(node.node, t))
|
||||
}
|
||||
})
|
||||
|
||||
path.node.arguments = joinStringLiterals(path.node.arguments, t)
|
||||
|
||||
if (
|
||||
canAppendStrings &&
|
||||
state.emotionSourceMap &&
|
||||
!sourceMap &&
|
||||
path.node.loc !== undefined
|
||||
) {
|
||||
sourceMap = getSourceMap(path.node.loc.start, state)
|
||||
}
|
||||
|
||||
if (
|
||||
path.node.arguments.length === 1 &&
|
||||
t.isStringLiteral(path.node.arguments[0])
|
||||
) {
|
||||
let cssString = path.node.arguments[0].value
|
||||
let res = serializeStyles([cssString])
|
||||
let prodNode = t.objectExpression([
|
||||
t.objectProperty(t.identifier('name'), t.stringLiteral(res.name)),
|
||||
t.objectProperty(t.identifier('styles'), t.stringLiteral(res.styles))
|
||||
])
|
||||
let node = prodNode
|
||||
if (sourceMap) {
|
||||
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])
|
||||
}
|
||||
let devNode = t.objectExpression([
|
||||
t.objectProperty(t.identifier('name'), t.stringLiteral(res.name)),
|
||||
t.objectProperty(t.identifier('styles'), t.stringLiteral(res.styles)),
|
||||
t.objectProperty(t.identifier('map'), t.stringLiteral(sourceMap)),
|
||||
t.objectProperty(
|
||||
t.identifier('toString'),
|
||||
cloneNode(t, state.emotionStringifiedCssId)
|
||||
)
|
||||
])
|
||||
node = createSourceMapConditional(t, prodNode, devNode)
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
if (sourceMap) {
|
||||
let lastIndex = path.node.arguments.length - 1
|
||||
let last = path.node.arguments[lastIndex]
|
||||
let sourceMapConditional = createSourceMapConditional(
|
||||
t,
|
||||
t.stringLiteral(''),
|
||||
t.stringLiteral(sourceMap)
|
||||
)
|
||||
if (t.isStringLiteral(last)) {
|
||||
path.node.arguments[lastIndex] = t.binaryExpression(
|
||||
'+',
|
||||
last,
|
||||
sourceMapConditional
|
||||
)
|
||||
} else {
|
||||
const makeTemplateObjectCallPath = getTypeScriptMakeTemplateObjectPath(
|
||||
path
|
||||
)
|
||||
|
||||
if (makeTemplateObjectCallPath) {
|
||||
const sourceMapId = state.file.scope.generateUidIdentifier(
|
||||
'emotionSourceMap'
|
||||
)
|
||||
const sourceMapDeclaration = t.variableDeclaration('var', [
|
||||
t.variableDeclarator(sourceMapId, sourceMapConditional)
|
||||
])
|
||||
sourceMapDeclaration._compact = true
|
||||
state.file.path.unshiftContainer('body', [sourceMapDeclaration])
|
||||
|
||||
makeTemplateObjectCallPath.get('arguments').forEach(argPath => {
|
||||
const elements = argPath.get('elements')
|
||||
const lastElement = elements[elements.length - 1]
|
||||
lastElement.replaceWith(
|
||||
t.binaryExpression(
|
||||
'+',
|
||||
lastElement.node,
|
||||
cloneNode(t, sourceMapId)
|
||||
)
|
||||
)
|
||||
})
|
||||
} else if (!isTaggedTemplateTranspiledByBabel(path)) {
|
||||
path.node.arguments.push(sourceMapConditional)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
80
web/node_modules/babel-plugin-emotion/src/utils/transpiled-output-utils.js
generated
vendored
Normal file
80
web/node_modules/babel-plugin-emotion/src/utils/transpiled-output-utils.js
generated
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
// @flow
|
||||
|
||||
// this only works correctly in modules, but we don't run on scripts anyway, so it's fine
|
||||
// the difference is that in modules template objects are being cached per call site
|
||||
export function getTypeScriptMakeTemplateObjectPath(path: *) {
|
||||
if (path.node.arguments.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
const firstArgPath = path.get('arguments')[0]
|
||||
|
||||
if (
|
||||
firstArgPath.isLogicalExpression() &&
|
||||
firstArgPath.get('left').isIdentifier() &&
|
||||
firstArgPath.get('right').isAssignmentExpression() &&
|
||||
firstArgPath.get('right.right').isCallExpression() &&
|
||||
firstArgPath.get('right.right.callee').isIdentifier() &&
|
||||
firstArgPath.node.right.right.callee.name.includes('makeTemplateObject') &&
|
||||
firstArgPath.node.right.right.arguments.length === 2
|
||||
) {
|
||||
return firstArgPath.get('right.right')
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
// this is only used to prevent appending strings/expressions to arguments incorectly
|
||||
// we could push them to found array expressions, as we do it for TS-transpile output ¯\_(ツ)_/¯
|
||||
// it seems overly complicated though - mainly because we'd also have to check against existing stuff of a particular type (source maps & labels)
|
||||
// considering Babel double-transpilation as a valid use case seems rather far-fetched
|
||||
export function isTaggedTemplateTranspiledByBabel(path: *) {
|
||||
if (path.node.arguments.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
const firstArgPath = path.get('arguments')[0]
|
||||
|
||||
if (
|
||||
!firstArgPath.isCallExpression() ||
|
||||
!firstArgPath.get('callee').isIdentifier()
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
const calleeName = firstArgPath.node.callee.name
|
||||
|
||||
if (!calleeName.includes('templateObject')) {
|
||||
return false
|
||||
}
|
||||
|
||||
const bindingPath = path.scope.getBinding(calleeName).path
|
||||
|
||||
if (!bindingPath.isFunction()) {
|
||||
return false
|
||||
}
|
||||
|
||||
const functionBody = bindingPath.get('body.body')
|
||||
|
||||
if (!functionBody[0].isVariableDeclaration()) {
|
||||
return false
|
||||
}
|
||||
|
||||
const declarationInit = functionBody[0].get('declarations')[0].get('init')
|
||||
|
||||
if (!declarationInit.isCallExpression()) {
|
||||
return false
|
||||
}
|
||||
|
||||
const declarationInitArguments = declarationInit.get('arguments')
|
||||
|
||||
if (
|
||||
declarationInitArguments.length === 0 ||
|
||||
declarationInitArguments.length > 2 ||
|
||||
declarationInitArguments.some(argPath => !argPath.isArrayExpression())
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue