@teleporthq/teleport-plugin-html-base-component 0.43.0-alpha.0 → 0.43.3

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.
@@ -56,68 +56,468 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
56
56
  };
57
57
  import { HTMLComponentGeneratorError, ChunkType, FileType, } from '@teleporthq/teleport-types';
58
58
  import { join, relative } from 'path';
59
- import { HASTBuilders, HASTUtils } from '@teleporthq/teleport-plugin-common';
60
- import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared';
59
+ import { HASTBuilders, HASTUtils, ASTUtils } from '@teleporthq/teleport-plugin-common';
60
+ import { GenericUtils, StringUtils, UIDLUtils } from '@teleporthq/teleport-shared';
61
61
  import { staticNode } from '@teleporthq/teleport-uidl-builders';
62
62
  import { createCSSPlugin } from '@teleporthq/teleport-plugin-css';
63
+ import { generateUniqueKeys, createNodesLookup } from '@teleporthq/teleport-uidl-resolver';
63
64
  import { DEFAULT_COMPONENT_CHUNK_NAME } from './constants';
64
- export var generateHtmlSynatx = function (node, templatesLookUp, propDefinitions, stateDefinitions, subComponentOptions, structure) { return __awaiter(void 0, void 0, void 0, function () {
65
- return __generator(this, function (_a) {
66
- switch (node.type) {
67
- case 'inject':
68
- case 'raw':
69
- return [2 /*return*/, HASTBuilders.createTextNode(node.content.toString())];
70
- case 'static':
71
- return [2 /*return*/, HASTBuilders.createTextNode(StringUtils.encode(node.content.toString()))];
72
- case 'slot':
73
- return [2 /*return*/, HASTBuilders.createHTMLNode(node.type)];
74
- case 'element':
75
- return [2 /*return*/, generatElementNode(node, templatesLookUp, propDefinitions, stateDefinitions, subComponentOptions, structure)];
76
- case 'dynamic':
77
- return [2 /*return*/, generateDynamicNode(node, templatesLookUp, propDefinitions, stateDefinitions, subComponentOptions, structure)];
78
- default:
79
- throw new HTMLComponentGeneratorError("generateHtmlSyntax encountered a node of unsupported type: ".concat(JSON.stringify(node, null, 2), " "));
65
+ var getTranslation = function (id, options) {
66
+ var _a, _b;
67
+ var i18n = options.internationalization;
68
+ if (!(i18n === null || i18n === void 0 ? void 0 : i18n.translations)) {
69
+ return null;
70
+ }
71
+ var locale = i18n.targetLocale || ((_a = i18n.main) === null || _a === void 0 ? void 0 : _a.locale);
72
+ if (!locale) {
73
+ return null;
74
+ }
75
+ return ((_b = i18n.translations[locale]) === null || _b === void 0 ? void 0 : _b[id]) || null;
76
+ };
77
+ var resolveTranslationText = function (translation) {
78
+ if (translation.type === 'static') {
79
+ return String(translation.content);
80
+ }
81
+ if (translation.type === 'element' && translation.content.children) {
82
+ return translation.content.children
83
+ .map(function (child) {
84
+ if (child.type === 'static') {
85
+ return String(child.content);
86
+ }
87
+ if (child.type === 'element') {
88
+ return resolveTranslationText(child);
89
+ }
90
+ return '';
91
+ })
92
+ .join('');
93
+ }
94
+ return '';
95
+ };
96
+ var isValidURL = function (url) {
97
+ try {
98
+ /* tslint:disable:no-unused-expression */
99
+ new URL(url);
100
+ return true;
101
+ }
102
+ catch (error) {
103
+ return false;
104
+ }
105
+ };
106
+ var addNodeToLookup = function (key, tag, nodesLoookup) {
107
+ // In html code-generation we combine the nodes of the component that is being consumed with the current component.
108
+ // As html can't load the component at runtime like react or any other frameworks. So, we merge the component as a standalone
109
+ // component in the current component.
110
+ var currentLookup = nodesLoookup[key];
111
+ if (currentLookup) {
112
+ if (Array.isArray(currentLookup)) {
113
+ Array.isArray(tag) ? currentLookup.push.apply(currentLookup, tag) : currentLookup.push(tag);
114
+ }
115
+ else {
116
+ nodesLoookup[key] = Array.isArray(tag) ? __spreadArray([currentLookup], tag, true) : [currentLookup, tag];
117
+ }
118
+ return;
119
+ }
120
+ nodesLoookup[key] = tag;
121
+ };
122
+ export var generateHtmlSyntax = function (node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions) { return __awaiter(void 0, void 0, void 0, function () {
123
+ var _a, rawNode, elementNode, dynamicNode, repeatNode, conditionalNodeComment, _b, staticValue, reference, _c, conditions, matchingCriteria, _d, referenceType, id, _e, refPath, usedProp, defaultValue, _i, refPath_1, path, dynamicConditions, matchCondition, conditionString, isConditionPassing, expressionEntries, localValue, _f, expressionEntries_1, expr, currentItem, _g, refPath_2, path, localConditions, localMatchCondition, localConditionString, isLocalConditionPassing, content, uidlDynamicRef, generatedNode, isProp, uidlDynamicRef, generatedNode, successNode;
124
+ var _h, _j;
125
+ return __generator(this, function (_k) {
126
+ switch (_k.label) {
127
+ case 0:
128
+ _a = node.type;
129
+ switch (_a) {
130
+ case 'inject': return [3 /*break*/, 1];
131
+ case 'raw': return [3 /*break*/, 2];
132
+ case 'static': return [3 /*break*/, 3];
133
+ case 'slot': return [3 /*break*/, 4];
134
+ case 'element': return [3 /*break*/, 5];
135
+ case 'dynamic': return [3 /*break*/, 7];
136
+ case 'repeat': return [3 /*break*/, 9];
137
+ case 'conditional': return [3 /*break*/, 11];
138
+ case 'expr': return [3 /*break*/, 12];
139
+ case 'cms-list-repeater': return [3 /*break*/, 17];
140
+ case 'cms-item': return [3 /*break*/, 18];
141
+ case 'cms-list': return [3 /*break*/, 18];
142
+ case 'data-source-item': return [3 /*break*/, 18];
143
+ case 'data-source-list': return [3 /*break*/, 18];
144
+ }
145
+ return [3 /*break*/, 19];
146
+ case 1: return [2 /*return*/, HASTBuilders.createTextNode(node.content.toString())];
147
+ case 2:
148
+ {
149
+ rawNode = node;
150
+ return [2 /*return*/, HASTBuilders.createTextNode((rawNode.fallback || rawNode.content).toString())];
151
+ }
152
+ _k.label = 3;
153
+ case 3: return [2 /*return*/, HASTBuilders.createTextNode(StringUtils.encode(node.content.toString()))];
154
+ case 4: return [2 /*return*/, HASTBuilders.createHTMLNode(node.type)];
155
+ case 5: return [4 /*yield*/, generateElementNode(node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
156
+ case 6:
157
+ elementNode = _k.sent();
158
+ return [2 /*return*/, elementNode];
159
+ case 7: return [4 /*yield*/, generateDynamicNode(node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
160
+ case 8:
161
+ dynamicNode = _k.sent();
162
+ return [2 /*return*/, dynamicNode];
163
+ case 9: return [4 /*yield*/, generateHtmlSyntax(node.content.node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
164
+ case 10:
165
+ repeatNode = _k.sent();
166
+ return [2 /*return*/, repeatNode];
167
+ case 11:
168
+ conditionalNodeComment = HASTBuilders.createTextNode('');
169
+ _b = node.content, staticValue = _b.value, reference = _b.reference, _c = _b.condition, conditions = _c.conditions, matchingCriteria = _c.matchingCriteria;
170
+ if (reference.type !== 'dynamic') {
171
+ return [2 /*return*/, conditionalNodeComment];
172
+ }
173
+ _d = reference.content, referenceType = _d.referenceType, id = _d.id, _e = _d.refPath, refPath = _e === void 0 ? [] : _e;
174
+ switch (referenceType) {
175
+ case 'prop': {
176
+ usedProp = propDefinitions[id];
177
+ if (usedProp === undefined || usedProp.defaultValue === undefined) {
178
+ return [2 /*return*/, conditionalNodeComment];
179
+ }
180
+ defaultValue = usedProp.defaultValue;
181
+ for (_i = 0, refPath_1 = refPath; _i < refPath_1.length; _i++) {
182
+ path = refPath_1[_i];
183
+ defaultValue = defaultValue === null || defaultValue === void 0 ? void 0 : defaultValue[path];
184
+ }
185
+ // If defaultValue is undefined or null after path traversal, use original default
186
+ defaultValue = defaultValue !== null && defaultValue !== void 0 ? defaultValue : usedProp.defaultValue;
187
+ dynamicConditions = createConditionalStatement(staticValue !== undefined ? [{ operand: staticValue, operation: '===' }] : conditions, defaultValue);
188
+ matchCondition = matchingCriteria && matchingCriteria === 'all' ? '&&' : '||';
189
+ conditionString = dynamicConditions.join(" ".concat(matchCondition, " "));
190
+ try {
191
+ isConditionPassing = new Function("return ".concat(conditionString))();
192
+ if (isConditionPassing) {
193
+ return [2 /*return*/, generateHtmlSyntax(node.content.node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
194
+ }
195
+ }
196
+ catch (error) {
197
+ return [2 /*return*/, conditionalNodeComment];
198
+ }
199
+ return [2 /*return*/, conditionalNodeComment];
200
+ }
201
+ case 'local': {
202
+ if (!resolvedExpressions || resolvedExpressions.currentIndex === undefined) {
203
+ return [2 /*return*/, conditionalNodeComment];
204
+ }
205
+ expressionEntries = Object.values(resolvedExpressions.expressions || {});
206
+ localValue = void 0;
207
+ for (_f = 0, expressionEntries_1 = expressionEntries; _f < expressionEntries_1.length; _f++) {
208
+ expr = expressionEntries_1[_f];
209
+ if (expr && Array.isArray(expr.defaultValue)) {
210
+ currentItem = expr.defaultValue[resolvedExpressions.currentIndex];
211
+ if (currentItem !== undefined) {
212
+ localValue = currentItem;
213
+ for (_g = 0, refPath_2 = refPath; _g < refPath_2.length; _g++) {
214
+ path = refPath_2[_g];
215
+ localValue = localValue === null || localValue === void 0 ? void 0 : localValue[path];
216
+ }
217
+ break;
218
+ }
219
+ }
220
+ }
221
+ if (localValue === undefined) {
222
+ return [2 /*return*/, conditionalNodeComment];
223
+ }
224
+ localConditions = createConditionalStatement(staticValue !== undefined ? [{ operand: staticValue, operation: '===' }] : conditions, localValue);
225
+ localMatchCondition = matchingCriteria && matchingCriteria === 'all' ? '&&' : '||';
226
+ localConditionString = localConditions.join(" ".concat(localMatchCondition, " "));
227
+ try {
228
+ isLocalConditionPassing = new Function("return ".concat(localConditionString))();
229
+ if (isLocalConditionPassing) {
230
+ return [2 /*return*/, generateHtmlSyntax(node.content.node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
231
+ }
232
+ }
233
+ catch (error) {
234
+ return [2 /*return*/, conditionalNodeComment];
235
+ }
236
+ return [2 /*return*/, conditionalNodeComment];
237
+ }
238
+ case 'state':
239
+ default:
240
+ return [2 /*return*/, conditionalNodeComment];
241
+ }
242
+ _k.label = 12;
243
+ case 12:
244
+ content = node.content.split('?.');
245
+ if (!(resolvedExpressions && ((_h = resolvedExpressions.expressions) === null || _h === void 0 ? void 0 : _h[content[0] || '']))) return [3 /*break*/, 14];
246
+ uidlDynamicRef = {
247
+ type: 'dynamic',
248
+ content: {
249
+ referenceType: 'prop',
250
+ refPath: __spreadArray([resolvedExpressions.currentIndex.toString()], content.slice(1), true),
251
+ id: content[0],
252
+ },
253
+ };
254
+ return [4 /*yield*/, generateDynamicNode(uidlDynamicRef, compName, nodesLookup, resolvedExpressions.expressions, stateDefinitions, subComponentOptions, structure)];
255
+ case 13:
256
+ generatedNode = _k.sent();
257
+ return [2 /*return*/, generatedNode];
258
+ case 14:
259
+ if (!(content[0] && ((propDefinitions === null || propDefinitions === void 0 ? void 0 : propDefinitions[content[0]]) || (stateDefinitions === null || stateDefinitions === void 0 ? void 0 : stateDefinitions[content[0]])))) return [3 /*break*/, 16];
260
+ isProp = Boolean(propDefinitions === null || propDefinitions === void 0 ? void 0 : propDefinitions[content[0]]);
261
+ uidlDynamicRef = {
262
+ type: 'dynamic',
263
+ content: {
264
+ referenceType: isProp ? 'prop' : 'state',
265
+ refPath: content.slice(1),
266
+ id: content[0],
267
+ },
268
+ };
269
+ return [4 /*yield*/, generateDynamicNode(uidlDynamicRef, compName, nodesLookup, isProp ? propDefinitions : stateDefinitions, stateDefinitions, subComponentOptions, structure)];
270
+ case 15:
271
+ generatedNode = _k.sent();
272
+ return [2 /*return*/, generatedNode];
273
+ case 16: return [2 /*return*/, HASTBuilders.createComment('Expressions are not supported in HTML')];
274
+ case 17: return [2 /*return*/, generateRepeaterNode(node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
275
+ case 18:
276
+ successNode = (_j = node.content.nodes) === null || _j === void 0 ? void 0 : _j.success;
277
+ if (successNode) {
278
+ return [2 /*return*/, generateHtmlSyntax(successNode, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
279
+ }
280
+ // If no success node, return empty div
281
+ return [2 /*return*/, HASTBuilders.createHTMLNode('div')];
282
+ case 19: throw new HTMLComponentGeneratorError("generateHtmlSyntax encountered a node of unsupported type: ".concat(JSON.stringify(node, null, 2), " "));
80
283
  }
81
- return [2 /*return*/];
82
284
  });
83
285
  }); };
84
- var generatElementNode = function (node, templatesLookUp, propDefinitions, stateDefinitions, subComponentOptions, structure) { return __awaiter(void 0, void 0, void 0, function () {
85
- var _a, elementType, children, _b, attrs, _c, style, _d, referencedStyles, dependency, key, elementNode, dependencies, compTag, _i, children_1, child, childTag;
86
- return __generator(this, function (_e) {
87
- switch (_e.label) {
286
+ var createConditionalStatement = function (conditions, leftOperand) {
287
+ return conditions.map(function (condition) {
288
+ var operation = condition.operation, operand = condition.operand;
289
+ if (operand === undefined) {
290
+ return "".concat(ASTUtils.convertToUnaryOperator(operation)).concat(getValueType(operand));
291
+ }
292
+ return "".concat(getValueType(leftOperand), " ").concat(ASTUtils.convertToBinaryOperator(operation), " ").concat(getValueType(operand));
293
+ });
294
+ };
295
+ var getValueType = function (value) {
296
+ var valueType = typeof value;
297
+ switch (valueType) {
298
+ case 'string':
299
+ return "\"".concat(value, "\"");
300
+ case 'number':
301
+ return value;
302
+ case 'boolean':
303
+ return value;
304
+ case 'object':
305
+ // `typeof null === 'object'` — render as the null literal so comparisons
306
+ // against a missing/null default evaluate sensibly.
307
+ if (value === null) {
308
+ return 'null';
309
+ }
310
+ // Handle dynamic references (local, prop, state)
311
+ if (value && typeof value === 'object' && 'type' in value) {
312
+ var dynamicValue = value;
313
+ if (dynamicValue.type === 'dynamic' && dynamicValue.content) {
314
+ var _a = dynamicValue.content, referenceType = _a.referenceType, id = _a.id, refPath = _a.refPath;
315
+ if (referenceType === 'local' && id) {
316
+ // Local reference from repeater context
317
+ if (refPath && refPath.length > 0) {
318
+ return "".concat(id, ".").concat(refPath.join('.'));
319
+ }
320
+ return id;
321
+ }
322
+ else if (referenceType === 'prop' || referenceType === 'state') {
323
+ // Prop or state reference
324
+ var key = refPath && refPath.length > 0 ? refPath.join('.') : id;
325
+ return key;
326
+ }
327
+ }
328
+ }
329
+ // Handle link-type prop default values ({ url, newTab }). Collapse to the
330
+ // url string so comparisons like `mapUrl !== '--'` evaluate sensibly.
331
+ if (value &&
332
+ typeof value === 'object' &&
333
+ 'url' in value &&
334
+ typeof value.url === 'string') {
335
+ return "\"".concat(value.url, "\"");
336
+ }
337
+ throw new HTMLComponentGeneratorError("Conditional node received an operand of type ".concat(valueType, " \n\n Received ").concat(JSON.stringify(value)));
338
+ default:
339
+ throw new HTMLComponentGeneratorError("Conditional node received an operand of type ".concat(valueType, " \n\n Received ").concat(JSON.stringify(value)));
340
+ }
341
+ };
342
+ var generateRepeaterNode = function (node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions) { return __awaiter(void 0, void 0, void 0, function () {
343
+ var nodes, contextId, sourceValue, propDef, nestedPath, parentContextKey, parentPropDef, pathMatch, parentItem, nestedValue, parsedSource, elementNode, emptyChildren, _i, emptyChildren_1, child, childTag, listChildren, index, _a, listChildren_1, child, childTag;
344
+ var _b;
345
+ var _c;
346
+ return __generator(this, function (_d) {
347
+ switch (_d.label) {
88
348
  case 0:
89
- _a = node.content, elementType = _a.elementType, children = _a.children, _b = _a.attrs, attrs = _b === void 0 ? {} : _b, _c = _a.style, style = _c === void 0 ? {} : _c, _d = _a.referencedStyles, referencedStyles = _d === void 0 ? {} : _d, dependency = _a.dependency, key = _a.key;
90
- elementNode = HASTBuilders.createHTMLNode(elementType);
91
- templatesLookUp[key] = elementNode;
92
- dependencies = structure.dependencies;
93
- if (dependency && (dependency === null || dependency === void 0 ? void 0 : dependency.type) !== 'local') {
94
- dependencies[dependency.path] = dependency;
349
+ nodes = node.content.nodes;
350
+ contextId = node.content.renderPropIdentifier;
351
+ sourceValue = node.content.source;
352
+ propDef = sourceValue && typeof sourceValue === 'string'
353
+ ? propDefinitions[Object.keys(propDefinitions).find(function (propKey) { return sourceValue.includes(propKey); }) || '']
354
+ : undefined;
355
+ nestedPath = null;
356
+ if (propDef && resolvedExpressions && sourceValue && typeof sourceValue === 'string') {
357
+ parentContextKey = Object.keys(resolvedExpressions.expressions || {}).find(function (key) {
358
+ return sourceValue.includes(key);
359
+ });
360
+ if (parentContextKey) {
361
+ parentPropDef = resolvedExpressions.expressions[parentContextKey];
362
+ pathMatch = sourceValue.match(new RegExp("".concat(parentContextKey.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), "((?:\\?\\.\\w+)+)")));
363
+ if (pathMatch && pathMatch[1]) {
364
+ nestedPath = pathMatch[1].split('?.').filter(Boolean);
365
+ }
366
+ if (nestedPath && parentPropDef && Array.isArray(parentPropDef.defaultValue)) {
367
+ parentItem = parentPropDef.defaultValue[resolvedExpressions.currentIndex];
368
+ if (parentItem && typeof parentItem === 'object' && !Array.isArray(parentItem)) {
369
+ nestedValue = nestedPath.reduce(function (acc, key) {
370
+ return acc && typeof acc === 'object' && !Array.isArray(acc)
371
+ ? acc[key]
372
+ : acc;
373
+ }, parentItem);
374
+ if (Array.isArray(nestedValue)) {
375
+ propDef = {
376
+ defaultValue: nestedValue,
377
+ id: contextId,
378
+ type: 'array',
379
+ };
380
+ }
381
+ }
382
+ }
383
+ }
384
+ }
385
+ if (!propDef || !Array.isArray(propDef.defaultValue)) {
386
+ // If no prop is found we might have a static source value
387
+ try {
388
+ parsedSource = JSON.parse(sourceValue);
389
+ propDef = {
390
+ defaultValue: parsedSource,
391
+ id: contextId,
392
+ type: 'array',
393
+ };
394
+ }
395
+ catch (_e) {
396
+ // Silent fail
397
+ }
398
+ }
399
+ // We do the check again to keep typescript happy, otherwise this could be in catch
400
+ if (!propDef || !Array.isArray(propDef.defaultValue)) {
401
+ return [2 /*return*/, HASTBuilders.createComment('CMS Array Mapper/Repeater not supported in HTML without a prop source')];
402
+ }
403
+ propDefinitions[contextId] = propDef;
404
+ elementNode = HASTBuilders.createHTMLNode('div');
405
+ node.content.nodes.list.content.style = { display: { type: 'static', content: 'contents' } };
406
+ if (node.content.nodes.empty) {
407
+ node.content.nodes.empty.content.style = { display: { type: 'static', content: 'contents' } };
408
+ }
409
+ if (node.content.nodes.loading) {
410
+ node.content.nodes.loading.content.style = { display: { type: 'static', content: 'contents' } };
411
+ }
412
+ if (!(propDef.defaultValue.length === 0)) return [3 /*break*/, 5];
413
+ emptyChildren = (_c = nodes.empty) === null || _c === void 0 ? void 0 : _c.content.children;
414
+ if (!emptyChildren) return [3 /*break*/, 4];
415
+ _i = 0, emptyChildren_1 = emptyChildren;
416
+ _d.label = 1;
417
+ case 1:
418
+ if (!(_i < emptyChildren_1.length)) return [3 /*break*/, 4];
419
+ child = emptyChildren_1[_i];
420
+ return [4 /*yield*/, generateHtmlSyntax(child, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure)];
421
+ case 2:
422
+ childTag = _d.sent();
423
+ if (typeof childTag === 'string') {
424
+ HASTUtils.addTextNode(elementNode, childTag);
425
+ }
426
+ else {
427
+ HASTUtils.addChildNode(elementNode, childTag);
428
+ }
429
+ _d.label = 3;
430
+ case 3:
431
+ _i++;
432
+ return [3 /*break*/, 1];
433
+ case 4:
434
+ if (nodes.empty) {
435
+ addNodeToLookup("".concat(node.content.nodes.empty.content.key), elementNode, nodesLookup);
436
+ }
437
+ return [2 /*return*/, elementNode];
438
+ case 5:
439
+ listChildren = nodes.list.content.children;
440
+ if (!listChildren) return [3 /*break*/, 11];
441
+ index = 0;
442
+ _d.label = 6;
443
+ case 6:
444
+ if (!(index < propDef.defaultValue.length)) return [3 /*break*/, 11];
445
+ _a = 0, listChildren_1 = listChildren;
446
+ _d.label = 7;
447
+ case 7:
448
+ if (!(_a < listChildren_1.length)) return [3 /*break*/, 10];
449
+ child = listChildren_1[_a];
450
+ return [4 /*yield*/, generateHtmlSyntax(child, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, { currentIndex: index, expressions: (_b = {}, _b[contextId] = propDef, _b) })];
451
+ case 8:
452
+ childTag = _d.sent();
453
+ if (typeof childTag === 'string') {
454
+ HASTUtils.addTextNode(elementNode, childTag);
455
+ }
456
+ else {
457
+ HASTUtils.addChildNode(elementNode, childTag);
458
+ }
459
+ _d.label = 9;
460
+ case 9:
461
+ _a++;
462
+ return [3 /*break*/, 7];
463
+ case 10:
464
+ index++;
465
+ return [3 /*break*/, 6];
466
+ case 11:
467
+ addNodeToLookup("".concat(node.content.nodes.list.content.key), elementNode, nodesLookup);
468
+ return [2 /*return*/, elementNode];
469
+ }
470
+ });
471
+ }); };
472
+ var generateElementNode = function (node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions) { return __awaiter(void 0, void 0, void 0, function () {
473
+ var successNode, _a, elementType, children, _b, attrs, _c, style, _d, referencedStyles, dependency, dependencies, compTag, elementNode, _i, children_1, child, childTag;
474
+ var _e;
475
+ return __generator(this, function (_f) {
476
+ switch (_f.label) {
477
+ case 0:
478
+ // Check if this is a wrapped data-source node
479
+ if (node.content &&
480
+ typeof node.content === 'object' &&
481
+ 'type' in node.content &&
482
+ (node.content.type === 'data-source-item' || node.content.type === 'data-source-list')) {
483
+ successNode = (_e = node.content.nodes) === null || _e === void 0 ? void 0 : _e.success;
484
+ if (successNode) {
485
+ return [2 /*return*/, generateHtmlSyntax(successNode, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
486
+ }
487
+ // If no success node, return empty div
488
+ return [2 /*return*/, HASTBuilders.createHTMLNode('div')];
95
489
  }
490
+ _a = node.content, elementType = _a.elementType, children = _a.children, _b = _a.attrs, attrs = _b === void 0 ? {} : _b, _c = _a.style, style = _c === void 0 ? {} : _c, _d = _a.referencedStyles, referencedStyles = _d === void 0 ? {} : _d, dependency = _a.dependency;
491
+ dependencies = structure.dependencies;
96
492
  if (!(dependency && (dependency === null || dependency === void 0 ? void 0 : dependency.type) === 'local')) return [3 /*break*/, 2];
97
- return [4 /*yield*/, generateComponentContent(node, propDefinitions, stateDefinitions, subComponentOptions, structure)];
493
+ return [4 /*yield*/, generateComponentContent(node, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
98
494
  case 1:
99
- compTag = _e.sent();
495
+ compTag = _f.sent();
496
+ if ('tagName' in compTag) {
497
+ compTag.children.unshift(HASTBuilders.createComment("".concat(node.content.semanticType, " component")));
498
+ }
100
499
  return [2 /*return*/, compTag];
101
500
  case 2:
501
+ if (dependency && (dependency === null || dependency === void 0 ? void 0 : dependency.type) !== 'local') {
502
+ dependencies[dependency.path] = dependency;
503
+ }
504
+ elementNode = HASTBuilders.createHTMLNode(elementType);
102
505
  if (!children) return [3 /*break*/, 6];
103
506
  _i = 0, children_1 = children;
104
- _e.label = 3;
507
+ _f.label = 3;
105
508
  case 3:
106
509
  if (!(_i < children_1.length)) return [3 /*break*/, 6];
107
510
  child = children_1[_i];
108
- return [4 /*yield*/, generateHtmlSynatx(child, templatesLookUp, propDefinitions, stateDefinitions, subComponentOptions, structure)];
511
+ return [4 /*yield*/, generateHtmlSyntax(child, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
109
512
  case 4:
110
- childTag = _e.sent();
111
- if (!childTag) {
112
- return [2 /*return*/];
113
- }
513
+ childTag = _f.sent();
114
514
  if (typeof childTag === 'string') {
115
515
  HASTUtils.addTextNode(elementNode, childTag);
116
516
  }
117
517
  else {
118
518
  HASTUtils.addChildNode(elementNode, childTag);
119
519
  }
120
- _e.label = 5;
520
+ _f.label = 5;
121
521
  case 5:
122
522
  _i++;
123
523
  return [3 /*break*/, 3];
@@ -126,39 +526,48 @@ var generatElementNode = function (node, templatesLookUp, propDefinitions, state
126
526
  Object.keys(referencedStyles).forEach(function (styleRef) {
127
527
  var refStyle = referencedStyles[styleRef];
128
528
  if (refStyle.content.mapType === 'inlined') {
129
- handleStyles(node, refStyle.content.styles, propDefinitions, stateDefinitions);
130
- return;
529
+ handleStyles(node, refStyle.content.styles, propDefinitions, stateDefinitions, structure.options);
131
530
  }
132
531
  });
133
532
  }
134
533
  if (Object.keys(style).length > 0) {
135
- handleStyles(node, style, propDefinitions, stateDefinitions);
136
- }
137
- if (Object.keys(attrs).length > 0) {
138
- handleAttributes(elementType, elementNode, attrs, propDefinitions, stateDefinitions, structure.options.projectRouteDefinition, structure.outputOptions);
534
+ handleStyles(node, style, propDefinitions, stateDefinitions, structure.options);
139
535
  }
536
+ handleAttributes(elementType, elementNode, attrs, propDefinitions, stateDefinitions, structure.options.projectRouteDefinition, structure.outputOptions, structure.options, resolvedExpressions === null || resolvedExpressions === void 0 ? void 0 : resolvedExpressions.currentIndex);
537
+ addNodeToLookup(node.content.key, elementNode, nodesLookup);
140
538
  return [2 /*return*/, elementNode];
141
539
  }
142
540
  });
143
541
  }); };
144
- var generateComponentContent = function (node, propDefinitions, stateDefinitions, subComponentOptions, structure) { return __awaiter(void 0, void 0, void 0, function () {
145
- var externals, plugins, _a, elementType, _b, attrs, key, _c, children, dependencies, _d, chunks, options, comp, lookUpTemplates, compHasSlots, combinedProps, propsForInstance, combinedStates, statesForInstance, elementNode, compTag, cssPlugin, initialStructure, result, chunk, styleChunk;
146
- var _e;
147
- return __generator(this, function (_f) {
148
- switch (_f.label) {
542
+ var createLookupTable = function (component, nodesLookup) {
543
+ var lookup = {};
544
+ for (var _i = 0, _a = Object.keys(nodesLookup); _i < _a.length; _i++) {
545
+ var node = _a[_i];
546
+ lookup[node] = {
547
+ count: 1,
548
+ nextKey: '1',
549
+ };
550
+ }
551
+ createNodesLookup(component, lookup);
552
+ return lookup;
553
+ };
554
+ var generateComponentContent = function (node, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions) { return __awaiter(void 0, void 0, void 0, function () {
555
+ var externals, plugins, _a, standaloneHtmlComponents, _b, elementType, _c, attrs, _d, children, dependencies, _e, chunks, options, componentName, component, componentClone, lookupTableForCurrentPage, combinedProps, combinedStates, statesForInstance, propsForInstance, _loop_1, _i, _f, propKey, componentWrapper, isExistingNode, wrapperAttrs, componentInstanceToGenerate, compTag, cssPlugin, initialStructure, result;
556
+ var _g, _h, _j;
557
+ return __generator(this, function (_k) {
558
+ switch (_k.label) {
149
559
  case 0:
150
- externals = subComponentOptions.externals, plugins = subComponentOptions.plugins;
151
- _a = node.content, elementType = _a.elementType, _b = _a.attrs, attrs = _b === void 0 ? {} : _b, key = _a.key, _c = _a.children, children = _c === void 0 ? [] : _c;
152
- dependencies = structure.dependencies, _d = structure.chunks, chunks = _d === void 0 ? [] : _d, options = structure.options;
153
- comp = UIDLUtils.cloneObject(externals[elementType] || {});
154
- lookUpTemplates = {};
155
- compHasSlots = false;
156
- if (!comp || !(comp === null || comp === void 0 ? void 0 : comp.node)) {
157
- throw new HTMLComponentGeneratorError("".concat(elementType, " is not found from the externals. \n\n Received ").concat(JSON.stringify(Object.keys(externals), null, 2)));
560
+ externals = subComponentOptions.externals, plugins = subComponentOptions.plugins, _a = subComponentOptions.standaloneHtmlComponents, standaloneHtmlComponents = _a === void 0 ? false : _a;
561
+ _b = node.content, elementType = _b.elementType, _c = _b.attrs, attrs = _c === void 0 ? {} : _c, _d = _b.children, children = _d === void 0 ? [] : _d;
562
+ dependencies = structure.dependencies, _e = structure.chunks, chunks = _e === void 0 ? [] : _e, options = structure.options;
563
+ componentName = elementType === 'Component' ? 'AppComponent' : elementType;
564
+ component = externals[componentName];
565
+ if (component === undefined) {
566
+ throw new HTMLComponentGeneratorError("".concat(componentName, " is missing from externals object"));
158
567
  }
568
+ componentClone = UIDLUtils.cloneObject(component);
159
569
  if (children.length) {
160
- compHasSlots = true;
161
- UIDLUtils.traverseNodes(comp.node, function (childNode, parentNode) {
570
+ UIDLUtils.traverseNodes(componentClone.node, function (childNode, parentNode) {
162
571
  var _a, _b;
163
572
  if (childNode.type === 'slot' && parentNode.type === 'element') {
164
573
  var nonSlotNodes = (_b = (_a = parentNode.content) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b.filter(function (n) { return n.type !== 'slot'; });
@@ -168,6 +577,7 @@ var generateComponentContent = function (node, propDefinitions, stateDefinitions
168
577
  content: {
169
578
  key: 'custom-slot',
170
579
  elementType: 'slot',
580
+ name: componentClone.name + 'slot',
171
581
  style: {
172
582
  display: {
173
583
  type: 'static',
@@ -186,46 +596,133 @@ var generateComponentContent = function (node, propDefinitions, stateDefinitions
186
596
  */
187
597
  node.content.children = [];
188
598
  }
189
- combinedProps = __assign(__assign({}, propDefinitions), ((comp === null || comp === void 0 ? void 0 : comp.propDefinitions) || {}));
190
- propsForInstance = Object.keys(combinedProps).reduce(function (acc, propKey) {
191
- var _a, _b;
192
- if (attrs[propKey]) {
193
- acc[propKey] = __assign(__assign({}, combinedProps[propKey]), { defaultValue: ((_a = attrs[propKey]) === null || _a === void 0 ? void 0 : _a.content) || ((_b = combinedProps[propKey]) === null || _b === void 0 ? void 0 : _b.defaultValue) });
194
- }
195
- else {
196
- acc[propKey] = combinedProps[propKey];
197
- }
599
+ lookupTableForCurrentPage = createLookupTable(componentClone, nodesLookup);
600
+ generateUniqueKeys(componentClone, lookupTableForCurrentPage);
601
+ combinedProps = __assign(__assign({}, Object.keys(propDefinitions).reduce(function (acc, propKey) {
602
+ acc[propKey] = propDefinitions[propKey];
198
603
  return acc;
199
- }, {});
200
- combinedStates = __assign(__assign({}, stateDefinitions), ((comp === null || comp === void 0 ? void 0 : comp.stateDefinitions) || {}));
604
+ }, {})), ((componentClone === null || componentClone === void 0 ? void 0 : componentClone.propDefinitions) || {}));
605
+ combinedStates = __assign(__assign({}, stateDefinitions), ((componentClone === null || componentClone === void 0 ? void 0 : componentClone.stateDefinitions) || {}));
201
606
  statesForInstance = Object.keys(combinedStates).reduce(function (acc, propKey) {
202
607
  var _a, _b;
203
- if (attrs[propKey]) {
204
- acc[propKey] = __assign(__assign({}, combinedStates[propKey]), { defaultValue: ((_a = attrs[propKey]) === null || _a === void 0 ? void 0 : _a.content) || ((_b = combinedStates[propKey]) === null || _b === void 0 ? void 0 : _b.defaultValue) });
608
+ var attr = attrs[propKey];
609
+ if ((attr === null || attr === void 0 ? void 0 : attr.type) === 'object') {
610
+ throw new Error("Object attributes are not supported in html exports");
611
+ }
612
+ if (attr) {
613
+ acc[propKey] = __assign(__assign({}, combinedStates[propKey]), { defaultValue: (_a = attr === null || attr === void 0 ? void 0 : attr.content) !== null && _a !== void 0 ? _a : (_b = combinedStates[propKey]) === null || _b === void 0 ? void 0 : _b.defaultValue });
205
614
  }
206
615
  else {
207
616
  acc[propKey] = combinedStates[propKey];
208
617
  }
209
618
  return acc;
210
619
  }, {});
211
- elementNode = HASTBuilders.createHTMLNode(StringUtils.camelCaseToDashCase(elementType));
212
- lookUpTemplates[key] = elementNode;
213
- return [4 /*yield*/, generateHtmlSynatx(__assign(__assign({}, comp.node), { content: __assign(__assign({}, comp.node.content), { style: __assign(__assign({}, (((_e = comp.node.content) === null || _e === void 0 ? void 0 : _e.style) || {})), { display: {
214
- type: 'static',
215
- content: 'contents',
216
- } }) }) }), lookUpTemplates, propsForInstance, statesForInstance, subComponentOptions, structure)];
620
+ propsForInstance = {};
621
+ _loop_1 = function (propKey) {
622
+ var attribute = attrs[propKey];
623
+ if ((attribute === null || attribute === void 0 ? void 0 : attribute.type) === 'element') {
624
+ propsForInstance[propKey] = __assign(__assign({}, combinedProps[propKey]), { defaultValue: attrs[propKey] });
625
+ }
626
+ if ((attribute === null || attribute === void 0 ? void 0 : attribute.type) === 'dynamic') {
627
+ // When we are using a component instance in a component and the attribute
628
+ // that is passed to the component is of dynamic reference.
629
+ // If means, the component is redirecting the prop that is received to the prop of the component that it is consuming.
630
+ // In this case, we need to pass the value of the prop that is received to the prop of the component that it is consuming.
631
+ // And similary we do the same for the states.
632
+ switch (attribute.content.referenceType) {
633
+ case 'prop':
634
+ propsForInstance[propKey] = combinedProps[attribute.content.id];
635
+ break;
636
+ case 'state':
637
+ propsForInstance[propKey] = combinedStates[attribute.content.id];
638
+ break;
639
+ case 'expr':
640
+ // Ignore expr type attributes in html comp instances for the time being.
641
+ break;
642
+ default:
643
+ throw new Error("ReferenceType ".concat(attribute.content.referenceType, " is not supported in HTML Export."));
644
+ }
645
+ }
646
+ if ((attribute === null || attribute === void 0 ? void 0 : attribute.type) === 'object') {
647
+ propsForInstance[propKey] = __assign(__assign({}, combinedProps[propKey]), { defaultValue: (attribute === null || attribute === void 0 ? void 0 : attribute.content) || ((_g = combinedProps[propKey]) === null || _g === void 0 ? void 0 : _g.defaultValue) });
648
+ }
649
+ if ((attribute === null || attribute === void 0 ? void 0 : attribute.type) === 'expr') {
650
+ var _l = attribute.content.split('?.'), ctxId_1 = _l[0], refPath = _l.slice(1);
651
+ var propKeyFromAttr = Object.keys(combinedProps).find(function (key) { return key === ctxId_1; });
652
+ var resolvedValue = combinedProps[propKeyFromAttr];
653
+ var hasRefPath = refPath.length > 0;
654
+ // Build the path using repeater index when available
655
+ var fullRefPath = typeof (resolvedExpressions === null || resolvedExpressions === void 0 ? void 0 : resolvedExpressions.currentIndex) === 'number' && hasRefPath
656
+ ? __spreadArray([resolvedExpressions.currentIndex.toString()], refPath, true) : refPath;
657
+ if (Array.isArray(resolvedValue)) {
658
+ // If the resolved value itself is an array definition, pass it through
659
+ propsForInstance[propKey] = resolvedValue;
660
+ }
661
+ else {
662
+ var defaultVal = resolvedValue === null || resolvedValue === void 0 ? void 0 : resolvedValue.defaultValue;
663
+ var extracted = hasRefPath && defaultVal !== undefined
664
+ ? extractDefaultValueFromRefPath(defaultVal, fullRefPath)
665
+ : defaultVal !== null && defaultVal !== void 0 ? defaultVal : null;
666
+ propsForInstance[propKey] = __assign(__assign({}, resolvedValue), { defaultValue: extracted });
667
+ }
668
+ }
669
+ if ((attribute === null || attribute === void 0 ? void 0 : attribute.type) !== 'dynamic' &&
670
+ (attribute === null || attribute === void 0 ? void 0 : attribute.type) !== 'element' &&
671
+ (attribute === null || attribute === void 0 ? void 0 : attribute.type) !== 'object' &&
672
+ (attribute === null || attribute === void 0 ? void 0 : attribute.type) !== 'expr') {
673
+ propsForInstance[propKey] = __assign(__assign({}, combinedProps[propKey]), { defaultValue: (_h = attribute === null || attribute === void 0 ? void 0 : attribute.content) !== null && _h !== void 0 ? _h : (_j = combinedProps[propKey]) === null || _j === void 0 ? void 0 : _j.defaultValue });
674
+ }
675
+ if (attribute === undefined) {
676
+ var propFromCurrentComponent = combinedProps[propKey];
677
+ propsForInstance[propKey] = propFromCurrentComponent;
678
+ }
679
+ };
680
+ // this is where we check if the component we are conusming is actually passing any props to the instance.
681
+ // We check if we are passing any props and pick the value from the atrrs, if not we pick the value from the propDefinitions of
682
+ // the component instance that we are using here.
683
+ for (_i = 0, _f = Object.keys(combinedProps); _i < _f.length; _i++) {
684
+ propKey = _f[_i];
685
+ _loop_1(propKey);
686
+ }
687
+ componentWrapper = StringUtils.camelCaseToDashCase("".concat(componentName, "-wrapper"));
688
+ isExistingNode = nodesLookup[componentWrapper];
689
+ if (isExistingNode !== undefined) {
690
+ componentWrapper = "".concat(componentWrapper, "-").concat(StringUtils.generateRandomString());
691
+ }
692
+ wrapperAttrs = {};
693
+ Object.keys(attrs).forEach(function (attrKey) {
694
+ if (attrKey.startsWith('dataNode') || attrKey.startsWith('data-node')) {
695
+ wrapperAttrs[attrKey] = attrs[attrKey];
696
+ }
697
+ });
698
+ componentInstanceToGenerate = {
699
+ type: 'element',
700
+ content: {
701
+ elementType: componentWrapper,
702
+ key: componentWrapper,
703
+ children: [componentClone.node],
704
+ attrs: wrapperAttrs,
705
+ style: {
706
+ display: {
707
+ type: 'static',
708
+ content: 'contents',
709
+ },
710
+ },
711
+ },
712
+ };
713
+ return [4 /*yield*/, generateHtmlSyntax(componentInstanceToGenerate, component.name, nodesLookup, propsForInstance, statesForInstance, subComponentOptions, structure, resolvedExpressions)];
217
714
  case 1:
218
- compTag = (_f.sent());
715
+ compTag = _k.sent();
219
716
  cssPlugin = createCSSPlugin({
220
717
  templateStyle: 'html',
221
718
  templateChunkName: DEFAULT_COMPONENT_CHUNK_NAME,
222
- declareDependency: 'import',
223
- forceScoping: true,
224
- chunkName: comp.name,
719
+ declareDependency: standaloneHtmlComponents ? 'none' : 'import',
720
+ chunkName: componentClone.name,
225
721
  staticPropReferences: true,
722
+ standaloneHtmlComponents: standaloneHtmlComponents,
226
723
  });
227
724
  initialStructure = {
228
- uidl: __assign(__assign({}, comp), { propDefinitions: propsForInstance, stateDefinitions: statesForInstance }),
725
+ uidl: __assign(__assign({}, componentClone), { node: componentInstanceToGenerate, propDefinitions: propsForInstance, stateDefinitions: statesForInstance }),
229
726
  chunks: [
230
727
  {
231
728
  type: ChunkType.HAST,
@@ -234,7 +731,7 @@ var generateComponentContent = function (node, propDefinitions, stateDefinitions
234
731
  linkAfter: [],
235
732
  content: compTag,
236
733
  meta: {
237
- nodesLookup: lookUpTemplates,
734
+ nodesLookup: nodesLookup,
238
735
  },
239
736
  },
240
737
  ],
@@ -253,132 +750,271 @@ var generateComponentContent = function (node, propDefinitions, stateDefinitions
253
750
  });
254
751
  }); }, Promise.resolve(initialStructure))];
255
752
  case 2:
256
- result = _f.sent();
257
- if (compHasSlots) {
258
- result.chunks.forEach(function (chunk) {
259
- if (chunk.fileType === FileType.CSS) {
260
- chunks.push(chunk);
753
+ result = _k.sent();
754
+ result.chunks.forEach(function (chunk) {
755
+ if (chunk.fileType === FileType.CSS) {
756
+ chunks.push(chunk);
757
+ }
758
+ });
759
+ addNodeToLookup(node.content.key, compTag, nodesLookup);
760
+ return [2 /*return*/, compTag];
761
+ }
762
+ });
763
+ }); };
764
+ var generateDynamicNode = function (node, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions) { return __awaiter(void 0, void 0, void 0, function () {
765
+ var translation, localeTag, commentNode, globalTag, commentNode, usedReferenceValue, extracted, elementNode, elementClone, iterElementTag, generatedElementTag, spanTagWrapper, commentNode, spanTag;
766
+ var _a;
767
+ return __generator(this, function (_b) {
768
+ switch (_b.label) {
769
+ case 0:
770
+ if (node.content.referenceType === 'locale') {
771
+ translation = getTranslation(node.content.id, structure.options);
772
+ if (translation) {
773
+ if (translation.type === 'static') {
774
+ return [2 /*return*/, HASTBuilders.createTextNode(String(translation.content))];
261
775
  }
262
- });
263
- }
264
- else {
265
- chunk = chunks.find(function (item) { return item.name === comp.name; });
266
- if (!chunk) {
267
- styleChunk = result.chunks.find(function (item) { return item.fileType === FileType.CSS; });
268
- if (!styleChunk) {
269
- return [2 /*return*/];
776
+ if (translation.type === 'element') {
777
+ return [2 /*return*/, generateHtmlSyntax(translation, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure)];
270
778
  }
271
- chunks.push(styleChunk);
272
779
  }
780
+ localeTag = HASTBuilders.createHTMLNode('span');
781
+ commentNode = HASTBuilders.createComment("Content for locale ".concat(node.content.id));
782
+ HASTUtils.addChildNode(localeTag, commentNode);
783
+ return [2 /*return*/, localeTag];
273
784
  }
274
- return [2 /*return*/, compTag];
785
+ if (node.content.referenceType === 'global' ||
786
+ node.content.referenceType === 'globalState') {
787
+ globalTag = HASTBuilders.createHTMLNode('span');
788
+ commentNode = HASTBuilders.createComment("Global reference: ".concat(node.content.id));
789
+ HASTUtils.addChildNode(globalTag, commentNode);
790
+ return [2 /*return*/, globalTag];
791
+ }
792
+ usedReferenceValue = getValueFromReference(node.content.id, node.content.referenceType === 'prop' ? propDefinitions : stateDefinitions);
793
+ if ((usedReferenceValue.type === 'object' || usedReferenceValue.type === 'array') &&
794
+ usedReferenceValue.defaultValue) {
795
+ extracted = extractDefaultValueFromRefPath(usedReferenceValue.defaultValue, node.content.refPath);
796
+ if (extracted === undefined || extracted === null) {
797
+ return [2 /*return*/, HASTBuilders.createTextNode('')];
798
+ }
799
+ return [2 /*return*/, HASTBuilders.createTextNode(String(extracted))];
800
+ }
801
+ if (!(usedReferenceValue.type === 'element')) return [3 /*break*/, 5];
802
+ elementNode = usedReferenceValue.defaultValue;
803
+ if (!elementNode) return [3 /*break*/, 4];
804
+ if (!(resolvedExpressions && typeof resolvedExpressions.currentIndex === 'number')) return [3 /*break*/, 2];
805
+ elementClone = UIDLUtils.cloneObject(elementNode);
806
+ if ((_a = elementClone === null || elementClone === void 0 ? void 0 : elementClone.content) === null || _a === void 0 ? void 0 : _a.key) {
807
+ elementClone.content.key = "".concat(elementClone.content.key, "-").concat(resolvedExpressions.currentIndex);
808
+ }
809
+ return [4 /*yield*/, generateHtmlSyntax(elementClone, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
810
+ case 1:
811
+ iterElementTag = _b.sent();
812
+ return [2 /*return*/, iterElementTag];
813
+ case 2:
814
+ if (elementNode.content.key in nodesLookup) {
815
+ return [2 /*return*/, nodesLookup[elementNode.content.key]];
816
+ }
817
+ return [4 /*yield*/, generateHtmlSyntax(elementNode, compName, nodesLookup, propDefinitions, stateDefinitions, subComponentOptions, structure, resolvedExpressions)];
818
+ case 3:
819
+ generatedElementTag = _b.sent();
820
+ return [2 /*return*/, generatedElementTag];
821
+ case 4:
822
+ spanTagWrapper = HASTBuilders.createHTMLNode('span');
823
+ commentNode = HASTBuilders.createComment("Content for slot ".concat(node.content.id));
824
+ HASTUtils.addChildNode(spanTagWrapper, commentNode);
825
+ return [2 /*return*/, spanTagWrapper];
826
+ case 5:
827
+ spanTag = HASTBuilders.createHTMLNode('span');
828
+ HASTUtils.addTextNode(spanTag, String(usedReferenceValue.defaultValue));
829
+ return [2 /*return*/, spanTag];
275
830
  }
276
831
  });
277
832
  }); };
278
- var generateDynamicNode = function (node, _, propDefinitions, stateDefinitions) {
279
- var spanTag = HASTBuilders.createHTMLNode('span');
280
- var usedReferenceValue = node.content.referenceType === 'prop'
281
- ? getValueFromReference(node.content.id, propDefinitions)
282
- : getValueFromReference(node.content.id, stateDefinitions);
283
- HASTUtils.addTextNode(spanTag, String(usedReferenceValue));
284
- return spanTag;
285
- };
286
- var handleStyles = function (node, styles, propDefinitions, stateDefinitions) {
833
+ var handleStyles = function (node, styles, propDefinitions, stateDefinitions, options) {
287
834
  Object.keys(styles).forEach(function (styleKey) {
288
- var _a;
835
+ var _a, _b, _c, _d, _e;
289
836
  var style = styles[styleKey];
290
837
  if (style.type === 'dynamic' && ((_a = style.content) === null || _a === void 0 ? void 0 : _a.referenceType) !== 'token') {
291
- if (style.content.referenceType === 'prop') {
292
- style = getValueFromReference(style.content.id, propDefinitions);
838
+ if (((_b = style.content) === null || _b === void 0 ? void 0 : _b.referenceType) === 'locale') {
839
+ var translation = getTranslation(style.content.id, options);
840
+ var resolvedText = translation
841
+ ? resolveTranslationText(translation)
842
+ : "[locale: ".concat(style.content.id, "]");
843
+ node.content.style[styleKey] = staticNode(resolvedText);
844
+ return;
845
+ }
846
+ if (((_c = style.content) === null || _c === void 0 ? void 0 : _c.referenceType) === 'global' ||
847
+ ((_d = style.content) === null || _d === void 0 ? void 0 : _d.referenceType) === 'globalState') {
848
+ node.content.style[styleKey] = staticNode("[global: ".concat(style.content.id, "]"));
849
+ return;
293
850
  }
294
- else if (style.content.referenceType === 'state') {
295
- style = getValueFromReference(style.content.id, stateDefinitions);
851
+ var referencedValue = getValueFromReference(style.content.id, style.content.referenceType === 'prop' ? propDefinitions : stateDefinitions);
852
+ if (referencedValue.type === 'string' || referencedValue.type === 'number') {
853
+ style = String(extractDefaultValueFromRefPath(referencedValue.defaultValue, (_e = style === null || style === void 0 ? void 0 : style.content) === null || _e === void 0 ? void 0 : _e.refPath));
296
854
  }
297
855
  node.content.style[styleKey] = typeof style === 'string' ? staticNode(style) : style;
298
856
  }
299
857
  });
300
858
  };
301
- var handleAttributes = function (elementType, htmlNode, attrs, propDefinitions, stateDefinitions, routeDefinitions, outputOptions) {
302
- Object.keys(attrs).forEach(function (attrKey) {
859
+ var handleAttributes = function (elementType, htmlNode, attrs, propDefinitions, stateDefinitions, routeDefinitions, outputOptions, options, currentIndex) {
860
+ var _loop_2 = function (attrKey) {
303
861
  var attrValue = attrs[attrKey];
304
- if (attrKey === 'href' &&
305
- attrValue.type === 'static' &&
306
- typeof attrValue.content === 'string' &&
307
- attrValue.content.startsWith('/')) {
308
- var targetLink = void 0;
309
- var targetRoute = ((routeDefinitions === null || routeDefinitions === void 0 ? void 0 : routeDefinitions.values) || []).find(function (route) { return route.pageOptions.navLink === attrValue.content; });
310
- if (targetRoute) {
311
- targetLink = targetRoute.pageOptions.navLink;
862
+ var type = attrValue.type, content = attrValue.content;
863
+ switch (type) {
864
+ case 'static': {
865
+ if (attrKey === 'href' && typeof content === 'string' && content.startsWith('/')) {
866
+ var targetLink = void 0;
867
+ var targetRoute = ((routeDefinitions === null || routeDefinitions === void 0 ? void 0 : routeDefinitions.values) || []).find(function (route) { return route.pageOptions.navLink === content; });
868
+ if (targetRoute) {
869
+ targetLink = targetRoute.pageOptions.navLink;
870
+ }
871
+ if (!targetRoute && content === '/home') {
872
+ targetLink = '/';
873
+ }
874
+ if (!targetLink && !targetRoute) {
875
+ targetLink = content;
876
+ }
877
+ var currentPageRoute = join.apply(void 0, __spreadArray(__spreadArray([], ((outputOptions === null || outputOptions === void 0 ? void 0 : outputOptions.folderPath) || []), false), ['./'], false));
878
+ var localPrefix = relative("/".concat(currentPageRoute), "/".concat(targetLink === '/' ? 'index' : targetLink));
879
+ HASTUtils.addAttributeToNode(htmlNode, attrKey, "".concat(localPrefix, ".html"));
880
+ break;
881
+ }
882
+ if (typeof content === 'boolean') {
883
+ htmlNode.properties[attrKey] = content === true ? 'true' : 'false';
884
+ }
885
+ else if (typeof content === 'string' || typeof attrValue.content === 'number') {
886
+ var value = StringUtils.encode(String(attrValue.content));
887
+ /*
888
+ elementType of image is always mapped to img.
889
+ For reference, check `html-mapping` file.
890
+ */
891
+ if ((elementType === 'img' || elementType === 'video') &&
892
+ attrKey === 'src' &&
893
+ !isValidURL(value)) {
894
+ /*
895
+ By default we just prefix all the asset paths with just the
896
+ assetPrefix that is configured in the project. But for `html` generators
897
+ we need to prefix that with the current file location.
898
+
899
+ Because, all the other frameworks have a build setup. which serves all the
900
+ assets from the `public` folder. But in the case of `html` here is how it works
901
+
902
+ We load a file from `index.html` the request for the image goes from
903
+ '...url.../public/...image...'
904
+ If it's a nested url, then the request goes from
905
+ '...url/nested/public/...image..'
906
+
907
+ But the nested folder is available only on the root. With this
908
+ The url changes prefixes to
909
+
910
+ ../public/playground_assets/..image.. etc depending on the dept the file is in.
911
+ */
912
+ value = join(relative(join.apply(void 0, outputOptions.folderPath), './'), value);
913
+ }
914
+ HASTUtils.addAttributeToNode(htmlNode, attrKey, value);
915
+ }
916
+ break;
312
917
  }
313
- if (!targetRoute && attrValue.content === '/home') {
314
- targetLink = '/';
918
+ case 'dynamic': {
919
+ if (content.referenceType === 'locale') {
920
+ var translation = getTranslation(content.id, options);
921
+ var resolvedText = translation
922
+ ? resolveTranslationText(translation)
923
+ : "[locale: ".concat(content.id, "]");
924
+ HASTUtils.addAttributeToNode(htmlNode, attrKey, resolvedText);
925
+ break;
926
+ }
927
+ if (content.referenceType === 'global' ||
928
+ content.referenceType === 'globalState') {
929
+ HASTUtils.addAttributeToNode(htmlNode, attrKey, "[global: ".concat(content.id, "]"));
930
+ break;
931
+ }
932
+ var value = getValueFromReference(content.id, content.referenceType === 'prop' ? propDefinitions : stateDefinitions);
933
+ // A `func` prop has no meaningful static HTML representation; skip
934
+ // rather than emitting the stringified function body as an attribute.
935
+ if (value.type === 'func') {
936
+ break;
937
+ }
938
+ var extracted = extractDefaultValueFromRefPath(value.defaultValue, content.refPath);
939
+ var extractedValue = String(extracted);
940
+ if ((elementType === 'img' || elementType === 'video') &&
941
+ attrKey === 'src' &&
942
+ !extractedValue.startsWith('http')) {
943
+ var path = join(relative(join.apply(void 0, outputOptions.folderPath), './'), extractedValue);
944
+ HASTUtils.addAttributeToNode(htmlNode, attrKey, path);
945
+ break;
946
+ }
947
+ HASTUtils.addAttributeToNode(htmlNode, attrKey, extractedValue);
948
+ break;
315
949
  }
316
- if (!targetLink && !targetRoute) {
317
- targetLink = attrValue.content;
950
+ case 'raw': {
951
+ var rawAttr = attrValue;
952
+ HASTUtils.addAttributeToNode(htmlNode, attrKey, rawAttr.fallback || rawAttr.content);
953
+ break;
318
954
  }
319
- var currentPageRoute = join.apply(void 0, __spreadArray(__spreadArray([], ((outputOptions === null || outputOptions === void 0 ? void 0 : outputOptions.folderPath) || []), false), ['./'], false));
320
- var localPrefix = relative("/".concat(currentPageRoute), "/".concat(targetLink === '/' ? 'index' : targetLink));
321
- HASTUtils.addAttributeToNode(htmlNode, attrKey, "".concat(localPrefix, ".html"));
322
- return;
323
- }
324
- if (attrValue.type === 'dynamic') {
325
- var value = attrValue.content.referenceType === 'prop'
326
- ? getValueFromReference(attrValue.content.id, propDefinitions)
327
- : getValueFromReference(attrValue.content.id, stateDefinitions);
328
- HASTUtils.addAttributeToNode(htmlNode, attrKey, String(value));
329
- return;
330
- }
331
- if (attrValue.type === 'raw') {
332
- HASTUtils.addAttributeToNode(htmlNode, attrKey, attrValue.content);
333
- return;
334
- }
335
- if (typeof attrValue.content === 'boolean') {
336
- HASTUtils.addBooleanAttributeToNode(htmlNode, attrKey);
337
- return;
338
- }
339
- else if (typeof attrValue.content === 'string' || typeof attrValue.content === 'number') {
340
- var value = StringUtils.encode(String(attrValue.content));
341
- /*
342
- elementType of image is always mapped to img.
343
- For reference, check `html-mapping` file.
344
- */
345
- if (elementType === 'img' && attrKey === 'src') {
346
- /*
347
- By default we just prefix all the asset paths with just the
348
- assetPrefix that is configured in the project. But for `html` generators
349
- we need to prefix that with the current file location.
350
-
351
- Because, all the other frameworks have a build setup. which serves all the
352
- assets from the `public` folder. But in the case of `html` here is how it works
353
-
354
- We load a file from `index.html` the request for the image goes from
355
- '...url.../public/...image...'
356
- If it's a nested url, then the request goes from
357
- '...url/nested/public/...image..'
358
-
359
- But the nested folder is available only on the root. With this
360
- The url changes prefixes to
361
-
362
- ../public/playground_assets/..image.. etc depending on the dept the file is in.
363
- */
364
- value = join(relative(join.apply(void 0, outputOptions.folderPath), './'), value);
955
+ case 'expr': {
956
+ var fullPath = content.split('?.');
957
+ var prop = propDefinitions[(fullPath === null || fullPath === void 0 ? void 0 : fullPath[0]) || ''];
958
+ if (!prop) {
959
+ break;
960
+ }
961
+ var path = typeof currentIndex === 'number'
962
+ ? __spreadArray([currentIndex.toString()], fullPath.slice(1), true) : fullPath.slice(1);
963
+ var value = extractDefaultValueFromRefPath(prop.defaultValue, path);
964
+ if (!value) {
965
+ break;
966
+ }
967
+ HASTUtils.addAttributeToNode(htmlNode, attrKey, String(value));
968
+ break;
969
+ }
970
+ case 'element':
971
+ case 'import':
972
+ case 'object':
973
+ break;
974
+ default: {
975
+ throw new HTMLComponentGeneratorError("Received ".concat(JSON.stringify(attrValue, null, 2), " \n in handleAttributes for html"));
365
976
  }
366
- HASTUtils.addAttributeToNode(htmlNode, attrKey, value);
367
- return;
368
977
  }
369
- });
978
+ };
979
+ for (var _i = 0, _a = Object.keys(attrs); _i < _a.length; _i++) {
980
+ var attrKey = _a[_i];
981
+ _loop_2(attrKey);
982
+ }
370
983
  };
371
984
  var getValueFromReference = function (key, definitions) {
372
- var usedReferenceValue = definitions[key.includes('.') ? key.split('.')[0] : key];
985
+ var usedReferenceValue = definitions[key.includes('?.') ? key.split('?.')[0] : key];
373
986
  if (!usedReferenceValue) {
374
987
  throw new HTMLComponentGeneratorError("Definition for ".concat(key, " is missing from ").concat(JSON.stringify(definitions, null, 2)));
375
988
  }
376
- if (!usedReferenceValue.hasOwnProperty('defaultValue')) {
989
+ if ((usedReferenceValue === null || usedReferenceValue === void 0 ? void 0 : usedReferenceValue.type) &&
990
+ ['string', 'number', 'object', 'element', 'array', 'boolean', 'link', 'func'].includes(usedReferenceValue.type) === false) {
991
+ throw new HTMLComponentGeneratorError("Attribute is using dynamic value, but received of type ".concat(JSON.stringify(usedReferenceValue, null, 2)));
992
+ }
993
+ if (usedReferenceValue.type !== 'element' &&
994
+ usedReferenceValue.hasOwnProperty('defaultValue') === false) {
377
995
  throw new HTMLComponentGeneratorError("Default value is missing from dynamic reference - ".concat(JSON.stringify(usedReferenceValue, null, 2)));
378
996
  }
379
- if (!['string', 'number', 'object'].includes(usedReferenceValue === null || usedReferenceValue === void 0 ? void 0 : usedReferenceValue.type)) {
380
- throw new HTMLComponentGeneratorError("Attribute is using dynamic value, but received of type ".concat(JSON.stringify(usedReferenceValue, null, 2)));
997
+ return usedReferenceValue;
998
+ };
999
+ var extractDefaultValueFromRefPath = function (propDefaultValue, refPath) {
1000
+ if (!refPath || refPath.length === 0) {
1001
+ return propDefaultValue;
1002
+ }
1003
+ // Directly handle array indexing for the first segment when applicable
1004
+ if (Array.isArray(propDefaultValue)) {
1005
+ var first = refPath[0], rest = refPath.slice(1);
1006
+ var idx = Number(first);
1007
+ if (!Number.isNaN(idx) && idx >= 0 && idx < propDefaultValue.length) {
1008
+ var nextVal = propDefaultValue[idx];
1009
+ if (rest.length === 0) {
1010
+ return nextVal;
1011
+ }
1012
+ return extractDefaultValueFromRefPath(nextVal, rest);
1013
+ }
1014
+ }
1015
+ if (typeof propDefaultValue !== 'object') {
1016
+ return propDefaultValue;
381
1017
  }
382
- return String(usedReferenceValue.defaultValue);
1018
+ return GenericUtils.getValueFromPath(refPath.join('.'), propDefaultValue);
383
1019
  };
384
1020
  //# sourceMappingURL=node-handlers.js.map