UNPKG

7.73 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports.default = void 0;
5
6var _chalk = _interopRequireDefault(require("chalk"));
7
8var _generator = _interopRequireDefault(require("@babel/generator"));
9
10var _helperModuleImports = require("@babel/helper-module-imports");
11
12var _template = _interopRequireDefault(require("@babel/template"));
13
14var t = _interopRequireWildcard(require("@babel/types"));
15
16var _buildTaggedTemplate = _interopRequireDefault(require("../utils/buildTaggedTemplate"));
17
18var _createStyleNode = _interopRequireDefault(require("../utils/createStyleNode"));
19
20var _getNameFromPath = _interopRequireDefault(require("../utils/getNameFromPath"));
21
22var _isCssTag = _interopRequireDefault(require("../utils/isCssTag"));
23
24var _Symbols = require("../utils/Symbols");
25
26var _toVarsArray = _interopRequireDefault(require("../utils/toVarsArray"));
27
28var _trimExpressions = _interopRequireDefault(require("../utils/trimExpressions"));
29
30var _wrapInClass = _interopRequireDefault(require("../utils/wrapInClass"));
31
32function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
33
34function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
35
36function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
37
38const JSX_IDENTS = Symbol('Astroturf jsx identifiers');
39const buildImport = (0, _template.default)('require(FILENAME);');
40
41const isCreateElementCall = p => p.isCallExpression() && p.get('callee.property').node && p.get('callee.property').node.name === 'createElement';
42
43function buildCssProp(valuePath, name, options) {
44 const {
45 file,
46 pluginOptions,
47 isJsx
48 } = options;
49 const cssState = file.get(_Symbols.STYLES);
50 const nodeMap = file.get(_Symbols.COMPONENTS);
51
52 if (!pluginOptions.enableCssProp) {
53 if (!pluginOptions.noWarnings) // eslint-disable-next-line no-console
54 console.warn(_chalk.default.yellow('It looks like you are trying to use the css prop with', _chalk.default.bold('astroturf'), 'but have not enabled it. add', _chalk.default.bold('enableCssProp: true'), 'to the loader or plugin options to compile the css prop.'));
55 return null;
56 }
57
58 const displayName = `CssProp${++cssState.id}_${name}`;
59 let vars;
60 const style = (0, _createStyleNode.default)(valuePath, displayName, {
61 file,
62 pluginOptions
63 });
64
65 if (valuePath.isStringLiteral()) {
66 style.value = (0, _wrapInClass.default)(valuePath.node.value);
67 } else {
68 const exprPath = valuePath.isJSXExpressionContainer() ? valuePath.get('expression') : valuePath;
69
70 if (exprPath.isTemplateLiteral() || exprPath.isTaggedTemplateExpression() && (0, _isCssTag.default)(exprPath.get('tag'), pluginOptions)) {
71 const {
72 text,
73 imports,
74 dynamicInterpolations
75 } = (0, _buildTaggedTemplate.default)({
76 style,
77 nodeMap,
78 ...pluginOptions,
79 quasiPath: exprPath.isTemplateLiteral() ? exprPath : exprPath.get('quasi'),
80 useCssProperties: !!pluginOptions.customCssProperties
81 });
82 vars = (0, _toVarsArray.default)(dynamicInterpolations);
83 style.imports = imports;
84 style.interpolations = (0, _trimExpressions.default)(dynamicInterpolations);
85 style.value = imports + (0, _wrapInClass.default)(text);
86 }
87 }
88
89 if (style.value == null) {
90 return null;
91 }
92
93 let runtimeNode = t.arrayExpression([buildImport({
94 FILENAME: t.StringLiteral(style.relativeFilePath)
95 }).expression, vars].filter(Boolean));
96 nodeMap.set(runtimeNode.expression, style);
97
98 if (isJsx) {
99 runtimeNode = t.jsxExpressionContainer(runtimeNode);
100 }
101
102 cssState.styles.set(style.absoluteFilePath, style);
103 if (pluginOptions.generateInterpolations) style.code = (0, _generator.default)(runtimeNode).code;
104 return runtimeNode;
105}
106
107const cssPropertyVisitors = {
108 ObjectProperty(path, state) {
109 const {
110 file,
111 pluginOptions,
112 typeName
113 } = state;
114 if (path.get('key').node.name !== 'css') return;
115 const valuePath = path.get('value');
116 const compiledNode = buildCssProp(valuePath, typeName, {
117 file,
118 pluginOptions
119 });
120
121 if (compiledNode) {
122 valuePath.replaceWith(compiledNode);
123 state.processed = true;
124 }
125 }
126
127};
128var _default = {
129 Program: {
130 enter(path, state) {
131 // We need to re-export Fragment because of
132 // https://github.com/babel/babel/pull/7996#issuecomment-519653431
133 state[JSX_IDENTS] = {
134 jsx: path.scope.generateUidIdentifier('j'),
135 jsxFrag: path.scope.generateUidIdentifier('f')
136 };
137 },
138
139 exit(path, state) {
140 if (!state.file.get(_Symbols.HAS_CSS_PROP)) return;
141 const {
142 jsx,
143 jsxFrag
144 } = state[JSX_IDENTS];
145 const jsxPrgama = `* @jsx ${jsx.name} *`;
146 const jsxFragPrgama = `* @jsxFrag ${jsxFrag.name} *`;
147 path.addComment('leading', jsxPrgama);
148 path.addComment('leading', jsxFragPrgama);
149 (0, _helperModuleImports.addNamed)(path, 'jsx', 'astroturf', {
150 nameHint: jsx.name
151 });
152 (0, _helperModuleImports.addNamed)(path, 'F', 'astroturf', {
153 nameHint: jsxFrag.name
154 });
155 state.file.get(_Symbols.STYLES).changeset.unshift({
156 code: `/*${jsxPrgama}*/\n`
157 }, {
158 code: `/*${jsxFragPrgama}*/\n\n`
159 }, {
160 code: `const { jsx: ${jsx.name}, F: ${jsxFrag.name} } = require('astroturf');\n`
161 });
162 }
163
164 },
165
166 CallExpression(path, state) {
167 const {
168 file
169 } = state;
170 const pluginOptions = state.defaultedOptions;
171 if (!isCreateElementCall(path)) return;
172 const typeName = (0, _getNameFromPath.default)(path.get('arguments')[0]);
173 const propsPath = path.get('arguments')[1];
174 const innerState = {
175 pluginOptions,
176 file,
177 processed: false,
178 typeName
179 }; // We aren't checking very hard that this is a React createElement call
180
181 if (propsPath) {
182 propsPath.traverse(cssPropertyVisitors, innerState);
183 }
184
185 if (innerState.processed) {
186 const {
187 jsx
188 } = state[JSX_IDENTS];
189 const {
190 changeset
191 } = file.get(_Symbols.STYLES);
192 const callee = path.get('callee');
193 changeset.push({
194 code: jsx.name,
195 start: callee.node.start,
196 end: callee.node.end
197 });
198 callee.replaceWith(jsx);
199 file.set(_Symbols.HAS_CSS_PROP, true);
200 }
201 },
202
203 JSXAttribute(path, state) {
204 const {
205 file
206 } = state;
207 const pluginOptions = state.defaultedOptions;
208 if (path.node.name.name !== 'css') return;
209 const valuePath = path.get('value');
210 const parentPath = path.findParent(p => p.isJSXOpeningElement());
211 const compiledNode = buildCssProp(valuePath, parentPath && (0, _getNameFromPath.default)(parentPath.get('name')), {
212 file,
213 pluginOptions,
214 isJsx: true
215 });
216
217 if (compiledNode) {
218 valuePath.replaceWith(compiledNode);
219 file.set(_Symbols.HAS_CSS_PROP, true);
220 }
221 }
222
223};
224exports.default = _default;
\No newline at end of file