babel-plugin-vasille 3.2.1 → 4.0.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/lib/jsx.js CHANGED
@@ -35,24 +35,30 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.transformJsx = transformJsx;
37
37
  exports.transformJsxArray = transformJsxArray;
38
+ exports.processConditions = processConditions;
38
39
  const t = __importStar(require("@babel/types"));
40
+ const call_1 = require("./call");
39
41
  const internal_js_1 = require("./internal.js");
42
+ const jsx_detect_js_1 = require("./jsx-detect.js");
40
43
  const lib_js_1 = require("./lib.js");
41
44
  const mesh_js_1 = require("./mesh.js");
42
- const jsx_detect_js_1 = require("./jsx-detect.js");
43
- function transformJsx(path, internal) {
44
- if (t.isJSXElement(path.node)) {
45
- return [transformJsxElement(path, internal)];
45
+ function transformJsx(path, conditions, internal) {
46
+ if (path.isJSXElement()) {
47
+ return transformJsxElement(path, conditions, internal);
46
48
  }
47
49
  return transformJsxArray(path.get("children"), internal);
48
50
  }
49
51
  function transformJsxArray(paths, internal) {
50
52
  const result = [];
51
- for (const path of paths) {
52
- if (t.isJSXElement(path.node) || t.isJSXFragment(path.node)) {
53
- result.push(...transformJsx(path, internal));
53
+ const conditions = { cases: null };
54
+ paths.forEach(path => {
55
+ if (!path.isJSXElement() && !(path.isJSXText() && /^\s+$/.test(path.node.value))) {
56
+ result.push(...processConditions(conditions, internal));
57
+ }
58
+ if (path.isJSXElement() || path.isJSXFragment()) {
59
+ result.push(...transformJsx(path, conditions, internal));
54
60
  }
55
- else if (t.isJSXText(path.node)) {
61
+ else if (path.isJSXText()) {
56
62
  if (!/^\s+$/.test(path.node.value)) {
57
63
  const fixed = path.node.value
58
64
  .replace(/\n\s+$/m, "")
@@ -79,48 +85,95 @@ function transformJsxArray(paths, internal) {
79
85
  result.push(t.expressionStatement(call));
80
86
  }
81
87
  }
82
- else if (t.isJSXExpressionContainer(path.node)) {
83
- const value = transformJsxExpressionContainer(path, internal, false, false);
88
+ else if (path.isJSXExpressionContainer()) {
89
+ const value = transformJsxExpressionContainer(path, internal, false, false, true, true);
84
90
  const call = t.callExpression(t.memberExpression(internal_js_1.ctx, t.identifier("text")), [value]);
85
91
  call.loc = value.loc;
86
92
  result.push(t.expressionStatement(call));
87
93
  }
88
94
  else {
89
- throw path.buildCodeFrameError("Vasille: Spread child is not supported");
95
+ (0, lib_js_1.err)(lib_js_1.Errors.TokenNotSupported, path, "Spread child is not supported", internal);
90
96
  }
91
- }
97
+ });
98
+ result.push(...processConditions(conditions, internal));
92
99
  return result;
93
100
  }
94
- function transformJsxExpressionContainer(path, internal, acceptSlots, isInternalSlot) {
95
- const expression = path.node.expression;
96
- const loc = expression.loc;
101
+ function transformJsxExpressionContainer(path, internal, acceptSlots, isInternalSlot, acceptsReactive, acceptsRaw) {
102
+ const expression = path.get("expression");
103
+ const loc = expression.node.loc;
97
104
  if (acceptSlots &&
98
- (t.isFunctionExpression(expression) || t.isArrowFunctionExpression(expression)) &&
99
- (0, jsx_detect_js_1.bodyHasJsx)(expression.body)) {
100
- (0, mesh_js_1.compose)(path.get("expression"), internal, isInternalSlot, "slot");
105
+ (expression.isFunctionExpression() || expression.isArrowFunctionExpression()) &&
106
+ (0, jsx_detect_js_1.bodyHasJsx)(expression.node.body)) {
107
+ (0, mesh_js_1.compose)(expression, internal, isInternalSlot, true);
101
108
  if (!isInternalSlot) {
102
- if (expression.params.length < 1) {
103
- expression.params.push(t.identifier(`_${internal.prefix}`));
109
+ if (expression.node.params.length < 1) {
110
+ expression.node.params.push(t.identifier(`_${internal.prefix}`));
104
111
  }
105
- expression.params.push(internal_js_1.ctx);
112
+ expression.node.params.push(internal_js_1.ctx);
106
113
  }
107
114
  else {
108
- expression.params.unshift(internal_js_1.ctx);
115
+ expression.node.params.unshift(internal_js_1.ctx);
109
116
  }
110
- expression.loc = loc;
111
- return expression;
117
+ expression.node.loc = loc;
118
+ return expression.node;
112
119
  }
113
- else if (isInternalSlot && (t.isFunctionExpression(expression) || t.isArrowFunctionExpression(expression))) {
114
- expression.params.unshift(internal_js_1.ctx);
120
+ else if (isInternalSlot && (expression.isFunctionExpression() || expression.isArrowFunctionExpression())) {
121
+ expression.node.params.unshift(internal_js_1.ctx);
115
122
  }
116
- const exprPath = path.get("expression");
117
- let call = (0, lib_js_1.exprCall)(exprPath, expression, internal);
118
- if (!call && t.isIdentifier(expression) && internal.stack.get(expression.name) === 3 /* VariableState.ReactiveObject */) {
119
- call = t.callExpression(t.memberExpression(internal.id, t.identifier("rop")), [expression]);
123
+ /* istanbul ignore else */
124
+ if (expression.isExpression()) {
125
+ if (acceptsReactive) {
126
+ // cals backward
127
+ if ((0, call_1.calls)(expression, ["backward"], internal)) {
128
+ const argPath = expression.get("arguments")[0];
129
+ if (argPath && argPath.isExpression()) {
130
+ const argValue = argPath.node;
131
+ if ((0, lib_js_1.exprCall)(argPath, argPath.node, internal, { strong: true })) {
132
+ if (!argPath.isMemberExpression() && !argPath.isIdentifier()) {
133
+ argPath.node = argValue;
134
+ (0, lib_js_1.err)(lib_js_1.Errors.RulesOfVasille, argPath, "A reactive variable or object field expected, reactive expression are forward only", internal);
135
+ }
136
+ }
137
+ else {
138
+ argPath.node = argValue;
139
+ (0, lib_js_1.err)(lib_js_1.Errors.RulesOfVasille, argPath, "The backward argument is not reactive", internal);
140
+ }
141
+ }
142
+ else {
143
+ (0, lib_js_1.err)(lib_js_1.Errors.IncorrectArguments, expression, "The argument is missing", internal);
144
+ }
145
+ }
146
+ // calls forward
147
+ else if ((0, call_1.calls)(expression, ["forward"], internal)) {
148
+ const argPath = expression.get("arguments")[0];
149
+ if (argPath && argPath.isExpression()) {
150
+ const argValue = argPath.node;
151
+ if (!(0, lib_js_1.exprCall)(argPath, argPath.node, internal, { strong: true })) {
152
+ argPath.node = argValue;
153
+ (0, lib_js_1.err)(lib_js_1.Errors.RulesOfVasille, argPath, "A reactive expression expected, argument value is constant", internal);
154
+ }
155
+ else {
156
+ expression.node.arguments.unshift(internal_js_1.ctx);
157
+ }
158
+ }
159
+ else {
160
+ (0, lib_js_1.err)(lib_js_1.Errors.IncorrectArguments, expression, "The argument is missing", internal);
161
+ }
162
+ }
163
+ // two-side binding
164
+ else {
165
+ const isReactive = (0, lib_js_1.exprCall)(expression, expression.node, internal, { strong: !acceptsRaw });
166
+ if (!isReactive && !acceptsRaw) {
167
+ expression.replaceWith(internal.ref(expression.node));
168
+ }
169
+ }
170
+ }
171
+ else {
172
+ (0, mesh_js_1.meshExpression)(expression, internal);
173
+ }
120
174
  }
121
- const result = call ?? exprPath.node;
122
- result.loc = loc;
123
- return result;
175
+ expression.node.loc = loc;
176
+ return expression.node;
124
177
  }
125
178
  function idToProp(id, value, from) {
126
179
  let str = t.isIdentifier(id) || t.isJSXIdentifier(id) ? id.name : id.value;
@@ -137,7 +190,23 @@ function idToProp(id, value, from) {
137
190
  expr.loc = id.loc;
138
191
  return t.objectProperty(expr, value);
139
192
  }
140
- function transformJsxElement(path, internal) {
193
+ function processConditions(conditions, internal, _default) {
194
+ if (!conditions.cases) {
195
+ return [];
196
+ }
197
+ const ret = [
198
+ t.expressionStatement(internal.Switch(t.objectExpression([
199
+ t.objectProperty(t.identifier("cases"), t.arrayExpression(conditions.cases.map(item => t.objectExpression([
200
+ t.objectProperty(t.identifier("$case"), item.condition),
201
+ t.objectProperty(t.identifier("slot"), item.slot),
202
+ ])))),
203
+ ...(_default ? [t.objectProperty(t.identifier("default"), _default)] : []),
204
+ ]))),
205
+ ];
206
+ conditions.cases = null;
207
+ return ret;
208
+ }
209
+ function transformJsxElement(path, conditions, internal) {
141
210
  const name = path.node.openingElement.name;
142
211
  if (t.isJSXIdentifier(name) && name.name[0].toLowerCase() === name.name[0]) {
143
212
  const opening = path.get("openingElement");
@@ -153,67 +222,70 @@ function transformJsxElement(path, internal) {
153
222
  const attr = attrPath.node;
154
223
  if (t.isJSXAttribute(attr)) {
155
224
  const name = attr.name;
225
+ const valuePath = attrPath.get("value");
226
+ const expressionPath = valuePath.isJSXExpressionContainer() && valuePath.get("expression");
156
227
  /* istanbul ignore else */
157
228
  if (t.isJSXIdentifier(name)) {
158
229
  if (name.name.startsWith("on")) {
159
- if (t.isJSXExpressionContainer(attr.value) && t.isExpression(attr.value.expression)) {
160
- const path = attrPath.get("value");
230
+ if (expressionPath) {
161
231
  /* istanbul ignore else */
162
- if (t.isExpression(path.node.expression)) {
163
- (0, mesh_js_1.meshExpression)(path.get("expression"), internal);
232
+ if (expressionPath.isExpression()) {
233
+ (0, mesh_js_1.meshExpression)(expressionPath, internal);
234
+ events.push(idToProp(name, expressionPath.node, 2));
164
235
  }
165
- events.push(idToProp(name, path.node.expression, 2));
166
236
  }
167
237
  else {
168
- throw attrPath
169
- .get("value")
170
- .buildCodeFrameError("Vasille: Expected event handler.");
238
+ (0, lib_js_1.err)(lib_js_1.Errors.TokenNotSupported, valuePath, "Expected event handler", internal);
171
239
  }
172
240
  }
173
241
  else if (name.name === "class") {
174
242
  // class={[..]}
175
243
  /* istanbul ignore else */
176
- if (t.isJSXExpressionContainer(attr.value) && t.isArrayExpression(attr.value.expression)) {
177
- const valuePath = attrPath.get("value");
244
+ if (valuePath.isJSXExpressionContainer() && t.isArrayExpression(valuePath.node.expression)) {
178
245
  const arrayExprPath = valuePath.get("expression");
179
246
  for (const elementPath of arrayExprPath.get("elements")) {
180
- const item = elementPath.node;
181
- if (t.isExpression(item)) {
247
+ if (elementPath.isExpression()) {
182
248
  // class={[cond && "string"]}
183
- if (t.isLogicalExpression(item) && item.operator === "&&" && t.isStringLiteral(item.right)) {
184
- const call = (0, lib_js_1.exprCall)(elementPath.get("left"), item.left, internal);
185
- classObject.push(idToProp(item.right, call ?? item.left));
249
+ if (elementPath.isLogicalExpression() &&
250
+ elementPath.node.operator === "&&" &&
251
+ t.isStringLiteral(elementPath.node.right)) {
252
+ (0, lib_js_1.exprCall)(elementPath.get("left"), elementPath.node.left, internal, {});
253
+ classObject.push(idToProp(elementPath.node.right, elementPath.node.left));
186
254
  }
187
255
  // class={[{..}]}
188
- else if (t.isObjectExpression(item)) {
256
+ else if (elementPath.isObjectExpression()) {
189
257
  for (const propPath of elementPath.get("properties")) {
190
258
  // class={[{a: b}]}
191
- if (t.isObjectProperty(propPath.node)) {
192
- const prop = propPath;
193
- const value = (0, lib_js_1.exprCall)(prop.get("value"), prop.node.value, internal) ?? prop.node.value;
194
- if (t.isExpression(prop.node.key) && !t.isIdentifier(prop.node.key)) {
195
- (0, mesh_js_1.meshExpression)(prop.get("key"), internal);
259
+ if (propPath.isObjectProperty()) {
260
+ const keyPath = propPath.get("key");
261
+ const valuePath = propPath.get("value");
262
+ /* istanbul ignore else */
263
+ if (valuePath.isExpression()) {
264
+ (0, lib_js_1.exprCall)(valuePath, valuePath.node, internal, {});
265
+ }
266
+ if (keyPath.isExpression() && !keyPath.isIdentifier()) {
267
+ (0, mesh_js_1.meshExpression)(keyPath, internal);
196
268
  }
197
- classObject.push(t.objectProperty(prop.node.key, value));
269
+ classObject.push(t.objectProperty(keyPath.node, valuePath.node));
198
270
  }
199
271
  // class={[{...a}]}
200
- else if (t.isSpreadElement(propPath.node)) {
272
+ else if (propPath.isSpreadElement()) {
201
273
  classObject.push(propPath.node);
202
274
  }
203
275
  // class={[{a(){}}]}
204
276
  else {
205
- throw propPath.buildCodeFrameError("Vasille: Methods are not allowed here");
277
+ (0, lib_js_1.err)(lib_js_1.Errors.TokenNotSupported, propPath, "Methods are not allowed here", internal);
206
278
  }
207
279
  }
208
280
  }
209
281
  // class={[".."]}
210
- else if (t.isStringLiteral(elementPath.node)) {
282
+ else if (elementPath.isStringLiteral()) {
211
283
  classStatic.push(elementPath.node);
212
284
  }
213
285
  // class={[..]}
214
286
  else {
215
- const call = (0, lib_js_1.exprCall)(elementPath, item, internal);
216
- classElements.push(call ?? item);
287
+ (0, lib_js_1.exprCall)(elementPath, elementPath.node, internal, { strong: true });
288
+ classElements.push(elementPath.node);
217
289
  }
218
290
  }
219
291
  // class={[...array]}
@@ -223,58 +295,59 @@ function transformJsxElement(path, internal) {
223
295
  }
224
296
  }
225
297
  // class={"a b"}
226
- else if (t.isJSXExpressionContainer(attr.value) && t.isStringLiteral(attr.value.expression)) {
227
- attrs.push(t.objectProperty(t.identifier("class"), attr.value.expression));
298
+ else if (expressionPath && expressionPath.isStringLiteral()) {
299
+ attrs.push(t.objectProperty(t.identifier("class"), expressionPath.node));
228
300
  }
229
301
  // class={`a ${b}`}
230
- else if (t.isJSXExpressionContainer(attr.value) && t.isTemplateLiteral(attr.value.expression)) {
231
- const jsxAttrPath = attrPath;
232
- const jsxContainerPath = jsxAttrPath.get("value");
233
- const value = (0, lib_js_1.exprCall)(jsxContainerPath.get("expression"), attr.value.expression, internal);
234
- attrs.push(t.objectProperty(t.identifier("class"), value ?? attr.value.expression));
235
- if (value) {
302
+ else if (expressionPath && expressionPath.isExpression()) {
303
+ if ((0, lib_js_1.exprCall)(expressionPath, expressionPath.node, internal, { strong: true })) {
236
304
  console.warn(attrPath.buildCodeFrameError("Vasille: This will slow down your application"));
237
305
  }
306
+ attrs.push(t.objectProperty(t.identifier("class"), expressionPath.node));
238
307
  }
239
308
  // class={name}
240
- else if (t.isJSXExpressionContainer(attr.value) && t.isExpression(attr.value.expression)) {
241
- const expr = (0, lib_js_1.exprCall)(attrPath.get("value"), attr.value.expression, internal) ?? attr.value.expression;
242
- attrs.push(t.objectProperty(t.identifier("class"), expr));
309
+ else if (expressionPath && expressionPath.isExpression()) {
310
+ (0, lib_js_1.exprCall)(expressionPath, expressionPath.node, internal, {});
311
+ attrs.push(t.objectProperty(t.identifier("class"), expressionPath.node));
243
312
  }
244
313
  // class="a b"
245
- else if (t.isStringLiteral(attr.value)) {
246
- classStatic.push(attr.value);
314
+ else if (valuePath.isStringLiteral()) {
315
+ classStatic.push(valuePath.node);
247
316
  }
248
317
  }
249
318
  else if (name.name === "style") {
250
319
  // style={{..}}
251
320
  /* istanbul ignore else */
252
- if (t.isJSXExpressionContainer(attr.value) && t.isObjectExpression(attr.value.expression)) {
253
- const valuePath = attrPath.get("value");
254
- const objectPath = valuePath.get("expression");
255
- for (const propPath of objectPath.get("properties")) {
321
+ if (expressionPath && expressionPath.isObjectExpression()) {
322
+ for (const propPath of expressionPath.get("properties")) {
256
323
  // style={{a: b}}
257
- if (t.isObjectProperty(propPath.node)) {
324
+ if (propPath.isObjectProperty()) {
258
325
  const prop = propPath;
259
- const value = (0, lib_js_1.exprCall)(prop.get("value"), prop.node.value, internal) ?? prop.node.value;
260
- if (t.isExpression(prop.node.key) && !t.isIdentifier(prop.node.key)) {
261
- (0, mesh_js_1.meshExpression)(prop.get("key"), internal);
326
+ const valuePath = prop.get("value");
327
+ /* istanbul ignore else */
328
+ if (valuePath.isExpression()) {
329
+ (0, lib_js_1.exprCall)(valuePath, valuePath.node, internal, { strong: true });
330
+ }
331
+ const value = valuePath.node;
332
+ const keyPath = propPath.get("key");
333
+ if (keyPath.isExpression() && !keyPath.isIdentifier()) {
334
+ (0, mesh_js_1.meshExpression)(keyPath, internal);
262
335
  }
263
336
  // style={{a: "b"}} -> static in compile time
264
- if (t.isIdentifier(prop.node.key) && t.isStringLiteral(prop.node.value)) {
265
- styleStatic.push([prop.node.key, prop.node.value]);
337
+ if (keyPath.isIdentifier() && valuePath.isStringLiteral()) {
338
+ styleStatic.push([keyPath.node, valuePath.node]);
266
339
  }
267
340
  // style={{a: 23}} -> static in compile time
268
- else if (t.isIdentifier(prop.node.key) && t.isNumericLiteral(prop.node.value)) {
269
- styleStatic.push([prop.node.key, t.stringLiteral(`${prop.node.value.value}px`)]);
341
+ else if (keyPath.isIdentifier() && valuePath.isNumericLiteral()) {
342
+ styleStatic.push([keyPath.node, t.stringLiteral(`${valuePath.node.value}px`)]);
270
343
  }
271
344
  // style={{a: [1, 2, 3]}} -> static in compile time
272
- else if (t.isIdentifier(prop.node.key) &&
273
- t.isArrayExpression(prop.node.value) &&
274
- prop.node.value.elements.every(item => t.isNumericLiteral(item))) {
345
+ else if (keyPath.isIdentifier() &&
346
+ valuePath.isArrayExpression() &&
347
+ valuePath.node.elements.every(item => t.isNumericLiteral(item))) {
275
348
  styleStatic.push([
276
- prop.node.key,
277
- t.stringLiteral(prop.node.value.elements
349
+ keyPath.node,
350
+ t.stringLiteral(valuePath.node.elements
278
351
  .map(item => {
279
352
  return `${item.value}px`;
280
353
  })
@@ -292,64 +365,66 @@ function transformJsxElement(path, internal) {
292
365
  }
293
366
  // style={{a(){}}}
294
367
  else {
295
- throw propPath.buildCodeFrameError("Vasille: Methods are not allowed here");
368
+ (0, lib_js_1.err)(lib_js_1.Errors.TokenNotSupported, propPath, "Methods are not allowed here", internal);
296
369
  }
297
370
  }
298
371
  }
299
372
  // style=".."
300
- else if (t.isStringLiteral(attr.value)) {
301
- attrs.push(t.objectProperty(t.identifier("style"), attr.value));
373
+ else if (valuePath.isStringLiteral()) {
374
+ attrs.push(t.objectProperty(t.identifier("style"), valuePath.node));
302
375
  }
303
376
  // style={".."}
304
- else if (t.isJSXExpressionContainer(attr.value) && t.isStringLiteral(attr.value.expression)) {
305
- attrs.push(t.objectProperty(t.identifier("style"), attr.value.expression));
377
+ else if (expressionPath && expressionPath.isStringLiteral()) {
378
+ attrs.push(t.objectProperty(t.identifier("style"), expressionPath.node));
306
379
  }
307
380
  // style={`a: ${b}px`}
308
- else if (t.isJSXExpressionContainer(attr.value) && t.isTemplateLiteral(attr.value.expression)) {
309
- const jsxAttrPath = attrPath;
310
- const jsxContainerPath = jsxAttrPath.get("value");
311
- const literalPath = jsxContainerPath.get("expression");
312
- const value = (0, lib_js_1.exprCall)(literalPath, attr.value.expression, internal);
313
- attrs.push(t.objectProperty(t.identifier("style"), value ?? attr.value.expression));
314
- if (value) {
381
+ else if (expressionPath && expressionPath.isExpression()) {
382
+ if ((0, lib_js_1.exprCall)(expressionPath, expressionPath.node, internal, { strong: true })) {
315
383
  console.warn(attrPath.buildCodeFrameError("Vasille: This will slow down your application"));
316
384
  }
317
- }
318
- else if (t.isJSXExpressionContainer(attr.value) && t.isExpression(attr.value.expression)) {
319
- const expr = (0, lib_js_1.exprCall)(attrPath.get("value"), attr.value.expression, internal) ?? attr.value.expression;
320
- attrs.push(t.objectProperty(t.identifier("style"), expr));
385
+ attrs.push(t.objectProperty(t.identifier("style"), expressionPath.node));
321
386
  }
322
387
  }
323
388
  else {
324
389
  /* istanbul ignore else */
325
- if (!attr.value || t.isJSXExpressionContainer(attr.value)) {
326
- attrs.push(idToProp(name, t.isExpression(attr.value?.expression) ? attr.value.expression : t.booleanLiteral(true)));
390
+ if (expressionPath && expressionPath.isExpression()) {
391
+ attrs.push(idToProp(name, expressionPath.node));
327
392
  }
328
393
  else if (t.isStringLiteral(attr.value)) {
329
394
  attrs.push(idToProp(name, attr.value));
330
395
  }
396
+ else {
397
+ attrs.push(idToProp(name, t.booleanLiteral(true)));
398
+ }
331
399
  }
332
400
  }
333
401
  if (t.isJSXNamespacedName(name)) {
334
402
  if (name.namespace.name === "bind") {
403
+ let pushed = false;
335
404
  /* istanbul ignore else */
336
- if (t.isJSXExpressionContainer(attr.value) || !attr.value) {
337
- const value = t.isExpression(attr.value?.expression)
338
- ? (0, lib_js_1.exprCall)(attrPath.get("value").get("expression"), attr.value.expression, internal)
339
- : undefined;
340
- bind.push(idToProp(name.name, value ?? (t.isExpression(attr.value?.expression) ? attr.value.expression : t.booleanLiteral(true))));
405
+ if (expressionPath) {
406
+ /* istanbul ignore else */
407
+ if (expressionPath.isExpression()) {
408
+ (0, lib_js_1.exprCall)(expressionPath, expressionPath.node, internal, { strong: true });
409
+ bind.push(idToProp(name.name, expressionPath.node));
410
+ pushed = true;
411
+ }
341
412
  }
342
413
  else if (t.isStringLiteral(attr.value)) {
343
414
  bind.push(idToProp(name.name, attr.value));
415
+ pushed = true;
416
+ }
417
+ if (!pushed) {
418
+ bind.push(idToProp(name.name, t.booleanLiteral(true)));
344
419
  }
345
420
  }
346
421
  else {
347
- throw attrPath.buildCodeFrameError("Vasille: only bind namespace is supported");
422
+ (0, lib_js_1.err)(lib_js_1.Errors.ParserError, attrPath, "Only bind namespace is supported", internal);
348
423
  }
349
424
  }
350
425
  }
351
426
  else {
352
- throw attrPath.buildCodeFrameError("Vasille: Spread attribute is not allowed on HTML tags.");
427
+ (0, lib_js_1.err)(lib_js_1.Errors.ParserError, attrPath, "Spread attribute is not allowed on HTML tags", internal);
353
428
  }
354
429
  }
355
430
  if (classStatic.length > 0) {
@@ -381,7 +456,7 @@ function transformJsxElement(path, internal) {
381
456
  ...(statements.length > 0 ? [t.arrowFunctionExpression([internal_js_1.ctx], t.blockStatement(statements))] : []),
382
457
  ]);
383
458
  call.loc = path.node.loc;
384
- return t.expressionStatement(call);
459
+ return [...processConditions(conditions, internal), t.expressionStatement(call)];
385
460
  }
386
461
  if (t.isJSXIdentifier(name)) {
387
462
  const element = path.node;
@@ -390,34 +465,41 @@ function transformJsxElement(path, internal) {
390
465
  let run;
391
466
  const mapped = internal.mapping.get(name.name);
392
467
  if (mapped === "Debug" && internal.stack.get(name.name) === undefined && !internal.devMode) {
393
- return t.emptyStatement();
468
+ return processConditions(conditions, internal);
394
469
  }
395
470
  for (const attrPath of opening.get("attributes")) {
396
471
  const attr = attrPath.node;
397
472
  // <A prop=../>
398
473
  if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {
474
+ const valuePath = attrPath.isJSXAttribute() && attrPath.get("value");
475
+ const needReactive = attr.name.name.startsWith("$");
399
476
  // <A prop=".."/>
400
477
  /* istanbul ignore else */
401
478
  if (t.isStringLiteral(attr.value)) {
402
- props.push(idToProp(attr.name, attr.value));
479
+ props.push(idToProp(attr.name, needReactive ? internal.ref(attr.value) : attr.value));
403
480
  }
404
481
  // <A prop={..}/>
405
- else if (t.isJSXExpressionContainer(attr.value)) {
482
+ else if (valuePath && valuePath.isJSXExpressionContainer()) {
406
483
  const isSystem = internal.mapping.has(name.name);
407
- const value = transformJsxExpressionContainer(attrPath.get("value"), internal, !isSystem || attr.name.name === "slot", isSystem && attr.name.name === "slot");
484
+ const requiresReactive = attr.name.name.startsWith("$");
485
+ const value = transformJsxExpressionContainer(valuePath, internal, !isSystem || attr.name.name === "slot", isSystem && attr.name.name === "slot", requiresReactive, !requiresReactive);
408
486
  props.push(idToProp(attr.name, value));
409
487
  }
410
488
  else if (!attr.value) {
411
- props.push(idToProp(attr.name, t.booleanLiteral(true)));
489
+ props.push(idToProp(attr.name, needReactive ? internal.ref(t.booleanLiteral(true)) : t.booleanLiteral(true)));
412
490
  }
413
491
  }
414
492
  // <A {...arg}/>
415
- else if (t.isJSXSpreadAttribute(attr)) {
416
- props.push(t.spreadElement(attr.argument));
493
+ else if (attrPath.isJSXSpreadAttribute()) {
494
+ (0, mesh_js_1.meshExpression)(attrPath.get("argument"), internal);
495
+ props.push(t.spreadElement(attrPath.node.argument));
496
+ if (mapped === "If" || mapped === "ElseIf" || mapped === "Else") {
497
+ (0, lib_js_1.err)(lib_js_1.Errors.RulesOfVasille, attrPath, "If, Else and ElseIf are syntax sugar, use Switch if you need more runtime elasticity", internal);
498
+ }
417
499
  }
418
500
  // <A space:name=../>
419
501
  else {
420
- throw attrPath.buildCodeFrameError("Vasille: Namespaced attributes names are not supported");
502
+ (0, lib_js_1.err)(lib_js_1.Errors.ParserError, attrPath, "Namespaced attributes names are not supported", internal);
421
503
  }
422
504
  }
423
505
  const filteredChildren = element.children.filter(item => {
@@ -427,11 +509,12 @@ function transformJsxElement(path, internal) {
427
509
  return !!item.value.trim();
428
510
  });
429
511
  const isInternal = internal.mapping.has(name.name);
512
+ // The child is a slot value
430
513
  if (filteredChildren.length === 1 &&
431
514
  t.isJSXExpressionContainer(filteredChildren[0]) &&
432
515
  (t.isFunctionExpression(filteredChildren[0].expression) ||
433
516
  t.isArrowFunctionExpression(filteredChildren[0].expression))) {
434
- transformJsxExpressionContainer(path.get("children")[element.children.indexOf(filteredChildren[0])], internal, true, isInternal);
517
+ transformJsxExpressionContainer(path.get("children")[element.children.indexOf(filteredChildren[0])], internal, true, isInternal, false, true);
435
518
  run = filteredChildren[0].expression;
436
519
  }
437
520
  else {
@@ -444,9 +527,42 @@ function transformJsxElement(path, internal) {
444
527
  run = t.arrowFunctionExpression(params, t.blockStatement(statements));
445
528
  }
446
529
  }
530
+ const ret = [];
531
+ const filter = (v) => {
532
+ return t.isObjectProperty(v);
533
+ };
534
+ if (mapped === "If" || mapped === "ElseIf" || mapped === "Else") {
535
+ const condition = props.filter(filter).find(prop => {
536
+ return t.isStringLiteral(prop.key) && prop.key.value === "$condition";
537
+ })?.value;
538
+ const slot = run ??
539
+ props.filter(filter).find(prop => {
540
+ return t.isIdentifier(prop.key) && prop.key.name === "slot";
541
+ })?.value;
542
+ if (mapped === "If") {
543
+ ret.push(...processConditions(conditions, internal));
544
+ }
545
+ if ((mapped === "ElseIf" || mapped === "Else") && !conditions.cases) {
546
+ (0, lib_js_1.err)(lib_js_1.Errors.RulesOfVasille, path, "Malformed JSX If tag is missing", internal);
547
+ }
548
+ if (mapped === "If" || mapped === "ElseIf") {
549
+ if (t.isExpression(condition) && (t.isFunctionExpression(slot) || t.isArrowFunctionExpression(slot))) {
550
+ if (!conditions.cases) {
551
+ conditions.cases = [{ condition, slot }];
552
+ }
553
+ else {
554
+ conditions.cases.push({ condition, slot });
555
+ }
556
+ }
557
+ }
558
+ if (mapped === "Else") {
559
+ ret.push(...processConditions(conditions, internal, t.isFunctionExpression(slot) || t.isArrowFunctionExpression(slot) ? slot : undefined));
560
+ }
561
+ return ret;
562
+ }
447
563
  const call = t.callExpression(t.identifier(name.name), [t.objectExpression(props), internal_js_1.ctx, ...(run ? [run] : [])]);
448
564
  call.loc = path.node.loc;
449
- return t.expressionStatement(call);
565
+ return [...ret, t.expressionStatement(call)];
450
566
  }
451
- throw path.buildCodeFrameError("Vasille: Unsupported tag detected, html lowercase tag names and components are accepted");
567
+ return (0, lib_js_1.err)(lib_js_1.Errors.ParserError, path, "Unsupported tag detected, html lowercase tag names and components are accepted", internal, []);
452
568
  }