Dashboard sipadu mbip
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

babel-plugin-emotion.esm.js 34KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. import nodePath from 'path';
  2. import { SourceMapGenerator } from 'source-map';
  3. import convert from 'convert-source-map';
  4. import findRoot from 'find-root';
  5. import memoize from '@emotion/memoize';
  6. import hashString from '@emotion/hash';
  7. import escapeRegexp from 'escape-string-regexp';
  8. import { serializeStyles } from '@emotion/serialize';
  9. import { addNamed, addDefault } from '@babel/helper-module-imports';
  10. import { createMacro } from 'babel-plugin-macros';
  11. // babel-plugin-styled-components
  12. // https://github.com/styled-components/babel-plugin-styled-components/blob/8d44acc36f067d60d4e09f9c22ff89695bc332d2/src/minify/index.js
  13. var multilineCommentRegex = /\/\*[^!](.|[\r\n])*?\*\//g;
  14. var lineCommentStart = /\/\//g;
  15. var symbolRegex = /(\s*[;:{},]\s*)/g; // Counts occurences of substr inside str
  16. var countOccurences = function countOccurences(str, substr) {
  17. return str.split(substr).length - 1;
  18. }; // Joins substrings until predicate returns true
  19. var reduceSubstr = function reduceSubstr(substrs, join, predicate) {
  20. var length = substrs.length;
  21. var res = substrs[0];
  22. if (length === 1) {
  23. return res;
  24. }
  25. for (var i = 1; i < length; i++) {
  26. if (predicate(res)) {
  27. break;
  28. }
  29. res += join + substrs[i];
  30. }
  31. return res;
  32. }; // Joins at comment starts when it's inside a string or parantheses
  33. // effectively removing line comments
  34. var stripLineComment = function stripLineComment(line) {
  35. return reduceSubstr(line.split(lineCommentStart), '//', function (str) {
  36. return !str.endsWith(':') && // NOTE: This is another guard against urls, if they're not inside strings or parantheses.
  37. countOccurences(str, "'") % 2 === 0 && countOccurences(str, '"') % 2 === 0 && countOccurences(str, '(') === countOccurences(str, ')');
  38. });
  39. };
  40. var compressSymbols = function compressSymbols(code) {
  41. return code.split(symbolRegex).reduce(function (str, fragment, index) {
  42. // Even-indices are non-symbol fragments
  43. if (index % 2 === 0) {
  44. return str + fragment;
  45. } // Only manipulate symbols outside of strings
  46. if (countOccurences(str, "'") % 2 === 0 && countOccurences(str, '"') % 2 === 0) {
  47. return str + fragment.trim();
  48. }
  49. return str + fragment;
  50. }, '');
  51. }; // Detects lines that are exclusively line comments
  52. var isLineComment = function isLineComment(line) {
  53. return line.trim().startsWith('//');
  54. };
  55. var linebreakRegex = /[\r\n]\s*/g;
  56. var spacesAndLinebreakRegex = /\s+|\n+/g;
  57. function multilineReplacer(match) {
  58. // When we encounter a standard multi-line CSS comment and it contains a '@'
  59. // character, we keep the comment but optimize it into a single line. Some
  60. // Stylis plugins, such as the stylis-rtl via the cssjanus plugin, use this
  61. // special comment syntax to control behavior (such as: /* @noflip */).
  62. // We can do this with standard CSS comments because they will work with
  63. // compression, as opposed to non-standard single-line comments that will
  64. // break compressed CSS. If the comment doesn't contain '@', then we replace
  65. // it with a line break, which effectively removes it from the output.
  66. var keepComment = match.indexOf('@') > -1;
  67. if (keepComment) {
  68. return match.replace(spacesAndLinebreakRegex, ' ').trim();
  69. }
  70. return '\n';
  71. }
  72. var minify = function minify(code) {
  73. var newCode = code.replace(multilineCommentRegex, multilineReplacer) // If allowed, remove line breaks and extra space from multi-line comments so they appear on one line
  74. .split(linebreakRegex) // Split at newlines
  75. .filter(function (line) {
  76. return line.length > 0 && !isLineComment(line);
  77. }) // Removes lines containing only line comments
  78. .map(stripLineComment) // Remove line comments inside text
  79. .join(' '); // Rejoin all lines
  80. return compressSymbols(newCode);
  81. };
  82. function getExpressionsFromTemplateLiteral(node, t) {
  83. var raw = createRawStringFromTemplateLiteral(node);
  84. var minified = minify(raw);
  85. return replacePlaceholdersWithExpressions(minified, node.expressions || [], t);
  86. }
  87. var interleave = function interleave(strings, interpolations) {
  88. return interpolations.reduce(function (array, interp, i) {
  89. return array.concat([interp], strings[i + 1]);
  90. }, [strings[0]]);
  91. };
  92. function getDynamicMatches(str) {
  93. var re = /xxx(\d+)xxx/gm;
  94. var match;
  95. var matches = [];
  96. while ((match = re.exec(str)) !== null) {
  97. // so that flow doesn't complain
  98. if (match !== null) {
  99. matches.push({
  100. value: match[0],
  101. p1: parseInt(match[1], 10),
  102. index: match.index
  103. });
  104. }
  105. }
  106. return matches;
  107. }
  108. function replacePlaceholdersWithExpressions(str, expressions, t) {
  109. var matches = getDynamicMatches(str);
  110. if (matches.length === 0) {
  111. if (str === '') {
  112. return [];
  113. }
  114. return [t.stringLiteral(str)];
  115. }
  116. var strings = [];
  117. var finalExpressions = [];
  118. var cursor = 0;
  119. matches.forEach(function (_ref, i) {
  120. var value = _ref.value,
  121. p1 = _ref.p1,
  122. index = _ref.index;
  123. var preMatch = str.substring(cursor, index);
  124. cursor = cursor + preMatch.length + value.length;
  125. if (preMatch) {
  126. strings.push(t.stringLiteral(preMatch));
  127. } else if (i === 0) {
  128. strings.push(t.stringLiteral(''));
  129. }
  130. finalExpressions.push(expressions[p1]);
  131. if (i === matches.length - 1) {
  132. strings.push(t.stringLiteral(str.substring(index + value.length)));
  133. }
  134. });
  135. return interleave(strings, finalExpressions).filter(function (node) {
  136. return node.value !== '';
  137. });
  138. }
  139. function createRawStringFromTemplateLiteral(quasi) {
  140. var strs = quasi.quasis.map(function (x) {
  141. return x.value.cooked;
  142. });
  143. var src = strs.reduce(function (arr, str, i) {
  144. arr.push(str);
  145. if (i !== strs.length - 1) {
  146. arr.push("xxx" + i + "xxx");
  147. }
  148. return arr;
  149. }, []).join('').trim();
  150. return src;
  151. }
  152. var invalidClassNameCharacters = /[!"#$%&'()*+,./:;<=>?@[\]^`|}~{]/g;
  153. var sanitizeLabelPart = function sanitizeLabelPart(labelPart) {
  154. return labelPart.trim().replace(invalidClassNameCharacters, '-');
  155. };
  156. function getLabel(identifierName, autoLabel, labelFormat, filename) {
  157. if (!identifierName || !autoLabel) return null;
  158. if (!labelFormat) return sanitizeLabelPart(identifierName);
  159. var parsedPath = nodePath.parse(filename);
  160. var localDirname = nodePath.basename(parsedPath.dir);
  161. var localFilename = parsedPath.name;
  162. if (localFilename === 'index') {
  163. localFilename = localDirname;
  164. }
  165. return labelFormat.replace(/\[local\]/gi, sanitizeLabelPart(identifierName)).replace(/\[filename\]/gi, sanitizeLabelPart(localFilename)).replace(/\[dirname\]/gi, sanitizeLabelPart(localDirname));
  166. }
  167. function getLabelFromPath(path, state, t) {
  168. return getLabel(getIdentifierName(path, t), state.opts.autoLabel === undefined ? process.env.NODE_ENV !== 'production' : state.opts.autoLabel, state.opts.labelFormat, state.file.opts.filename);
  169. }
  170. var pascalCaseRegex = /^[A-Z][A-Za-z]+/;
  171. function getDeclaratorName(path, t) {
  172. // $FlowFixMe
  173. var parent = path.findParent(function (p) {
  174. return p.isVariableDeclarator() || p.isFunctionDeclaration() || p.isFunctionExpression() || p.isArrowFunctionExpression() || p.isObjectProperty();
  175. });
  176. if (!parent) {
  177. return '';
  178. } // we probably have a css call assigned to a variable
  179. // so we'll just return the variable name
  180. if (parent.isVariableDeclarator()) {
  181. if (t.isIdentifier(parent.node.id)) {
  182. return parent.node.id.name;
  183. }
  184. return '';
  185. } // we probably have an inline css prop usage
  186. if (parent.isFunctionDeclaration()) {
  187. var _name = parent.node.id.name;
  188. if (pascalCaseRegex.test(_name)) {
  189. return _name;
  190. }
  191. return '';
  192. } // we could also have an object property
  193. if (parent.isObjectProperty() && !parent.node.computed) {
  194. return parent.node.key.name;
  195. }
  196. var variableDeclarator = path.findParent(function (p) {
  197. return p.isVariableDeclarator();
  198. });
  199. if (!variableDeclarator) {
  200. return '';
  201. }
  202. var name = variableDeclarator.node.id.name;
  203. if (pascalCaseRegex.test(name)) {
  204. return name;
  205. }
  206. return '';
  207. }
  208. function getIdentifierName(path, t) {
  209. var classOrClassPropertyParent;
  210. if (t.isObjectProperty(path.parentPath) && path.parentPath.node.computed === false && (t.isIdentifier(path.parentPath.node.key) || t.isStringLiteral(path.parentPath.node.key))) {
  211. return path.parentPath.node.key.name || path.parentPath.node.key.value;
  212. }
  213. if (path) {
  214. // $FlowFixMe
  215. classOrClassPropertyParent = path.findParent(function (p) {
  216. return t.isClassProperty(p) || t.isClass(p);
  217. });
  218. }
  219. if (classOrClassPropertyParent) {
  220. if (t.isClassProperty(classOrClassPropertyParent) && classOrClassPropertyParent.node.computed === false && t.isIdentifier(classOrClassPropertyParent.node.key)) {
  221. return classOrClassPropertyParent.node.key.name;
  222. }
  223. if (t.isClass(classOrClassPropertyParent) && classOrClassPropertyParent.node.id) {
  224. return t.isIdentifier(classOrClassPropertyParent.node.id) ? classOrClassPropertyParent.node.id.name : '';
  225. }
  226. }
  227. var declaratorName = getDeclaratorName(path, t); // if the name starts with _ it was probably generated by babel so we should ignore it
  228. if (declaratorName.charAt(0) === '_') {
  229. return '';
  230. }
  231. return declaratorName;
  232. }
  233. function getGeneratorOpts(file) {
  234. return file.opts.generatorOpts ? file.opts.generatorOpts : file.opts;
  235. }
  236. function makeSourceMapGenerator(file) {
  237. var generatorOpts = getGeneratorOpts(file);
  238. var filename = generatorOpts.sourceFileName;
  239. var generator = new SourceMapGenerator({
  240. file: filename,
  241. sourceRoot: generatorOpts.sourceRoot
  242. });
  243. generator.setSourceContent(filename, file.code);
  244. return generator;
  245. }
  246. function getSourceMap(offset, state) {
  247. var generator = makeSourceMapGenerator(state.file);
  248. var generatorOpts = getGeneratorOpts(state.file);
  249. if (generatorOpts.sourceFileName && generatorOpts.sourceFileName !== 'unknown') {
  250. generator.addMapping({
  251. generated: {
  252. line: 1,
  253. column: 0
  254. },
  255. source: generatorOpts.sourceFileName,
  256. original: offset
  257. });
  258. return convert.fromObject(generator).toComment({
  259. multiline: true
  260. });
  261. }
  262. return '';
  263. }
  264. var hashArray = function hashArray(arr) {
  265. return hashString(arr.join(''));
  266. };
  267. var unsafeRequire = require;
  268. var getPackageRootPath = memoize(function (filename) {
  269. return findRoot(filename);
  270. });
  271. var separator = new RegExp(escapeRegexp(nodePath.sep), 'g');
  272. var normalizePath = function normalizePath(path) {
  273. return nodePath.normalize(path).replace(separator, '/');
  274. };
  275. function getTargetClassName(state, t) {
  276. if (state.emotionTargetClassNameCount === undefined) {
  277. state.emotionTargetClassNameCount = 0;
  278. }
  279. var hasFilepath = state.file.opts.filename && state.file.opts.filename !== 'unknown';
  280. var filename = hasFilepath ? state.file.opts.filename : ''; // normalize the file path to ignore folder structure
  281. // outside the current node project and arch-specific delimiters
  282. var moduleName = '';
  283. var rootPath = filename;
  284. try {
  285. rootPath = getPackageRootPath(filename);
  286. moduleName = unsafeRequire(rootPath + '/package.json').name;
  287. } catch (err) {}
  288. var finalPath = filename === rootPath ? 'root' : filename.slice(rootPath.length);
  289. var positionInFile = state.emotionTargetClassNameCount++;
  290. var stuffToHash = [moduleName];
  291. if (finalPath) {
  292. stuffToHash.push(normalizePath(finalPath));
  293. } else {
  294. stuffToHash.push(state.file.code);
  295. }
  296. var stableClassName = "e" + hashArray(stuffToHash) + positionInFile;
  297. return stableClassName;
  298. }
  299. // it's meant to simplify the most common cases so i don't want to make it especially complex
  300. // also, this will be unnecessary when prepack is ready
  301. function simplifyObject(node, t) {
  302. var finalString = '';
  303. for (var i = 0; i < node.properties.length; i++) {
  304. var _ref;
  305. var property = node.properties[i];
  306. 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)) {
  307. return node;
  308. }
  309. var key = property.key.name || property.key.value;
  310. if (key === 'styles') {
  311. return node;
  312. }
  313. if (t.isObjectExpression(property.value)) {
  314. var simplifiedChild = simplifyObject(property.value, t);
  315. if (!t.isStringLiteral(simplifiedChild)) {
  316. return node;
  317. }
  318. finalString += key + "{" + simplifiedChild.value + "}";
  319. continue;
  320. }
  321. var value = property.value.value;
  322. finalString += serializeStyles([(_ref = {}, _ref[key] = value, _ref)]).styles;
  323. }
  324. return t.stringLiteral(finalString);
  325. }
  326. function isTaggedTemplateExpressionTranspiledByTypeScript(path) {
  327. if (path.node.arguments.length !== 1) {
  328. return false;
  329. }
  330. var argPath = path.get('arguments')[0];
  331. return argPath.isLogicalExpression() && argPath.get('left').isIdentifier() && argPath.node.left.name.includes('templateObject') && argPath.get('right').isAssignmentExpression() && argPath.get('right').get('right').isCallExpression() && argPath.get('right').get('right').get('callee').isIdentifier() && argPath.node.right.right.callee.name.includes('makeTemplateObject') && argPath.node.right.right.arguments.length === 2;
  332. }
  333. var appendStringToArguments = function appendStringToArguments(path, string, t) {
  334. if (!string) {
  335. return;
  336. }
  337. var args = path.node.arguments;
  338. if (t.isStringLiteral(args[args.length - 1])) {
  339. args[args.length - 1].value += string;
  340. } else if (isTaggedTemplateExpressionTranspiledByTypeScript(path)) {
  341. var makeTemplateObjectCallPath = path.get('arguments')[0].get('right').get('right');
  342. makeTemplateObjectCallPath.get('arguments').forEach(function (argPath) {
  343. var elements = argPath.get('elements');
  344. var lastElement = elements[elements.length - 1];
  345. lastElement.replaceWith(t.stringLiteral(lastElement.node.value + string));
  346. });
  347. } else {
  348. args.push(t.stringLiteral(string));
  349. }
  350. };
  351. var joinStringLiterals = function joinStringLiterals(expressions, t) {
  352. return expressions.reduce(function (finalExpressions, currentExpression, i) {
  353. if (!t.isStringLiteral(currentExpression)) {
  354. finalExpressions.push(currentExpression);
  355. } else if (t.isStringLiteral(finalExpressions[finalExpressions.length - 1])) {
  356. finalExpressions[finalExpressions.length - 1].value += currentExpression.value;
  357. } else {
  358. finalExpressions.push(currentExpression);
  359. }
  360. return finalExpressions;
  361. }, []);
  362. };
  363. var 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
  364. var cloneNode = function cloneNode(t, node) {
  365. return typeof t.cloneNode === 'function' ? t.cloneNode(node) : t.cloneDeep(node);
  366. };
  367. function createSourceMapConditional(t, production, development) {
  368. return t.conditionalExpression(t.binaryExpression('===', t.memberExpression(t.memberExpression(t.identifier('process'), t.identifier('env')), t.identifier('NODE_ENV')), t.stringLiteral('production')), production, development);
  369. }
  370. var transformExpressionWithStyles = function transformExpressionWithStyles(_ref) {
  371. var babel = _ref.babel,
  372. state = _ref.state,
  373. path = _ref.path,
  374. shouldLabel = _ref.shouldLabel,
  375. _ref$sourceMap = _ref.sourceMap,
  376. sourceMap = _ref$sourceMap === void 0 ? '' : _ref$sourceMap;
  377. var t = babel.types;
  378. if (t.isTaggedTemplateExpression(path)) {
  379. var expressions = getExpressionsFromTemplateLiteral(path.node.quasi, t);
  380. if (state.emotionSourceMap && path.node.quasi.loc !== undefined) {
  381. sourceMap = getSourceMap(path.node.quasi.loc.start, state);
  382. }
  383. path.replaceWith(t.callExpression(path.node.tag, expressions));
  384. }
  385. if (t.isCallExpression(path)) {
  386. var canAppendStrings = path.node.arguments.every(function (arg) {
  387. return arg.type !== 'SpreadElement';
  388. });
  389. if (canAppendStrings && shouldLabel) {
  390. var label = getLabelFromPath(path, state, t);
  391. if (label) {
  392. appendStringToArguments(path, ";label:" + label + ";", t);
  393. }
  394. }
  395. var isPure = true;
  396. path.get('arguments').forEach(function (node) {
  397. if (!node.isPure()) {
  398. isPure = false;
  399. }
  400. if (t.isObjectExpression(node)) {
  401. node.replaceWith(simplifyObject(node.node, t));
  402. }
  403. });
  404. path.node.arguments = joinStringLiterals(path.node.arguments, t);
  405. if (canAppendStrings && state.emotionSourceMap && !sourceMap && path.node.loc !== undefined) {
  406. sourceMap = getSourceMap(path.node.loc.start, state);
  407. }
  408. if (path.node.arguments.length === 1 && t.isStringLiteral(path.node.arguments[0])) {
  409. var cssString = path.node.arguments[0].value;
  410. var res = serializeStyles([cssString]);
  411. var prodNode = t.objectExpression([t.objectProperty(t.identifier('name'), t.stringLiteral(res.name)), t.objectProperty(t.identifier('styles'), t.stringLiteral(res.styles))]);
  412. var node = prodNode;
  413. if (sourceMap) {
  414. if (!state.emotionStringifiedCssId) {
  415. var uid = state.file.scope.generateUidIdentifier('__EMOTION_STRINGIFIED_CSS_ERROR__');
  416. state.emotionStringifiedCssId = uid;
  417. var cssObjectToString = t.functionDeclaration(uid, [], t.blockStatement([t.returnStatement(t.stringLiteral(CSS_OBJECT_STRINGIFIED_ERROR))]));
  418. cssObjectToString._compact = true;
  419. state.file.path.unshiftContainer('body', [cssObjectToString]);
  420. }
  421. var 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))]);
  422. node = createSourceMapConditional(t, prodNode, devNode);
  423. }
  424. return {
  425. node: node,
  426. isPure: true
  427. };
  428. }
  429. if (sourceMap) {
  430. var lastIndex = path.node.arguments.length - 1;
  431. var last = path.node.arguments[lastIndex];
  432. var sourceMapConditional = createSourceMapConditional(t, t.stringLiteral(''), t.stringLiteral(sourceMap));
  433. if (t.isStringLiteral(last)) {
  434. path.node.arguments[lastIndex] = t.binaryExpression('+', last, sourceMapConditional);
  435. } else if (isTaggedTemplateExpressionTranspiledByTypeScript(path)) {
  436. var makeTemplateObjectCallPath = path.get('arguments')[0].get('right').get('right');
  437. makeTemplateObjectCallPath.get('arguments').forEach(function (argPath) {
  438. var elements = argPath.get('elements');
  439. var lastElement = elements[elements.length - 1];
  440. lastElement.replaceWith(t.binaryExpression('+', lastElement.node, cloneNode(t, sourceMapConditional)));
  441. });
  442. } else {
  443. path.node.arguments.push(sourceMapConditional);
  444. }
  445. }
  446. return {
  447. node: undefined,
  448. isPure: isPure
  449. };
  450. }
  451. return {
  452. node: undefined,
  453. isPure: false
  454. };
  455. };
  456. var getStyledOptions = function getStyledOptions(t, path, state) {
  457. var properties = [t.objectProperty(t.identifier('target'), t.stringLiteral(getTargetClassName(state)))];
  458. var label = getLabelFromPath(path, state, t);
  459. if (label) {
  460. properties.push(t.objectProperty(t.identifier('label'), t.stringLiteral(label)));
  461. }
  462. var args = path.node.arguments;
  463. var optionsArgument = args.length >= 2 ? args[1] : null;
  464. if (optionsArgument) {
  465. if (!t.isObjectExpression(optionsArgument)) {
  466. return t.callExpression(state.file.addHelper('extends'), [t.objectExpression([]), t.objectExpression(properties), optionsArgument]);
  467. }
  468. properties.unshift.apply(properties, optionsArgument.properties);
  469. }
  470. return t.objectExpression( // $FlowFixMe
  471. properties);
  472. };
  473. var createEmotionMacro = function createEmotionMacro(instancePath) {
  474. return createMacro(function macro(_ref) {
  475. var references = _ref.references,
  476. state = _ref.state,
  477. babel = _ref.babel,
  478. isEmotionCall = _ref.isEmotionCall;
  479. if (!isEmotionCall) {
  480. state.emotionSourceMap = true;
  481. }
  482. var t = babel.types;
  483. Object.keys(references).forEach(function (referenceKey) {
  484. var isPure = true;
  485. var runtimeNode = addNamed(state.file.path, referenceKey, instancePath);
  486. switch (referenceKey) {
  487. case 'injectGlobal':
  488. {
  489. isPure = false;
  490. }
  491. // eslint-disable-next-line no-fallthrough
  492. case 'css':
  493. case 'keyframes':
  494. {
  495. references[referenceKey].reverse().forEach(function (reference) {
  496. var path = reference.parentPath;
  497. reference.replaceWith(t.cloneDeep(runtimeNode));
  498. if (isPure) {
  499. path.addComment('leading', '#__PURE__');
  500. }
  501. var _transformExpressionW = transformExpressionWithStyles({
  502. babel: babel,
  503. state: state,
  504. path: path,
  505. shouldLabel: true
  506. }),
  507. node = _transformExpressionW.node;
  508. if (node) {
  509. path.node.arguments[0] = node;
  510. }
  511. });
  512. break;
  513. }
  514. default:
  515. {
  516. references[referenceKey].reverse().forEach(function (reference) {
  517. reference.replaceWith(t.cloneDeep(runtimeNode));
  518. });
  519. }
  520. }
  521. });
  522. });
  523. };
  524. var createStyledMacro = function createStyledMacro(_ref) {
  525. var importPath = _ref.importPath,
  526. _ref$originalImportPa = _ref.originalImportPath,
  527. originalImportPath = _ref$originalImportPa === void 0 ? importPath : _ref$originalImportPa,
  528. isWeb = _ref.isWeb;
  529. return createMacro(function (_ref2) {
  530. var references = _ref2.references,
  531. state = _ref2.state,
  532. babel = _ref2.babel,
  533. isEmotionCall = _ref2.isEmotionCall;
  534. if (!isEmotionCall) {
  535. state.emotionSourceMap = true;
  536. }
  537. var t = babel.types;
  538. if (references["default"] && references["default"].length) {
  539. var _styledIdentifier;
  540. var getStyledIdentifier = function getStyledIdentifier() {
  541. if (_styledIdentifier === undefined) {
  542. _styledIdentifier = addDefault(state.file.path, importPath, {
  543. nameHint: 'styled'
  544. });
  545. }
  546. return t.cloneDeep(_styledIdentifier);
  547. };
  548. var originalImportPathStyledIdentifier;
  549. var getOriginalImportPathStyledIdentifier = function getOriginalImportPathStyledIdentifier() {
  550. if (originalImportPathStyledIdentifier === undefined) {
  551. originalImportPathStyledIdentifier = addDefault(state.file.path, originalImportPath, {
  552. nameHint: 'styled'
  553. });
  554. }
  555. return t.cloneDeep(originalImportPathStyledIdentifier);
  556. };
  557. if (importPath === originalImportPath) {
  558. getOriginalImportPathStyledIdentifier = getStyledIdentifier;
  559. }
  560. references["default"].forEach(function (reference) {
  561. var isCall = false;
  562. if (t.isMemberExpression(reference.parent) && reference.parent.computed === false) {
  563. isCall = true;
  564. if ( // checks if the first character is lowercase
  565. // becasue we don't want to transform the member expression if
  566. // it's in primitives/native
  567. reference.parent.property.name.charCodeAt(0) > 96) {
  568. reference.parentPath.replaceWith(t.callExpression(getStyledIdentifier(), [t.stringLiteral(reference.parent.property.name)]));
  569. } else {
  570. reference.replaceWith(getStyledIdentifier());
  571. }
  572. } else if (reference.parentPath && reference.parentPath.parentPath && t.isCallExpression(reference.parentPath) && reference.parent.callee === reference.node) {
  573. isCall = true;
  574. reference.replaceWith(getStyledIdentifier());
  575. } else {
  576. reference.replaceWith(getOriginalImportPathStyledIdentifier());
  577. }
  578. if (reference.parentPath && reference.parentPath.parentPath) {
  579. var styledCallPath = reference.parentPath.parentPath;
  580. var _transformExpressionW = transformExpressionWithStyles({
  581. path: styledCallPath,
  582. state: state,
  583. babel: babel,
  584. shouldLabel: false
  585. }),
  586. node = _transformExpressionW.node;
  587. if (node && isWeb) {
  588. // we know the argument length will be 1 since that's the only time we will have a node since it will be static
  589. styledCallPath.node.arguments[0] = node;
  590. }
  591. }
  592. if (isCall) {
  593. reference.addComment('leading', '#__PURE__');
  594. if (isWeb) {
  595. reference.parentPath.node.arguments[1] = getStyledOptions(t, reference.parentPath, state);
  596. }
  597. }
  598. });
  599. }
  600. Object.keys(references).filter(function (x) {
  601. return x !== 'default';
  602. }).forEach(function (referenceKey) {
  603. var runtimeNode = addNamed(state.file.path, referenceKey, importPath);
  604. references[referenceKey].reverse().forEach(function (reference) {
  605. reference.replaceWith(t.cloneDeep(runtimeNode));
  606. });
  607. });
  608. });
  609. };
  610. var transformCssCallExpression = function transformCssCallExpression(_ref) {
  611. var babel = _ref.babel,
  612. state = _ref.state,
  613. path = _ref.path,
  614. sourceMap = _ref.sourceMap;
  615. var _transformExpressionW = transformExpressionWithStyles({
  616. babel: babel,
  617. state: state,
  618. path: path,
  619. shouldLabel: true,
  620. sourceMap: sourceMap
  621. }),
  622. node = _transformExpressionW.node,
  623. isPure = _transformExpressionW.isPure;
  624. if (node) {
  625. path.replaceWith(node);
  626. if (isPure) {
  627. path.hoist();
  628. }
  629. } else {
  630. path.addComment('leading', '#__PURE__');
  631. }
  632. };
  633. var cssMacro = createMacro(function (_ref2) {
  634. var references = _ref2.references,
  635. state = _ref2.state,
  636. babel = _ref2.babel,
  637. isEmotionCall = _ref2.isEmotionCall;
  638. if (!isEmotionCall) {
  639. state.emotionSourceMap = true;
  640. }
  641. var t = babel.types;
  642. if (references["default"] && references["default"].length) {
  643. references["default"].reverse().forEach(function (reference) {
  644. if (!state.cssIdentifier) {
  645. state.cssIdentifier = addDefault(reference, '@emotion/css', {
  646. nameHint: 'css'
  647. });
  648. }
  649. reference.replaceWith(t.cloneDeep(state.cssIdentifier));
  650. transformCssCallExpression({
  651. babel: babel,
  652. state: state,
  653. path: reference.parentPath
  654. });
  655. });
  656. }
  657. Object.keys(references).filter(function (x) {
  658. return x !== 'default';
  659. }).forEach(function (referenceKey) {
  660. var runtimeNode = addNamed(state.file.path, referenceKey, '@emotion/css', {
  661. nameHint: referenceKey
  662. });
  663. references[referenceKey].reverse().forEach(function (reference) {
  664. reference.replaceWith(t.cloneDeep(runtimeNode));
  665. });
  666. });
  667. });
  668. var webStyledMacro = createStyledMacro({
  669. importPath: '@emotion/styled-base',
  670. originalImportPath: '@emotion/styled',
  671. isWeb: true
  672. });
  673. var nativeStyledMacro = createStyledMacro({
  674. importPath: '@emotion/native',
  675. originalImportPath: '@emotion/native',
  676. isWeb: false
  677. });
  678. var primitivesStyledMacro = createStyledMacro({
  679. importPath: '@emotion/primitives',
  680. originalImportPath: '@emotion/primitives',
  681. isWeb: false
  682. });
  683. var macros = {
  684. createEmotionMacro: createEmotionMacro,
  685. css: cssMacro,
  686. createStyledMacro: createStyledMacro
  687. };
  688. var emotionCoreMacroThatsNotARealMacro = function emotionCoreMacroThatsNotARealMacro(_ref) {
  689. var references = _ref.references,
  690. state = _ref.state,
  691. babel = _ref.babel;
  692. Object.keys(references).forEach(function (refKey) {
  693. if (refKey === 'css') {
  694. references[refKey].forEach(function (path) {
  695. transformCssCallExpression({
  696. babel: babel,
  697. state: state,
  698. path: path.parentPath
  699. });
  700. });
  701. }
  702. });
  703. };
  704. emotionCoreMacroThatsNotARealMacro.keepImport = true;
  705. function getAbsolutePath(instancePath, rootPath) {
  706. if (instancePath.charAt(0) === '.') {
  707. var absoluteInstancePath = nodePath.resolve(rootPath, instancePath);
  708. return absoluteInstancePath;
  709. }
  710. return false;
  711. }
  712. function getInstancePathToCompare(instancePath, rootPath) {
  713. var absolutePath = getAbsolutePath(instancePath, rootPath);
  714. if (absolutePath === false) {
  715. return instancePath;
  716. }
  717. return absolutePath;
  718. }
  719. function index (babel) {
  720. var t = babel.types;
  721. return {
  722. name: 'emotion',
  723. inherits: require('babel-plugin-syntax-jsx'),
  724. visitor: {
  725. ImportDeclaration: function ImportDeclaration(path, state) {
  726. var hasFilepath = path.hub.file.opts.filename && path.hub.file.opts.filename !== 'unknown';
  727. var dirname = hasFilepath ? nodePath.dirname(path.hub.file.opts.filename) : '';
  728. if (!state.pluginMacros[path.node.source.value] && state.emotionInstancePaths.indexOf(getInstancePathToCompare(path.node.source.value, dirname)) !== -1) {
  729. state.pluginMacros[path.node.source.value] = createEmotionMacro(path.node.source.value);
  730. }
  731. var pluginMacros = state.pluginMacros; // most of this is from https://github.com/kentcdodds/babel-plugin-macros/blob/master/src/index.js
  732. if (pluginMacros[path.node.source.value] === undefined) {
  733. return;
  734. }
  735. if (t.isImportNamespaceSpecifier(path.node.specifiers[0])) {
  736. return;
  737. }
  738. var imports = path.node.specifiers.map(function (s) {
  739. return {
  740. localName: s.local.name,
  741. importedName: s.type === 'ImportDefaultSpecifier' ? 'default' : s.imported.name
  742. };
  743. });
  744. var shouldExit = false;
  745. var hasReferences = false;
  746. var referencePathsByImportName = imports.reduce(function (byName, _ref2) {
  747. var importedName = _ref2.importedName,
  748. localName = _ref2.localName;
  749. var binding = path.scope.getBinding(localName);
  750. if (!binding) {
  751. shouldExit = true;
  752. return byName;
  753. }
  754. byName[importedName] = binding.referencePaths;
  755. hasReferences = hasReferences || Boolean(byName[importedName].length);
  756. return byName;
  757. }, {});
  758. if (!hasReferences || shouldExit) {
  759. return;
  760. }
  761. /**
  762. * Other plugins that run before babel-plugin-macros might use path.replace, where a path is
  763. * put into its own replacement. Apparently babel does not update the scope after such
  764. * an operation. As a remedy, the whole scope is traversed again with an empty "Identifier"
  765. * visitor - this makes the problem go away.
  766. *
  767. * See: https://github.com/kentcdodds/import-all.macro/issues/7
  768. */
  769. state.file.scope.path.traverse({
  770. Identifier: function Identifier() {}
  771. });
  772. pluginMacros[path.node.source.value]({
  773. references: referencePathsByImportName,
  774. state: state,
  775. babel: babel,
  776. isBabelMacrosCall: true,
  777. isEmotionCall: true
  778. });
  779. if (!pluginMacros[path.node.source.value].keepImport) {
  780. path.remove();
  781. }
  782. },
  783. Program: function Program(path, state) {
  784. state.emotionInstancePaths = (state.opts.instances || []).map(function (instancePath) {
  785. return getInstancePathToCompare(instancePath, process.cwd());
  786. });
  787. state.pluginMacros = {
  788. '@emotion/css': cssMacro,
  789. '@emotion/styled': webStyledMacro,
  790. '@emotion/core': emotionCoreMacroThatsNotARealMacro,
  791. '@emotion/primitives': primitivesStyledMacro,
  792. '@emotion/native': nativeStyledMacro,
  793. emotion: createEmotionMacro('emotion')
  794. };
  795. if (state.opts.cssPropOptimization === undefined) {
  796. for (var _iterator = path.node.body, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
  797. var _ref3;
  798. if (_isArray) {
  799. if (_i >= _iterator.length) break;
  800. _ref3 = _iterator[_i++];
  801. } else {
  802. _i = _iterator.next();
  803. if (_i.done) break;
  804. _ref3 = _i.value;
  805. }
  806. var node = _ref3;
  807. if (t.isImportDeclaration(node) && node.source.value === '@emotion/core' && node.specifiers.some(function (x) {
  808. return t.isImportSpecifier(x) && x.imported.name === 'jsx';
  809. })) {
  810. state.transformCssProp = true;
  811. break;
  812. }
  813. }
  814. } else {
  815. state.transformCssProp = state.opts.cssPropOptimization;
  816. }
  817. if (state.opts.sourceMap === false) {
  818. state.emotionSourceMap = false;
  819. } else {
  820. state.emotionSourceMap = true;
  821. }
  822. },
  823. JSXAttribute: function JSXAttribute(path, state) {
  824. if (path.node.name.name !== 'css' || !state.transformCssProp) {
  825. return;
  826. }
  827. if (t.isJSXExpressionContainer(path.node.value) && (t.isObjectExpression(path.node.value.expression) || t.isArrayExpression(path.node.value.expression))) {
  828. var expressionPath = path.get('value.expression');
  829. var sourceMap = state.emotionSourceMap && path.node.loc !== undefined ? getSourceMap(path.node.loc.start, state) : '';
  830. expressionPath.replaceWith(t.callExpression( // the name of this identifier doesn't really matter at all
  831. // it'll never appear in generated code
  832. t.identifier('___shouldNeverAppearCSS'), [path.node.value.expression]));
  833. transformCssCallExpression({
  834. babel: babel,
  835. state: state,
  836. path: expressionPath,
  837. sourceMap: sourceMap
  838. });
  839. if (t.isCallExpression(expressionPath)) {
  840. if (!state.cssIdentifier) {
  841. state.cssIdentifier = addDefault(path, '@emotion/css', {
  842. nameHint: 'css'
  843. });
  844. }
  845. expressionPath.get('callee').replaceWith(t.cloneDeep(state.cssIdentifier));
  846. }
  847. }
  848. },
  849. CallExpression: {
  850. exit: function exit(path, state) {
  851. try {
  852. if (path.node.callee && path.node.callee.property && path.node.callee.property.name === 'withComponent') {
  853. switch (path.node.arguments.length) {
  854. case 1:
  855. case 2:
  856. {
  857. path.node.arguments[1] = getStyledOptions(t, path, state);
  858. }
  859. }
  860. }
  861. } catch (e) {
  862. throw path.buildCodeFrameError(e);
  863. }
  864. }
  865. }
  866. }
  867. };
  868. }
  869. export default index;
  870. export { macros };