1 | "use strict";
|
2 |
|
3 | exports.__esModule = true;
|
4 | exports.default = void 0;
|
5 |
|
6 | var _path = require("path");
|
7 |
|
8 | var _groupBy = _interopRequireDefault(require("lodash/groupBy"));
|
9 |
|
10 | var _uniq = _interopRequireDefault(require("lodash/uniq"));
|
11 |
|
12 | var _resolve = _interopRequireDefault(require("resolve"));
|
13 |
|
14 | var _cssUnits = _interopRequireDefault(require("./cssUnits"));
|
15 |
|
16 | var _getNameFromPath = _interopRequireDefault(require("./getNameFromPath"));
|
17 |
|
18 | var _murmurHash = _interopRequireDefault(require("./murmurHash"));
|
19 |
|
20 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
21 |
|
22 | const rComposes = /\b(?:composes\s*?:\s*([^;>]*?)(?:from\s(.+?))?(?=[;}/\n\r]))/gim;
|
23 | const rPlaceholder = /###ASTROTURF_PLACEHOLDER_\d*?###/g;
|
24 |
|
25 | const rUnit = new RegExp(`^(${_cssUnits.default.join('|')})(;|,|\n| |\\))`);
|
26 |
|
27 | function defaultResolveDependency({
|
28 | request
|
29 | }, localStyle) {
|
30 | const source = _resolve.default.sync(request, {
|
31 | basedir: (0, _path.dirname)(localStyle.absoluteFilePath)
|
32 | });
|
33 |
|
34 | return {
|
35 | source
|
36 | };
|
37 | }
|
38 |
|
39 | function resolveMemberExpression(path) {
|
40 | let nextPath = path.resolve();
|
41 |
|
42 | while (nextPath && nextPath.isMemberExpression()) {
|
43 | nextPath = nextPath.get('object').resolve();
|
44 | }
|
45 |
|
46 | return nextPath;
|
47 | }
|
48 |
|
49 | function resolveImport(path) {
|
50 | const resolvedPath = resolveMemberExpression(path);
|
51 | const binding = resolvedPath.scope.getBinding(resolvedPath.node.name);
|
52 | if (!binding || binding.kind !== 'module') return false;
|
53 | const importPath = binding.path;
|
54 | const parent = importPath.parentPath;
|
55 | if (!parent.isImportDeclaration()) return null;
|
56 | const request = parent.node.source.value;
|
57 | let identifier;
|
58 |
|
59 | if (importPath.isImportNamespaceSpecifier()) {
|
60 | if (!path.isMemberExpression()) throw new Error('this is weird');
|
61 | identifier = (0, _getNameFromPath.default)(path.get('property'));
|
62 | } else if (importPath.isImportDefaultSpecifier()) {
|
63 | identifier = (0, _getNameFromPath.default)(resolvedPath);
|
64 | } else if (importPath.isImportSpecifier()) {
|
65 |
|
66 | identifier = (0, _getNameFromPath.default)(importPath.get('imported'));
|
67 | }
|
68 |
|
69 | return {
|
70 | identifier,
|
71 | request,
|
72 | type: importPath.node.type
|
73 | };
|
74 | }
|
75 |
|
76 | function resolveStyleInterpolation(path, nodeMap, localStyle, resolveDependency = defaultResolveDependency) {
|
77 | const resolvedPath = resolveMemberExpression(path);
|
78 | const style = resolvedPath && nodeMap.get(resolvedPath.node);
|
79 |
|
80 | if (style) {
|
81 | return {
|
82 | imported: !style.isStyledComponent ? path.get('property').node.name : 'cls1',
|
83 | source: (0, _path.relative)((0, _path.dirname)(localStyle.absoluteFilePath), style.absoluteFilePath)
|
84 | };
|
85 | }
|
86 |
|
87 | if (resolveDependency) {
|
88 | const resolvedImport = resolveImport(path);
|
89 |
|
90 | if (resolvedImport) {
|
91 | const {
|
92 | identifier
|
93 | } = resolvedImport;
|
94 | const interpolation = resolveDependency(resolvedImport, localStyle, path.node) || null;
|
95 | const isStyledComponent = interpolation.isStyledComponent == null ? identifier.toLowerCase()[0] !== identifier[0] : interpolation.isStyledComponent;
|
96 | return interpolation && {
|
97 | imported: !isStyledComponent ? path.get('property').node.name : 'cls1',
|
98 | ...interpolation
|
99 | };
|
100 | }
|
101 | }
|
102 |
|
103 | return null;
|
104 | }
|
105 |
|
106 | const getPlaceholder = idx => `###ASTROTURF_PLACEHOLDER_${idx}###`;
|
107 |
|
108 | var _default = ({
|
109 | quasiPath,
|
110 | nodeMap,
|
111 | tagName,
|
112 | resolveDependency,
|
113 | useCssProperties,
|
114 | style: localStyle
|
115 | }) => {
|
116 | const quasi = quasiPath.node;
|
117 | const styleInterpolations = new Map();
|
118 | const dynamicInterpolations = new Set();
|
119 | const expressions = quasiPath.get('expressions');
|
120 | let text = '';
|
121 | let lastDynamic = null;
|
122 | quasi.quasis.forEach((tmplNode, idx) => {
|
123 | const {
|
124 | cooked
|
125 | } = tmplNode.value;
|
126 | const expr = expressions[idx];
|
127 | let matches;
|
128 |
|
129 |
|
130 |
|
131 | if (lastDynamic && text.endsWith(`var(--${lastDynamic.id})`) && (matches = cooked.match(rUnit))) {
|
132 | const [, unit] = matches;
|
133 | lastDynamic.unit = unit;
|
134 | text += cooked.replace(rUnit, '$2');
|
135 | } else {
|
136 | text += cooked;
|
137 | }
|
138 |
|
139 | if (!expr) {
|
140 | return;
|
141 | }
|
142 |
|
143 | const result = expr.evaluate();
|
144 |
|
145 | if (result.confident) {
|
146 | text += result.value;
|
147 | return;
|
148 | }
|
149 |
|
150 |
|
151 | const interpolation = resolveStyleInterpolation(expr, nodeMap, localStyle, resolveDependency);
|
152 |
|
153 | if (interpolation) {
|
154 | interpolation.expr = expr;
|
155 | const ph = getPlaceholder(idx);
|
156 | styleInterpolations.set(ph, interpolation);
|
157 | text += ph;
|
158 | return;
|
159 | }
|
160 |
|
161 | if (!useCssProperties) {
|
162 | throw expr.buildCodeFrameError(`Could not resolve interpolation to a value, ${tagName} returned class name, or styled component. ` + 'All interpolated styled components must be in the same file and values must be statically determinable at compile time.');
|
163 | }
|
164 |
|
165 |
|
166 | const id = `a${(0, _murmurHash.default)(`${localStyle.identifier}-${idx}`)}`;
|
167 | lastDynamic = {
|
168 | id,
|
169 | expr,
|
170 | unit: ''
|
171 | };
|
172 | dynamicInterpolations.add(lastDynamic);
|
173 | text += `var(--${id})`;
|
174 | });
|
175 |
|
176 | text = text.replace(rComposes, (composes, classNames, fromPart) => {
|
177 | const classList = classNames.replace(/(\n|\r|\n\r)/, '').split(/\s+/);
|
178 | const composed = classList.map(className => styleInterpolations.get(className)).filter(Boolean);
|
179 | if (!composed.length) return composes;
|
180 |
|
181 | if (fromPart) {
|
182 |
|
183 | throw classList[0].expr.buildCodeFrameError('A styled interpolation found inside a `composes` rule with a "from". ' + 'Interpolated values should be in their own `composes` without specifying the file.');
|
184 | }
|
185 |
|
186 | if (composed.length < classList.length) {
|
187 | throw classList[0].expr.buildCodeFrameError('Mixing interpolated and non-interpolated classes in a `composes` rule is not allowed.');
|
188 | }
|
189 |
|
190 | return Object.entries((0, _groupBy.default)(composed, i => i.source)).reduce((acc, [source, values]) => {
|
191 | const classes = (0, _uniq.default)(values.map(v => v.imported)).join(' ');
|
192 | return `${acc ? `${acc};\n` : ''}composes: ${classes} from "${source}"`;
|
193 | }, '');
|
194 | });
|
195 | let id = 0;
|
196 | let imports = '';
|
197 | text = text.replace(rPlaceholder, match => {
|
198 | const {
|
199 | imported,
|
200 | source
|
201 | } = styleInterpolations.get(match);
|
202 | const localName = `a${id++}`;
|
203 | imports += `@value ${imported} as ${localName} from "${source}";\n`;
|
204 | return `.${localName}`;
|
205 | });
|
206 | if (imports) imports += '\n\n';
|
207 | return {
|
208 | text,
|
209 | imports,
|
210 | dynamicInterpolations
|
211 | };
|
212 | };
|
213 |
|
214 | exports.default = _default; |
\ | No newline at end of file |