@plumeria/utils 19.6.1 → 19.7.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/dist/compile.js +10 -3
- package/dist/dynamicKey.d.ts +11 -1
- package/dist/dynamicKey.js +200 -33
- package/dist/parser.d.ts +2 -0
- package/dist/parser.js +36 -17
- package/dist/stylePropFilter.js +4 -3
- package/dist/transform.js +31 -9
- package/package.json +2 -2
package/dist/compile.js
CHANGED
|
@@ -41,6 +41,7 @@ const path = __importStar(require("path"));
|
|
|
41
41
|
const rs = __importStar(require("@rust-gear/glob"));
|
|
42
42
|
const index_1 = require("./index");
|
|
43
43
|
const index_2 = require("./index");
|
|
44
|
+
const dynamicKey_1 = require("./dynamicKey");
|
|
44
45
|
const unwrapExport = (node) => {
|
|
45
46
|
if (node?.type === 'ExportDeclaration')
|
|
46
47
|
return node.declaration;
|
|
@@ -626,6 +627,7 @@ function compileCSS(options) {
|
|
|
626
627
|
const tempStaticTable = { ...ctx.mergedStaticTable };
|
|
627
628
|
const providedParams = new Set();
|
|
628
629
|
const runtime = [];
|
|
630
|
+
const definite = new Set();
|
|
629
631
|
const resolveObjectArg = (argExpr) => (0, index_1.objectExpressionToObject)({
|
|
630
632
|
...argExpr,
|
|
631
633
|
properties: argExpr.properties.filter((prop) => prop.type === 'Identifier' ||
|
|
@@ -662,8 +664,11 @@ function compileCSS(options) {
|
|
|
662
664
|
tempStaticTable[local] = argObj[key];
|
|
663
665
|
providedParams.add(local);
|
|
664
666
|
}
|
|
665
|
-
else
|
|
667
|
+
else {
|
|
666
668
|
runtime.push(local);
|
|
669
|
+
if ((0, dynamicKey_1.isDefinedArgument)(source))
|
|
670
|
+
definite.add(local);
|
|
671
|
+
}
|
|
667
672
|
});
|
|
668
673
|
}
|
|
669
674
|
else if (callArgs.length === 1 &&
|
|
@@ -677,14 +682,16 @@ function compileCSS(options) {
|
|
|
677
682
|
});
|
|
678
683
|
}
|
|
679
684
|
else {
|
|
680
|
-
callArgs.forEach((
|
|
685
|
+
callArgs.forEach((callArg, i) => {
|
|
681
686
|
const p = func.params[i];
|
|
682
687
|
if (!p)
|
|
683
688
|
return;
|
|
684
689
|
runtime.push(p);
|
|
690
|
+
if ((0, dynamicKey_1.isDefinedArgument)(callArg.expression))
|
|
691
|
+
definite.add(p);
|
|
685
692
|
});
|
|
686
693
|
}
|
|
687
|
-
const resolved = (0, index_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams);
|
|
694
|
+
const resolved = (0, index_1.resolveDynamicStyle)(func, runtime, tempStaticTable, dynamicTablesOf(ctx), providedParams, definite);
|
|
688
695
|
const { style } = resolved;
|
|
689
696
|
return style;
|
|
690
697
|
};
|
package/dist/dynamicKey.d.ts
CHANGED
|
@@ -35,6 +35,14 @@ export type DynamicStyleTables = {
|
|
|
35
35
|
createStaticHashTable: CreateStaticHashTable;
|
|
36
36
|
createStaticObjectTable: CreateStaticObjectTable;
|
|
37
37
|
};
|
|
38
|
+
export type DerivedPiece = string | {
|
|
39
|
+
param: string;
|
|
40
|
+
fallback?: string;
|
|
41
|
+
};
|
|
42
|
+
export type DerivedVar = {
|
|
43
|
+
name: string;
|
|
44
|
+
pieces: DerivedPiece[];
|
|
45
|
+
};
|
|
38
46
|
export type DynamicStyleResult = {
|
|
39
47
|
style: CSSObject;
|
|
40
48
|
varGroups: Map<string, Array<{
|
|
@@ -43,6 +51,8 @@ export type DynamicStyleResult = {
|
|
|
43
51
|
unit: string;
|
|
44
52
|
written: boolean;
|
|
45
53
|
}>>;
|
|
54
|
+
derived: DerivedVar[];
|
|
46
55
|
};
|
|
47
|
-
export declare const
|
|
56
|
+
export declare const isDefinedArgument: (expression: Expression) => boolean;
|
|
57
|
+
export declare const resolveDynamicStyle: (func: StyleFunction, runtimeParams: string[], staticTable: StaticTable, tables: DynamicStyleTables, providedParams?: ReadonlySet<string>, definiteParams?: ReadonlySet<string>) => DynamicStyleResult;
|
|
48
58
|
export {};
|
package/dist/dynamicKey.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveDynamicStyle = exports.applyVarFallback = exports.splitVarByUnit = exports.isUnitlessProp = exports.styleFunctionsOf = void 0;
|
|
3
|
+
exports.resolveDynamicStyle = exports.isDefinedArgument = exports.applyVarFallback = exports.splitVarByUnit = exports.isUnitlessProp = exports.styleFunctionsOf = void 0;
|
|
4
4
|
const zss_engine_1 = require("zss-engine");
|
|
5
5
|
const zss_engine_2 = require("zss-engine");
|
|
6
6
|
const parser_1 = require("./parser");
|
|
@@ -229,55 +229,222 @@ const applyVarFallback = (style, cssVar, literal, unit) => {
|
|
|
229
229
|
}
|
|
230
230
|
};
|
|
231
231
|
exports.applyVarFallback = applyVarFallback;
|
|
232
|
-
const
|
|
232
|
+
const ARITHMETIC = new Set(['+', '-', '*', '/', '%', '**']);
|
|
233
|
+
const isSign = (node) => parser_1.t.isUnaryExpression(node) && (node.operator === '-' || node.operator === '+');
|
|
234
|
+
const isDefinedArgument = (expression) => {
|
|
235
|
+
const node = (0, parser_1.unwrapExpression)(expression);
|
|
236
|
+
if (parser_1.t.isStringLiteral(node) ||
|
|
237
|
+
parser_1.t.isNumericLiteral(node) ||
|
|
238
|
+
parser_1.t.isBooleanLiteral(node) ||
|
|
239
|
+
parser_1.t.isNullLiteral(node) ||
|
|
240
|
+
parser_1.t.isTemplateLiteral(node))
|
|
241
|
+
return true;
|
|
242
|
+
return isSign(node) && parser_1.t.isNumericLiteral((0, parser_1.unwrapExpression)(node.argument));
|
|
243
|
+
};
|
|
244
|
+
exports.isDefinedArgument = isDefinedArgument;
|
|
245
|
+
const defaultError = (param, node, literal) => {
|
|
246
|
+
const kind = literal === null || parser_1.t.isNullLiteral(node)
|
|
247
|
+
? 'null'
|
|
248
|
+
: typeof literal === 'boolean'
|
|
249
|
+
? 'a boolean'
|
|
250
|
+
: literal !== undefined
|
|
251
|
+
? 'an object'
|
|
252
|
+
: undefined;
|
|
253
|
+
return new Error(kind
|
|
254
|
+
? `[plumeria] The default of "${param}" is ${kind}, which a dynamic style function cannot fall back on. Use a string or a number, or pass the value from the call.`
|
|
255
|
+
: `[plumeria] Cannot resolve the default of "${param}" at build time (${(0, parser_1.expressionLabel)(node)}). A dynamic style function falls back on it when the argument is undefined, so it has to be a string or a number plumeria can read. Pass the value from the call instead.`);
|
|
256
|
+
};
|
|
257
|
+
const replaceNodes = (node, replacements) => {
|
|
258
|
+
if (!node || typeof node !== 'object')
|
|
259
|
+
return node;
|
|
260
|
+
const replacement = replacements.get(node);
|
|
261
|
+
if (replacement)
|
|
262
|
+
return replacement;
|
|
263
|
+
if (Array.isArray(node))
|
|
264
|
+
return node.map((item) => replaceNodes(item, replacements));
|
|
265
|
+
const copy = {};
|
|
266
|
+
for (const key of Object.keys(node))
|
|
267
|
+
copy[key] =
|
|
268
|
+
key === 'span' ? node[key] : replaceNodes(node[key], replacements);
|
|
269
|
+
return copy;
|
|
270
|
+
};
|
|
271
|
+
const literalSource = (value) => {
|
|
272
|
+
if (typeof value === 'string')
|
|
273
|
+
return JSON.stringify(value);
|
|
274
|
+
const text = String(value);
|
|
275
|
+
return text.startsWith('-') ? `(${text})` : text;
|
|
276
|
+
};
|
|
277
|
+
const deriveArithmetic = (body, runtimeParams, varParams, defaults, evaluate) => {
|
|
278
|
+
const derived = [];
|
|
279
|
+
const names = new Map();
|
|
280
|
+
const replacements = new Map();
|
|
281
|
+
const render = (expression) => {
|
|
282
|
+
const node = (0, parser_1.unwrapExpression)(expression);
|
|
283
|
+
if (parser_1.t.isIdentifier(node) && runtimeParams.has(node.value)) {
|
|
284
|
+
const fallback = defaults.get(node.value);
|
|
285
|
+
return [
|
|
286
|
+
fallback === undefined
|
|
287
|
+
? { param: node.value }
|
|
288
|
+
: { param: node.value, fallback: literalSource(fallback) },
|
|
289
|
+
];
|
|
290
|
+
}
|
|
291
|
+
if (parser_1.t.isBinaryExpression(node) && ARITHMETIC.has(node.operator)) {
|
|
292
|
+
const left = render(node.left);
|
|
293
|
+
const right = render(node.right);
|
|
294
|
+
if (!left || !right)
|
|
295
|
+
return null;
|
|
296
|
+
return ['(', ...left, ` ${node.operator} `, ...right, ')'];
|
|
297
|
+
}
|
|
298
|
+
if (isSign(node)) {
|
|
299
|
+
const argument = render(node.argument);
|
|
300
|
+
return argument && ['(', node.operator, '(', ...argument, ')', ')'];
|
|
301
|
+
}
|
|
302
|
+
if ((0, parser_1.readsParams)(node, runtimeParams))
|
|
303
|
+
return null;
|
|
304
|
+
const value = evaluate(node);
|
|
305
|
+
return typeof value === 'number' ? [literalSource(value)] : null;
|
|
306
|
+
};
|
|
307
|
+
const register = (node, pieces) => {
|
|
308
|
+
const first = pieces.find((piece) => typeof piece !== 'string');
|
|
309
|
+
if (!first) {
|
|
310
|
+
replacements.set(node, {
|
|
311
|
+
type: 'NumericLiteral',
|
|
312
|
+
span: node.span,
|
|
313
|
+
value: evaluate(node),
|
|
314
|
+
});
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const key = JSON.stringify(pieces);
|
|
318
|
+
let name = names.get(key);
|
|
319
|
+
if (!name) {
|
|
320
|
+
name = `${first.param}-${derived.length + 1}`;
|
|
321
|
+
names.set(key, name);
|
|
322
|
+
derived.push({ name, pieces });
|
|
323
|
+
}
|
|
324
|
+
replacements.set(node, {
|
|
325
|
+
type: 'Identifier',
|
|
326
|
+
span: node.span,
|
|
327
|
+
value: name,
|
|
328
|
+
optional: false,
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
const visit = (expression) => {
|
|
332
|
+
const node = (0, parser_1.unwrapExpression)(expression);
|
|
333
|
+
if (parser_1.t.isObjectExpression(node)) {
|
|
334
|
+
node.properties.forEach((prop) => {
|
|
335
|
+
if (prop.type === 'KeyValueProperty')
|
|
336
|
+
visit(prop.value);
|
|
337
|
+
});
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
if (parser_1.t.isTemplateLiteral(node)) {
|
|
341
|
+
node.expressions.forEach(visit);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const arithmetic = parser_1.t.isBinaryExpression(node) && ARITHMETIC.has(node.operator);
|
|
345
|
+
if (!arithmetic && !isSign(node))
|
|
346
|
+
return;
|
|
347
|
+
if (!(0, parser_1.readsParams)(node, varParams))
|
|
348
|
+
return;
|
|
349
|
+
const pieces = render(node);
|
|
350
|
+
if (pieces) {
|
|
351
|
+
register(node, pieces.slice(1, -1));
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (arithmetic && node.operator === '+') {
|
|
355
|
+
visit(node.left);
|
|
356
|
+
visit(node.right);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
visit(body);
|
|
360
|
+
return {
|
|
361
|
+
body: replacements.size > 0 ? replaceNodes(body, replacements) : body,
|
|
362
|
+
derived,
|
|
363
|
+
};
|
|
364
|
+
};
|
|
365
|
+
const resolveDynamicStyle = (func, runtimeParams, staticTable, tables, providedParams, definiteParams) => {
|
|
233
366
|
if (func.unsupportedParams)
|
|
234
367
|
throw new Error('[plumeria] Dynamic styles require named parameters or object destructuring; array and rest parameters are not supported.');
|
|
235
368
|
const tempStaticTable = Object.create(staticTable);
|
|
236
|
-
const
|
|
369
|
+
const evaluate = (expr, table) => (0, parser_1.objectExpressionToObject)({
|
|
370
|
+
type: 'ObjectExpression',
|
|
371
|
+
span: func.body.span,
|
|
372
|
+
properties: [
|
|
373
|
+
{
|
|
374
|
+
type: 'KeyValueProperty',
|
|
375
|
+
key: {
|
|
376
|
+
type: 'Identifier',
|
|
377
|
+
span: func.body.span,
|
|
378
|
+
value: 'value',
|
|
379
|
+
optional: false,
|
|
380
|
+
},
|
|
381
|
+
value: expr,
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
}, table, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable).value;
|
|
237
385
|
const withDefault = Object.entries(func.defaults ?? {}).filter(([param]) => providedParams
|
|
238
386
|
? !providedParams.has(param)
|
|
239
387
|
: tempStaticTable[param] === undefined);
|
|
388
|
+
const defaultLiterals = new Map();
|
|
389
|
+
withDefault.forEach(([param, expr]) => {
|
|
390
|
+
const node = (0, parser_1.unwrapExpression)(expr);
|
|
391
|
+
if (parser_1.t.isIdentifier(node) && node.value === 'undefined')
|
|
392
|
+
return;
|
|
393
|
+
const definite = definiteParams?.has(param) || !(0, parser_1.readsParams)(func.body, new Set([param]));
|
|
394
|
+
let literal;
|
|
395
|
+
try {
|
|
396
|
+
literal = evaluate(expr, staticTable);
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
if (definite)
|
|
400
|
+
return;
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
if (typeof literal === 'string' || typeof literal === 'number') {
|
|
404
|
+
defaultLiterals.set(param, literal);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (!definite)
|
|
408
|
+
throw defaultError(param, node, literal);
|
|
409
|
+
});
|
|
410
|
+
const holeDefaults = new Map([...defaultLiterals].filter(([param]) => !definiteParams?.has(param)));
|
|
240
411
|
const cssVars = {};
|
|
241
412
|
const varParams = Array.from(new Set([...runtimeParams, ...withDefault.map(([param]) => param)]));
|
|
242
|
-
|
|
243
|
-
|
|
413
|
+
const runtimeSet = new Set(runtimeParams);
|
|
414
|
+
const constantTable = Object.create(staticTable);
|
|
415
|
+
defaultLiterals.forEach((literal, param) => {
|
|
416
|
+
if (!runtimeSet.has(param))
|
|
417
|
+
constantTable[param] = literal;
|
|
418
|
+
});
|
|
419
|
+
const { body, derived } = deriveArithmetic(func.body, runtimeSet, new Set(varParams), holeDefaults, (node) => {
|
|
420
|
+
try {
|
|
421
|
+
return evaluate(node, constantTable);
|
|
422
|
+
}
|
|
423
|
+
catch {
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
const resolveBody = () => (0, parser_1.objectExpressionToObject)(body, tempStaticTable, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable);
|
|
428
|
+
const varNames = [...varParams, ...derived.map(({ name }) => name)];
|
|
429
|
+
if (varNames.length > 0) {
|
|
430
|
+
varNames.forEach((name) => (tempStaticTable[name] = name));
|
|
244
431
|
const hash = (0, zss_engine_2.genBase36Hash)(resolveBody(), 1, 8);
|
|
245
|
-
|
|
246
|
-
const cssVar = `--${hash}-${
|
|
247
|
-
tempStaticTable[
|
|
248
|
-
cssVars[
|
|
432
|
+
varNames.forEach((name) => {
|
|
433
|
+
const cssVar = `--${hash}-${name}`;
|
|
434
|
+
tempStaticTable[name] = `var(${cssVar})`;
|
|
435
|
+
cssVars[name] = cssVar;
|
|
249
436
|
});
|
|
250
437
|
}
|
|
251
438
|
const style = resolveBody();
|
|
252
439
|
const varGroups = new Map();
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
varGroups.set(param, (0, exports.splitVarByUnit)(style, cssVar));
|
|
440
|
+
varNames.forEach((name) => {
|
|
441
|
+
varGroups.set(name, (0, exports.splitVarByUnit)(style, cssVars[name]));
|
|
256
442
|
});
|
|
257
|
-
|
|
258
|
-
const resolved = (0, parser_1.objectExpressionToObject)({
|
|
259
|
-
type: 'ObjectExpression',
|
|
260
|
-
span: func.body.span,
|
|
261
|
-
properties: [
|
|
262
|
-
{
|
|
263
|
-
type: 'KeyValueProperty',
|
|
264
|
-
key: {
|
|
265
|
-
type: 'Identifier',
|
|
266
|
-
span: func.body.span,
|
|
267
|
-
value: 'value',
|
|
268
|
-
optional: false,
|
|
269
|
-
},
|
|
270
|
-
value: expr,
|
|
271
|
-
},
|
|
272
|
-
],
|
|
273
|
-
}, staticTable, tables.keyframesHashTable, tables.viewTransitionHashTable, tables.createThemeHashTable, tables.createThemeObjectTable, tables.createHashTable, tables.createStaticHashTable, tables.createStaticObjectTable);
|
|
274
|
-
const literal = resolved.value;
|
|
275
|
-
if (typeof literal !== 'string' && typeof literal !== 'number')
|
|
276
|
-
return;
|
|
443
|
+
defaultLiterals.forEach((literal, param) => {
|
|
277
444
|
varGroups
|
|
278
445
|
.get(param)
|
|
279
446
|
.forEach(({ cssVar, unit, written }) => (0, exports.applyVarFallback)(style, cssVar, literal, { unit, written }));
|
|
280
447
|
});
|
|
281
|
-
return { style, varGroups };
|
|
448
|
+
return { style, varGroups, derived };
|
|
282
449
|
};
|
|
283
450
|
exports.resolveDynamicStyle = resolveDynamicStyle;
|
package/dist/parser.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { CSSObject, Tables, StaticTable, KeyframesHashTable, ViewTransition
|
|
|
2
2
|
import type { Module, Expression, CallExpression, Identifier, KeyValueProperty, StringLiteral, NumericLiteral, BooleanLiteral, ObjectExpression, MemberExpression, TemplateLiteral, BinaryExpression, UnaryExpression, ParenthesisExpression, VariableDeclaration, VariableDeclarator, ExportDeclaration, ConditionalExpression, JSXExpression, ArrowFunctionExpression, FunctionExpression } from '@swc/core';
|
|
3
3
|
export declare function unwrapExpression(node: any): any;
|
|
4
4
|
export declare const getRootIdentifier: (node: Expression) => string | null;
|
|
5
|
+
export declare const expressionLabel: (node: Expression) => string;
|
|
5
6
|
export declare function resolveOriginError(node: Expression, rootName: string | null, localImports: Record<string, {
|
|
6
7
|
actualPath: string;
|
|
7
8
|
importedName: string;
|
|
@@ -45,6 +46,7 @@ export declare function traverse(node: Module | JSXExpression, visitor: {
|
|
|
45
46
|
export declare function objectExpressionToObject(node: ObjectExpression, staticTable: StaticTable, keyframesHashTable: KeyframesHashTable, viewTransitionHashTable: ViewTransitionHashTable, createThemeHashTable: CreateThemeHashTable, createThemeObjectTable: CreateThemeObjectTable, createHashTable: CreateHashTable, createStaticHashTable: CreateStaticHashTable, createStaticObjectTable: CreateStaticObjectTable, resolveVariable?: (name: string) => any): CSSObject;
|
|
46
47
|
export declare function collectLocalConstNodes(ast: Module): Map<string, any>;
|
|
47
48
|
export declare function collectLocalConsts(ast: Module): Record<string, any>;
|
|
49
|
+
export declare function readsParams(node: any, params: Set<string>): boolean;
|
|
48
50
|
export declare function resolveThemeSelector(node: Expression, staticTable: StaticTable, createStaticHashTable: CreateStaticHashTable, createStaticObjectTable: CreateStaticObjectTable): string;
|
|
49
51
|
export declare function resolveFileError(actualPath: string, importedName: string): {
|
|
50
52
|
filePath: string;
|
package/dist/parser.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.appendSheet = exports.t = exports.getRootIdentifier = void 0;
|
|
36
|
+
exports.appendSheet = exports.t = exports.expressionLabel = exports.getRootIdentifier = void 0;
|
|
37
37
|
exports.unwrapExpression = unwrapExpression;
|
|
38
38
|
exports.resolveOriginError = resolveOriginError;
|
|
39
39
|
exports.resolveComponentKey = resolveComponentKey;
|
|
@@ -41,6 +41,7 @@ exports.traverse = traverse;
|
|
|
41
41
|
exports.objectExpressionToObject = objectExpressionToObject;
|
|
42
42
|
exports.collectLocalConstNodes = collectLocalConstNodes;
|
|
43
43
|
exports.collectLocalConsts = collectLocalConsts;
|
|
44
|
+
exports.readsParams = readsParams;
|
|
44
45
|
exports.resolveThemeSelector = resolveThemeSelector;
|
|
45
46
|
exports.resolveFileError = resolveFileError;
|
|
46
47
|
exports.fileTableKeys = fileTableKeys;
|
|
@@ -127,12 +128,13 @@ const expressionLabel = (node) => {
|
|
|
127
128
|
if (exports.t.isMemberExpression(node)) {
|
|
128
129
|
const property = node.property;
|
|
129
130
|
if (property.type === 'Identifier')
|
|
130
|
-
return `${expressionLabel(node.object)}.${property.value}`;
|
|
131
|
+
return `${(0, exports.expressionLabel)(node.object)}.${property.value}`;
|
|
131
132
|
if (property.type === 'Computed')
|
|
132
|
-
return `${expressionLabel(node.object)}[${expressionLabel(property.expression)}]`;
|
|
133
|
+
return `${(0, exports.expressionLabel)(node.object)}[${(0, exports.expressionLabel)(property.expression)}]`;
|
|
133
134
|
}
|
|
134
135
|
return EXPRESSION_KINDS[node.type] ?? 'an expression';
|
|
135
136
|
};
|
|
137
|
+
exports.expressionLabel = expressionLabel;
|
|
136
138
|
const getNamespaceMember = (node, rootName) => {
|
|
137
139
|
node = unwrapExpression(node);
|
|
138
140
|
if (exports.t.isCallExpression(node)) {
|
|
@@ -299,6 +301,12 @@ function objectExpressionToObject(node, staticTable, keyframesHashTable, viewTra
|
|
|
299
301
|
const key = getPropertyKey(prop.key, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
300
302
|
if (!key)
|
|
301
303
|
return;
|
|
304
|
+
if (typeof key === 'string' &&
|
|
305
|
+
(key.startsWith(':') || key.startsWith('['))) {
|
|
306
|
+
const name = (0, zss_engine_1.findSameNameNesting)(key);
|
|
307
|
+
if (name)
|
|
308
|
+
throw new Error(`[plumeria] "${name}()" cannot be nested inside another "${name}()": "${key}". Rewrite the selector without nesting.`);
|
|
309
|
+
}
|
|
302
310
|
const val = unwrapExpression(prop.value);
|
|
303
311
|
if (exports.t.isIdentifier(val) || exports.t.isMemberExpression(val)) {
|
|
304
312
|
if (resolveVariable && exports.t.isMemberExpression(val)) {
|
|
@@ -309,7 +317,7 @@ function objectExpressionToObject(node, staticTable, keyframesHashTable, viewTra
|
|
|
309
317
|
[root]: resolved,
|
|
310
318
|
}));
|
|
311
319
|
if (member === undefined)
|
|
312
|
-
throw new Error(`[plumeria] Unknown style member: ${expressionLabel(val)} does not exist.`);
|
|
320
|
+
throw new Error(`[plumeria] Unknown style member: ${(0, exports.expressionLabel)(val)} does not exist.`);
|
|
313
321
|
obj[key] = member;
|
|
314
322
|
return;
|
|
315
323
|
}
|
|
@@ -715,7 +723,7 @@ function evaluateTemplateLiteral(node, staticTable, keyframesHashTable, viewTran
|
|
|
715
723
|
const expr = node.expressions[i];
|
|
716
724
|
const evaluatedExpr = evaluateExpression(expr, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
717
725
|
if (evaluatedExpr === null || typeof evaluatedExpr === 'object')
|
|
718
|
-
throw new Error(`[plumeria] Template value cannot be resolved to a primitive: ${expressionLabel(expr)} inside \${} must resolve to a string or number at build time.`);
|
|
726
|
+
throw new Error(`[plumeria] Template value cannot be resolved to a primitive: ${(0, exports.expressionLabel)(expr)} inside \${} must resolve to a string or number at build time.`);
|
|
719
727
|
result += String(evaluatedExpr);
|
|
720
728
|
}
|
|
721
729
|
}
|
|
@@ -872,7 +880,7 @@ function evaluateExpression(node, staticTable, keyframesHashTable, viewTransitio
|
|
|
872
880
|
if (resolvedStatic !== undefined) {
|
|
873
881
|
return resolvedStatic;
|
|
874
882
|
}
|
|
875
|
-
throw new Error(`[plumeria] Cannot resolve static member expression: ${expressionLabel(node)}. Its object must be a const or a value created by css.createStatic or css.createTheme.`);
|
|
883
|
+
throw new Error(`[plumeria] Cannot resolve static member expression: ${(0, exports.expressionLabel)(node)}. Its object must be a const or a value created by css.createStatic or css.createTheme.`);
|
|
876
884
|
}
|
|
877
885
|
if (exports.t.isBinaryExpression(node)) {
|
|
878
886
|
return evaluateBinaryExpression(node, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
@@ -892,12 +900,12 @@ function evaluateExpression(node, staticTable, keyframesHashTable, viewTransitio
|
|
|
892
900
|
if (node.operator === '~')
|
|
893
901
|
return ~value;
|
|
894
902
|
}
|
|
895
|
-
throw new Error(`[plumeria] Unsupported unary operand for ${node.operator}: ${expressionLabel(node.argument)} must resolve to a number at build time.`);
|
|
903
|
+
throw new Error(`[plumeria] Unsupported unary operand for ${node.operator}: ${(0, exports.expressionLabel)(node.argument)} must resolve to a number at build time.`);
|
|
896
904
|
}
|
|
897
905
|
if (exports.t.isParenthesisExpression(node)) {
|
|
898
906
|
return evaluateExpression(node.expression, staticTable, keyframesHashTable, viewTransitionHashTable, createThemeHashTable, createThemeObjectTable, createStaticHashTable, createStaticObjectTable);
|
|
899
907
|
}
|
|
900
|
-
throw new Error(`[plumeria] Unsupported expression type: ${expressionLabel(node)}. Style values must be literals, consts, or arithmetic and template expressions of them.`);
|
|
908
|
+
throw new Error(`[plumeria] Unsupported expression type: ${(0, exports.expressionLabel)(node)}. Style values must be literals, consts, or arithmetic and template expressions of them.`);
|
|
901
909
|
}
|
|
902
910
|
function resolveKeyframesTableMemberExpression(node, keyframesHashTable) {
|
|
903
911
|
if (exports.t.isIdentifier(node)) {
|
|
@@ -1858,22 +1866,27 @@ function runScan(scanCwd, styleProp) {
|
|
|
1858
1866
|
if (callArgs.some((a) => a.spread))
|
|
1859
1867
|
return null;
|
|
1860
1868
|
const runtime = [];
|
|
1869
|
+
const definite = new Set();
|
|
1861
1870
|
if (func.named) {
|
|
1862
1871
|
const argExpr = callArgs[0]?.expression;
|
|
1863
1872
|
if (callArgs.length > 1 ||
|
|
1864
1873
|
(argExpr && argExpr.type !== 'ObjectExpression'))
|
|
1865
1874
|
return null;
|
|
1866
|
-
const given = new
|
|
1875
|
+
const given = new Map();
|
|
1867
1876
|
(argExpr?.properties ?? []).forEach((prop) => {
|
|
1868
1877
|
if (prop.type === 'Identifier')
|
|
1869
|
-
given.
|
|
1878
|
+
given.set(prop.value, prop);
|
|
1870
1879
|
else if (prop.type === 'KeyValueProperty' &&
|
|
1871
1880
|
(exports.t.isIdentifier(prop.key) || exports.t.isStringLiteral(prop.key)))
|
|
1872
|
-
given.
|
|
1881
|
+
given.set(String(prop.key.value), prop.value);
|
|
1873
1882
|
});
|
|
1874
1883
|
for (const { key, local } of func.named) {
|
|
1875
|
-
|
|
1884
|
+
const source = given.get(key);
|
|
1885
|
+
if (source) {
|
|
1876
1886
|
runtime.push(local);
|
|
1887
|
+
if ((0, dynamicKey_1.isDefinedArgument)(source))
|
|
1888
|
+
definite.add(local);
|
|
1889
|
+
}
|
|
1877
1890
|
else if (!func.defaults?.[local])
|
|
1878
1891
|
return null;
|
|
1879
1892
|
}
|
|
@@ -1883,14 +1896,20 @@ function runScan(scanCwd, styleProp) {
|
|
|
1883
1896
|
return null;
|
|
1884
1897
|
}
|
|
1885
1898
|
else {
|
|
1886
|
-
callArgs.forEach((
|
|
1899
|
+
callArgs.forEach((callArg, i) => {
|
|
1887
1900
|
const param = func.params[i];
|
|
1888
|
-
if (param)
|
|
1889
|
-
|
|
1901
|
+
if (!param)
|
|
1902
|
+
return;
|
|
1903
|
+
runtime.push(param);
|
|
1904
|
+
if ((0, dynamicKey_1.isDefinedArgument)(callArg.expression))
|
|
1905
|
+
definite.add(param);
|
|
1890
1906
|
});
|
|
1891
1907
|
}
|
|
1892
|
-
const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime, dynamicStaticTable, dynamicStyleTables, new Set());
|
|
1893
|
-
const hasVars =
|
|
1908
|
+
const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime, dynamicStaticTable, dynamicStyleTables, new Set(), definite);
|
|
1909
|
+
const hasVars = [
|
|
1910
|
+
...runtime,
|
|
1911
|
+
...resolved.derived.map(({ name }) => name),
|
|
1912
|
+
].some((param) => (resolved.varGroups.get(param) ?? []).length > 0);
|
|
1894
1913
|
return { style: resolved.style, hasVars };
|
|
1895
1914
|
};
|
|
1896
1915
|
const resolveCallStylePropInScan = (expr) => {
|
package/dist/stylePropFilter.js
CHANGED
|
@@ -5,7 +5,7 @@ const CORE = '@plumeria/core';
|
|
|
5
5
|
const isIdentifierStart = (c) => (c >= 65 && c <= 90) || (c >= 97 && c <= 122) || c === 95 || c === 36;
|
|
6
6
|
const isNameChar = (c) => isIdentifierStart(c) || (c >= 48 && c <= 57) || c === 46 || c === 45;
|
|
7
7
|
const isSpace = (c) => c === 32 || (c >= 9 && c <= 13);
|
|
8
|
-
const EXPRESSION_BEFORE = new Set(Array.from('(,=:[!&|?{}
|
|
8
|
+
const EXPRESSION_BEFORE = new Set(Array.from('(,=:[!&|?{};+-*%<>~^/', (c) => c.charCodeAt(0)));
|
|
9
9
|
const EXPRESSION_WORDS = new Set([
|
|
10
10
|
'return',
|
|
11
11
|
'yield',
|
|
@@ -202,7 +202,7 @@ const writesAttribute = (source, name) => {
|
|
|
202
202
|
if (end === -1)
|
|
203
203
|
return true;
|
|
204
204
|
i = end;
|
|
205
|
-
previous = 96;
|
|
205
|
+
previous = source.charCodeAt(i) === 123 ? 123 : 96;
|
|
206
206
|
continue;
|
|
207
207
|
}
|
|
208
208
|
if (c === 123) {
|
|
@@ -217,7 +217,7 @@ const writesAttribute = (source, name) => {
|
|
|
217
217
|
if (end === -1)
|
|
218
218
|
return true;
|
|
219
219
|
i = end;
|
|
220
|
-
previous = 96;
|
|
220
|
+
previous = source.charCodeAt(i) === 123 ? 123 : 96;
|
|
221
221
|
continue;
|
|
222
222
|
}
|
|
223
223
|
if (kind === 'attribute') {
|
|
@@ -237,6 +237,7 @@ const writesAttribute = (source, name) => {
|
|
|
237
237
|
source.charCodeAt(previousEnd - 2) === previous;
|
|
238
238
|
const expressionStart = previous === 0 ||
|
|
239
239
|
(EXPRESSION_BEFORE.has(previous) && !afterUpdate) ||
|
|
240
|
+
(previous === 46 && source.startsWith('...', previousEnd - 3)) ||
|
|
240
241
|
(isNameChar(previous) &&
|
|
241
242
|
EXPRESSION_WORDS.has(wordBefore(source, previousEnd)));
|
|
242
243
|
if (c === 47 && expressionStart) {
|
package/dist/transform.js
CHANGED
|
@@ -1200,18 +1200,40 @@ const transformSource = async (env) => {
|
|
|
1200
1200
|
runtime.push({ param: p, source: callArg.expression });
|
|
1201
1201
|
});
|
|
1202
1202
|
}
|
|
1203
|
-
const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables, providedParams
|
|
1204
|
-
|
|
1205
|
-
|
|
1203
|
+
const resolved = (0, dynamicKey_1.resolveDynamicStyle)(func, runtime.map(({ param }) => param), tempStaticTable, dynamicStyleTables, providedParams, new Set(runtime
|
|
1204
|
+
.filter(({ source }) => (0, dynamicKey_1.isDefinedArgument)(source))
|
|
1205
|
+
.map(({ param }) => param)));
|
|
1206
|
+
const { style, varGroups, derived } = resolved;
|
|
1207
|
+
const argSources = new Map();
|
|
1206
1208
|
runtime.forEach(({ param, source }) => {
|
|
1207
|
-
const groups = varGroups.get(param);
|
|
1208
|
-
if (!groups?.length)
|
|
1209
|
-
return;
|
|
1210
1209
|
const argStart = source.span.start - baseByteOffset;
|
|
1211
1210
|
const argEnd = source.span.end - baseByteOffset;
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1211
|
+
argSources.set(param, sourceBuffer.subarray(argStart, argEnd).toString('utf-8'));
|
|
1212
|
+
});
|
|
1213
|
+
const runtimeSources = runtime.map(({ param }) => ({
|
|
1214
|
+
name: param,
|
|
1215
|
+
argSource: argSources.get(param),
|
|
1216
|
+
}));
|
|
1217
|
+
derived.forEach(({ name, pieces }) => {
|
|
1218
|
+
runtimeSources.push({
|
|
1219
|
+
name,
|
|
1220
|
+
argSource: pieces
|
|
1221
|
+
.map((piece) => {
|
|
1222
|
+
if (typeof piece === 'string')
|
|
1223
|
+
return piece;
|
|
1224
|
+
const argument = `(${argSources.get(piece.param)})`;
|
|
1225
|
+
return piece.fallback === undefined
|
|
1226
|
+
? argument
|
|
1227
|
+
: `(${argument} === undefined ? ${piece.fallback} : ${argument})`;
|
|
1228
|
+
})
|
|
1229
|
+
.join(''),
|
|
1230
|
+
});
|
|
1231
|
+
});
|
|
1232
|
+
const vars = [];
|
|
1233
|
+
runtimeSources.forEach(({ name, argSource }) => {
|
|
1234
|
+
const groups = varGroups.get(name);
|
|
1235
|
+
if (!groups?.length)
|
|
1236
|
+
return;
|
|
1215
1237
|
const maybeNumber = Number(argSource);
|
|
1216
1238
|
groups.forEach(({ cssVar, prop, unit, written }) => {
|
|
1217
1239
|
let valueExpr;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumeria/utils",
|
|
3
|
-
"version": "19.
|
|
3
|
+
"version": "19.7.0",
|
|
4
4
|
"description": "Plumeria Utils",
|
|
5
5
|
"author": "Refirst 11",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@swc/core": "1.15.47",
|
|
26
26
|
"lightningcss": "^1.32.0",
|
|
27
27
|
"postcss": "8.5.26",
|
|
28
|
-
"zss-engine": "2.8.
|
|
28
|
+
"zss-engine": "2.8.2"
|
|
29
29
|
},
|
|
30
30
|
"publishConfig": {
|
|
31
31
|
"access": "public",
|