@fluffjs/cli 0.4.5 → 0.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/BabelHelpers.js +8 -5
- package/Cli.d.ts +9 -5
- package/Cli.js +218 -155
- package/CodeGenerator.d.ts +19 -10
- package/CodeGenerator.js +146 -106
- package/ComponentCompiler.d.ts +19 -3
- package/ComponentCompiler.js +175 -47
- package/DevServer.d.ts +6 -4
- package/DevServer.js +102 -23
- package/DomPreProcessor.js +22 -40
- package/IndexHtmlTransformer.js +20 -28
- package/PluginLoader.d.ts +22 -0
- package/PluginLoader.js +286 -0
- package/PluginManager.d.ts +39 -0
- package/PluginManager.js +209 -0
- package/TemplateParser.d.ts +5 -0
- package/TemplateParser.js +55 -0
- package/babel-plugin-directive.d.ts +12 -0
- package/babel-plugin-directive.js +78 -0
- package/babel-plugin-reactive.js +19 -14
- package/fluff-esbuild-plugin.js +66 -22
- package/interfaces/ClassTransformContext.d.ts +8 -0
- package/interfaces/ClassTransformContext.js +1 -0
- package/interfaces/CodeGenContext.d.ts +9 -0
- package/interfaces/CodeGenContext.js +1 -0
- package/interfaces/DiscoveryInfo.d.ts +15 -0
- package/interfaces/DiscoveryInfo.js +1 -0
- package/interfaces/EntryPointContext.d.ts +6 -0
- package/interfaces/EntryPointContext.js +1 -0
- package/interfaces/FluffConfigInterface.d.ts +2 -0
- package/interfaces/FluffPlugin.d.ts +26 -0
- package/interfaces/FluffPlugin.js +1 -0
- package/interfaces/FluffPluginOptions.d.ts +3 -0
- package/interfaces/FluffTarget.d.ts +1 -0
- package/interfaces/HtmlTransformOptions.d.ts +2 -0
- package/interfaces/PluginCustomTable.d.ts +6 -0
- package/interfaces/PluginCustomTable.js +1 -0
- package/interfaces/PluginHookDependency.d.ts +5 -0
- package/interfaces/PluginHookDependency.js +1 -0
- package/interfaces/PluginHookName.d.ts +2 -0
- package/interfaces/PluginHookName.js +1 -0
- package/interfaces/ScopeElementConfig.d.ts +5 -0
- package/interfaces/ScopeElementConfig.js +1 -0
- package/interfaces/index.d.ts +8 -0
- package/package.json +5 -3
- package/PeerDependencies.d.ts +0 -6
- package/PeerDependencies.js +0 -7
package/CodeGenerator.d.ts
CHANGED
|
@@ -4,7 +4,9 @@ import type { ForMarkerConfig } from './interfaces/ForMarkerConfig.js';
|
|
|
4
4
|
import type { IfMarkerConfig } from './interfaces/IfMarkerConfig.js';
|
|
5
5
|
import type { SwitchMarkerConfig } from './interfaces/SwitchMarkerConfig.js';
|
|
6
6
|
import type { TextMarkerConfig } from './interfaces/TextMarkerConfig.js';
|
|
7
|
+
import type { PluginManager } from './PluginManager.js';
|
|
7
8
|
import type { ParsedTemplate } from './TemplateParser.js';
|
|
9
|
+
import type { Parse5DocumentFragment } from './Typeguards.js';
|
|
8
10
|
export type { BreakMarkerConfig } from './interfaces/BreakMarkerConfig.js';
|
|
9
11
|
export type { ForMarkerConfig } from './interfaces/ForMarkerConfig.js';
|
|
10
12
|
export type { IfMarkerConfig } from './interfaces/IfMarkerConfig.js';
|
|
@@ -42,14 +44,15 @@ export type CompactBinding = [
|
|
|
42
44
|
Record<string, unknown>?
|
|
43
45
|
];
|
|
44
46
|
export declare class CodeGenerator {
|
|
45
|
-
private readonly componentSelectors;
|
|
46
|
-
private readonly componentSelector;
|
|
47
47
|
private static readonly globalExprIdsByExpr;
|
|
48
48
|
private static globalExprs;
|
|
49
49
|
private static readonly globalHandlerIdsByExpr;
|
|
50
50
|
private static globalHandlers;
|
|
51
51
|
private static readonly globalStringTable;
|
|
52
52
|
private static readonly globalStringIndices;
|
|
53
|
+
private readonly componentSelectors;
|
|
54
|
+
private readonly directiveSelectors;
|
|
55
|
+
private readonly componentSelector;
|
|
53
56
|
private markerId;
|
|
54
57
|
private readonly markerConfigs;
|
|
55
58
|
private readonly usedExprIds;
|
|
@@ -58,25 +61,29 @@ export declare class CodeGenerator {
|
|
|
58
61
|
private rootFragment;
|
|
59
62
|
private readonly collectedTemplates;
|
|
60
63
|
private readonly namespaceStack;
|
|
61
|
-
constructor(componentSelectors?: Set<string>, componentSelector?: string);
|
|
64
|
+
constructor(componentSelectors?: Set<string>, componentSelector?: string, directiveSelectors?: Set<string>);
|
|
62
65
|
static resetGlobalState(): void;
|
|
63
66
|
static internString(str: string): number;
|
|
64
67
|
static getStringTable(): string[];
|
|
68
|
+
static internExpression(expr: string): number;
|
|
69
|
+
static generateGlobalExprTable(pluginManager?: PluginManager): string;
|
|
70
|
+
private static buildExpressionArrowFunction;
|
|
71
|
+
private static buildHandlerArrowFunction;
|
|
72
|
+
private static normalizeCompiledExpr;
|
|
65
73
|
generateRenderMethod(template: ParsedTemplate, styles?: string): string;
|
|
66
74
|
generateHtml(template: ParsedTemplate): string;
|
|
67
75
|
generateRenderMethodFromHtml(html: string, styles?: string, markerConfigExpr?: t.Expression): string;
|
|
68
76
|
getMarkerConfigExpression(): t.Expression;
|
|
77
|
+
generateBindingsSetup(): string;
|
|
78
|
+
getBindingsMap(): Record<string, CompactBinding[]>;
|
|
79
|
+
getBindingsMapRef(): Map<string, CompactBinding[]>;
|
|
80
|
+
getMarkerConfigsRef(): Map<number, MarkerConfig>;
|
|
81
|
+
getRootFragment(): Parse5DocumentFragment | null;
|
|
82
|
+
generateExpressionAssignments(): string;
|
|
69
83
|
private buildMarkerConfigExpression;
|
|
70
84
|
private buildMarkerConfigArray;
|
|
71
85
|
private buildCompactDepsExpression;
|
|
72
86
|
private buildCompactPropertyChainExpression;
|
|
73
|
-
generateBindingsSetup(): string;
|
|
74
|
-
getBindingsMap(): Record<string, CompactBinding[]>;
|
|
75
|
-
generateExpressionAssignments(): string;
|
|
76
|
-
static generateGlobalExprTable(): string;
|
|
77
|
-
private static buildExpressionArrowFunction;
|
|
78
|
-
private static buildHandlerArrowFunction;
|
|
79
|
-
private static normalizeCompiledExpr;
|
|
80
87
|
private nextMarkerId;
|
|
81
88
|
private renderNodesToParent;
|
|
82
89
|
private renderNodeToParent;
|
|
@@ -85,6 +92,8 @@ export declare class CodeGenerator {
|
|
|
85
92
|
private renderToTemplateWithNamespace;
|
|
86
93
|
private renderTextToParent;
|
|
87
94
|
private isComponentTag;
|
|
95
|
+
private findMatchingDirectives;
|
|
96
|
+
private matchesDirectiveSelector;
|
|
88
97
|
private serializeBinding;
|
|
89
98
|
private internDep;
|
|
90
99
|
private internExpression;
|
package/CodeGenerator.js
CHANGED
|
@@ -20,14 +20,15 @@ const BINDING_TYPE_MAP = {
|
|
|
20
20
|
'ref': BIND_REF
|
|
21
21
|
};
|
|
22
22
|
export class CodeGenerator {
|
|
23
|
-
componentSelectors;
|
|
24
|
-
componentSelector;
|
|
25
23
|
static globalExprIdsByExpr = new Map();
|
|
26
24
|
static globalExprs = [];
|
|
27
25
|
static globalHandlerIdsByExpr = new Map();
|
|
28
26
|
static globalHandlers = [];
|
|
29
27
|
static globalStringTable = [];
|
|
30
28
|
static globalStringIndices = new Map();
|
|
29
|
+
componentSelectors;
|
|
30
|
+
directiveSelectors;
|
|
31
|
+
componentSelector;
|
|
31
32
|
markerId = 0;
|
|
32
33
|
markerConfigs = new Map();
|
|
33
34
|
usedExprIds = [];
|
|
@@ -36,9 +37,10 @@ export class CodeGenerator {
|
|
|
36
37
|
rootFragment = null;
|
|
37
38
|
collectedTemplates = [];
|
|
38
39
|
namespaceStack = [Parse5Helpers.NS_HTML];
|
|
39
|
-
constructor(componentSelectors = new Set(), componentSelector = '') {
|
|
40
|
+
constructor(componentSelectors = new Set(), componentSelector = '', directiveSelectors = new Set()) {
|
|
40
41
|
this.componentSelectors = componentSelectors;
|
|
41
42
|
this.componentSelector = componentSelector;
|
|
43
|
+
this.directiveSelectors = directiveSelectors;
|
|
42
44
|
}
|
|
43
45
|
static resetGlobalState() {
|
|
44
46
|
CodeGenerator.globalExprIdsByExpr.clear();
|
|
@@ -61,6 +63,65 @@ export class CodeGenerator {
|
|
|
61
63
|
static getStringTable() {
|
|
62
64
|
return CodeGenerator.globalStringTable;
|
|
63
65
|
}
|
|
66
|
+
static internExpression(expr) {
|
|
67
|
+
const existing = CodeGenerator.globalExprIdsByExpr.get(expr);
|
|
68
|
+
if (existing !== undefined) {
|
|
69
|
+
return existing;
|
|
70
|
+
}
|
|
71
|
+
const id = CodeGenerator.globalExprs.length;
|
|
72
|
+
CodeGenerator.globalExprs.push(expr);
|
|
73
|
+
CodeGenerator.globalExprIdsByExpr.set(expr, id);
|
|
74
|
+
return id;
|
|
75
|
+
}
|
|
76
|
+
static generateGlobalExprTable(pluginManager) {
|
|
77
|
+
const exprElements = CodeGenerator.globalExprs.map(e => {
|
|
78
|
+
const normalizedExpr = CodeGenerator.normalizeCompiledExpr(e);
|
|
79
|
+
return CodeGenerator.buildExpressionArrowFunction(['t', 'l'], normalizedExpr);
|
|
80
|
+
});
|
|
81
|
+
const handlerElements = CodeGenerator.globalHandlers.map(h => {
|
|
82
|
+
const normalizedHandler = CodeGenerator.normalizeCompiledExpr(h);
|
|
83
|
+
return CodeGenerator.buildHandlerArrowFunction(['t', 'l', '__ev'], normalizedHandler);
|
|
84
|
+
});
|
|
85
|
+
const stringElements = CodeGenerator.globalStringTable.map(s => t.stringLiteral(s));
|
|
86
|
+
const fluffBaseImport = t.importDeclaration([t.importSpecifier(t.identifier('FluffBase'), t.identifier('FluffBase'))], t.stringLiteral('@fluffjs/fluff'));
|
|
87
|
+
const tableArgs = [
|
|
88
|
+
t.arrayExpression(exprElements), t.arrayExpression(handlerElements), t.arrayExpression(stringElements)
|
|
89
|
+
];
|
|
90
|
+
if (pluginManager?.hasPlugins) {
|
|
91
|
+
const customTables = pluginManager.collectCustomTables();
|
|
92
|
+
if (customTables.length > 0) {
|
|
93
|
+
const tablesObject = t.objectExpression(customTables.map(table => t.objectProperty(t.stringLiteral(table.name), t.arrayExpression(table.elements))));
|
|
94
|
+
tableArgs.push(tablesObject);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const setExprTableCall = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('FluffBase'), t.identifier('__setExpressionTable')), tableArgs));
|
|
98
|
+
const program = t.program([fluffBaseImport, setExprTableCall]);
|
|
99
|
+
return generate(program, { compact: false }).code;
|
|
100
|
+
}
|
|
101
|
+
static buildExpressionArrowFunction(params, bodyExpr) {
|
|
102
|
+
const paramNodes = params.map(p => t.identifier(p));
|
|
103
|
+
const exprAst = parse(`(${bodyExpr})`, { sourceType: 'module' });
|
|
104
|
+
const [exprStmt] = exprAst.program.body;
|
|
105
|
+
if (t.isExpressionStatement(exprStmt)) {
|
|
106
|
+
return t.arrowFunctionExpression(paramNodes, exprStmt.expression);
|
|
107
|
+
}
|
|
108
|
+
return t.arrowFunctionExpression(paramNodes, t.identifier('undefined'));
|
|
109
|
+
}
|
|
110
|
+
static buildHandlerArrowFunction(params, bodyCode) {
|
|
111
|
+
const paramNodes = params.map(p => t.identifier(p));
|
|
112
|
+
const bodyStatements = parseMethodBody(bodyCode);
|
|
113
|
+
return t.arrowFunctionExpression(paramNodes, t.blockStatement(bodyStatements));
|
|
114
|
+
}
|
|
115
|
+
static normalizeCompiledExpr(expr) {
|
|
116
|
+
let result = expr;
|
|
117
|
+
if (result.includes('this')) {
|
|
118
|
+
result = ExpressionTransformer.replaceThisExpression(result, 't');
|
|
119
|
+
}
|
|
120
|
+
if (result.includes('$event')) {
|
|
121
|
+
result = ExpressionTransformer.renameVariable(result, '$event', '__ev');
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
64
125
|
generateRenderMethod(template, styles) {
|
|
65
126
|
this.markerId = 0;
|
|
66
127
|
this.markerConfigs.clear();
|
|
@@ -101,11 +162,50 @@ export class CodeGenerator {
|
|
|
101
162
|
getMarkerConfigExpression() {
|
|
102
163
|
return this.buildMarkerConfigExpression();
|
|
103
164
|
}
|
|
165
|
+
generateBindingsSetup() {
|
|
166
|
+
const statements = [
|
|
167
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('__initializeMarkers')), [t.identifier('MarkerManager')])),
|
|
168
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.super(), t.identifier('__setupBindings')), []))
|
|
169
|
+
];
|
|
170
|
+
const program = t.program(statements);
|
|
171
|
+
return generate(program, { compact: false }).code;
|
|
172
|
+
}
|
|
173
|
+
getBindingsMap() {
|
|
174
|
+
return Object.fromEntries(this.bindingsMap.entries());
|
|
175
|
+
}
|
|
176
|
+
getBindingsMapRef() {
|
|
177
|
+
return this.bindingsMap;
|
|
178
|
+
}
|
|
179
|
+
getMarkerConfigsRef() {
|
|
180
|
+
return this.markerConfigs;
|
|
181
|
+
}
|
|
182
|
+
getRootFragment() {
|
|
183
|
+
return this.rootFragment;
|
|
184
|
+
}
|
|
185
|
+
generateExpressionAssignments() {
|
|
186
|
+
const statements = [];
|
|
187
|
+
for (const id of this.usedExprIds) {
|
|
188
|
+
const expr = CodeGenerator.globalExprs[id];
|
|
189
|
+
const normalizedExpr = CodeGenerator.normalizeCompiledExpr(expr);
|
|
190
|
+
const arrowFunc = CodeGenerator.buildExpressionArrowFunction(['t', 'l'], normalizedExpr);
|
|
191
|
+
statements.push(t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.memberExpression(t.identifier('FluffBase'), t.identifier('__e')), t.numericLiteral(id), true), arrowFunc)));
|
|
192
|
+
}
|
|
193
|
+
for (const id of this.usedHandlerIds) {
|
|
194
|
+
const handler = CodeGenerator.globalHandlers[id];
|
|
195
|
+
const normalizedHandler = CodeGenerator.normalizeCompiledExpr(handler);
|
|
196
|
+
const arrowFunc = CodeGenerator.buildHandlerArrowFunction(['t', 'l', '__ev'], normalizedHandler);
|
|
197
|
+
statements.push(t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.memberExpression(t.identifier('FluffBase'), t.identifier('__h')), t.numericLiteral(id), true), arrowFunc)));
|
|
198
|
+
}
|
|
199
|
+
if (statements.length === 0) {
|
|
200
|
+
return '';
|
|
201
|
+
}
|
|
202
|
+
const program = t.program(statements);
|
|
203
|
+
return generate(program, { compact: false }).code;
|
|
204
|
+
}
|
|
104
205
|
buildMarkerConfigExpression() {
|
|
105
206
|
const entries = Array.from(this.markerConfigs.entries())
|
|
106
207
|
.map(([id, config]) => t.arrayExpression([
|
|
107
|
-
t.numericLiteral(id),
|
|
108
|
-
this.buildMarkerConfigArray(config)
|
|
208
|
+
t.numericLiteral(id), this.buildMarkerConfigArray(config)
|
|
109
209
|
]));
|
|
110
210
|
return t.arrayExpression(entries);
|
|
111
211
|
}
|
|
@@ -119,12 +219,10 @@ export class CodeGenerator {
|
|
|
119
219
|
t.numericLiteral(typeNum),
|
|
120
220
|
t.numericLiteral(config.exprId),
|
|
121
221
|
config.deps ? this.buildCompactDepsExpression(config.deps) : t.nullLiteral(),
|
|
122
|
-
config.pipes && config.pipes.length > 0
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
])))
|
|
127
|
-
: t.nullLiteral()
|
|
222
|
+
config.pipes && config.pipes.length > 0 ? t.arrayExpression(config.pipes.map(pipe => t.arrayExpression([
|
|
223
|
+
t.numericLiteral(CodeGenerator.internString(pipe.name)),
|
|
224
|
+
t.arrayExpression(pipe.argExprIds.map(arg => t.numericLiteral(arg)))
|
|
225
|
+
]))) : t.nullLiteral()
|
|
128
226
|
];
|
|
129
227
|
return t.arrayExpression(elements);
|
|
130
228
|
}
|
|
@@ -147,18 +245,14 @@ export class CodeGenerator {
|
|
|
147
245
|
t.numericLiteral(config.iterableExprId),
|
|
148
246
|
t.booleanLiteral(config.hasEmpty),
|
|
149
247
|
config.deps ? this.buildCompactDepsExpression(config.deps) : t.nullLiteral(),
|
|
150
|
-
config.trackBy !== undefined
|
|
151
|
-
? t.numericLiteral(CodeGenerator.internString(config.trackBy))
|
|
152
|
-
: t.nullLiteral()
|
|
248
|
+
config.trackBy !== undefined ? t.numericLiteral(CodeGenerator.internString(config.trackBy)) : t.nullLiteral()
|
|
153
249
|
]);
|
|
154
250
|
}
|
|
155
251
|
else if (config.type === 'switch') {
|
|
156
252
|
const cases = t.arrayExpression(config.cases.map(caseConfig => t.arrayExpression([
|
|
157
253
|
t.booleanLiteral(caseConfig.isDefault),
|
|
158
254
|
t.booleanLiteral(caseConfig.fallthrough),
|
|
159
|
-
caseConfig.valueExprId !== undefined
|
|
160
|
-
? t.numericLiteral(caseConfig.valueExprId)
|
|
161
|
-
: t.nullLiteral()
|
|
255
|
+
caseConfig.valueExprId !== undefined ? t.numericLiteral(caseConfig.valueExprId) : t.nullLiteral()
|
|
162
256
|
])));
|
|
163
257
|
return t.arrayExpression([
|
|
164
258
|
t.numericLiteral(typeNum),
|
|
@@ -181,80 +275,6 @@ export class CodeGenerator {
|
|
|
181
275
|
}
|
|
182
276
|
return t.numericLiteral(CodeGenerator.internString(dep));
|
|
183
277
|
}
|
|
184
|
-
generateBindingsSetup() {
|
|
185
|
-
const statements = [
|
|
186
|
-
t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('__initializeMarkers')), [t.identifier('MarkerManager')])),
|
|
187
|
-
t.expressionStatement(t.callExpression(t.memberExpression(t.super(), t.identifier('__setupBindings')), []))
|
|
188
|
-
];
|
|
189
|
-
const program = t.program(statements);
|
|
190
|
-
return generate(program, { compact: false }).code;
|
|
191
|
-
}
|
|
192
|
-
getBindingsMap() {
|
|
193
|
-
return Object.fromEntries(this.bindingsMap.entries());
|
|
194
|
-
}
|
|
195
|
-
generateExpressionAssignments() {
|
|
196
|
-
const statements = [];
|
|
197
|
-
for (const id of this.usedExprIds) {
|
|
198
|
-
const expr = CodeGenerator.globalExprs[id];
|
|
199
|
-
const normalizedExpr = CodeGenerator.normalizeCompiledExpr(expr);
|
|
200
|
-
const arrowFunc = CodeGenerator.buildExpressionArrowFunction(['t', 'l'], normalizedExpr);
|
|
201
|
-
statements.push(t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.memberExpression(t.identifier('FluffBase'), t.identifier('__e')), t.numericLiteral(id), true), arrowFunc)));
|
|
202
|
-
}
|
|
203
|
-
for (const id of this.usedHandlerIds) {
|
|
204
|
-
const handler = CodeGenerator.globalHandlers[id];
|
|
205
|
-
const normalizedHandler = CodeGenerator.normalizeCompiledExpr(handler);
|
|
206
|
-
const arrowFunc = CodeGenerator.buildHandlerArrowFunction(['t', 'l', '__ev'], normalizedHandler);
|
|
207
|
-
statements.push(t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.memberExpression(t.identifier('FluffBase'), t.identifier('__h')), t.numericLiteral(id), true), arrowFunc)));
|
|
208
|
-
}
|
|
209
|
-
if (statements.length === 0) {
|
|
210
|
-
return '';
|
|
211
|
-
}
|
|
212
|
-
const program = t.program(statements);
|
|
213
|
-
return generate(program, { compact: false }).code;
|
|
214
|
-
}
|
|
215
|
-
static generateGlobalExprTable() {
|
|
216
|
-
const exprElements = CodeGenerator.globalExprs.map(e => {
|
|
217
|
-
const normalizedExpr = CodeGenerator.normalizeCompiledExpr(e);
|
|
218
|
-
return CodeGenerator.buildExpressionArrowFunction(['t', 'l'], normalizedExpr);
|
|
219
|
-
});
|
|
220
|
-
const handlerElements = CodeGenerator.globalHandlers.map(h => {
|
|
221
|
-
const normalizedHandler = CodeGenerator.normalizeCompiledExpr(h);
|
|
222
|
-
return CodeGenerator.buildHandlerArrowFunction(['t', 'l', '__ev'], normalizedHandler);
|
|
223
|
-
});
|
|
224
|
-
const stringElements = CodeGenerator.globalStringTable.map(s => t.stringLiteral(s));
|
|
225
|
-
const fluffBaseImport = t.importDeclaration([t.importSpecifier(t.identifier('FluffBase'), t.identifier('FluffBase'))], t.stringLiteral('@fluffjs/fluff'));
|
|
226
|
-
const setExprTableCall = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('FluffBase'), t.identifier('__setExpressionTable')), [
|
|
227
|
-
t.arrayExpression(exprElements),
|
|
228
|
-
t.arrayExpression(handlerElements),
|
|
229
|
-
t.arrayExpression(stringElements)
|
|
230
|
-
]));
|
|
231
|
-
const program = t.program([fluffBaseImport, setExprTableCall]);
|
|
232
|
-
return generate(program, { compact: false }).code;
|
|
233
|
-
}
|
|
234
|
-
static buildExpressionArrowFunction(params, bodyExpr) {
|
|
235
|
-
const paramNodes = params.map(p => t.identifier(p));
|
|
236
|
-
const exprAst = parse(`(${bodyExpr})`, { sourceType: 'module' });
|
|
237
|
-
const [exprStmt] = exprAst.program.body;
|
|
238
|
-
if (t.isExpressionStatement(exprStmt)) {
|
|
239
|
-
return t.arrowFunctionExpression(paramNodes, exprStmt.expression);
|
|
240
|
-
}
|
|
241
|
-
return t.arrowFunctionExpression(paramNodes, t.identifier('undefined'));
|
|
242
|
-
}
|
|
243
|
-
static buildHandlerArrowFunction(params, bodyCode) {
|
|
244
|
-
const paramNodes = params.map(p => t.identifier(p));
|
|
245
|
-
const bodyStatements = parseMethodBody(bodyCode);
|
|
246
|
-
return t.arrowFunctionExpression(paramNodes, t.blockStatement(bodyStatements));
|
|
247
|
-
}
|
|
248
|
-
static normalizeCompiledExpr(expr) {
|
|
249
|
-
let result = expr;
|
|
250
|
-
if (result.includes('this')) {
|
|
251
|
-
result = ExpressionTransformer.replaceThisExpression(result, 't');
|
|
252
|
-
}
|
|
253
|
-
if (result.includes('$event')) {
|
|
254
|
-
result = ExpressionTransformer.renameVariable(result, '$event', '__ev');
|
|
255
|
-
}
|
|
256
|
-
return result;
|
|
257
|
-
}
|
|
258
278
|
nextMarkerId() {
|
|
259
279
|
return this.markerId++;
|
|
260
280
|
}
|
|
@@ -296,6 +316,10 @@ export class CodeGenerator {
|
|
|
296
316
|
if (this.isComponentTag(node.tagName)) {
|
|
297
317
|
attrs.push({ name: 'x-fluff-component', value: '' });
|
|
298
318
|
}
|
|
319
|
+
const matchedDirectives = this.findMatchingDirectives(node);
|
|
320
|
+
if (matchedDirectives.length > 0) {
|
|
321
|
+
attrs.push({ name: 'data-fluff-directives', value: matchedDirectives.join(',') });
|
|
322
|
+
}
|
|
299
323
|
for (const [name, value] of Object.entries(node.attributes)) {
|
|
300
324
|
attrs.push({ name, value });
|
|
301
325
|
}
|
|
@@ -338,7 +362,12 @@ export class CodeGenerator {
|
|
|
338
362
|
const currentNs = this.getCurrentNamespace();
|
|
339
363
|
if (currentNs !== Parse5Helpers.NS_HTML) {
|
|
340
364
|
const wrapperTag = currentNs === Parse5Helpers.NS_SVG ? 'svg' : 'math';
|
|
341
|
-
const wrapper = Parse5Helpers.createElement(wrapperTag, [
|
|
365
|
+
const wrapper = Parse5Helpers.createElement(wrapperTag, [
|
|
366
|
+
{
|
|
367
|
+
name: 'data-fluff-ns-wrapper',
|
|
368
|
+
value: ''
|
|
369
|
+
}
|
|
370
|
+
], currentNs);
|
|
342
371
|
Parse5Helpers.appendChild(tplContent, wrapper);
|
|
343
372
|
this.renderNodesToParent(nodes, wrapper);
|
|
344
373
|
}
|
|
@@ -352,20 +381,35 @@ export class CodeGenerator {
|
|
|
352
381
|
Parse5Helpers.appendText(parent, node.content);
|
|
353
382
|
}
|
|
354
383
|
isComponentTag(tagName) {
|
|
355
|
-
const resolvedTagName = tagName.startsWith(RESTRICTED_ELEMENT_PREFIX)
|
|
356
|
-
? tagName.slice(RESTRICTED_ELEMENT_PREFIX.length)
|
|
357
|
-
: tagName;
|
|
384
|
+
const resolvedTagName = tagName.startsWith(RESTRICTED_ELEMENT_PREFIX) ? tagName.slice(RESTRICTED_ELEMENT_PREFIX.length) : tagName;
|
|
358
385
|
return this.componentSelectors.has(resolvedTagName);
|
|
359
386
|
}
|
|
387
|
+
findMatchingDirectives(node) {
|
|
388
|
+
const matched = [];
|
|
389
|
+
for (const selector of this.directiveSelectors) {
|
|
390
|
+
if (this.matchesDirectiveSelector(node, selector)) {
|
|
391
|
+
matched.push(selector);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return matched;
|
|
395
|
+
}
|
|
396
|
+
matchesDirectiveSelector(node, selector) {
|
|
397
|
+
if (selector.startsWith('[') && selector.endsWith(']')) {
|
|
398
|
+
const attrName = selector.slice(1, -1);
|
|
399
|
+
const attrNameLower = attrName.toLowerCase();
|
|
400
|
+
const hasAttr = attrNameLower in node.attributes;
|
|
401
|
+
const hasBinding = node.bindings.some(b => b.name === attrName);
|
|
402
|
+
return hasAttr || hasBinding;
|
|
403
|
+
}
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
360
406
|
serializeBinding(binding) {
|
|
361
407
|
const nameIdx = CodeGenerator.internString(binding.name);
|
|
362
408
|
const bindType = BINDING_TYPE_MAP[binding.binding];
|
|
363
409
|
if (binding.binding === 'ref') {
|
|
364
410
|
return [nameIdx, bindType, null, null];
|
|
365
411
|
}
|
|
366
|
-
const deps = binding.deps
|
|
367
|
-
? binding.deps.map(dep => this.internDep(dep))
|
|
368
|
-
: null;
|
|
412
|
+
const deps = binding.deps ? binding.deps.map(dep => this.internDep(dep)) : null;
|
|
369
413
|
let id = null;
|
|
370
414
|
if (binding.binding === 'event') {
|
|
371
415
|
if (!binding.expression) {
|
|
@@ -390,8 +434,7 @@ export class CodeGenerator {
|
|
|
390
434
|
}
|
|
391
435
|
if (binding.pipes && binding.pipes.length > 0) {
|
|
392
436
|
extras.p = binding.pipes.map(pipe => ([
|
|
393
|
-
CodeGenerator.internString(pipe.name),
|
|
394
|
-
pipe.args.map(arg => this.internExpression(arg))
|
|
437
|
+
CodeGenerator.internString(pipe.name), pipe.args.map(arg => this.internExpression(arg))
|
|
395
438
|
]));
|
|
396
439
|
}
|
|
397
440
|
if (Object.keys(extras).length > 0) {
|
|
@@ -440,8 +483,7 @@ export class CodeGenerator {
|
|
|
440
483
|
exprId: this.internExpression(node.expression),
|
|
441
484
|
deps: node.deps,
|
|
442
485
|
pipes: node.pipes?.map(pipe => ({
|
|
443
|
-
name: pipe.name,
|
|
444
|
-
argExprIds: pipe.args.map(arg => this.internExpression(arg))
|
|
486
|
+
name: pipe.name, argExprIds: pipe.args.map(arg => this.internExpression(arg))
|
|
445
487
|
}))
|
|
446
488
|
};
|
|
447
489
|
this.markerConfigs.set(id, config);
|
|
@@ -454,10 +496,8 @@ export class CodeGenerator {
|
|
|
454
496
|
renderIfToParent(node, parent) {
|
|
455
497
|
const id = this.nextMarkerId();
|
|
456
498
|
const config = {
|
|
457
|
-
type: 'if',
|
|
458
|
-
|
|
459
|
-
exprId: b.condition ? this.internExpression(b.condition) : undefined,
|
|
460
|
-
deps: b.conditionDeps
|
|
499
|
+
type: 'if', branches: node.branches.map(b => ({
|
|
500
|
+
exprId: b.condition ? this.internExpression(b.condition) : undefined, deps: b.conditionDeps
|
|
461
501
|
}))
|
|
462
502
|
};
|
|
463
503
|
this.markerConfigs.set(id, config);
|
package/ComponentCompiler.d.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import type { ClassTransformOptions } from './babel-plugin-class-transform.js';
|
|
2
2
|
import type { ComponentMetadata } from './babel-plugin-component.js';
|
|
3
|
+
import type { DirectiveMetadata } from './babel-plugin-directive.js';
|
|
3
4
|
import type { CompileResult } from './interfaces/CompileResult.js';
|
|
5
|
+
import type { PluginManager } from './PluginManager.js';
|
|
4
6
|
import { TemplateParser } from './TemplateParser.js';
|
|
5
7
|
export type { CompileResult } from './interfaces/CompileResult.js';
|
|
6
8
|
export declare class ComponentCompiler {
|
|
7
9
|
private readonly componentSelectors;
|
|
8
|
-
private
|
|
9
|
-
|
|
10
|
-
private
|
|
10
|
+
private readonly directiveSelectors;
|
|
11
|
+
private readonly directivePaths;
|
|
12
|
+
private pluginManager;
|
|
13
|
+
setPluginManager(manager: PluginManager): void;
|
|
14
|
+
getDirectivePaths(): string[];
|
|
15
|
+
getComponentMetadata(filePath: string): ComponentMetadata | null;
|
|
16
|
+
getDirectiveMetadata(filePath: string): DirectiveMetadata | null;
|
|
11
17
|
discoverComponents(dir: string): Promise<string[]>;
|
|
12
18
|
compileComponentForBundle(filePath: string, minify?: boolean, sourcemap?: boolean, skipDefine?: boolean, production?: boolean): Promise<CompileResult>;
|
|
13
19
|
stripTypeScriptWithSourceMap(code: string, filePath: string, sourcemap?: boolean): Promise<CompileResult>;
|
|
@@ -16,8 +22,18 @@ export declare class ComponentCompiler {
|
|
|
16
22
|
transformPipeDecorators(code: string, filePath?: string): Promise<string>;
|
|
17
23
|
stripTypeScript(code: string, filePath?: string): Promise<string>;
|
|
18
24
|
extractComponentMetadata(code: string, filePath: string): Promise<ComponentMetadata | null>;
|
|
25
|
+
extractDirectiveMetadata(code: string, filePath: string): Promise<{
|
|
26
|
+
metadata: DirectiveMetadata;
|
|
27
|
+
transformedCode: string;
|
|
28
|
+
} | null>;
|
|
29
|
+
compileDirectiveForBundle(filePath: string, sourcemap?: boolean, production?: boolean): Promise<CompileResult>;
|
|
19
30
|
transformClass(code: string, filePath: string, options: ClassTransformOptions): Promise<string>;
|
|
20
31
|
transformLibraryImports(code: string, filePath: string): Promise<string>;
|
|
32
|
+
protected createTemplateParser(_filePath: string): TemplateParser;
|
|
33
|
+
private getReactivePropsForFile;
|
|
34
|
+
private runBabelTransform;
|
|
35
|
+
private addDirectiveRegistration;
|
|
36
|
+
private addFluffDirectiveImport;
|
|
21
37
|
private createComponentSourceMap;
|
|
22
38
|
private addFluffImport;
|
|
23
39
|
private addBindingsMap;
|