@plumeria/compiler 19.3.0 → 19.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser.js +1 -0
- package/index.d.ts +90 -0
- package/index.js +602 -0
- package/package.json +47 -13
- package/dist/index.d.ts +0 -9
- package/dist/index.js +0 -1148
package/dist/index.js
DELETED
|
@@ -1,1148 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.compileCSS = compileCSS;
|
|
37
|
-
const core_1 = require("@swc/core");
|
|
38
|
-
const zss_engine_1 = require("zss-engine");
|
|
39
|
-
const fs = __importStar(require("fs"));
|
|
40
|
-
const path = __importStar(require("path"));
|
|
41
|
-
const rs = __importStar(require("@rust-gear/glob"));
|
|
42
|
-
const utils_1 = require("@plumeria/utils");
|
|
43
|
-
const utils_2 = require("@plumeria/utils");
|
|
44
|
-
const unwrapExport = (node) => {
|
|
45
|
-
if (node?.type === 'ExportDeclaration')
|
|
46
|
-
return node.declaration;
|
|
47
|
-
if (node?.type === 'ExportDefaultDeclaration')
|
|
48
|
-
return node.decl;
|
|
49
|
-
if (node?.type === 'ExportDefaultExpression')
|
|
50
|
-
return node.expression;
|
|
51
|
-
return node;
|
|
52
|
-
};
|
|
53
|
-
const isFunctionNode = (node) => node?.type === 'FunctionDeclaration' ||
|
|
54
|
-
node?.type === 'FunctionExpression' ||
|
|
55
|
-
node?.type === 'ArrowFunctionExpression';
|
|
56
|
-
const componentFunctionOf = (node) => {
|
|
57
|
-
if (isFunctionNode(node))
|
|
58
|
-
return node;
|
|
59
|
-
if (node?.type === 'CallExpression') {
|
|
60
|
-
for (const arg of node.arguments ?? []) {
|
|
61
|
-
const fn = componentFunctionOf(arg.expression);
|
|
62
|
-
if (fn)
|
|
63
|
-
return fn;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return undefined;
|
|
67
|
-
};
|
|
68
|
-
const unwrapPatternDefault = (pattern) => pattern?.type === 'AssignmentPattern' ? pattern.left : pattern;
|
|
69
|
-
const resolveLocalStyleAlias = (aliases, expression) => {
|
|
70
|
-
let current = expression;
|
|
71
|
-
const seen = new Set();
|
|
72
|
-
while (utils_1.t.isIdentifier(current)) {
|
|
73
|
-
const name = current.value;
|
|
74
|
-
if (seen.has(name))
|
|
75
|
-
break;
|
|
76
|
-
seen.add(name);
|
|
77
|
-
const candidates = aliases[name];
|
|
78
|
-
if (!candidates || candidates.length === 0)
|
|
79
|
-
break;
|
|
80
|
-
const candidate = candidates.find((candidate) => candidate.context === current.ctxt);
|
|
81
|
-
if (!candidate)
|
|
82
|
-
break;
|
|
83
|
-
current = candidate.expression;
|
|
84
|
-
}
|
|
85
|
-
return current;
|
|
86
|
-
};
|
|
87
|
-
const destructuredPropAliases = (fn) => {
|
|
88
|
-
const aliases = new Map();
|
|
89
|
-
const first = fn.params[0];
|
|
90
|
-
const pattern = unwrapPatternDefault(first?.pat ?? first);
|
|
91
|
-
if (pattern?.type !== 'ObjectPattern')
|
|
92
|
-
return aliases;
|
|
93
|
-
for (const item of pattern.properties ?? []) {
|
|
94
|
-
if (item.type !== 'KeyValuePatternProperty')
|
|
95
|
-
continue;
|
|
96
|
-
const local = unwrapPatternDefault(item.value);
|
|
97
|
-
const key = item.key;
|
|
98
|
-
if (!utils_1.t.isIdentifier(local))
|
|
99
|
-
continue;
|
|
100
|
-
if (!utils_1.t.isIdentifier(key) && !utils_1.t.isStringLiteral(key))
|
|
101
|
-
continue;
|
|
102
|
-
const name = String(key.value);
|
|
103
|
-
if (name !== local.value)
|
|
104
|
-
aliases.set(local.value, name);
|
|
105
|
-
}
|
|
106
|
-
return aliases;
|
|
107
|
-
};
|
|
108
|
-
const sourceOf = (node, sourceBuffer, baseByteOffset) => sourceBuffer
|
|
109
|
-
.subarray(node.span.start - baseByteOffset, node.span.end - baseByteOffset)
|
|
110
|
-
.toString('utf-8');
|
|
111
|
-
const isNoOpStyle = (node) => utils_1.t.isNullLiteral(node) ||
|
|
112
|
-
(utils_1.t.isBooleanLiteral(node) && node.value === false) ||
|
|
113
|
-
(utils_1.t.isIdentifier(node) && node.value === 'undefined');
|
|
114
|
-
const propDefaultError = (source, fileName) => new Error(`[plumeria] A style prop default must be a defined style: "${source}". ` +
|
|
115
|
-
`Apply a conditional or dynamic style where the element is styled. (${fileName})`);
|
|
116
|
-
const spreadStyleError = (source, fileName) => new Error(`[plumeria] Spread elements in a style array are not supported: "...${source}". ` +
|
|
117
|
-
`List each style explicitly. (${fileName})`);
|
|
118
|
-
const isStaticArgValue = (node) => node.type === 'StringLiteral' ||
|
|
119
|
-
node.type === 'NumericLiteral' ||
|
|
120
|
-
node.type === 'BooleanLiteral' ||
|
|
121
|
-
(node.type === 'TemplateLiteral' && node.expressions.length === 0) ||
|
|
122
|
-
utils_1.t.isIdentifier(node) ||
|
|
123
|
-
utils_1.t.isMemberExpression(node);
|
|
124
|
-
const dynamicTablesOf = (ctx) => ({
|
|
125
|
-
keyframesHashTable: ctx.mergedKeyframesTable,
|
|
126
|
-
viewTransitionHashTable: ctx.mergedViewTransitionTable,
|
|
127
|
-
createThemeHashTable: ctx.mergedCreateThemeHashTable,
|
|
128
|
-
createThemeObjectTable: ctx.scannedTables.createThemeObjectTable,
|
|
129
|
-
createHashTable: ctx.mergedCreateTable,
|
|
130
|
-
createStaticHashTable: ctx.mergedCreateStaticHashTable,
|
|
131
|
-
createStaticObjectTable: ctx.scannedTables.createStaticObjectTable,
|
|
132
|
-
});
|
|
133
|
-
function extractStylesFromExpression(expression, ctx) {
|
|
134
|
-
let expr = expression;
|
|
135
|
-
expr = (0, utils_1.unwrapExpression)(expr);
|
|
136
|
-
if (ctx.localStyleAliases) {
|
|
137
|
-
expr = resolveLocalStyleAlias(ctx.localStyleAliases, expr);
|
|
138
|
-
}
|
|
139
|
-
const results = [];
|
|
140
|
-
if (utils_1.t.isMemberExpression(expr)) {
|
|
141
|
-
const memberExpr = expr;
|
|
142
|
-
if (utils_1.t.isIdentifier(memberExpr.object)) {
|
|
143
|
-
const variableName = memberExpr.object.value;
|
|
144
|
-
if (utils_1.t.isIdentifier(memberExpr.property)) {
|
|
145
|
-
const propertyName = memberExpr.property.value;
|
|
146
|
-
const styleSet = ctx.localCreateStyles[variableName];
|
|
147
|
-
if (styleSet && styleSet.obj[propertyName]) {
|
|
148
|
-
results.push(styleSet.obj[propertyName]);
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
const hash = ctx.mergedCreateTable[variableName];
|
|
152
|
-
if (hash) {
|
|
153
|
-
const object = ctx.scannedTables.createObjectTable[hash];
|
|
154
|
-
if (object && object[propertyName]) {
|
|
155
|
-
results.push(object[propertyName]);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
else if (memberExpr.property.type === 'Computed') {
|
|
161
|
-
const computedProp = memberExpr.property;
|
|
162
|
-
const innerExpr = computedProp.expression;
|
|
163
|
-
let styleObj;
|
|
164
|
-
const styleSet = ctx.localCreateStyles[variableName];
|
|
165
|
-
if (styleSet) {
|
|
166
|
-
styleObj = styleSet.obj;
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
const hash = ctx.mergedCreateTable[variableName];
|
|
170
|
-
if (hash) {
|
|
171
|
-
styleObj = ctx.scannedTables.createObjectTable[hash];
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (styleObj) {
|
|
175
|
-
if (utils_1.t.isStringLiteral(innerExpr)) {
|
|
176
|
-
const key = innerExpr.value;
|
|
177
|
-
if (styleObj[key]) {
|
|
178
|
-
results.push(styleObj[key]);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
Object.values(styleObj).forEach((style) => {
|
|
183
|
-
if (style && typeof style === 'object') {
|
|
184
|
-
results.push(style);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
else if (utils_1.t.isIdentifier(expr)) {
|
|
193
|
-
const identifier = expr;
|
|
194
|
-
const object = ctx.localCreateStyles[identifier.value];
|
|
195
|
-
if (object)
|
|
196
|
-
results.push(object.obj);
|
|
197
|
-
else {
|
|
198
|
-
const hash = ctx.mergedCreateTable[identifier.value];
|
|
199
|
-
if (hash) {
|
|
200
|
-
const objectFromTable = ctx.scannedTables.createObjectTable[hash];
|
|
201
|
-
if (objectFromTable)
|
|
202
|
-
results.push(objectFromTable);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
else if (expr.type === 'ArrayExpression') {
|
|
207
|
-
const spreads = [];
|
|
208
|
-
const elementStyles = [];
|
|
209
|
-
for (const element of expr.elements ?? []) {
|
|
210
|
-
if (!element)
|
|
211
|
-
continue;
|
|
212
|
-
if (element.spread) {
|
|
213
|
-
spreads.push(element.expression);
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
elementStyles.push(...extractStylesFromExpression(element.expression, ctx));
|
|
217
|
-
}
|
|
218
|
-
for (const spread of spreads) {
|
|
219
|
-
if (elementStyles.length > 0 ||
|
|
220
|
-
extractStylesFromExpression(spread, ctx).length > 0)
|
|
221
|
-
throw spreadStyleError(sourceOf(spread, ctx.sourceBuffer, ctx.baseByteOffset), path.basename(ctx.resourcePath));
|
|
222
|
-
}
|
|
223
|
-
results.push(...elementStyles);
|
|
224
|
-
}
|
|
225
|
-
else if (utils_1.t.isConditionalExpression(expr)) {
|
|
226
|
-
const condExpr = expr;
|
|
227
|
-
results.push(...extractStylesFromExpression(condExpr.consequent, ctx));
|
|
228
|
-
results.push(...extractStylesFromExpression(condExpr.alternate, ctx));
|
|
229
|
-
}
|
|
230
|
-
else if (utils_1.t.isBinaryExpression(expr) &&
|
|
231
|
-
['&&', '||', '??'].includes(expr.operator)) {
|
|
232
|
-
const binaryExpr = expr;
|
|
233
|
-
results.push(...extractStylesFromExpression(binaryExpr.left, ctx));
|
|
234
|
-
results.push(...extractStylesFromExpression(binaryExpr.right, ctx));
|
|
235
|
-
}
|
|
236
|
-
return results;
|
|
237
|
-
}
|
|
238
|
-
function compileCSS(options) {
|
|
239
|
-
const { include, exclude, cwd = process.cwd(), styleProp = utils_1.DEFAULT_STYLE_PROP, } = options;
|
|
240
|
-
const propertyPolicy = (0, utils_1.resolvePropertyPolicy)(options);
|
|
241
|
-
const allSheets = new Set();
|
|
242
|
-
const files = rs.globSync(include, {
|
|
243
|
-
cwd,
|
|
244
|
-
exclude: exclude,
|
|
245
|
-
sort: true,
|
|
246
|
-
});
|
|
247
|
-
const scannedTables = (0, utils_1.scanOverlay)(cwd, styleProp);
|
|
248
|
-
const processFile = (filePath) => {
|
|
249
|
-
const resourcePath = path.resolve(cwd, filePath);
|
|
250
|
-
const source = fs.readFileSync(resourcePath, 'utf-8');
|
|
251
|
-
const extractedSheets = [];
|
|
252
|
-
const ast = (0, core_1.parseSync)(source, {
|
|
253
|
-
syntax: 'typescript',
|
|
254
|
-
tsx: true,
|
|
255
|
-
target: 'es2022',
|
|
256
|
-
});
|
|
257
|
-
(0, utils_1.assertPropertyPolicy)(ast, propertyPolicy, resourcePath);
|
|
258
|
-
const leadingLen = (0, utils_2.getLeadingCommentLength)(source);
|
|
259
|
-
const sourceBuffer = Buffer.from(source, 'utf-8');
|
|
260
|
-
const leadingBytes = Buffer.byteLength(source.slice(0, leadingLen), 'utf-8');
|
|
261
|
-
const baseByteOffset = ast.span.start - leadingBytes;
|
|
262
|
-
const localConsts = (0, utils_1.collectLocalConsts)(ast);
|
|
263
|
-
const importMap = {};
|
|
264
|
-
const keyframesImportMap = {};
|
|
265
|
-
const viewTransitionImportMap = {};
|
|
266
|
-
const createImportMap = {};
|
|
267
|
-
const createFunctionImportMap = {};
|
|
268
|
-
const createThemeImportMap = {};
|
|
269
|
-
const createStaticImportMap = {};
|
|
270
|
-
const plumeriaAliases = {};
|
|
271
|
-
const localImports = {};
|
|
272
|
-
const localStyleAliases = {};
|
|
273
|
-
const registeredStyleCalls = new Set();
|
|
274
|
-
(0, utils_1.traverse)(ast, {
|
|
275
|
-
ImportDeclaration({ node }) {
|
|
276
|
-
const sourcePath = node.source.value;
|
|
277
|
-
if (sourcePath === '@plumeria/core') {
|
|
278
|
-
node.specifiers.forEach((specifier) => {
|
|
279
|
-
if (specifier.type === 'ImportNamespaceSpecifier') {
|
|
280
|
-
plumeriaAliases[specifier.local.value] = 'NAMESPACE';
|
|
281
|
-
}
|
|
282
|
-
else if (specifier.type === 'ImportDefaultSpecifier') {
|
|
283
|
-
plumeriaAliases[specifier.local.value] = 'NAMESPACE';
|
|
284
|
-
}
|
|
285
|
-
else if (specifier.type === 'ImportSpecifier') {
|
|
286
|
-
const importedName = specifier.imported
|
|
287
|
-
? specifier.imported.value
|
|
288
|
-
: specifier.local.value;
|
|
289
|
-
plumeriaAliases[specifier.local.value] = importedName;
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
const actualPath = (0, utils_1.resolveImportPath)(sourcePath, resourcePath);
|
|
294
|
-
if (actualPath) {
|
|
295
|
-
node.specifiers.forEach((specifier) => {
|
|
296
|
-
if (specifier.type === 'ImportNamespaceSpecifier') {
|
|
297
|
-
localImports[specifier.local.value] = {
|
|
298
|
-
actualPath,
|
|
299
|
-
importedName: '*',
|
|
300
|
-
};
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
if (specifier.type === 'ImportSpecifier' ||
|
|
304
|
-
specifier.type === 'ImportDefaultSpecifier') {
|
|
305
|
-
const importedName = specifier.type === 'ImportDefaultSpecifier'
|
|
306
|
-
? 'default'
|
|
307
|
-
: specifier.imported
|
|
308
|
-
? specifier.imported.value
|
|
309
|
-
: specifier.local.value;
|
|
310
|
-
const localName = specifier.local.value;
|
|
311
|
-
let resolvedKey = `${actualPath}-${importedName}`;
|
|
312
|
-
const resolved = (0, utils_1.resolveExport)(actualPath, importedName);
|
|
313
|
-
if (resolved) {
|
|
314
|
-
resolvedKey = `${resolved.filePath}-${resolved.localName}`;
|
|
315
|
-
}
|
|
316
|
-
const uniqueKey = resolvedKey;
|
|
317
|
-
localImports[localName] = { actualPath, importedName };
|
|
318
|
-
if (scannedTables.staticTable[uniqueKey])
|
|
319
|
-
importMap[localName] = scannedTables.staticTable[uniqueKey];
|
|
320
|
-
if (scannedTables.keyframesHashTable[uniqueKey])
|
|
321
|
-
keyframesImportMap[localName] =
|
|
322
|
-
scannedTables.keyframesHashTable[uniqueKey];
|
|
323
|
-
if (scannedTables.viewTransitionHashTable[uniqueKey])
|
|
324
|
-
viewTransitionImportMap[localName] =
|
|
325
|
-
scannedTables.viewTransitionHashTable[uniqueKey];
|
|
326
|
-
if (scannedTables.createHashTable[uniqueKey])
|
|
327
|
-
createImportMap[localName] =
|
|
328
|
-
scannedTables.createHashTable[uniqueKey];
|
|
329
|
-
if (scannedTables.createFunctionTable[uniqueKey])
|
|
330
|
-
createFunctionImportMap[localName] = (0, utils_1.styleFunctionsOf)(scannedTables.createFunctionTable[uniqueKey]);
|
|
331
|
-
if (scannedTables.createThemeHashTable[uniqueKey])
|
|
332
|
-
createThemeImportMap[localName] =
|
|
333
|
-
scannedTables.createThemeHashTable[uniqueKey];
|
|
334
|
-
if (scannedTables.createStaticHashTable[uniqueKey])
|
|
335
|
-
createStaticImportMap[localName] =
|
|
336
|
-
scannedTables.createStaticHashTable[uniqueKey];
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
},
|
|
341
|
-
});
|
|
342
|
-
const mergedStaticTable = Object.create(scannedTables.staticTable);
|
|
343
|
-
for (const key of Object.keys(localConsts)) {
|
|
344
|
-
mergedStaticTable[key] = localConsts[key];
|
|
345
|
-
}
|
|
346
|
-
for (const key of Object.keys(importMap)) {
|
|
347
|
-
mergedStaticTable[key] = importMap[key];
|
|
348
|
-
}
|
|
349
|
-
const mergedKeyframesTable = Object.create(scannedTables.keyframesHashTable);
|
|
350
|
-
for (const key of (0, utils_1.fileTableKeys)(resourcePath, 'keyframesHashTable') ?? []) {
|
|
351
|
-
mergedKeyframesTable[key.slice(resourcePath.length + 1)] =
|
|
352
|
-
scannedTables.keyframesHashTable[key];
|
|
353
|
-
}
|
|
354
|
-
for (const key of Object.keys(keyframesImportMap)) {
|
|
355
|
-
mergedKeyframesTable[key] = keyframesImportMap[key];
|
|
356
|
-
}
|
|
357
|
-
const mergedViewTransitionTable = Object.create(scannedTables.viewTransitionHashTable);
|
|
358
|
-
for (const key of (0, utils_1.fileTableKeys)(resourcePath, 'viewTransitionHashTable') ??
|
|
359
|
-
[]) {
|
|
360
|
-
mergedViewTransitionTable[key.slice(resourcePath.length + 1)] =
|
|
361
|
-
scannedTables.viewTransitionHashTable[key];
|
|
362
|
-
}
|
|
363
|
-
for (const key of Object.keys(viewTransitionImportMap)) {
|
|
364
|
-
mergedViewTransitionTable[key] = viewTransitionImportMap[key];
|
|
365
|
-
}
|
|
366
|
-
const mergedCreateThemeHashTable = Object.create(scannedTables.createThemeHashTable);
|
|
367
|
-
for (const key of (0, utils_1.fileTableKeys)(resourcePath, 'createThemeHashTable') ??
|
|
368
|
-
[]) {
|
|
369
|
-
mergedCreateThemeHashTable[key.slice(resourcePath.length + 1)] =
|
|
370
|
-
scannedTables.createThemeHashTable[key];
|
|
371
|
-
}
|
|
372
|
-
for (const key of Object.keys(createThemeImportMap)) {
|
|
373
|
-
mergedCreateThemeHashTable[key] = createThemeImportMap[key];
|
|
374
|
-
}
|
|
375
|
-
const mergedCreateStaticHashTable = Object.create(scannedTables.createStaticHashTable);
|
|
376
|
-
for (const key of (0, utils_1.fileTableKeys)(resourcePath, 'createStaticHashTable') ??
|
|
377
|
-
[]) {
|
|
378
|
-
mergedCreateStaticHashTable[key.slice(resourcePath.length + 1)] =
|
|
379
|
-
scannedTables.createStaticHashTable[key];
|
|
380
|
-
}
|
|
381
|
-
for (const key of Object.keys(createStaticImportMap)) {
|
|
382
|
-
mergedCreateStaticHashTable[key] = createStaticImportMap[key];
|
|
383
|
-
}
|
|
384
|
-
const mergedCreateTable = Object.create(scannedTables.createHashTable);
|
|
385
|
-
for (const key of (0, utils_1.fileTableKeys)(resourcePath, 'createHashTable') ?? []) {
|
|
386
|
-
mergedCreateTable[key.slice(resourcePath.length + 1)] =
|
|
387
|
-
scannedTables.createHashTable[key];
|
|
388
|
-
}
|
|
389
|
-
for (const key of Object.keys(createImportMap)) {
|
|
390
|
-
mergedCreateTable[key] = createImportMap[key];
|
|
391
|
-
}
|
|
392
|
-
const ctx = {
|
|
393
|
-
resourcePath,
|
|
394
|
-
mergedStaticTable,
|
|
395
|
-
mergedKeyframesTable,
|
|
396
|
-
mergedViewTransitionTable,
|
|
397
|
-
mergedCreateThemeHashTable,
|
|
398
|
-
mergedCreateStaticHashTable,
|
|
399
|
-
mergedCreateTable,
|
|
400
|
-
scannedTables,
|
|
401
|
-
createFunctionImportMap,
|
|
402
|
-
localCreateStyles: {},
|
|
403
|
-
sourceBuffer,
|
|
404
|
-
baseByteOffset,
|
|
405
|
-
localStyleAliases,
|
|
406
|
-
};
|
|
407
|
-
const componentParamNames = new Set();
|
|
408
|
-
const addFirstParamName = (fn) => {
|
|
409
|
-
const first = fn.params[0];
|
|
410
|
-
const p = unwrapPatternDefault(first?.pat ?? first);
|
|
411
|
-
if (utils_1.t.isIdentifier(p)) {
|
|
412
|
-
componentParamNames.add(p.value);
|
|
413
|
-
}
|
|
414
|
-
else if (p?.type === 'ObjectPattern') {
|
|
415
|
-
for (const item of p.properties ?? []) {
|
|
416
|
-
if (item.type === 'RestElement' && utils_1.t.isIdentifier(item.argument)) {
|
|
417
|
-
componentParamNames.add(item.argument.value);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
for (const node of ast.body) {
|
|
423
|
-
const statement = unwrapExport(node);
|
|
424
|
-
if (isFunctionNode(statement)) {
|
|
425
|
-
addFirstParamName(statement);
|
|
426
|
-
}
|
|
427
|
-
else if (statement?.type === 'CallExpression') {
|
|
428
|
-
const fn = componentFunctionOf(statement);
|
|
429
|
-
if (fn)
|
|
430
|
-
addFirstParamName(fn);
|
|
431
|
-
}
|
|
432
|
-
else if (utils_1.t.isVariableDeclaration(statement)) {
|
|
433
|
-
for (const decl of statement.declarations) {
|
|
434
|
-
if (!utils_1.t.isIdentifier(decl.id) || !decl.init)
|
|
435
|
-
continue;
|
|
436
|
-
const fn = componentFunctionOf(decl.init);
|
|
437
|
-
if (fn)
|
|
438
|
-
addFirstParamName(fn);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
const components = [];
|
|
443
|
-
const propAliases = new Map();
|
|
444
|
-
const propDefaults = new Map();
|
|
445
|
-
const declaredProps = new Map();
|
|
446
|
-
const addComponent = (name, fn) => {
|
|
447
|
-
components.push({ name, node: fn });
|
|
448
|
-
const first = fn.params[0];
|
|
449
|
-
const pattern = unwrapPatternDefault(first?.pat ?? first);
|
|
450
|
-
const defaults = new Map();
|
|
451
|
-
for (const item of pattern?.properties ?? []) {
|
|
452
|
-
if (item.type === 'AssignmentPatternProperty' && item.value)
|
|
453
|
-
defaults.set(item.key.value, item.value);
|
|
454
|
-
if (item.type === 'KeyValuePatternProperty' &&
|
|
455
|
-
item.value?.type === 'AssignmentPattern')
|
|
456
|
-
defaults.set(item.key.value, item.value.right);
|
|
457
|
-
}
|
|
458
|
-
propDefaults.set(name, defaults);
|
|
459
|
-
const aliases = destructuredPropAliases(fn);
|
|
460
|
-
if (aliases.size > 0)
|
|
461
|
-
propAliases.set(name, aliases);
|
|
462
|
-
const declared = new Set();
|
|
463
|
-
for (const item of pattern?.properties ?? []) {
|
|
464
|
-
const key = item.key;
|
|
465
|
-
if (utils_1.t.isIdentifier(key) || utils_1.t.isStringLiteral(key))
|
|
466
|
-
declared.add(String(key.value));
|
|
467
|
-
}
|
|
468
|
-
if (declared.size > 0)
|
|
469
|
-
declaredProps.set(name, declared);
|
|
470
|
-
};
|
|
471
|
-
for (const node of ast.body) {
|
|
472
|
-
const statement = unwrapExport(node);
|
|
473
|
-
if (isFunctionNode(statement)) {
|
|
474
|
-
addComponent(statement.identifier?.value ?? 'default', statement);
|
|
475
|
-
}
|
|
476
|
-
else if (statement?.type === 'CallExpression') {
|
|
477
|
-
const fn = componentFunctionOf(statement);
|
|
478
|
-
if (fn)
|
|
479
|
-
addComponent('default', fn);
|
|
480
|
-
}
|
|
481
|
-
else if (utils_1.t.isVariableDeclaration(statement)) {
|
|
482
|
-
for (const decl of statement.declarations) {
|
|
483
|
-
if (!utils_1.t.isIdentifier(decl.id))
|
|
484
|
-
continue;
|
|
485
|
-
const fn = componentFunctionOf(decl.init);
|
|
486
|
-
if (fn)
|
|
487
|
-
addComponent(decl.id.value, fn);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
const ownerComponentOf = (at) => components.find((c) => at.span.start >= c.node.span.start &&
|
|
492
|
-
at.span.start <= c.node.span.end)?.name;
|
|
493
|
-
const processStyle = (style) => {
|
|
494
|
-
(0, utils_1.extractOndemandStyles)(style, (0, utils_1.appendSheet)(extractedSheets), scannedTables);
|
|
495
|
-
const records = (0, utils_1.getStyleRecords)(style);
|
|
496
|
-
records.forEach((r) => extractedSheets.push(r.sheet));
|
|
497
|
-
};
|
|
498
|
-
const extractAndProcessConditionals = (args, isStyleProp) => {
|
|
499
|
-
args.forEach((arg) => {
|
|
500
|
-
arg.expression = resolveLocalStyleAlias(localStyleAliases, arg.expression);
|
|
501
|
-
});
|
|
502
|
-
const conditionals = [];
|
|
503
|
-
let baseStyle = {};
|
|
504
|
-
const resolveStyleObject = (expr) => {
|
|
505
|
-
expr = resolveLocalStyleAlias(localStyleAliases, (0, utils_1.unwrapExpression)(expr));
|
|
506
|
-
if (expr.type === 'ArrayExpression') {
|
|
507
|
-
let merged = {};
|
|
508
|
-
for (const element of expr.elements ?? []) {
|
|
509
|
-
if (!element)
|
|
510
|
-
continue;
|
|
511
|
-
if (element.spread)
|
|
512
|
-
throw spreadStyleError(getSource(element.expression), path.basename(resourcePath));
|
|
513
|
-
const style = resolveStyleObject(element.expression);
|
|
514
|
-
if (!style)
|
|
515
|
-
return null;
|
|
516
|
-
merged = (0, utils_1.deepMerge)(merged, style);
|
|
517
|
-
}
|
|
518
|
-
return merged;
|
|
519
|
-
}
|
|
520
|
-
if (utils_1.t.isObjectExpression(expr)) {
|
|
521
|
-
return (0, utils_1.objectExpressionToObject)(expr, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
522
|
-
}
|
|
523
|
-
else if (utils_1.t.isMemberExpression(expr) &&
|
|
524
|
-
utils_1.t.isIdentifier(expr.object) &&
|
|
525
|
-
(utils_1.t.isIdentifier(expr.property) || expr.property.type === 'Computed')) {
|
|
526
|
-
const varName = expr.object.value;
|
|
527
|
-
let propName;
|
|
528
|
-
if (expr.property.type === 'Computed') {
|
|
529
|
-
const keyExpr = expr.property.expression;
|
|
530
|
-
if (!utils_1.t.isStringLiteral(keyExpr))
|
|
531
|
-
return null;
|
|
532
|
-
propName = keyExpr.value;
|
|
533
|
-
}
|
|
534
|
-
else {
|
|
535
|
-
propName = expr.property.value;
|
|
536
|
-
}
|
|
537
|
-
const styleInfo = ctx.localCreateStyles[varName];
|
|
538
|
-
if (styleInfo && styleInfo.type === 'create') {
|
|
539
|
-
const style = styleInfo.obj[propName];
|
|
540
|
-
if (typeof style === 'object' && style !== null) {
|
|
541
|
-
return style;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
const hash = ctx.mergedCreateTable[varName];
|
|
545
|
-
if (hash) {
|
|
546
|
-
const obj = ctx.scannedTables.createObjectTable[hash];
|
|
547
|
-
if (obj && obj[propName] && typeof obj[propName] === 'object') {
|
|
548
|
-
return obj[propName];
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
else if (utils_1.t.isIdentifier(expr)) {
|
|
553
|
-
const varName = expr.value;
|
|
554
|
-
const styleInfo = ctx.localCreateStyles[varName];
|
|
555
|
-
if (styleInfo && styleInfo.type === 'create') {
|
|
556
|
-
return styleInfo.obj;
|
|
557
|
-
}
|
|
558
|
-
const hash = ctx.mergedCreateTable[varName];
|
|
559
|
-
if (hash) {
|
|
560
|
-
const obj = ctx.scannedTables.createObjectTable[hash];
|
|
561
|
-
if (obj && typeof obj === 'object') {
|
|
562
|
-
return obj;
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
return null;
|
|
567
|
-
};
|
|
568
|
-
const getSource = (node) => sourceOf(node, ctx.sourceBuffer, ctx.baseByteOffset);
|
|
569
|
-
const assertResolvable = (node) => {
|
|
570
|
-
if (utils_1.t.isIdentifier(node) && node.value === 'undefined')
|
|
571
|
-
return;
|
|
572
|
-
if (utils_1.t.isMemberExpression(node) ||
|
|
573
|
-
utils_1.t.isIdentifier(node) ||
|
|
574
|
-
utils_1.t.isCallExpression(node) ||
|
|
575
|
-
utils_1.t.isArrowFunctionExpression(node) ||
|
|
576
|
-
utils_1.t.isFunctionExpression(node)) {
|
|
577
|
-
const rootId = (0, utils_1.getRootIdentifier)(node);
|
|
578
|
-
const isPlumeriaStyle = rootId &&
|
|
579
|
-
(ctx.localCreateStyles[rootId] !== undefined ||
|
|
580
|
-
ctx.mergedCreateTable[rootId] !== undefined);
|
|
581
|
-
if (!isPlumeriaStyle) {
|
|
582
|
-
const failure = (0, utils_1.resolveOriginError)(node, rootId, localImports);
|
|
583
|
-
throw new Error(failure
|
|
584
|
-
? `[plumeria] ${failure.message} (${path.basename(failure.filePath)})`
|
|
585
|
-
: `[plumeria] Dynamic or unresolvable style object "${getSource(node)}" is not supported. (${path.basename(resourcePath)})`);
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
};
|
|
589
|
-
const resolveBracketGroupStyles = (node) => {
|
|
590
|
-
if (!utils_1.t.isMemberExpression(node) ||
|
|
591
|
-
!utils_1.t.isIdentifier(node.object) ||
|
|
592
|
-
node.property.type !== 'Computed' ||
|
|
593
|
-
utils_1.t.isStringLiteral(node.property.expression)) {
|
|
594
|
-
return null;
|
|
595
|
-
}
|
|
596
|
-
const varName = node.object.value;
|
|
597
|
-
const styleInfo = ctx.localCreateStyles[varName];
|
|
598
|
-
let obj;
|
|
599
|
-
if (styleInfo && styleInfo.type === 'create') {
|
|
600
|
-
obj = styleInfo.obj;
|
|
601
|
-
}
|
|
602
|
-
else {
|
|
603
|
-
const hash = ctx.mergedCreateTable[varName];
|
|
604
|
-
if (hash) {
|
|
605
|
-
obj = ctx.scannedTables.createObjectTable[hash];
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
if (!obj)
|
|
609
|
-
return null;
|
|
610
|
-
return Object.values(obj).filter((v) => typeof v === 'object' && v !== null);
|
|
611
|
-
};
|
|
612
|
-
const resolveDynamicCall = (expr) => {
|
|
613
|
-
if (!utils_1.t.isCallExpression(expr) || !utils_1.t.isMemberExpression(expr.callee))
|
|
614
|
-
return null;
|
|
615
|
-
const callee = expr.callee;
|
|
616
|
-
if (!utils_1.t.isIdentifier(callee.object) || !utils_1.t.isIdentifier(callee.property))
|
|
617
|
-
return null;
|
|
618
|
-
const styleInfo = ctx.localCreateStyles[callee.object.value];
|
|
619
|
-
const func = styleInfo?.functions?.[callee.property.value] ??
|
|
620
|
-
ctx.createFunctionImportMap[callee.object.value]?.[callee.property.value];
|
|
621
|
-
if (!func)
|
|
622
|
-
return null;
|
|
623
|
-
const callArgs = expr.arguments;
|
|
624
|
-
if (callArgs.some((a) => a.spread))
|
|
625
|
-
return null;
|
|
626
|
-
const tempStaticTable = { ...ctx.mergedStaticTable };
|
|
627
|
-
const providedParams = new Set();
|
|
628
|
-
const runtime = [];
|
|
629
|
-
const resolveObjectArg = (argExpr) => (0, utils_1.objectExpressionToObject)({
|
|
630
|
-
...argExpr,
|
|
631
|
-
properties: argExpr.properties.filter((prop) => prop.type === 'Identifier' ||
|
|
632
|
-
(prop.type === 'KeyValueProperty' &&
|
|
633
|
-
isStaticArgValue(prop.value))),
|
|
634
|
-
}, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
635
|
-
if (func.named) {
|
|
636
|
-
const argExpr = callArgs[0]?.expression;
|
|
637
|
-
if (callArgs.length > 1 ||
|
|
638
|
-
(argExpr && argExpr.type !== 'ObjectExpression')) {
|
|
639
|
-
throw new Error(`[plumeria] ${getSource(expr)} takes one object argument, because ${callee.property.value} destructures its parameter. (${path.basename(resourcePath)})\n`);
|
|
640
|
-
}
|
|
641
|
-
const given = new Map();
|
|
642
|
-
(argExpr?.properties ?? []).forEach((prop) => {
|
|
643
|
-
if (prop.type === 'Identifier') {
|
|
644
|
-
given.set(prop.value, prop);
|
|
645
|
-
}
|
|
646
|
-
else if (prop.type === 'KeyValueProperty' &&
|
|
647
|
-
(utils_1.t.isIdentifier(prop.key) || utils_1.t.isStringLiteral(prop.key))) {
|
|
648
|
-
given.set(String(prop.key.value), prop.value);
|
|
649
|
-
}
|
|
650
|
-
});
|
|
651
|
-
const argObj = argExpr
|
|
652
|
-
? (resolveObjectArg(argExpr) ?? {})
|
|
653
|
-
: {};
|
|
654
|
-
func.named.forEach(({ key, local }) => {
|
|
655
|
-
const source = given.get(key);
|
|
656
|
-
if (!source) {
|
|
657
|
-
if (func.defaults?.[local])
|
|
658
|
-
return;
|
|
659
|
-
throw new Error(`[plumeria] ${getSource(expr)} leaves "${key}" unset, and a dynamic style function has no value to fall back on. (${path.basename(resourcePath)})\n`);
|
|
660
|
-
}
|
|
661
|
-
if (isStaticArgValue(source) && argObj[key] !== undefined) {
|
|
662
|
-
tempStaticTable[local] = argObj[key];
|
|
663
|
-
providedParams.add(local);
|
|
664
|
-
}
|
|
665
|
-
else
|
|
666
|
-
runtime.push(local);
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
else if (callArgs.length === 1 &&
|
|
670
|
-
callArgs[0].expression.type === 'ObjectExpression') {
|
|
671
|
-
const argObj = resolveObjectArg(callArgs[0].expression) ?? {};
|
|
672
|
-
func.params.forEach((p) => {
|
|
673
|
-
if (argObj[p] !== undefined) {
|
|
674
|
-
tempStaticTable[p] = argObj[p];
|
|
675
|
-
providedParams.add(p);
|
|
676
|
-
}
|
|
677
|
-
});
|
|
678
|
-
}
|
|
679
|
-
else {
|
|
680
|
-
callArgs.forEach((_callArg, i) => {
|
|
681
|
-
const p = func.params[i];
|
|
682
|
-
if (!p)
|
|
683
|
-
return;
|
|
684
|
-
runtime.push(p);
|
|
685
|
-
});
|
|
686
|
-
}
|
|
687
|
-
const resolved = (0, utils_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams);
|
|
688
|
-
const { style } = resolved;
|
|
689
|
-
return style;
|
|
690
|
-
};
|
|
691
|
-
const collectPropStyles = (expr) => {
|
|
692
|
-
const isParamMember = utils_1.t.isMemberExpression(expr) &&
|
|
693
|
-
utils_1.t.isIdentifier(expr.object) &&
|
|
694
|
-
componentParamNames.has(expr.object.value) &&
|
|
695
|
-
utils_1.t.isIdentifier(expr.property);
|
|
696
|
-
if (!utils_1.t.isIdentifier(expr) && !isParamMember)
|
|
697
|
-
return false;
|
|
698
|
-
const paramObject = isParamMember
|
|
699
|
-
? expr.object.value
|
|
700
|
-
: undefined;
|
|
701
|
-
const isPropsMember = Boolean(paramObject &&
|
|
702
|
-
ctx.localCreateStyles[paramObject] === undefined &&
|
|
703
|
-
ctx.mergedCreateTable[paramObject] === undefined);
|
|
704
|
-
const varName = utils_1.t.isIdentifier(expr)
|
|
705
|
-
? expr.value
|
|
706
|
-
: expr.property.value;
|
|
707
|
-
const owner = ownerComponentOf(expr);
|
|
708
|
-
const propName = (utils_1.t.isIdentifier(expr) && owner
|
|
709
|
-
? propAliases.get(owner)?.get(varName)
|
|
710
|
-
: undefined) ?? varName;
|
|
711
|
-
const possibilities = [];
|
|
712
|
-
if (owner) {
|
|
713
|
-
const entries = ctx.scannedTables.componentPropsTable?.[`${resourcePath}-${owner}`]?.[propName];
|
|
714
|
-
if (entries)
|
|
715
|
-
possibilities.push(...entries);
|
|
716
|
-
}
|
|
717
|
-
if (possibilities.length === 0) {
|
|
718
|
-
const filePrefix = `${resourcePath}-`;
|
|
719
|
-
for (const key of Object.keys(ctx.scannedTables.componentPropsTable || {})) {
|
|
720
|
-
if (!key.startsWith(filePrefix))
|
|
721
|
-
continue;
|
|
722
|
-
const entries = ctx.scannedTables.componentPropsTable?.[key]?.[propName];
|
|
723
|
-
if (entries)
|
|
724
|
-
possibilities.push(...entries);
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
const fallback = owner && propDefaults.get(owner)?.get(propName);
|
|
728
|
-
if (fallback && !isNoOpStyle((0, utils_1.unwrapExpression)(fallback))) {
|
|
729
|
-
const style = resolveStyleObject(fallback);
|
|
730
|
-
if (!style)
|
|
731
|
-
throw propDefaultError(getSource(fallback), path.basename(resourcePath));
|
|
732
|
-
processStyle(style);
|
|
733
|
-
}
|
|
734
|
-
if (possibilities.length > 0) {
|
|
735
|
-
const uniqueEntries = [];
|
|
736
|
-
possibilities.forEach((entry) => {
|
|
737
|
-
if (!uniqueEntries.some((x) => x.key === entry.key)) {
|
|
738
|
-
uniqueEntries.push(entry);
|
|
739
|
-
}
|
|
740
|
-
});
|
|
741
|
-
uniqueEntries.forEach((entry) => {
|
|
742
|
-
if (entry.styleObj && Object.keys(entry.styleObj).length > 0) {
|
|
743
|
-
processStyle(entry.styleObj);
|
|
744
|
-
}
|
|
745
|
-
});
|
|
746
|
-
return true;
|
|
747
|
-
}
|
|
748
|
-
if (fallback)
|
|
749
|
-
return true;
|
|
750
|
-
return Boolean(isPropsMember || (owner && declaredProps.get(owner)?.has(propName)));
|
|
751
|
-
};
|
|
752
|
-
const resolveDynamicStyleHere = (node) => {
|
|
753
|
-
const dynamic = resolveDynamicCall(node);
|
|
754
|
-
if (dynamic && !isStyleProp) {
|
|
755
|
-
throw new Error(`[plumeria] css.use(${getSource(node)}) does not support dynamic function keys. ` +
|
|
756
|
-
`(${path.basename(resourcePath)})`);
|
|
757
|
-
}
|
|
758
|
-
return dynamic;
|
|
759
|
-
};
|
|
760
|
-
const collectConditions = (node, currentTestStrings = []) => {
|
|
761
|
-
node = resolveLocalStyleAlias(localStyleAliases, (0, utils_1.unwrapExpression)(node));
|
|
762
|
-
if (node.type === 'ArrayExpression') {
|
|
763
|
-
let handled = true;
|
|
764
|
-
for (const element of node.elements ?? []) {
|
|
765
|
-
if (!element)
|
|
766
|
-
continue;
|
|
767
|
-
if (element.spread)
|
|
768
|
-
throw spreadStyleError(getSource(element.expression), path.basename(resourcePath));
|
|
769
|
-
handled =
|
|
770
|
-
collectConditions(element.expression, currentTestStrings) &&
|
|
771
|
-
handled;
|
|
772
|
-
}
|
|
773
|
-
return handled;
|
|
774
|
-
}
|
|
775
|
-
if (node.type === 'ConditionalExpression') {
|
|
776
|
-
const testSource = getSource(node.test);
|
|
777
|
-
if (currentTestStrings.length === 0) {
|
|
778
|
-
const trueStyle = resolveStyleObject(node.consequent);
|
|
779
|
-
const falseStyle = resolveStyleObject(node.alternate);
|
|
780
|
-
if (trueStyle && falseStyle) {
|
|
781
|
-
conditionals.push({
|
|
782
|
-
test: node,
|
|
783
|
-
testString: testSource,
|
|
784
|
-
truthy: trueStyle,
|
|
785
|
-
falsy: falseStyle,
|
|
786
|
-
varName: undefined,
|
|
787
|
-
});
|
|
788
|
-
return true;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
collectConditions(node.consequent, [
|
|
792
|
-
...currentTestStrings,
|
|
793
|
-
`(${testSource})`,
|
|
794
|
-
]);
|
|
795
|
-
collectConditions(node.alternate, [
|
|
796
|
-
...currentTestStrings,
|
|
797
|
-
`!(${testSource})`,
|
|
798
|
-
]);
|
|
799
|
-
return true;
|
|
800
|
-
}
|
|
801
|
-
else if (node.type === 'BinaryExpression' && node.operator === '&&') {
|
|
802
|
-
collectConditions(node.right, [
|
|
803
|
-
...currentTestStrings,
|
|
804
|
-
`(${getSource(node.left)})`,
|
|
805
|
-
]);
|
|
806
|
-
return true;
|
|
807
|
-
}
|
|
808
|
-
if (collectPropStyles(node))
|
|
809
|
-
return true;
|
|
810
|
-
const staticStyle = resolveStyleObject(node) ?? resolveDynamicStyleHere(node);
|
|
811
|
-
if (staticStyle) {
|
|
812
|
-
if (currentTestStrings.length === 0) {
|
|
813
|
-
baseStyle = (0, utils_1.deepMerge)(baseStyle, staticStyle);
|
|
814
|
-
}
|
|
815
|
-
else {
|
|
816
|
-
conditionals.push({
|
|
817
|
-
test: node,
|
|
818
|
-
testString: currentTestStrings.join(' && '),
|
|
819
|
-
truthy: staticStyle,
|
|
820
|
-
falsy: {},
|
|
821
|
-
varName: undefined,
|
|
822
|
-
});
|
|
823
|
-
}
|
|
824
|
-
return true;
|
|
825
|
-
}
|
|
826
|
-
if (currentTestStrings.length > 0) {
|
|
827
|
-
const groupStyles = resolveBracketGroupStyles(node);
|
|
828
|
-
if (groupStyles) {
|
|
829
|
-
groupStyles.forEach((style) => conditionals.push({
|
|
830
|
-
test: node,
|
|
831
|
-
testString: currentTestStrings.join(' && '),
|
|
832
|
-
truthy: style,
|
|
833
|
-
falsy: {},
|
|
834
|
-
varName: undefined,
|
|
835
|
-
}));
|
|
836
|
-
return true;
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
assertResolvable(node);
|
|
840
|
-
return false;
|
|
841
|
-
};
|
|
842
|
-
for (const arg of args) {
|
|
843
|
-
const expr = arg.expression;
|
|
844
|
-
if (collectPropStyles(expr))
|
|
845
|
-
continue;
|
|
846
|
-
const dynamicStyle = resolveDynamicStyleHere(expr);
|
|
847
|
-
if (dynamicStyle) {
|
|
848
|
-
baseStyle = (0, utils_1.deepMerge)(baseStyle, dynamicStyle);
|
|
849
|
-
continue;
|
|
850
|
-
}
|
|
851
|
-
if (collectConditions(arg.expression))
|
|
852
|
-
continue;
|
|
853
|
-
assertResolvable(expr);
|
|
854
|
-
const extractedStyles = extractStylesFromExpression(arg.expression, ctx);
|
|
855
|
-
extractedStyles.forEach(processStyle);
|
|
856
|
-
}
|
|
857
|
-
if (Object.keys(baseStyle).length > 0)
|
|
858
|
-
processStyle(baseStyle);
|
|
859
|
-
for (const cond of conditionals) {
|
|
860
|
-
if (cond.truthy && Object.keys(cond.truthy).length > 0)
|
|
861
|
-
processStyle(cond.truthy);
|
|
862
|
-
if (cond.falsy && Object.keys(cond.falsy).length > 0)
|
|
863
|
-
processStyle(cond.falsy);
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
const processedNodes = new WeakSet();
|
|
867
|
-
const processCall = (node) => {
|
|
868
|
-
if (processedNodes.has(node))
|
|
869
|
-
return;
|
|
870
|
-
processedNodes.add(node);
|
|
871
|
-
const callee = node.callee;
|
|
872
|
-
let propName;
|
|
873
|
-
if (utils_1.t.isMemberExpression(callee) &&
|
|
874
|
-
utils_1.t.isIdentifier(callee.object) &&
|
|
875
|
-
utils_1.t.isIdentifier(callee.property)) {
|
|
876
|
-
const objectName = callee.object.value;
|
|
877
|
-
const propertyName = callee.property.value;
|
|
878
|
-
if (plumeriaAliases[objectName] === 'NAMESPACE')
|
|
879
|
-
propName = propertyName;
|
|
880
|
-
}
|
|
881
|
-
else if (utils_1.t.isIdentifier(callee)) {
|
|
882
|
-
const originalName = plumeriaAliases[callee.value];
|
|
883
|
-
if (originalName)
|
|
884
|
-
propName = originalName;
|
|
885
|
-
}
|
|
886
|
-
if (propName) {
|
|
887
|
-
if (['create', 'createTheme', 'createStatic'].includes(propName) &&
|
|
888
|
-
!registeredStyleCalls.has(node.span.start)) {
|
|
889
|
-
throw new Error(`[plumeria] css.${propName} must be assigned to a named top-level variable. ` +
|
|
890
|
-
`Destructuring, assignment statements, and default-exported calls cannot be compiled. ` +
|
|
891
|
-
`(${path.basename(resourcePath)})`);
|
|
892
|
-
}
|
|
893
|
-
const args = node.arguments;
|
|
894
|
-
if (propName === 'use') {
|
|
895
|
-
const namesStyleFunction = (expr) => {
|
|
896
|
-
const node = (0, utils_1.unwrapExpression)(expr);
|
|
897
|
-
if (node.type === 'ArrayExpression') {
|
|
898
|
-
return (node.elements ?? []).some((element) => !!element && namesStyleFunction(element.expression));
|
|
899
|
-
}
|
|
900
|
-
if (!utils_1.t.isMemberExpression(node) ||
|
|
901
|
-
!utils_1.t.isIdentifier(node.object) ||
|
|
902
|
-
!utils_1.t.isIdentifier(node.property)) {
|
|
903
|
-
return false;
|
|
904
|
-
}
|
|
905
|
-
return Boolean(ctx.localCreateStyles[node.object.value]?.functions?.[node.property.value] ??
|
|
906
|
-
ctx.createFunctionImportMap[node.object.value]?.[node.property.value]);
|
|
907
|
-
};
|
|
908
|
-
if (args.some((arg) => namesStyleFunction(arg.expression))) {
|
|
909
|
-
throw new Error(`[plumeria] Dynamic or unresolvable style object "${sourceOf(node, sourceBuffer, baseByteOffset)}" is not supported. ` +
|
|
910
|
-
`(${path.basename(resourcePath)})`);
|
|
911
|
-
}
|
|
912
|
-
extractAndProcessConditionals(args, false);
|
|
913
|
-
}
|
|
914
|
-
else if (propName === 'keyframes' &&
|
|
915
|
-
args.length > 0 &&
|
|
916
|
-
utils_1.t.isObjectExpression(args[0].expression)) {
|
|
917
|
-
const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
918
|
-
const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
|
|
919
|
-
ctx.scannedTables.keyframesObjectTable[hash] = obj;
|
|
920
|
-
}
|
|
921
|
-
else if (propName === 'viewTransition' &&
|
|
922
|
-
args.length > 0 &&
|
|
923
|
-
utils_1.t.isObjectExpression(args[0].expression)) {
|
|
924
|
-
const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
925
|
-
const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
|
|
926
|
-
ctx.scannedTables.viewTransitionObjectTable[hash] = obj;
|
|
927
|
-
}
|
|
928
|
-
else if (propName === 'createTheme' &&
|
|
929
|
-
args.length >= 2 &&
|
|
930
|
-
utils_1.t.isObjectExpression(args[1].expression)) {
|
|
931
|
-
const selectorExpr = args[0].expression;
|
|
932
|
-
const selector = (0, utils_1.resolveThemeSelector)(selectorExpr, ctx.mergedStaticTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
933
|
-
if (!selector) {
|
|
934
|
-
throw new Error(`[plumeria] createTheme needs a selector it can read at build time. ` +
|
|
935
|
-
`Pass a string literal such as ".dark", or a name this file declares as one. (${path.basename(resourcePath)})`);
|
|
936
|
-
}
|
|
937
|
-
if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
|
|
938
|
-
throw new Error(`[plumeria] Unsupported at-rule: "${selector}". createTheme only supports ` +
|
|
939
|
-
`nesting at-rules such as @media, @container, @supports, @layer, and @scope. (${path.basename(resourcePath)})`);
|
|
940
|
-
}
|
|
941
|
-
const obj = (0, utils_1.objectExpressionToObject)(args[1].expression, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
942
|
-
const hash = (0, utils_1.themeHashOf)(selector, obj);
|
|
943
|
-
ctx.scannedTables.createThemeObjectTable[hash] = obj;
|
|
944
|
-
if (ctx.scannedTables.createThemeSelectorTable) {
|
|
945
|
-
ctx.scannedTables.createThemeSelectorTable[hash] = selector;
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
else if (propName === 'createStatic' &&
|
|
949
|
-
args.length > 0 &&
|
|
950
|
-
utils_1.t.isObjectExpression(args[0].expression)) {
|
|
951
|
-
const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
952
|
-
const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
|
|
953
|
-
ctx.scannedTables.createStaticObjectTable[hash] = obj;
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
};
|
|
957
|
-
const traverseInternal = (node) => {
|
|
958
|
-
if (!node || typeof node !== 'object')
|
|
959
|
-
return;
|
|
960
|
-
if (utils_1.t.isCallExpression(node))
|
|
961
|
-
processCall(node);
|
|
962
|
-
for (const k in node)
|
|
963
|
-
if (k !== 'span' && k !== 'loc')
|
|
964
|
-
traverseInternal(node[k]);
|
|
965
|
-
};
|
|
966
|
-
(0, utils_1.traverse)(ast, {
|
|
967
|
-
VariableDeclarator({ node }) {
|
|
968
|
-
if (utils_1.t.isIdentifier(node.id) && node.init) {
|
|
969
|
-
const init = (0, utils_1.unwrapExpression)(node.init);
|
|
970
|
-
if (utils_1.t.isCallExpression(init)) {
|
|
971
|
-
const callee = init.callee;
|
|
972
|
-
let pName;
|
|
973
|
-
if (utils_1.t.isMemberExpression(callee) &&
|
|
974
|
-
utils_1.t.isIdentifier(callee.object) &&
|
|
975
|
-
utils_1.t.isIdentifier(callee.property)) {
|
|
976
|
-
if (plumeriaAliases[callee.object.value] === 'NAMESPACE')
|
|
977
|
-
pName = callee.property.value;
|
|
978
|
-
}
|
|
979
|
-
else if (utils_1.t.isIdentifier(callee) &&
|
|
980
|
-
plumeriaAliases[callee.value]) {
|
|
981
|
-
pName = plumeriaAliases[callee.value];
|
|
982
|
-
}
|
|
983
|
-
const isTheme = pName === 'createTheme';
|
|
984
|
-
const definitionArg = pName === 'createTheme'
|
|
985
|
-
? init.arguments[1]?.expression
|
|
986
|
-
: init.arguments[0]?.expression;
|
|
987
|
-
const unwrappedDefinitionArg = definitionArg
|
|
988
|
-
? (0, utils_1.unwrapExpression)(definitionArg)
|
|
989
|
-
: undefined;
|
|
990
|
-
if (pName &&
|
|
991
|
-
unwrappedDefinitionArg &&
|
|
992
|
-
utils_1.t.isObjectExpression(unwrappedDefinitionArg) &&
|
|
993
|
-
((!isTheme && init.arguments.length === 1) ||
|
|
994
|
-
(isTheme && init.arguments.length >= 2))) {
|
|
995
|
-
registeredStyleCalls.add(init.span.start);
|
|
996
|
-
const arg = unwrappedDefinitionArg;
|
|
997
|
-
const resolveVariable = (name) => ctx.localCreateStyles[name]?.obj ||
|
|
998
|
-
(ctx.mergedCreateThemeHashTable[name]
|
|
999
|
-
? ctx.scannedTables.createAtomicMapTable[ctx.mergedCreateThemeHashTable[name]]
|
|
1000
|
-
: undefined);
|
|
1001
|
-
if (pName === 'create') {
|
|
1002
|
-
const obj = (0, utils_1.objectExpressionToObject)(arg, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable, resolveVariable);
|
|
1003
|
-
if (obj) {
|
|
1004
|
-
const styleFunctions = (0, utils_1.styleFunctionsOf)(arg);
|
|
1005
|
-
ctx.localCreateStyles[node.id.value] = {
|
|
1006
|
-
type: 'create',
|
|
1007
|
-
obj,
|
|
1008
|
-
functions: styleFunctions,
|
|
1009
|
-
};
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
else if (pName === 'createTheme') {
|
|
1013
|
-
const selectorExpr = init.arguments[0].expression;
|
|
1014
|
-
const selector = (0, utils_1.resolveThemeSelector)(selectorExpr, ctx.mergedStaticTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
1015
|
-
if (!selector) {
|
|
1016
|
-
throw new Error(`[plumeria] createTheme needs a selector it can read at build time. ` +
|
|
1017
|
-
`Pass a string literal such as ".dark", or a name this file declares as one. (${path.basename(resourcePath)})`);
|
|
1018
|
-
}
|
|
1019
|
-
if (selector.startsWith('@') && !(0, zss_engine_1.isAtRule)(selector)) {
|
|
1020
|
-
throw new Error(`[plumeria] Unsupported at-rule: "${selector}". createTheme only supports ` +
|
|
1021
|
-
`nesting at-rules such as @media, @container, @supports, @layer, and @scope. (${path.basename(resourcePath)})`);
|
|
1022
|
-
}
|
|
1023
|
-
const obj = (0, utils_1.objectExpressionToObject)(arg, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
1024
|
-
const hash = (0, utils_1.themeHashOf)(selector, obj);
|
|
1025
|
-
const uKey = `${resourcePath}-${node.id.value}`;
|
|
1026
|
-
ctx.scannedTables.createThemeHashTable[uKey] = hash;
|
|
1027
|
-
ctx.scannedTables.createThemeObjectTable[hash] = obj;
|
|
1028
|
-
if (ctx.scannedTables.createThemeSelectorTable) {
|
|
1029
|
-
ctx.scannedTables.createThemeSelectorTable[hash] = selector;
|
|
1030
|
-
}
|
|
1031
|
-
const themeHashMap = {};
|
|
1032
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
1033
|
-
const cssVarName = (0, zss_engine_1.camelToKebabCase)(key);
|
|
1034
|
-
const atomicHash = (0, zss_engine_1.genBase36Hash)({ _theme: hash, [key]: value }, 1, 8);
|
|
1035
|
-
themeHashMap[key] = `var(--${atomicHash}-${cssVarName})`;
|
|
1036
|
-
}
|
|
1037
|
-
ctx.scannedTables.createAtomicMapTable[hash] = themeHashMap;
|
|
1038
|
-
ctx.localCreateStyles[node.id.value] = {
|
|
1039
|
-
type: 'create',
|
|
1040
|
-
obj: ctx.scannedTables.createAtomicMapTable[hash],
|
|
1041
|
-
};
|
|
1042
|
-
}
|
|
1043
|
-
else if (pName === 'createStatic') {
|
|
1044
|
-
const obj = (0, utils_1.objectExpressionToObject)(arg, ctx.mergedStaticTable, ctx.mergedKeyframesTable, ctx.mergedViewTransitionTable, ctx.mergedCreateThemeHashTable, ctx.scannedTables.createThemeObjectTable, ctx.mergedCreateTable, ctx.mergedCreateStaticHashTable, ctx.scannedTables.createStaticObjectTable);
|
|
1045
|
-
if (obj) {
|
|
1046
|
-
const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
|
|
1047
|
-
const uKey = `${resourcePath}-${node.id.value}`;
|
|
1048
|
-
ctx.scannedTables.createStaticHashTable[uKey] = hash;
|
|
1049
|
-
ctx.scannedTables.createStaticObjectTable[hash] = obj;
|
|
1050
|
-
ctx.mergedCreateStaticHashTable[node.id.value] = hash;
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
else if (utils_1.t.isMemberExpression(init) &&
|
|
1056
|
-
utils_1.t.isIdentifier(init.object)) {
|
|
1057
|
-
const objName = init.object.value;
|
|
1058
|
-
if (ctx.localCreateStyles[objName] !== undefined ||
|
|
1059
|
-
ctx.mergedCreateTable[objName] !== undefined) {
|
|
1060
|
-
(localStyleAliases[node.id.value] ??= []).push({
|
|
1061
|
-
expression: init,
|
|
1062
|
-
context: node.id.ctxt,
|
|
1063
|
-
});
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
},
|
|
1068
|
-
});
|
|
1069
|
-
(0, utils_1.traverse)(ast, {
|
|
1070
|
-
VariableDeclarator({ node }) {
|
|
1071
|
-
if (utils_1.t.isIdentifier(node.id) && node.init) {
|
|
1072
|
-
traverseInternal(node.init);
|
|
1073
|
-
}
|
|
1074
|
-
},
|
|
1075
|
-
FunctionDeclaration({ node }) {
|
|
1076
|
-
if (node.identifier)
|
|
1077
|
-
traverseInternal(node.body);
|
|
1078
|
-
},
|
|
1079
|
-
CallExpression: (path) => {
|
|
1080
|
-
if (!processedNodes.has(path.node))
|
|
1081
|
-
processCall(path.node);
|
|
1082
|
-
},
|
|
1083
|
-
JSXOpeningElement({ node }) {
|
|
1084
|
-
if (node.name.type === 'Identifier') {
|
|
1085
|
-
const tagName = node.name.value;
|
|
1086
|
-
if (tagName[0] !== tagName[0].toUpperCase())
|
|
1087
|
-
return;
|
|
1088
|
-
}
|
|
1089
|
-
else if (node.name.type !== 'JSXMemberExpression') {
|
|
1090
|
-
return;
|
|
1091
|
-
}
|
|
1092
|
-
node.attributes.forEach((attr) => {
|
|
1093
|
-
if (attr.type !== 'JSXAttribute')
|
|
1094
|
-
return;
|
|
1095
|
-
if (attr.name.type !== 'Identifier')
|
|
1096
|
-
return;
|
|
1097
|
-
if (attr.name.value === styleProp)
|
|
1098
|
-
return;
|
|
1099
|
-
const value = attr.value;
|
|
1100
|
-
if (!value || value.type !== 'JSXExpressionContainer')
|
|
1101
|
-
return;
|
|
1102
|
-
if (value.expression.type === 'JSXEmptyExpression')
|
|
1103
|
-
return;
|
|
1104
|
-
let expr = value.expression;
|
|
1105
|
-
expr = resolveLocalStyleAlias(localStyleAliases, expr);
|
|
1106
|
-
extractStylesFromExpression(expr, ctx).forEach(processStyle);
|
|
1107
|
-
});
|
|
1108
|
-
},
|
|
1109
|
-
JSXAttribute({ node }) {
|
|
1110
|
-
if (node.name.type !== 'Identifier')
|
|
1111
|
-
return;
|
|
1112
|
-
if (node.name.value !== styleProp)
|
|
1113
|
-
return;
|
|
1114
|
-
if (!node.value || node.value.type !== 'JSXExpressionContainer')
|
|
1115
|
-
return;
|
|
1116
|
-
if (node.value.expression.type === 'JSXEmptyExpression')
|
|
1117
|
-
return;
|
|
1118
|
-
const expr = node.value.expression;
|
|
1119
|
-
const args = [];
|
|
1120
|
-
const addArgs = (node) => {
|
|
1121
|
-
node = (0, utils_1.unwrapExpression)(node);
|
|
1122
|
-
if (node.type === 'ArrayExpression') {
|
|
1123
|
-
for (const element of node.elements ?? []) {
|
|
1124
|
-
if (!element)
|
|
1125
|
-
continue;
|
|
1126
|
-
if (element.spread)
|
|
1127
|
-
throw spreadStyleError(sourceOf(element.expression, sourceBuffer, baseByteOffset), path.basename(resourcePath));
|
|
1128
|
-
addArgs(element.expression);
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
else {
|
|
1132
|
-
args.push({ expression: node });
|
|
1133
|
-
}
|
|
1134
|
-
};
|
|
1135
|
-
addArgs(expr);
|
|
1136
|
-
extractAndProcessConditionals(args, true);
|
|
1137
|
-
},
|
|
1138
|
-
});
|
|
1139
|
-
return extractedSheets;
|
|
1140
|
-
};
|
|
1141
|
-
for (const file of files) {
|
|
1142
|
-
const sheets = processFile(file);
|
|
1143
|
-
for (const sheet of sheets) {
|
|
1144
|
-
allSheets.add(sheet);
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
return Array.from(allSheets).join('\n');
|
|
1148
|
-
}
|