UNPKG

8.12 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports.processTaggedTemplateExpression = processTaggedTemplateExpression;
5exports["default"] = _default;
6exports.visitor = void 0;
7
8var t = _interopRequireWildcard(require("@babel/types"));
9
10var _constants = require("./_constants");
11
12var _utils = require("./_utils");
13
14function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
15
16function _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; }
17
18function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
19
20var isModuleExports = t.buildMatchMemberExpression('module.exports');
21
22function processTaggedTemplateExpression(_ref) {
23 var type = _ref.type,
24 path = _ref.path,
25 file = _ref.file,
26 splitRules = _ref.splitRules,
27 plugins = _ref.plugins,
28 vendorPrefixes = _ref.vendorPrefixes,
29 sourceMaps = _ref.sourceMaps;
30 var templateLiteral = path.get('quasi');
31 var scope; // Check whether there are undefined references or
32 // references to this.something (e.g. props or state).
33 // We allow dynamic styles only when resolving styles.
34
35 if (type !== 'resolve') {
36 (0, _utils.validateExternalExpressions)(templateLiteral);
37 } else if (!path.scope.path.isProgram()) {
38 scope = (0, _utils.getScope)(path);
39 }
40
41 var stylesInfo = (0, _utils.getJSXStyleInfo)(templateLiteral, scope);
42
43 var _computeClassNames = (0, _utils.computeClassNames)([stylesInfo]),
44 staticClassName = _computeClassNames.staticClassName,
45 className = _computeClassNames.className;
46
47 var styles = (0, _utils.processCss)(_extends({}, stylesInfo, {
48 staticClassName: staticClassName,
49 file: file,
50 isGlobal: type === 'global',
51 plugins: plugins,
52 vendorPrefixes: vendorPrefixes,
53 sourceMaps: sourceMaps
54 }), {
55 splitRules: splitRules
56 });
57
58 if (type === 'resolve') {
59 var hash = styles.hash,
60 _css = styles.css,
61 expressions = styles.expressions;
62 path.replaceWith( // {
63 // styles: <_JSXStyle ... />,
64 // className: 'jsx-123'
65 // }
66 t.objectExpression([t.objectProperty(t.identifier('styles'), (0, _utils.makeStyledJsxTag)(hash, _css, expressions)), t.objectProperty(t.identifier('className'), className)]));
67 return;
68 }
69
70 var id = path.parentPath.node.id;
71 var baseExportName = id ? id.name : 'default';
72 var parentPath = baseExportName === 'default' ? path.parentPath : path.findParent(function (path) {
73 return path.isVariableDeclaration() || path.isAssignmentExpression() && isModuleExports(path.get('left').node);
74 });
75
76 if (baseExportName !== 'default' && !parentPath.parentPath.isProgram()) {
77 parentPath = parentPath.parentPath;
78 }
79
80 var css = (0, _utils.cssToBabelType)(styles.css);
81 var newPath = t.isArrayExpression(css) ? css : t.newExpression(t.identifier('String'), [css]); // default exports
82
83 if (baseExportName === 'default') {
84 var defaultExportIdentifier = path.scope.generateUidIdentifier('defaultExport');
85 parentPath.insertBefore(t.variableDeclaration('const', [t.variableDeclarator(defaultExportIdentifier, newPath)]));
86 parentPath.insertBefore(addHash(defaultExportIdentifier, styles.hash));
87 path.replaceWith(defaultExportIdentifier);
88 return;
89 } // local and named exports
90
91
92 parentPath.insertAfter(addHash(t.identifier(baseExportName), styles.hash));
93 path.replaceWith(newPath);
94}
95
96function addHash(exportIdentifier, hash) {
97 var value = typeof hash === 'string' ? t.stringLiteral(hash) : hash;
98 return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(exportIdentifier, t.identifier('__hash')), value));
99}
100
101var visitor = {
102 ImportDeclaration: function ImportDeclaration(path, state) {
103 // import css from 'styled-jsx/css'
104 if (path.node.source.value !== 'styled-jsx/css') {
105 return;
106 } // Find all the imported specifiers.
107 // e.g import css, { global, resolve } from 'styled-jsx/css'
108 // -> ['css', 'global', 'resolve']
109
110
111 var specifiersNames = path.node.specifiers.map(function (specifier) {
112 return specifier.local.name;
113 });
114 specifiersNames.forEach(function (tagName) {
115 // Get all the reference paths i.e. the places that use the tagName above
116 // eg.
117 // css`div { color: red }`
118 // css.global`div { color: red }`
119 // global`div { color: red `
120 var binding = path.scope.getBinding(tagName);
121
122 if (!binding || !Array.isArray(binding.referencePaths)) {
123 return;
124 } // Produces an object containing all the TaggedTemplateExpression paths detected.
125 // The object contains { scoped, global, resolve }
126
127
128 var taggedTemplateExpressions = binding.referencePaths.map(function (ref) {
129 return ref.parentPath;
130 }).reduce(function (result, path) {
131 var taggedTemplateExpression;
132
133 if (path.isTaggedTemplateExpression()) {
134 // css`` global`` resolve``
135 taggedTemplateExpression = path;
136 } else if (path.parentPath && path.isMemberExpression() && path.parentPath.isTaggedTemplateExpression()) {
137 // This part is for css.global`` or css.resolve``
138 // using the default import css
139 taggedTemplateExpression = path.parentPath;
140 } else {
141 return result;
142 }
143
144 var tag = taggedTemplateExpression.get('tag');
145 var id = tag.isIdentifier() ? tag.node.name : tag.get('property').node.name;
146
147 if (result[id]) {
148 result[id].push(taggedTemplateExpression);
149 } else {
150 result.scoped.push(taggedTemplateExpression);
151 }
152
153 return result;
154 }, {
155 scoped: [],
156 global: [],
157 resolve: []
158 });
159 var hasJSXStyle = false;
160 var _state$opts = state.opts,
161 vendorPrefixes = _state$opts.vendorPrefixes,
162 sourceMaps = _state$opts.sourceMaps;
163 Object.keys(taggedTemplateExpressions).forEach(function (type) {
164 return taggedTemplateExpressions[type].forEach(function (path) {
165 hasJSXStyle = true; // Process each css block
166
167 processTaggedTemplateExpression({
168 type: type,
169 path: path,
170 file: state.file,
171 splitRules: typeof state.opts.optimizeForSpeed === 'boolean' ? state.opts.optimizeForSpeed : process.env.NODE_ENV === 'production',
172 plugins: state.plugins,
173 vendorPrefixes: vendorPrefixes,
174 sourceMaps: sourceMaps
175 });
176 });
177 }); // When using the `resolve` helper we need to add an import
178 // for the _JSXStyle component `styled-jsx/style`
179
180 if (hasJSXStyle && taggedTemplateExpressions.resolve.length > 0 && !state.hasInjectedJSXStyle && !path.scope.hasBinding(_constants.STYLE_COMPONENT)) {
181 state.hasInjectedJSXStyle = true;
182 (0, _utils.createReactComponentImportDeclaration)(state);
183 }
184 }); // Finally remove the import
185
186 path.remove();
187 }
188};
189exports.visitor = visitor;
190
191function _default() {
192 return _extends({
193 Program: function Program(path, state) {
194 (0, _utils.setStateOptions)(state);
195 }
196 }, visitor);
197}
\No newline at end of file