@cocreate/render 1.45.6 → 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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/index.js +1077 -1169
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,44 +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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
+
}
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
/**
|
|
@@ -101,1178 +103,1084 @@ function init(element) {
|
|
|
101
103
|
* @param {boolean} [options.remove] - Flag to indicate if the rendering should remove elements instead of updating or appending.
|
|
102
104
|
*/
|
|
103
105
|
async function render({
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
106
|
+
source,
|
|
107
|
+
element,
|
|
108
|
+
selector,
|
|
109
|
+
data,
|
|
110
|
+
key,
|
|
111
|
+
index,
|
|
112
|
+
currentIndex,
|
|
113
|
+
update,
|
|
114
|
+
remove
|
|
113
115
|
}) {
|
|
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
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
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
|
+
}
|
|
287
289
|
}
|
|
288
290
|
|
|
289
291
|
async function renderTemplate(template, data, key, index, keyPath) {
|
|
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
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
if (key !== "data") index = i;
|
|
507
|
-
|
|
508
|
-
clone.renderData = object
|
|
509
|
-
clone.index = index
|
|
510
|
-
await renderValues(
|
|
511
|
-
clone.element,
|
|
512
|
-
object,
|
|
513
|
-
key,
|
|
514
|
-
renderAs,
|
|
515
|
-
null,
|
|
516
|
-
null,
|
|
517
|
-
index
|
|
518
|
-
);
|
|
519
|
-
insertElement(
|
|
520
|
-
templateData,
|
|
521
|
-
clone.element,
|
|
522
|
-
index,
|
|
523
|
-
"",
|
|
524
|
-
data,
|
|
525
|
-
renderReverse
|
|
526
|
-
);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
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
|
+
}
|
|
530
508
|
}
|
|
531
509
|
|
|
532
510
|
function cloneTemplate(template) {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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;
|
|
568
546
|
}
|
|
569
547
|
|
|
570
548
|
function insertElement(
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
549
|
+
template,
|
|
550
|
+
element,
|
|
551
|
+
index,
|
|
552
|
+
currentIndex,
|
|
553
|
+
data,
|
|
554
|
+
renderReverse
|
|
577
555
|
) {
|
|
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
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
template.element.insertAdjacentElement("beforebegin", element);
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
template.clones = new Map(clones);
|
|
636
|
-
} else {
|
|
637
|
-
template.clones.set(eid, element);
|
|
638
|
-
template.element.insertAdjacentElement("beforebegin", element);
|
|
639
|
-
}
|
|
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
|
+
}
|
|
640
609
|
}
|
|
641
610
|
|
|
642
611
|
async function renderValues(node, data, key, renderAs, keyPath, parent, index) {
|
|
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
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
}
|
|
851
|
-
// });
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
}
|
|
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
|
+
}
|
|
856
819
|
}
|
|
857
820
|
|
|
858
821
|
async function renderValue(
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
822
|
+
node,
|
|
823
|
+
data,
|
|
824
|
+
placeholder,
|
|
825
|
+
renderAs,
|
|
826
|
+
renderedNode,
|
|
827
|
+
index
|
|
865
828
|
) {
|
|
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
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
match[0],
|
|
986
|
-
`<|${placeholderContent}|>`
|
|
987
|
-
);
|
|
988
|
-
omitted[`<|${placeholderContent}|>`] = match[0];
|
|
989
|
-
}
|
|
990
|
-
} else {
|
|
991
|
-
// If no value is found and no renderAs, exit the loop
|
|
992
|
-
match = null;
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
} while (match);
|
|
996
|
-
|
|
997
|
-
// Restore any omitted placeholders
|
|
998
|
-
for (let key of Object.keys(omitted)) {
|
|
999
|
-
output = output.replaceAll(key, omitted[key]);
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
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;
|
|
1003
948
|
}
|
|
1004
949
|
|
|
1005
950
|
function getRenderValue(node, data, key, renderAs) {
|
|
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
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
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;
|
|
1106
1048
|
}
|
|
1107
1049
|
|
|
1108
1050
|
async function renderKey(action) {
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
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
|
+
);
|
|
1139
1081
|
}
|
|
1140
1082
|
|
|
1141
1083
|
Actions.init({
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1084
|
+
name: "renderKey",
|
|
1085
|
+
callback: (action) => {
|
|
1086
|
+
renderKey(action);
|
|
1087
|
+
}
|
|
1146
1088
|
});
|
|
1147
1089
|
|
|
1148
1090
|
Actions.init({
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
}
|
|
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
|
+
}
|
|
1179
1120
|
});
|
|
1180
1121
|
|
|
1181
1122
|
Observer.init({
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1123
|
+
name: "render",
|
|
1124
|
+
types: ["addedNodes"],
|
|
1125
|
+
selector: elementSelector,
|
|
1126
|
+
callback: function (mutation) {
|
|
1127
|
+
init(mutation.target);
|
|
1128
|
+
}
|
|
1188
1129
|
});
|
|
1189
1130
|
|
|
1190
1131
|
Observer.init({
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
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
|
+
}
|
|
1200
1141
|
});
|
|
1201
1142
|
|
|
1202
1143
|
Observer.init({
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
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
|
+
}
|
|
1228
1169
|
});
|
|
1229
1170
|
|
|
1230
|
-
// Observer.init({
|
|
1231
|
-
// name: 'render',
|
|
1232
|
-
// types: ['addedNodes'],
|
|
1233
|
-
// selector: '[render-clone]',
|
|
1234
|
-
// callback: function (mutation) {
|
|
1235
|
-
// let renderedNode = renderedNodes.get(mutation.target)
|
|
1236
|
-
// if (!renderedNode) return
|
|
1237
|
-
|
|
1238
|
-
// render({ source, element, data, key, index, currentIndex, update, remove })
|
|
1239
|
-
|
|
1240
|
-
// let nextElement = mutation.target.nextElementSibling
|
|
1241
|
-
// if (!nextElement) return
|
|
1242
|
-
|
|
1243
|
-
// let nextRenderedNode = renderedNodes.get(nextElement)
|
|
1244
|
-
// if (!nextRenderedNode) return
|
|
1245
|
-
|
|
1246
|
-
// let clones
|
|
1247
|
-
// if (nextRenderedNode.template)
|
|
1248
|
-
// clones = nextRenderedNode.template.clones
|
|
1249
|
-
// else if (nextRenderedNode.clones)
|
|
1250
|
-
// clones = nextRenderedNode.clones
|
|
1251
|
-
|
|
1252
|
-
// const cloneValueArray = Array.from(clones.values())
|
|
1253
|
-
// let index = cloneValueArray.indexOf(nextElement);
|
|
1254
|
-
|
|
1255
|
-
// const cloneArray = Array.from(clones)
|
|
1256
|
-
|
|
1257
|
-
// cloneArray.splice(index, 0, [renderedNode.eid, mutation.target]);
|
|
1258
|
-
// clones = new Map(cloneArray);
|
|
1259
|
-
|
|
1260
|
-
// }
|
|
1261
|
-
// })
|
|
1262
|
-
|
|
1263
1171
|
Observer.init({
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
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
|
+
}
|
|
1274
1182
|
});
|
|
1275
1183
|
|
|
1276
1184
|
init();
|
|
1277
1185
|
|
|
1278
|
-
export { render, renderValue, sources, renderedNodes };
|
|
1186
|
+
export { render, renderValue, sources, renderedNodes };
|