UNPKG

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