UNPKG

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