@cocreate/render 1.45.5 → 1.46.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/.github/workflows/automated.yml +5 -6
- package/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/src/index.js +1077 -1153
package/src/index.js
CHANGED
|
@@ -25,10 +25,12 @@ import Actions from "@cocreate/actions";
|
|
|
25
25
|
import Observer from "@cocreate/observer";
|
|
26
26
|
import uuid from "@cocreate/uuid";
|
|
27
27
|
import {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
queryElements,
|
|
29
|
+
getValueFromObject,
|
|
30
|
+
dotNotationToObject,
|
|
31
|
+
ObjectId,
|
|
32
|
+
safeParse,
|
|
33
|
+
processOperatorsAsync
|
|
32
34
|
} from "@cocreate/utils";
|
|
33
35
|
import "@cocreate/element-prototype";
|
|
34
36
|
import "./index.css";
|
|
@@ -45,28 +47,44 @@ const elementSelector = "[render-query]";
|
|
|
45
47
|
* - render-query: [Describe what this attribute does]
|
|
46
48
|
*
|
|
47
49
|
* @param {(Element|Element[]|HTMLCollection|null)} [element] - Optional. A single element, an array of elements, an HTMLCollection, or null.
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
50
|
+
* - If an HTMLCollection or an array of elements is provided, each element in the collection/array is initialized.
|
|
51
|
+
* - If a single element is provided, only that element is initialized.
|
|
52
|
+
* - If null or omitted, the function queries and initializes all elements matching the 'elementSelector'.
|
|
51
53
|
*/
|
|
52
54
|
function init(element) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
55
|
+
if (
|
|
56
|
+
element &&
|
|
57
|
+
!(element instanceof HTMLCollection) &&
|
|
58
|
+
!Array.isArray(element)
|
|
59
|
+
)
|
|
60
|
+
element = [element];
|
|
61
|
+
else if (!element) element = document.querySelectorAll(elementSelector);
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < element.length; i++) {
|
|
64
|
+
let source = sources.get(element[i]);
|
|
65
|
+
if (!source) {
|
|
66
|
+
sources.set(element[i], { element: element[i] });
|
|
67
|
+
element[i].renderValue = async (data) =>
|
|
68
|
+
await render({ source: element[i], data });
|
|
69
|
+
element[i].getData = () => sources.get(element[i]).data;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let dataAttr = element[i].getAttribute("render-data");
|
|
73
|
+
|
|
74
|
+
if (dataAttr) {
|
|
75
|
+
try {
|
|
76
|
+
// Parse the string into a usable object
|
|
77
|
+
const parsedData = JSON.parse(dataAttr);
|
|
78
|
+
|
|
79
|
+
// Ensure the method exists before calling it
|
|
80
|
+
if (typeof element[i].renderValue === "function") {
|
|
81
|
+
element[i].renderValue(parsedData);
|
|
82
|
+
}
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error("Failed to parse render-data:", error);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
70
88
|
}
|
|
71
89
|
|
|
72
90
|
/**
|
|
@@ -85,1178 +103,1084 @@ function init(element) {
|
|
|
85
103
|
* @param {boolean} [options.remove] - Flag to indicate if the rendering should remove elements instead of updating or appending.
|
|
86
104
|
*/
|
|
87
105
|
async function render({
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
106
|
+
source,
|
|
107
|
+
element,
|
|
108
|
+
selector,
|
|
109
|
+
data,
|
|
110
|
+
key,
|
|
111
|
+
index,
|
|
112
|
+
currentIndex,
|
|
113
|
+
update,
|
|
114
|
+
remove
|
|
97
115
|
}) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
116
|
+
if (!data || (!source && !data)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!element) {
|
|
121
|
+
if (source instanceof HTMLElement) {
|
|
122
|
+
if (selector || (selector = source.getAttribute("render-query"))) {
|
|
123
|
+
element = queryElements({
|
|
124
|
+
element: source,
|
|
125
|
+
selector
|
|
126
|
+
});
|
|
127
|
+
} else if (source.children.length > 0) {
|
|
128
|
+
element = Array.from(source.children).find((child) =>
|
|
129
|
+
child.matches("template, [template], .template, [render]")
|
|
130
|
+
);
|
|
131
|
+
if (!element) {
|
|
132
|
+
element = source.querySelector(
|
|
133
|
+
"template, [template], .template, [render]"
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} else if (selector) {
|
|
138
|
+
element = queryElements({
|
|
139
|
+
selector
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!element || (Array.isArray(element) && !element.length)) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!key) {
|
|
149
|
+
if (source instanceof HTMLElement) {
|
|
150
|
+
key =
|
|
151
|
+
source.getAttribute("render") ||
|
|
152
|
+
source.getAttribute("key") ||
|
|
153
|
+
data.type;
|
|
154
|
+
} else {
|
|
155
|
+
key = data.type;
|
|
156
|
+
}
|
|
157
|
+
if (!key || key === "key") {
|
|
158
|
+
key = "object";
|
|
159
|
+
} else if (key === "{}" || (!key && data.method)) {
|
|
160
|
+
key = data.method ? data.method.split(".")[0] : undefined;
|
|
161
|
+
}
|
|
162
|
+
if (!key) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let sourceData = sources.get(source);
|
|
168
|
+
if (!sourceData) {
|
|
169
|
+
sourceData = { element: source, data: { ...data } };
|
|
170
|
+
sources.set(source, sourceData);
|
|
171
|
+
} else if (sourceData.data) {
|
|
172
|
+
sourceData.data = { ...data };
|
|
173
|
+
} else {
|
|
174
|
+
// TODO: Most effiecientway to comapre too objects or array of objects
|
|
175
|
+
if (data === sourceData.data) return;
|
|
176
|
+
sourceData.data = { ...data };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (data.$filter) {
|
|
180
|
+
index = index || data.$filter.startingIndex || data.$filter.index;
|
|
181
|
+
update = update || data.$filter.update;
|
|
182
|
+
remove = remove || data.$filter.remove;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (
|
|
186
|
+
!Array.isArray(element) &&
|
|
187
|
+
!(element instanceof HTMLCollection) &&
|
|
188
|
+
!(element instanceof NodeList)
|
|
189
|
+
) {
|
|
190
|
+
element = [element];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
for (let i = 0; i < element.length; i++) {
|
|
194
|
+
let renderedNode = renderedNodes.get(element[i]);
|
|
195
|
+
if (renderedNode) {
|
|
196
|
+
if (
|
|
197
|
+
renderedNode.clones &&
|
|
198
|
+
renderedNode.source &&
|
|
199
|
+
renderedNode.source.element
|
|
200
|
+
) {
|
|
201
|
+
let limit =
|
|
202
|
+
renderedNode.source.element.getAttribute("render-limit");
|
|
203
|
+
if (limit && renderedNode.clones.size >= parseInt(limit))
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
} else {
|
|
207
|
+
renderedNode = {
|
|
208
|
+
element: element[i],
|
|
209
|
+
source: sourceData,
|
|
210
|
+
clones: new Map()
|
|
211
|
+
};
|
|
212
|
+
renderedNodes.set(element[i], renderedNode);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
let clones = renderedNode.clones; // || renderedNode.template.clones..
|
|
216
|
+
if (!clones && renderedNode.template) {
|
|
217
|
+
clones = renderedNode.template.clones;
|
|
218
|
+
console.log("renderedNode.template.clones", clones);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
key = element[i].getAttribute("render") || key;
|
|
222
|
+
let renderedSource = renderedNode.source;
|
|
223
|
+
if (!renderedSource) {
|
|
224
|
+
if (renderedNode.parent && renderedNode.parent.template) {
|
|
225
|
+
renderedSource = renderedNode.parent.template.source;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
let renderType;
|
|
229
|
+
if (renderedSource && renderedSource.element) {
|
|
230
|
+
renderType = renderedSource.element.getAttribute("render-type");
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
let clone;
|
|
234
|
+
if (remove) {
|
|
235
|
+
for (let j = 0; j < data[key].length; j++) {
|
|
236
|
+
let cloneKey;
|
|
237
|
+
if (key === "object") {
|
|
238
|
+
cloneKey = data[key][j]._id;
|
|
239
|
+
} else {
|
|
240
|
+
cloneKey = data[key][j].name;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
clone = clones.get(cloneKey);
|
|
244
|
+
if (!clone) return;
|
|
245
|
+
|
|
246
|
+
clones.delete(cloneKey);
|
|
247
|
+
renderedNodes.delete(clone);
|
|
248
|
+
clone.remove();
|
|
249
|
+
}
|
|
250
|
+
} else if (
|
|
251
|
+
(key && (Array.isArray(data[key]) || renderType)) ||
|
|
252
|
+
Array.isArray(data)
|
|
253
|
+
) {
|
|
254
|
+
if (update) {
|
|
255
|
+
for (let j = 0; j < data[key].length; j++) {
|
|
256
|
+
if (key === "object") {
|
|
257
|
+
clone = clones.get(data[key][j]._id);
|
|
258
|
+
} else {
|
|
259
|
+
clone = clones.get(data[key][j].name);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!currentIndex) currentIndex = data.$filter.currentIndex;
|
|
263
|
+
|
|
264
|
+
if (!clone) return;
|
|
265
|
+
|
|
266
|
+
await renderValues(clone, { object: data[key][j] });
|
|
267
|
+
if (currentIndex >= 0)
|
|
268
|
+
insertElement(renderedNode, clone, index, currentIndex);
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
// TODO: if $auto here every subsequent clone will have same value, not replacing here will apply unique value to each clone
|
|
272
|
+
if (key === "$auto")
|
|
273
|
+
key = key.replace(/\$auto/g, uuid.generate(6));
|
|
274
|
+
|
|
275
|
+
if (key) element[i].setAttribute("render", key);
|
|
276
|
+
|
|
277
|
+
await renderTemplate(element[i], data, key, index);
|
|
278
|
+
}
|
|
279
|
+
} else {
|
|
280
|
+
let renderAs = element[i].getAttribute("render-as") || key;
|
|
281
|
+
await renderValues(element[i], data, key, renderAs);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Dispatch input and change events after rendering is complete
|
|
285
|
+
if (source instanceof HTMLElement) {
|
|
286
|
+
source.dispatchEvent(new Event("input"));
|
|
287
|
+
source.dispatchEvent(new Event("change"));
|
|
288
|
+
}
|
|
271
289
|
}
|
|
272
290
|
|
|
273
291
|
async function renderTemplate(template, data, key, index, keyPath) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
if (key !== "data") index = i;
|
|
491
|
-
|
|
492
|
-
clone.renderData = object
|
|
493
|
-
clone.index = index
|
|
494
|
-
await renderValues(
|
|
495
|
-
clone.element,
|
|
496
|
-
object,
|
|
497
|
-
key,
|
|
498
|
-
renderAs,
|
|
499
|
-
null,
|
|
500
|
-
null,
|
|
501
|
-
index
|
|
502
|
-
);
|
|
503
|
-
insertElement(
|
|
504
|
-
templateData,
|
|
505
|
-
clone.element,
|
|
506
|
-
index,
|
|
507
|
-
"",
|
|
508
|
-
data,
|
|
509
|
-
renderReverse
|
|
510
|
-
);
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
}
|
|
292
|
+
if (!(template instanceof HTMLElement)) {
|
|
293
|
+
console.log("template not an element but should be")
|
|
294
|
+
}
|
|
295
|
+
let templateData = renderedNodes.get(template);
|
|
296
|
+
if (!templateData) {
|
|
297
|
+
templateData = {element: template, clones: new Map() };
|
|
298
|
+
renderedNodes.set(template, templateData);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (!templateData.parent && !templateData.source) {
|
|
302
|
+
let parentRender = template.parentElement.closest("[render]")
|
|
303
|
+
if (parentRender || template.source)
|
|
304
|
+
templateData.parent = renderedNodes.get(parentRender) || template.source
|
|
305
|
+
else
|
|
306
|
+
console.log("template parent missing is there no parent or is this an error? and source is", templateData.source)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if(!templateData.source && templateData.parent && templateData.parent.source){
|
|
310
|
+
templateData.source = templateData.parent.source
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (!templateData.keyPath) {
|
|
314
|
+
if (keyPath) {
|
|
315
|
+
templateData.keyPath = keyPath;
|
|
316
|
+
} else if (templateData.parent && templateData.parent.keyPath) {
|
|
317
|
+
templateData.keyPath = templateData.parent.keyPath;
|
|
318
|
+
} else if (key) {
|
|
319
|
+
templateData.keyPath = key;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
let renderData;
|
|
324
|
+
if (key) {
|
|
325
|
+
renderData = getRenderValue(templateData.element, data, key);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (!renderData) {
|
|
329
|
+
renderData = data;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
templateData.renderData = renderData;
|
|
333
|
+
let el = templateData.element;
|
|
334
|
+
if (el.nodeType !== 1) {
|
|
335
|
+
el = templateData.parent.element;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
let renderAs = templateData.renderAs
|
|
339
|
+
if (!templateData.renderAs) {
|
|
340
|
+
renderAs =
|
|
341
|
+
el.getAttribute("render-as") ||
|
|
342
|
+
el.getAttribute("render") ||
|
|
343
|
+
key;
|
|
344
|
+
templateData.renderAs = renderAs;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
let renderType;
|
|
348
|
+
if (templateData.source && templateData.source.element)
|
|
349
|
+
renderType = templateData.source.element.getAttribute("render-type");
|
|
350
|
+
|
|
351
|
+
let renderReverse;
|
|
352
|
+
if (templateData.source && templateData.source.element) {
|
|
353
|
+
renderReverse =
|
|
354
|
+
templateData.source.element.getAttribute("render-reverse");
|
|
355
|
+
if (renderReverse === null)
|
|
356
|
+
renderReverse = el.getAttribute("render-reverse");
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
let exclude = el.getAttribute("render-exclude") || "";
|
|
360
|
+
if (exclude) {
|
|
361
|
+
exclude = exclude.replace(/ /g, "").split(",");
|
|
362
|
+
}
|
|
363
|
+
let reference = el.getAttribute("render-reference");
|
|
364
|
+
|
|
365
|
+
let isInsert = data.$filter && (data.$filter.create || data.$filter.update);
|
|
366
|
+
if (renderType !== "object") {
|
|
367
|
+
if ((!isInsert && !index) || data.$filter.overwrite) {
|
|
368
|
+
if (!templateData.clones) {
|
|
369
|
+
return
|
|
370
|
+
if (templateData.template) {
|
|
371
|
+
templateData.clones = templateData.template.clones
|
|
372
|
+
} else if (templateData.parent && templateData.parent.template) {
|
|
373
|
+
templateData.clones = templateData.parent.template.clones
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
for (const [key, element] of templateData.clones) {
|
|
378
|
+
renderedNodes.delete(element);
|
|
379
|
+
element.remove();
|
|
380
|
+
templateData.clones.delete(key);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if ((key && !Array.isArray(renderData)) || renderType === "object") {
|
|
386
|
+
if (renderType && Array.isArray(renderData) && renderData.length === 1)
|
|
387
|
+
renderData = renderData[0];
|
|
388
|
+
|
|
389
|
+
const keys = Object.keys(renderData);
|
|
390
|
+
for (let i = 0; i < keys.length; i++) {
|
|
391
|
+
let clone = templateData.clones.get(keys[i]);
|
|
392
|
+
clone = renderedNodes.get(clone);
|
|
393
|
+
|
|
394
|
+
if (
|
|
395
|
+
exclude.includes(keys[i]) ||
|
|
396
|
+
(reference === "false" &&
|
|
397
|
+
["$storage", "$database", "$array"].includes(key))
|
|
398
|
+
) {
|
|
399
|
+
if (clone) {
|
|
400
|
+
renderedNodes.delete(clone.element);
|
|
401
|
+
clone.element.remove();
|
|
402
|
+
templateData.clones.delete(keys[i]);
|
|
403
|
+
}
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
let value = renderData[keys[i]];
|
|
408
|
+
let type = "string";
|
|
409
|
+
|
|
410
|
+
if (Array.isArray(value)) type = "array";
|
|
411
|
+
else if (typeof value == "object") type = "object";
|
|
412
|
+
|
|
413
|
+
let Data = { [renderAs]: { key: keys[i], value, type } };
|
|
414
|
+
|
|
415
|
+
if (!clone) {
|
|
416
|
+
clone = cloneTemplate(templateData);
|
|
417
|
+
} else {
|
|
418
|
+
if (clone.renderedValue === value) {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
clone.renderedValue = value;
|
|
423
|
+
|
|
424
|
+
let renderedKey = key.split(".");
|
|
425
|
+
renderedKey = renderedKey[renderedKey.length - 1];
|
|
426
|
+
|
|
427
|
+
clone.key = keys[i];
|
|
428
|
+
clone.keyPath = templateData.keyPath + "." + renderedKey;
|
|
429
|
+
clone.parentKey = renderedKey;
|
|
430
|
+
clone.renderKey = key;
|
|
431
|
+
clone.element.setAttribute("renderedKey", keys[i]);
|
|
432
|
+
await renderValues(clone.element, Data, keys[i], renderAs);
|
|
433
|
+
insertElement(templateData, clone.element, index);
|
|
434
|
+
}
|
|
435
|
+
} else {
|
|
436
|
+
if (!key && !Array.isArray(renderData)) {
|
|
437
|
+
key = "data";
|
|
438
|
+
renderData = getValueFromObject(renderData, key);
|
|
439
|
+
if (!renderAs) renderAs = key;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (!renderData) {
|
|
443
|
+
let clone = cloneTemplate(templateData);
|
|
444
|
+
clone.keyPath = templateData.keyPath;
|
|
445
|
+
await renderValues(clone.element, data, key, renderAs);
|
|
446
|
+
insertElement(templateData, clone.element, index);
|
|
447
|
+
} else {
|
|
448
|
+
if (!Array.isArray(renderData)) renderData = [renderData];
|
|
449
|
+
|
|
450
|
+
for (let i = 0; i < renderData.length; i++) {
|
|
451
|
+
let clone = cloneTemplate(templateData);
|
|
452
|
+
|
|
453
|
+
let test = clone.element.getAttribute("render-as");
|
|
454
|
+
if (test) renderAs = test;
|
|
455
|
+
|
|
456
|
+
clone.keyPath = templateData.keyPath || "" + `[${i}]`;
|
|
457
|
+
|
|
458
|
+
let object;
|
|
459
|
+
if (
|
|
460
|
+
typeof renderData[i] === "object" &&
|
|
461
|
+
renderData[i] !== null
|
|
462
|
+
) {
|
|
463
|
+
object = { ...renderData[i] };
|
|
464
|
+
} else {
|
|
465
|
+
object = renderData[i];
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
for (let j = 0; j < exclude.length; j++)
|
|
469
|
+
delete object[exclude[j]];
|
|
470
|
+
|
|
471
|
+
if (reference === "false") {
|
|
472
|
+
delete object.$storage;
|
|
473
|
+
delete object.$database;
|
|
474
|
+
delete object.$array;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (renderAs) {
|
|
478
|
+
object = { [renderAs]: object };
|
|
479
|
+
if (renderAs.includes("."))
|
|
480
|
+
object = dotNotationToObject(object);
|
|
481
|
+
} else object = object;
|
|
482
|
+
|
|
483
|
+
let index;
|
|
484
|
+
if (key !== "data") index = i;
|
|
485
|
+
|
|
486
|
+
clone.renderData = object
|
|
487
|
+
clone.index = index
|
|
488
|
+
await renderValues(
|
|
489
|
+
clone.element,
|
|
490
|
+
object,
|
|
491
|
+
key,
|
|
492
|
+
renderAs,
|
|
493
|
+
null,
|
|
494
|
+
null,
|
|
495
|
+
index
|
|
496
|
+
);
|
|
497
|
+
insertElement(
|
|
498
|
+
templateData,
|
|
499
|
+
clone.element,
|
|
500
|
+
index,
|
|
501
|
+
"",
|
|
502
|
+
data,
|
|
503
|
+
renderReverse
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
514
508
|
}
|
|
515
509
|
|
|
516
510
|
function cloneTemplate(template) {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
511
|
+
let clone = template.element.cloneNode(true);
|
|
512
|
+
let cloneTagName = clone.tagName;
|
|
513
|
+
|
|
514
|
+
if (clone.tagName == "TEMPLATE") {
|
|
515
|
+
clone = template.element.content.firstElementChild;
|
|
516
|
+
for (let attribute of template.element.attributes) {
|
|
517
|
+
clone.setAttribute(attribute.name, attribute.value || "");
|
|
518
|
+
}
|
|
519
|
+
} else {
|
|
520
|
+
clone.classList.remove("template");
|
|
521
|
+
clone.removeAttribute("template");
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
clone.setAttribute("render-clone", "");
|
|
525
|
+
|
|
526
|
+
let renderAs = clone.getAttribute("render-as");
|
|
527
|
+
if (renderAs === "$auto") {
|
|
528
|
+
renderAs = uuid.generate(6);
|
|
529
|
+
clone = clone.outerHTML.replace(/\$auto/g, renderAs);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (typeof clone === "string") {
|
|
533
|
+
// TODO: Some elements are only allowed a specific element, need to find these elements and confirm proper rendering.
|
|
534
|
+
let container;
|
|
535
|
+
if (cloneTagName === "TR") container = document.createElement("tbody");
|
|
536
|
+
else container = document.createElement("div");
|
|
537
|
+
|
|
538
|
+
container.innerHTML = clone;
|
|
539
|
+
clone = container.firstChild;
|
|
540
|
+
container.remove();
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
let renderedNode = { template, element: clone };
|
|
544
|
+
renderedNodes.set(clone, renderedNode);
|
|
545
|
+
return renderedNode;
|
|
552
546
|
}
|
|
553
547
|
|
|
554
548
|
function insertElement(
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
549
|
+
template,
|
|
550
|
+
element,
|
|
551
|
+
index,
|
|
552
|
+
currentIndex,
|
|
553
|
+
data,
|
|
554
|
+
renderReverse
|
|
561
555
|
) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
template.element.insertAdjacentElement("beforebegin", element);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
template.clones = new Map(clones);
|
|
620
|
-
} else {
|
|
621
|
-
template.clones.set(eid, element);
|
|
622
|
-
template.element.insertAdjacentElement("beforebegin", element);
|
|
623
|
-
}
|
|
556
|
+
let eid = element.getAttribute("eid");
|
|
557
|
+
if (!eid) {
|
|
558
|
+
eid = uuid.generate(6);
|
|
559
|
+
element.setAttribute("eid", eid);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
if (index !== null && index >= 0) {
|
|
563
|
+
if (!template.clones) template = template.template;
|
|
564
|
+
|
|
565
|
+
let item;
|
|
566
|
+
if (!currentIndex && currentIndex !== 0) {
|
|
567
|
+
if (template.clones.has(eid)) return;
|
|
568
|
+
item = [eid, element];
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
const clones = Array.from(template.clones);
|
|
572
|
+
|
|
573
|
+
if (currentIndex || currentIndex === 0) {
|
|
574
|
+
item = clones.splice(currentIndex, 1)[0];
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
if (data && data.$filter && data.$filter.startingIndex)
|
|
578
|
+
index += data.$filter.startingIndex;
|
|
579
|
+
clones.splice(index, 0, item); // Insert item into clones at the specified index
|
|
580
|
+
|
|
581
|
+
if (renderReverse !== null && renderReverse !== "false" ) {
|
|
582
|
+
// Chat-specific logic: reverse rendering but still inserting based on sorting
|
|
583
|
+
if (clones[index + 1] && clones[index + 1][1] !== element) {
|
|
584
|
+
clones[index + 1][1].insertAdjacentElement("afterend", element);
|
|
585
|
+
} else if (clones[index] && clones[index][1] !== element) {
|
|
586
|
+
clones[index][1].insertAdjacentElement("beforeend", element);
|
|
587
|
+
} else {
|
|
588
|
+
template.element.insertAdjacentElement("afterend", element);
|
|
589
|
+
}
|
|
590
|
+
} else {
|
|
591
|
+
// Non-chat logic: handle ascending or descending order as usual
|
|
592
|
+
if (clones[index + 1] && clones[index + 1][1] !== element) {
|
|
593
|
+
clones[index + 1][1].insertAdjacentElement(
|
|
594
|
+
"beforebegin",
|
|
595
|
+
element
|
|
596
|
+
);
|
|
597
|
+
} else if (clones[index] && clones[index][1] !== element) {
|
|
598
|
+
clones[index][1].insertAdjacentElement("afterend", element);
|
|
599
|
+
} else {
|
|
600
|
+
template.element.insertAdjacentElement("beforebegin", element);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
template.clones = new Map(clones);
|
|
605
|
+
} else {
|
|
606
|
+
template.clones.set(eid, element);
|
|
607
|
+
template.element.insertAdjacentElement("beforebegin", element);
|
|
608
|
+
}
|
|
624
609
|
}
|
|
625
610
|
|
|
626
611
|
async function renderValues(node, data, key, renderAs, keyPath, parent, index) {
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
}
|
|
835
|
-
// });
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
}
|
|
612
|
+
if (!data) return;
|
|
613
|
+
|
|
614
|
+
let renderedNode = renderedNodes.get(node);
|
|
615
|
+
if (!renderedNode) renderedNode = { key, renderAs };
|
|
616
|
+
|
|
617
|
+
if (!renderedNode.key) renderedNode.key = key;
|
|
618
|
+
else if (!key) key = renderedNode.key;
|
|
619
|
+
|
|
620
|
+
if (!renderedNode.renderAs) renderedNode.renderAs = renderAs;
|
|
621
|
+
else if (!renderAs) renderAs = renderedNode.renderAs;
|
|
622
|
+
|
|
623
|
+
if (keyPath) renderedNode.keyPath = keyPath;
|
|
624
|
+
else if (renderedNode.keyPath) keyPath = renderedNode.keyPath;
|
|
625
|
+
|
|
626
|
+
if (parent) renderedNode.parent = parent;
|
|
627
|
+
|
|
628
|
+
if (node.nodeType == 1) {
|
|
629
|
+
if (node.hasAttribute("render-clone")) {
|
|
630
|
+
parent = renderedNode;
|
|
631
|
+
|
|
632
|
+
for (let eid of ["_id", "name", "key"]) {
|
|
633
|
+
if (renderAs) eid = data[renderAs][eid];
|
|
634
|
+
else eid = data[eid];
|
|
635
|
+
|
|
636
|
+
if (!eid) continue;
|
|
637
|
+
|
|
638
|
+
let oldEid = renderedNode.eid;
|
|
639
|
+
let temp = renderedNode.template;
|
|
640
|
+
if (!temp) {
|
|
641
|
+
console.log("temp could not be found");
|
|
642
|
+
} else if (!temp.clones) {
|
|
643
|
+
if (temp.template) temp = temp.template;
|
|
644
|
+
else console.log(temp);
|
|
645
|
+
|
|
646
|
+
if (oldEid && oldEid !== eid) temp.clones.delete(oldEid);
|
|
647
|
+
|
|
648
|
+
temp.clones.set(eid, node);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
renderedNode.eid = eid;
|
|
652
|
+
|
|
653
|
+
node.setAttribute("eid", eid);
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
for (let attr of node.attributes) {
|
|
659
|
+
let name = attr.name;
|
|
660
|
+
let value = attr.value;
|
|
661
|
+
|
|
662
|
+
let renderedAttribute = renderedNodes.get(attr);
|
|
663
|
+
if (!renderedAttribute) {
|
|
664
|
+
renderedAttribute = {
|
|
665
|
+
placeholder: { name, value },
|
|
666
|
+
key,
|
|
667
|
+
renderAs,
|
|
668
|
+
parent: renderedNode
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
let namePlaceholder = renderedAttribute.placeholder.name || name;
|
|
673
|
+
let valuePlaceholder = renderedAttribute.placeholder.value || value;
|
|
674
|
+
|
|
675
|
+
name = await renderValue(
|
|
676
|
+
attr,
|
|
677
|
+
data,
|
|
678
|
+
namePlaceholder,
|
|
679
|
+
renderAs,
|
|
680
|
+
renderedAttribute,
|
|
681
|
+
index
|
|
682
|
+
);
|
|
683
|
+
value = await renderValue(
|
|
684
|
+
attr,
|
|
685
|
+
data,
|
|
686
|
+
valuePlaceholder,
|
|
687
|
+
renderAs,
|
|
688
|
+
renderedAttribute,
|
|
689
|
+
index
|
|
690
|
+
);
|
|
691
|
+
if (namePlaceholder.includes("{{") && name) {
|
|
692
|
+
const attributes = name.match(/([^\s]+="[^"]*"|[^\s]+)/g) || [];
|
|
693
|
+
attributes.forEach((attr) => {
|
|
694
|
+
let [attributeName, attributeValue] = attr.split("=");
|
|
695
|
+
attributeValue = attributeValue
|
|
696
|
+
? attributeValue.replace(/"/g, "")
|
|
697
|
+
: "";
|
|
698
|
+
node.setAttribute(attributeName, attributeValue);
|
|
699
|
+
});
|
|
700
|
+
} else if (name === undefined || name === null || name === "") {
|
|
701
|
+
renderedNodes.delete(attr);
|
|
702
|
+
node.removeAttribute(attr.name);
|
|
703
|
+
} else if (
|
|
704
|
+
name &&
|
|
705
|
+
(value || value === "") &&
|
|
706
|
+
(name !== attr.name || value !== attr.value)
|
|
707
|
+
)
|
|
708
|
+
node.setAttribute(name, value);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
if (CoCreate.state) {
|
|
712
|
+
if (node.hasAttribute("[state_id]"))
|
|
713
|
+
CoCreate.state.initElement(node);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
if (node.tagName === "SCRIPT" && node.src) {
|
|
717
|
+
if (
|
|
718
|
+
node.src.includes("CoCreate.js") ||
|
|
719
|
+
node.src.includes("CoCreate.min.js")
|
|
720
|
+
) {
|
|
721
|
+
node.remove();
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
if (node.tagName === "LINK" && node.href) {
|
|
727
|
+
if (
|
|
728
|
+
node.href.includes("CoCreate.css") ||
|
|
729
|
+
node.href.includes("CoCreate.min.css")
|
|
730
|
+
) {
|
|
731
|
+
node.remove();
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
if (node.hasAttribute("render") && !node.hasAttribute("render-clone")) {
|
|
736
|
+
let renderKey = node.getAttribute("render") || key
|
|
737
|
+
renderTemplate(node, data, renderKey);
|
|
738
|
+
} else if (node.childNodes.length > 0) {
|
|
739
|
+
for (let childNode of node.childNodes) {
|
|
740
|
+
await renderValues(
|
|
741
|
+
childNode,
|
|
742
|
+
data,
|
|
743
|
+
key,
|
|
744
|
+
renderAs,
|
|
745
|
+
keyPath,
|
|
746
|
+
parent,
|
|
747
|
+
index
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
} else if (node.nodeType == 3) {
|
|
752
|
+
let valueType = node.parentElement.getAttribute("value-type");
|
|
753
|
+
|
|
754
|
+
let textContent, text;
|
|
755
|
+
|
|
756
|
+
if (!renderedNode.placeholder && node.textContent.match(/{{(.*?)}}/))
|
|
757
|
+
renderedNode.placeholder = node.textContent;
|
|
758
|
+
|
|
759
|
+
if (!renderedNode.placeholder) return;
|
|
760
|
+
textContent = renderedNode.placeholder || node.textContent;
|
|
761
|
+
|
|
762
|
+
text = await renderValue(
|
|
763
|
+
node,
|
|
764
|
+
data,
|
|
765
|
+
textContent,
|
|
766
|
+
renderAs,
|
|
767
|
+
renderedNode,
|
|
768
|
+
index
|
|
769
|
+
);
|
|
770
|
+
|
|
771
|
+
if (text || text == "") {
|
|
772
|
+
if (text != renderedNode.text) {
|
|
773
|
+
renderedNode.text = text;
|
|
774
|
+
|
|
775
|
+
if (
|
|
776
|
+
valueType == "text" ||
|
|
777
|
+
valueType == "string" ||
|
|
778
|
+
valueType != "html"
|
|
779
|
+
) {
|
|
780
|
+
node.textContent = text;
|
|
781
|
+
} else {
|
|
782
|
+
const newNode = document.createElement("div");
|
|
783
|
+
newNode.innerHTML = text;
|
|
784
|
+
let parentElement = node.parentElement;
|
|
785
|
+
|
|
786
|
+
let renderedParent = renderedNodes.get(parentElement);
|
|
787
|
+
if (!renderedParent) {
|
|
788
|
+
renderedParent = {
|
|
789
|
+
placeholder: textContent,
|
|
790
|
+
key,
|
|
791
|
+
renderAs
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
renderedParent.text = text;
|
|
795
|
+
for (let newChild of newNode.childNodes) {
|
|
796
|
+
renderedNode.element = newChild;
|
|
797
|
+
renderedNodes.set(newChild, renderedNode);
|
|
798
|
+
}
|
|
799
|
+
renderedNodes.delete(node);
|
|
800
|
+
node.replaceWith(...newNode.childNodes);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
if (node.childNodes.length > 0) {
|
|
804
|
+
for (let childNode of node.childNodes) {
|
|
805
|
+
await renderValues(
|
|
806
|
+
childNode,
|
|
807
|
+
data,
|
|
808
|
+
key,
|
|
809
|
+
renderAs,
|
|
810
|
+
keyPath,
|
|
811
|
+
parent,
|
|
812
|
+
index
|
|
813
|
+
);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
840
819
|
}
|
|
841
820
|
|
|
842
821
|
async function renderValue(
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
822
|
+
node,
|
|
823
|
+
data,
|
|
824
|
+
placeholder,
|
|
825
|
+
renderAs,
|
|
826
|
+
renderedNode,
|
|
827
|
+
index
|
|
849
828
|
) {
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
match[0],
|
|
970
|
-
`<|${placeholderContent}|>`
|
|
971
|
-
);
|
|
972
|
-
omitted[`<|${placeholderContent}|>`] = match[0];
|
|
973
|
-
}
|
|
974
|
-
} else {
|
|
975
|
-
// If no value is found and no renderAs, exit the loop
|
|
976
|
-
match = null;
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
} while (match);
|
|
980
|
-
|
|
981
|
-
// Restore any omitted placeholders
|
|
982
|
-
for (let key of Object.keys(omitted)) {
|
|
983
|
-
output = output.replaceAll(key, omitted[key]);
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
return output;
|
|
829
|
+
let output = placeholder;
|
|
830
|
+
|
|
831
|
+
// Determine the actual HTMLElement for processOperatorsAsync
|
|
832
|
+
// If the node is not an Element (nodeType 1), get its owner or parent element.
|
|
833
|
+
// This safely covers Attributes (ownerElement), Text, Comments, etc. (parentElement)
|
|
834
|
+
let contextElement = node;
|
|
835
|
+
if (node && node.nodeType !== 1) {
|
|
836
|
+
contextElement = node.ownerElement || node.parentElement;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// DEPRECATED: {[ ]} and {( )}
|
|
840
|
+
// Matches ONLY the innermost {{ }} brackets.
|
|
841
|
+
let regex = /\{\{((?:(?!\{\{|\}\})[\s\S])+?)\}\}/;
|
|
842
|
+
let omitted = {};
|
|
843
|
+
|
|
844
|
+
let match;
|
|
845
|
+
do {
|
|
846
|
+
match = output.match(regex);
|
|
847
|
+
if (match) {
|
|
848
|
+
let value;
|
|
849
|
+
let placeholderContent = match[1].trim();
|
|
850
|
+
|
|
851
|
+
try {
|
|
852
|
+
if (placeholderContent === "index" && index >= 0) {
|
|
853
|
+
value = index;
|
|
854
|
+
} else {
|
|
855
|
+
// --- UNIFIED PARSING PROCESS ---
|
|
856
|
+
let preProcessed = placeholderContent;
|
|
857
|
+
|
|
858
|
+
// 1. PRE-PROCESSOR FOR QUOTED OPERATORS
|
|
859
|
+
let quoteRegex = /(['"])(.*?)\1/g;
|
|
860
|
+
let quoteMatch;
|
|
861
|
+
let replacements = [];
|
|
862
|
+
while ((quoteMatch = quoteRegex.exec(preProcessed)) !== null) {
|
|
863
|
+
let quoteType = quoteMatch[1];
|
|
864
|
+
let content = quoteMatch[2];
|
|
865
|
+
if (content.trim().startsWith('$')) {
|
|
866
|
+
let resolved = await processOperatorsAsync(contextElement, content);
|
|
867
|
+
if (resolved === null || resolved === undefined) resolved = "";
|
|
868
|
+
replacements.push({
|
|
869
|
+
original: quoteMatch[0],
|
|
870
|
+
replacement: `${quoteType}${resolved}${quoteType}`
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
for (let r of replacements) {
|
|
876
|
+
preProcessed = preProcessed.replace(r.original, r.replacement);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// 2. PRE-PROCESSOR: Resolve unquoted DOM selectors, custom operators, and CRUD JSON
|
|
880
|
+
preProcessed = await processOperatorsAsync(
|
|
881
|
+
contextElement,
|
|
882
|
+
preProcessed
|
|
883
|
+
);
|
|
884
|
+
|
|
885
|
+
// 3. DATA LOOKUP: Resolve simple keys from the provided data object
|
|
886
|
+
// Keep `node` here because getRenderValue needs to look up the attribute cache!
|
|
887
|
+
value = getRenderValue(
|
|
888
|
+
node,
|
|
889
|
+
data,
|
|
890
|
+
preProcessed,
|
|
891
|
+
renderAs
|
|
892
|
+
);
|
|
893
|
+
|
|
894
|
+
// 4. EXPRESSION EVALUATOR: Handle Math and Ternary logic
|
|
895
|
+
if (value === undefined || value === null) {
|
|
896
|
+
const dataProxy = new Proxy(data || {}, {
|
|
897
|
+
get(target, prop) {
|
|
898
|
+
if (typeof prop !== "string") return target[prop];
|
|
899
|
+
if (prop in target) return target[prop];
|
|
900
|
+
return getRenderValue(node, data, prop, renderAs);
|
|
901
|
+
},
|
|
902
|
+
has(target, prop) {
|
|
903
|
+
if (typeof prop !== "string") return prop in target;
|
|
904
|
+
return true;
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
const parsedValue = safeParse(preProcessed, dataProxy);
|
|
909
|
+
|
|
910
|
+
if (parsedValue !== null) {
|
|
911
|
+
value = parsedValue;
|
|
912
|
+
} else if (preProcessed !== placeholderContent) {
|
|
913
|
+
value = preProcessed;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
} catch (error) {
|
|
918
|
+
console.error(error);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
// Replace the placeholder with the resolved value
|
|
922
|
+
if (value !== undefined && value !== null) {
|
|
923
|
+
if (typeof value === "object") {
|
|
924
|
+
value = JSON.stringify(value, null, 2);
|
|
925
|
+
}
|
|
926
|
+
output = output.replaceAll(match[0], value);
|
|
927
|
+
} else if (renderAs) {
|
|
928
|
+
if (match[0].startsWith(`{{${renderAs}.`)) {
|
|
929
|
+
output = output.replaceAll(match[0], "");
|
|
930
|
+
} else if (placeholderContent) {
|
|
931
|
+
output = output.replaceAll(
|
|
932
|
+
match[0],
|
|
933
|
+
`<|${placeholderContent}|>`
|
|
934
|
+
);
|
|
935
|
+
omitted[`<|${placeholderContent}|>`] = match[0];
|
|
936
|
+
}
|
|
937
|
+
} else {
|
|
938
|
+
match = null;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
} while (match);
|
|
942
|
+
|
|
943
|
+
for (let key of Object.keys(omitted)) {
|
|
944
|
+
output = output.replaceAll(key, omitted[key]);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
return output;
|
|
987
948
|
}
|
|
988
949
|
|
|
989
950
|
function getRenderValue(node, data, key, renderAs) {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
return value;
|
|
951
|
+
let operator;
|
|
952
|
+
if (key.startsWith("$")) {
|
|
953
|
+
let keys = key.split(".");
|
|
954
|
+
operator = keys.shift();
|
|
955
|
+
if (keys.length > 0) {
|
|
956
|
+
key = keys.join(".");
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
let value = getValueFromObject(data, key);
|
|
961
|
+
|
|
962
|
+
if (!value && value !== "" && node) {
|
|
963
|
+
let parentTemplate = node;
|
|
964
|
+
do {
|
|
965
|
+
let parentNode = renderedNodes.get(parentTemplate);
|
|
966
|
+
if (parentNode) {
|
|
967
|
+
if (!value && (parentNode.parent || parentNode.template)) {
|
|
968
|
+
let Data,
|
|
969
|
+
eid,
|
|
970
|
+
parent = parentNode.parent || parentNode.template;
|
|
971
|
+
do {
|
|
972
|
+
if (key.includes("keyPath")) {
|
|
973
|
+
value = parentNode.keyPath || parent.keyPath;
|
|
974
|
+
} else if (key.includes("parentKey")) {
|
|
975
|
+
value =
|
|
976
|
+
parentNode.parentKey ||
|
|
977
|
+
parent.parentKey ||
|
|
978
|
+
parent.parent.parentKey;
|
|
979
|
+
} else if (key.includes("renderAs")) {
|
|
980
|
+
value = renderAs;
|
|
981
|
+
} else if (key === "object" || key === "_id")
|
|
982
|
+
value = ObjectId().toString();
|
|
983
|
+
else if (key === "uuid") {
|
|
984
|
+
value = uuid.generate(6);
|
|
985
|
+
} else if (parent.source) {
|
|
986
|
+
Data = parent.source.data;
|
|
987
|
+
} else if (parent.parent) {
|
|
988
|
+
parent = parent.parent;
|
|
989
|
+
} else if (parent.template) {
|
|
990
|
+
parent = parent.template;
|
|
991
|
+
} else {
|
|
992
|
+
parent = undefined;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
if (!Data && parent && parent.eid) eid = parent.eid;
|
|
996
|
+
} while (!value && parent && !Data);
|
|
997
|
+
|
|
998
|
+
if (!value && Data) {
|
|
999
|
+
value = getValueFromObject(Data, key);
|
|
1000
|
+
}
|
|
1001
|
+
if (!value && key.includes(".")) {
|
|
1002
|
+
let renderedData = getValueFromObject(
|
|
1003
|
+
Data,
|
|
1004
|
+
key.split(".")[0]
|
|
1005
|
+
);
|
|
1006
|
+
if (renderedData) {
|
|
1007
|
+
let index;
|
|
1008
|
+
if (
|
|
1009
|
+
!parent.clones.size ||
|
|
1010
|
+
parent.clones.size === 1
|
|
1011
|
+
) {
|
|
1012
|
+
index = 0;
|
|
1013
|
+
} else if (eid) {
|
|
1014
|
+
index = Array.from(
|
|
1015
|
+
parent.clones.keys()
|
|
1016
|
+
).indexOf(eid);
|
|
1017
|
+
} else console.log("eid not found");
|
|
1018
|
+
|
|
1019
|
+
if (index >= 0) {
|
|
1020
|
+
Data = {
|
|
1021
|
+
[key.split(".")[0]]: renderedData[index]
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
value = getValueFromObject(Data, key);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
if (!value && parentTemplate.parentElement) {
|
|
1031
|
+
parentTemplate =
|
|
1032
|
+
parentTemplate.parentElement.closest("[render]");
|
|
1033
|
+
} else {
|
|
1034
|
+
parentTemplate = undefined;
|
|
1035
|
+
}
|
|
1036
|
+
} while (!value && parentTemplate);
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
if (operator) {
|
|
1040
|
+
if (value) {
|
|
1041
|
+
console.log("return processed render value using operator", value);
|
|
1042
|
+
} else {
|
|
1043
|
+
console.log("return render operator", operator);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
return value;
|
|
1090
1048
|
}
|
|
1091
1049
|
|
|
1092
1050
|
async function renderKey(action) {
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1051
|
+
// TODO: custom render-keys
|
|
1052
|
+
let element = action.element;
|
|
1053
|
+
let form = action.form || document;
|
|
1054
|
+
let params = action.params;
|
|
1055
|
+
|
|
1056
|
+
if (!params) {
|
|
1057
|
+
params = "render-key";
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
let data = {};
|
|
1061
|
+
let selector = `[${params}]`;
|
|
1062
|
+
let elements = form.querySelectorAll(selector);
|
|
1063
|
+
for (let el of elements) {
|
|
1064
|
+
let attribute = el.getAttribute(params);
|
|
1065
|
+
if (attribute) data[attribute] = await el.getValue();
|
|
1066
|
+
}
|
|
1067
|
+
data = dotNotationToObject(data);
|
|
1068
|
+
let renderData = { data: { [params]: data } };
|
|
1069
|
+
|
|
1070
|
+
let renderSelector = element.getAttribute("render-query");
|
|
1071
|
+
if (!renderSelector) return;
|
|
1072
|
+
|
|
1073
|
+
renderData.selector = renderSelector;
|
|
1074
|
+
render(renderData);
|
|
1075
|
+
|
|
1076
|
+
action.element.dispatchEvent(
|
|
1077
|
+
new CustomEvent("renderKey", {
|
|
1078
|
+
detail: { data }
|
|
1079
|
+
})
|
|
1080
|
+
);
|
|
1123
1081
|
}
|
|
1124
1082
|
|
|
1125
1083
|
Actions.init({
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1084
|
+
name: "renderKey",
|
|
1085
|
+
callback: (action) => {
|
|
1086
|
+
renderKey(action);
|
|
1087
|
+
}
|
|
1130
1088
|
});
|
|
1131
1089
|
|
|
1132
1090
|
Actions.init({
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
}
|
|
1091
|
+
name: "render",
|
|
1092
|
+
callback: async (action) => {
|
|
1093
|
+
if (!action.form) return;
|
|
1094
|
+
|
|
1095
|
+
let elements;
|
|
1096
|
+
if (action.params)
|
|
1097
|
+
elements = queryElements({
|
|
1098
|
+
element: action.element,
|
|
1099
|
+
selector: action.params,
|
|
1100
|
+
type: "selector"
|
|
1101
|
+
});
|
|
1102
|
+
else
|
|
1103
|
+
elements = queryElements({
|
|
1104
|
+
element: action.element,
|
|
1105
|
+
prefix: "render"
|
|
1106
|
+
});
|
|
1107
|
+
|
|
1108
|
+
let data = await action.form.getData();
|
|
1109
|
+
let array = action.form.getAttribute("array");
|
|
1110
|
+
if (array) data = data.find((obj) => obj.array === array);
|
|
1111
|
+
for (let i = 0; i < elements.length; i++)
|
|
1112
|
+
await render({ source: elements[i], data });
|
|
1113
|
+
|
|
1114
|
+
action.element.dispatchEvent(
|
|
1115
|
+
new CustomEvent("render", {
|
|
1116
|
+
detail: {}
|
|
1117
|
+
})
|
|
1118
|
+
);
|
|
1119
|
+
}
|
|
1163
1120
|
});
|
|
1164
1121
|
|
|
1165
1122
|
Observer.init({
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1123
|
+
name: "render",
|
|
1124
|
+
types: ["addedNodes"],
|
|
1125
|
+
selector: elementSelector,
|
|
1126
|
+
callback: function (mutation) {
|
|
1127
|
+
init(mutation.target);
|
|
1128
|
+
}
|
|
1172
1129
|
});
|
|
1173
1130
|
|
|
1174
1131
|
Observer.init({
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1132
|
+
name: "fileRender",
|
|
1133
|
+
types: ["attributes"],
|
|
1134
|
+
attributeFilter: ["render-query"],
|
|
1135
|
+
callback: async function (mutation) {
|
|
1136
|
+
render({
|
|
1137
|
+
element: mutation.target,
|
|
1138
|
+
data: await mutation.target.getValue()
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1184
1141
|
});
|
|
1185
1142
|
|
|
1186
1143
|
Observer.init({
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1144
|
+
name: "render",
|
|
1145
|
+
types: ["addedNodes"],
|
|
1146
|
+
selector: "[render-element]",
|
|
1147
|
+
callback: function (mutation) {
|
|
1148
|
+
if (mutation.target.hasAttribute("render-clone")) return;
|
|
1149
|
+
let parentElement = mutation.target.parentElement.closest("[render]");
|
|
1150
|
+
if (!parentElement) return;
|
|
1151
|
+
|
|
1152
|
+
let renderedNode = renderedNodes.get(parentElement);
|
|
1153
|
+
let data;
|
|
1154
|
+
if (renderedNode) {
|
|
1155
|
+
if (renderedNode.renderData) {
|
|
1156
|
+
data = renderedNode.renderData;
|
|
1157
|
+
}
|
|
1158
|
+
} else {
|
|
1159
|
+
let sourceElement = mutation.target.parentElement.closest("[render-query]")
|
|
1160
|
+
let sourceData = sources.get(sourceElement);
|
|
1161
|
+
if (sourceData) {
|
|
1162
|
+
data = sourceData.data;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
if (data) {
|
|
1166
|
+
render({ element: mutation.target, data });
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1212
1169
|
});
|
|
1213
1170
|
|
|
1214
|
-
// Observer.init({
|
|
1215
|
-
// name: 'render',
|
|
1216
|
-
// types: ['addedNodes'],
|
|
1217
|
-
// selector: '[render-clone]',
|
|
1218
|
-
// callback: function (mutation) {
|
|
1219
|
-
// let renderedNode = renderedNodes.get(mutation.target)
|
|
1220
|
-
// if (!renderedNode) return
|
|
1221
|
-
|
|
1222
|
-
// render({ source, element, data, key, index, currentIndex, update, remove })
|
|
1223
|
-
|
|
1224
|
-
// let nextElement = mutation.target.nextElementSibling
|
|
1225
|
-
// if (!nextElement) return
|
|
1226
|
-
|
|
1227
|
-
// let nextRenderedNode = renderedNodes.get(nextElement)
|
|
1228
|
-
// if (!nextRenderedNode) return
|
|
1229
|
-
|
|
1230
|
-
// let clones
|
|
1231
|
-
// if (nextRenderedNode.template)
|
|
1232
|
-
// clones = nextRenderedNode.template.clones
|
|
1233
|
-
// else if (nextRenderedNode.clones)
|
|
1234
|
-
// clones = nextRenderedNode.clones
|
|
1235
|
-
|
|
1236
|
-
// const cloneValueArray = Array.from(clones.values())
|
|
1237
|
-
// let index = cloneValueArray.indexOf(nextElement);
|
|
1238
|
-
|
|
1239
|
-
// const cloneArray = Array.from(clones)
|
|
1240
|
-
|
|
1241
|
-
// cloneArray.splice(index, 0, [renderedNode.eid, mutation.target]);
|
|
1242
|
-
// clones = new Map(cloneArray);
|
|
1243
|
-
|
|
1244
|
-
// }
|
|
1245
|
-
// })
|
|
1246
|
-
|
|
1247
1171
|
Observer.init({
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1172
|
+
name: "renderNodesRemoved",
|
|
1173
|
+
types: ["removedNodes"],
|
|
1174
|
+
selector: "[render-clone]",
|
|
1175
|
+
callback: function (mutation) {
|
|
1176
|
+
if (mutation.target.parentElement) return;
|
|
1177
|
+
let renderedNode = renderedNodes.get(mutation.target);
|
|
1178
|
+
if (!renderedNode) return;
|
|
1179
|
+
renderedNode.template.clones.delete(renderedNode.eid);
|
|
1180
|
+
renderedNodes.delete(mutation.target);
|
|
1181
|
+
}
|
|
1258
1182
|
});
|
|
1259
1183
|
|
|
1260
1184
|
init();
|
|
1261
1185
|
|
|
1262
|
-
export { render, renderValue, sources, renderedNodes };
|
|
1186
|
+
export { render, renderValue, sources, renderedNodes };
|