@cocreate/render 1.24.14 → 1.24.16

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/src/index.js CHANGED
@@ -1,531 +1,531 @@
1
- /*globals CustomEvent*/
2
- import action from '@cocreate/actions';
3
- import observer from '@cocreate/observer';
4
- import uuid from '@cocreate/uuid';
5
- import { queryDocumentSelector, getValueFromObject, dotNotationToObject } from '@cocreate/utils';
6
- import '@cocreate/element-prototype';
7
- import './index.css';
8
- // import api from '@cocreate/api';
9
-
10
- const CoCreateRender = {
11
-
12
- __getValue: function(data, attrValue, el) {
13
- let result = /{{\s*([\w\W]+)\s*}}/g.exec(attrValue);
14
- if (result) {
15
- let value = getValueFromObject(data, result[1].trim());
16
- if (!value && value !== '') {
17
- let parentTemplate
18
- if (el && el.nodeType == 1) {
19
- if (el.hasAttribute('templateid') && el.parentElement)
20
- parentTemplate = el.parentElement.closest('[templateid]')
21
- else
22
- parentTemplate = el.closest('[templateid]')
23
- }
24
-
25
- if (parentTemplate) {
26
- do {
27
- if (parentTemplate.renderedData)
28
- value = getValueFromObject(parentTemplate.renderedData, result[1].trim());
29
- if (!value && parentTemplate.parentElement)
30
- parentTemplate = parentTemplate.parentElement.closest('[templateid]')
31
- else
32
- parentTemplate = ""
33
- } while (!value && parentTemplate)
34
- }
35
- }
36
- return value;
37
- }
38
- return false;
39
- },
40
-
41
- __createObject: function (data, path) {
42
- try {
43
- if (!path) return data;
44
-
45
- let keys = path.split('.');
46
- let newObject = data;
47
-
48
- for (var i = keys.length - 1; i >= 0; i--) {
49
- newObject = {[keys[i]]: newObject};
50
- }
51
- return newObject;
52
-
53
- } catch (error) {
54
- console.log("Error in getValueFromObject", error);
55
- return false;
56
- }
57
- },
58
-
59
- __replaceValue: function(data, inputValue, renderKey, el) {
60
- let outputValue = inputValue;
61
- let placeholders = inputValue.match(/{{([A-Za-z0-9_.,\[\]\- ]*)}}/g);
62
- if (placeholders) {
63
- for (let placeholder of placeholders) {
64
- let value = this.__getValue(data, placeholder, el);
65
-
66
- if (value || value === "") {
67
- if (typeof(value) == "object")
68
- value = this.generateString(value)
69
-
70
- outputValue = outputValue.replace(placeholder, value);
71
- } else if (renderKey && placeholder.includes(`{{${renderKey}.`)) {
72
- outputValue = '';
73
- }
74
- }
75
- }
76
- return outputValue;
77
- },
78
-
79
- generateString: function(value, str = ''){
80
- // let str = '';
81
- // do {
82
- let flag = true;
83
- if (str)
84
- flag = false;
85
- for (const key of Object.keys(value)) {
86
- let val = value[key]
87
- if (typeof(val) == "object") {
88
- str += `${key}: \n`;
89
- this.generateString(val, str)
90
- }
91
- else
92
- str += `${key}: ${val}\n`;
93
- }
94
- // } while()
95
- if (flag)
96
- return str
97
- },
98
-
99
- render: function(template, data) {
100
- const self = this;
101
- let type = '';
102
- let arrayData = data;
103
-
104
- let exclude = template.getAttribute('render-exclude') || ''
105
- if (exclude) {
106
- exclude = exclude.replace(/ /g, '').split(",")
107
- if (!Array.isArray(exclude))
108
- exclude = [exclude]
109
- }
110
-
111
- const isRenderObject = template.hasAttribute('render-object');
112
- if (isRenderObject) {
113
- const renderObject = template.getAttribute('render-object');
114
- type = renderObject || ''
115
- }
116
-
117
- const isRenderArray = template.hasAttribute('render-array');
118
- if (isRenderArray){
119
- var renderArray = template.getAttribute('render-array');
120
- if (renderArray)
121
- arrayData = data[renderArray];
122
- type = renderArray || '';
123
- }
124
-
125
- let renderKey = template.getAttribute('render-key') || type;
126
-
127
- if (!template.renderedKeys)
128
- template.renderedKeys = new Map()
129
-
130
- if (isRenderObject && type) {
131
- let Data = getValueFromObject(arrayData, type);
132
- let array = self.renderObject(Data, renderKey, exclude)
133
- for (let item of array) {
134
- if (!template.renderedKeys.has(item[renderKey].key)){
135
- template.renderedKeys.set(item[renderKey].key, '')
136
- let cloneEl = this.cloneEl(template);
137
- cloneEl.setAttribute('renderedKey', item[renderKey].key)
138
- self.setValue([cloneEl], item, renderArray, renderKey);
139
- template.insertAdjacentElement('beforebegin', cloneEl);
140
- }
141
- }
142
- } else {
143
-
144
- if (!Array.isArray(arrayData))
145
- arrayData = getValueFromObject(data, type);
146
-
147
- if (!arrayData) {
148
- let cloneEl = this.cloneEl(template);
149
- self.setValue([cloneEl], data, renderArray, renderKey);
150
- template.insertAdjacentElement('beforebegin', cloneEl);
151
- }
152
-
153
- if (!Array.isArray(arrayData))
154
- arrayData = [arrayData]
155
-
156
- if (type && Array.isArray(arrayData)) {
157
- arrayData.forEach((item) => {
158
- if (!template.renderedKeys.has(item)){
159
- template.renderedKeys.set(item, '')
160
-
161
- let cloneEl = this.cloneEl(template);
162
- let object = self.__createObject(item, renderKey);
163
- self.setValue([cloneEl], object, renderArray, renderKey);
164
- template.insertAdjacentElement('beforebegin', cloneEl);
165
- }
166
- });
167
- }
168
- }
169
- },
170
-
171
- renderObject: function(data, renderKey, exclude) {
172
- let array = []
173
- if (!data)
174
- return array
175
- for (const key of Object.keys(data)) {
176
- let value = data[key]
177
- if (!exclude.includes(key)) {
178
- let type = 'string';
179
- if (typeof(value) == "object")
180
- if (Array.isArray(value))
181
- type = 'array'
182
- else
183
- type = 'object'
184
- array.push({[renderKey]: {key, value, type}})
185
- }
186
- }
187
- return array
188
- },
189
-
190
- cloneEl: function(template) {
191
- let cloneEl = template.cloneNode(true);
192
-
193
- let templateId = cloneEl.getAttribute('template_id');
194
- if (!templateId)
195
- templateId = cloneEl.getAttribute('template');
196
-
197
- if (templateId) {
198
- cloneEl.setAttribute('templateId', templateId);
199
- cloneEl.removeAttribute('template_id');
200
- cloneEl.removeAttribute('template');
201
- }
202
-
203
- if (cloneEl.tagName == 'TEMPLATE'){
204
- cloneEl = template.content.firstElementChild
205
- for (let attribute of template.attributes){
206
- let attrName = attribute.name;
207
- let attrValue = attribute.value || '';
208
- cloneEl.setAttribute(attrName, attrValue);
209
- }
210
- }
211
- else {
212
- cloneEl.classList.remove('template');
213
- cloneEl.removeAttribute('template');
214
- }
215
- cloneEl.setAttribute('render-clone', '');
216
-
217
- return cloneEl;
218
- },
219
-
220
- document_id: '',
221
- setValue: function(els, data, renderArray, renderKey){
222
- if (!data) return;
223
- let isRenderKey
224
- if (data.renderKey)
225
- isRenderKey = true
226
-
227
- const that = this;
228
- Array.from(els).forEach(el => {
229
- let updateData;
230
-
231
- if (el.nodeType == 1) {
232
- if (el.hasAttribute('render-clone')) {
233
- if (!el.renderedData)
234
- el.renderedData = {...data}
235
- else if (Object.keys(el.renderedData)[0] == Object.keys(data)[0]) {
236
- el.renderedData = {...data}
237
- }
238
-
239
- }
240
-
241
- if (el.renderMap && !isRenderKey) {
242
- let placeholder = el.renderMap.get(el)
243
- if (placeholder){
244
- renderKey = placeholder.renderKey
245
- renderArray = placeholder.renderArray
246
- if (renderArray && Array.isArray(data[renderArray]))
247
- updateData = data[renderArray][0]
248
- else if (data[renderArray])
249
- updateData = data[renderArray]
250
-
251
- if (renderKey) {
252
- if (updateData)
253
- updateData = {[renderKey]: updateData}
254
- else
255
- updateData = {[renderKey]: data}
256
- }
257
-
258
- let textContent = placeholder.placeholder
259
- let text = that.__replaceValue(updateData, textContent, renderKey, el);
260
- if (text && text != el.renderedValue)
261
- el.innerHTML = placeholder.placeholder
262
- }
263
- }
264
-
265
- Array.from(el.attributes).forEach(attr=>{
266
- let attr_name = attr.name.toLowerCase();
267
- let attrValue = attr.value;
268
- let placeholder
269
- if (attr.renderMap)
270
- placeholder = attr.renderMap.get(attr)
271
- else
272
- that.renderMap(attr, attr.value, renderArray, renderKey)
273
-
274
- if (placeholder && !isRenderKey){
275
- let temp = placeholder.placeholder;
276
- // let updateData
277
- // renderKey = placeholder.renderKey
278
- // renderArray = placeholder.renderArray
279
- // if (renderArray && Array.isArray(data[renderArray]))
280
- // updateData = data[renderArray][0]
281
- // else if (data[renderArray])
282
- // updateData = data[renderArray]
283
-
284
- // if (renderKey) {
285
- // if (updateData)
286
- // updateData = {[renderKey]: updateData}
287
- // else
288
- // updateData = {[renderKey]: data}
289
- // }
290
- if (updateData)
291
- attrValue = that.__replaceValue(updateData, temp, renderKey, el);
292
- if (attrValue == attr.value)
293
- attrValue = undefined
294
- }
295
- else
296
- attrValue = that.__replaceValue(data, attrValue, renderKey, el);
297
-
298
- // TODO: support attibute name replace if has {{}}
299
- // attr_name = that.__replaceValue(data, attr_name, renderKey, el);
300
-
301
- if (attrValue || attrValue == "") {
302
- el.setAttribute(attr_name, attrValue);
303
- }
304
- });
305
-
306
- if (CoCreate.pass) {
307
- if (el.hasAttribute('[pass_id]'))
308
- CoCreate.pass.initElement(el)
309
- }
310
-
311
- if (el.tagName === 'SCRIPT' && el.src) {
312
- if (el.src.includes('CoCreate.js') || el.src.includes('CoCreate.min.js')) {
313
- el.remove()
314
- return
315
- }
316
- }
317
-
318
- if (el.tagName === 'LINK' && el.href) {
319
- if (el.href.includes('CoCreate.css') || el.href.includes('CoCreate.min.css')) {
320
- el.remove()
321
- return
322
- }
323
- }
324
-
325
- if (el.childNodes.length > 0) {
326
- that.setValue(el.childNodes, updateData || data, renderArray, renderKey);
327
- }
328
-
329
- if ((el.tagName == 'TEMPLATE' || el.hasAttribute('template') || el.classList.contains('template')) && !el.hasAttribute('template_id')) {
330
- if (el.getAttribute('render-object') || el.getAttribute('render-array'))
331
- that.render(el, data);
332
- }
333
-
334
- }
335
-
336
- if (el.nodeType == 3) {
337
- let valueType = el.parentElement.getAttribute('value-type')
338
-
339
- let textContent, placeholder, text;
340
- if (el.renderMap)
341
- placeholder = el.renderMap.get(el)
342
- if (placeholder && !isRenderKey) {
343
- let updateData = data;
344
- textContent = placeholder.placeholder
345
- renderKey = placeholder.renderKey
346
- renderArray = placeholder.renderArray
347
- if (renderArray && Array.isArray(data[renderArray]))
348
- updateData = data[renderArray][0]
349
- else
350
- updateData = data[renderArray]
351
- if (renderKey)
352
- updateData = {[renderKey]: updateData}
353
- text = that.__replaceValue(updateData, textContent, renderKey, el);
354
- }
355
-
356
- if (!placeholder && !text) {
357
- textContent = el.textContent;
358
- if (!el.renderMap)
359
- that.renderMap(el, textContent, renderArray, renderKey)
360
- text = that.__replaceValue(data, textContent, renderKey, el);
361
- }
362
-
363
- if (text || text == "") {
364
- if (text != el.renderedValue) {
365
- el.renderedValue = text
366
- if (valueType == 'text' || valueType == 'string'){
367
- el.renderedValue = text
368
- el.textContent = text;
369
- } else {
370
- const newNode = document.createElement('div');
371
- newNode.innerHTML = text;
372
- let parentElement = el.parentElement
373
- parentElement.renderedValue = text
374
- if (!parentElement.renderMap) {
375
- that.renderMap(parentElement, textContent, renderArray, renderKey)
376
- } else if (!parentElement['renderMap'].has(parentElement))
377
- that.renderMap(parentElement, textContent, renderArray, renderKey)
378
- el.replaceWith(...newNode.childNodes)
379
-
380
- if (el.childNodes.length > 0) {
381
- that.setValue(el.childNodes, updateData || data, renderArray, renderKey);
382
- }
383
- }
384
- }
385
- }
386
- }
387
- });
388
- },
389
-
390
- renderMap: function(node, placeholder, renderArray, renderKey) {
391
- if (!node.renderMap) {
392
- node['renderMap'] = new Map();
393
- }
394
- if (placeholder && renderKey)
395
- node['renderMap'].set(node, {placeholder, renderArray, renderKey})
396
- },
397
-
398
- data: function({selector, data, elements}) {
399
- if (selector) {
400
- let template = queryDocumentSelector(selector);
401
- if (!template) return;
402
- if (template.tagName == 'TEMPLATE' || template.hasAttribute('template') || template.classList.contains('template')) {
403
- template.renderedKeys = undefined
404
- this.render(template, data);
405
- }
406
- else
407
- this.setValue([template], data);
408
- } else if (elements) {
409
- if (elements.length == 1 && (elements[0].tagName == 'TEMPLATE' || elements[0].hasAttribute('template') || elements[0].classList.contains('template'))){
410
- this.render(elements[0], data);
411
- }
412
- else
413
- this.setValue(elements, data);
414
- }
415
-
416
- }
417
-
418
- };
419
-
420
- function renderKey(element, params) {
421
- // TODO: custom render-keys
422
- const form = element.closest("form") || document;
423
- if (!params)
424
- params = 'render-key'
425
-
426
- let data = {}
427
- let selector = `[${params}]`
428
- let elements = form.querySelectorAll(selector);
429
- for (let el of elements) {
430
- let attribute = el.getAttribute(params)
431
- if (attribute)
432
- data[attribute] = el.getValue()
433
- }
434
- data = dotNotationToObject(data)
435
- let renderData = {data: {[params]: data}}
436
-
437
- let templateSelector = `[template_id='${params}']`
438
- let template = document.querySelectorAll(templateSelector);
439
- if (template)
440
- renderData.elements = template
441
- else
442
- renderData.selector = `[template='${params}']`
443
-
444
- CoCreateRender.data(renderData);
445
-
446
- document.dispatchEvent(new CustomEvent('renderKey', {
447
- detail: { data }
448
- }));
449
- }
450
-
451
- action.init({
452
- name: "renderKey",
453
- callback: (btn, params) => {
454
- renderKey(btn, params);
455
- }
456
- });
457
-
458
- observer.init({
459
- name: 'render',
460
- observe: ['addedNodes'],
461
- target: '[render]',
462
- callback: function(mutation) {
463
- let element = mutation.target
464
- element.removeAttribute('render')
465
-
466
- let parentElement = element.parentElement
467
- if (parentElement) {
468
- let el = element
469
- let parentKeys = [];
470
- let renderedData = new Map();
471
- do {
472
- let data;
473
- el = el.parentElement
474
- if (el) {
475
- if (el.hasAttribute('render-clone'))
476
- data = el.renderedData
477
- if (data) {
478
- renderedData.set(data, '')
479
- }
480
- let parentKey = el.getAttribute('parentKey')
481
- if (parentKey && parentKey != null) {
482
- if (/^\d+$/.test(parentKey))
483
- parentKey = `[${parentKey}]`
484
- parentKeys.push(parentKey)
485
- }
486
- }
487
- } while (el)
488
-
489
- let renderKey = element.getAttribute('render-key')
490
-
491
- let parentKey;
492
- parentKey = parentElement.getAttribute('parentKey')
493
- if (renderKey == '$auto' || parentKey || parentKeys) {
494
- let template = element.outerHTML
495
- if (renderKey) {
496
- template = template.replace(/\$auto/g, uuid.generate(6));
497
- }
498
- if (parentKeys.length > 0) {
499
- let string = ''
500
- if (parentKeys.length == 1){
501
- string = parentKeys[0]
502
- }
503
- else
504
- string = parentKeys.reverse().join('.')
505
- string = string.replace(/.\[/g, '[');
506
- template = template.replace(/\$parents/g, string);
507
- }
508
- if (parentKey) {
509
- template = template.replace(/\$parent/g, parentKey);
510
- }
511
-
512
- parentElement.innerHTML = template
513
-
514
- }
515
-
516
- element = parentElement.firstElementChild
517
- let obj = {}
518
- let array = Array.from(renderedData.keys())
519
- for (let data of array.reverse()){
520
- obj = {...obj, ...data}
521
- }
522
-
523
- CoCreateRender.data({
524
- elements: [element],
525
- data: obj
526
- });
527
- }
528
- }
529
- });
530
-
1
+ /*globals CustomEvent*/
2
+ import action from '@cocreate/actions';
3
+ import observer from '@cocreate/observer';
4
+ import uuid from '@cocreate/uuid';
5
+ import { queryDocumentSelector, getValueFromObject, dotNotationToObject } from '@cocreate/utils';
6
+ import '@cocreate/element-prototype';
7
+ import './index.css';
8
+ // import api from '@cocreate/api';
9
+
10
+ const CoCreateRender = {
11
+
12
+ __getValue: function(data, attrValue, el) {
13
+ let result = /{{\s*([\w\W]+)\s*}}/g.exec(attrValue);
14
+ if (result) {
15
+ let value = getValueFromObject(data, result[1].trim());
16
+ if (!value && value !== '') {
17
+ let parentTemplate
18
+ if (el && el.nodeType == 1) {
19
+ if (el.hasAttribute('templateid') && el.parentElement)
20
+ parentTemplate = el.parentElement.closest('[templateid]')
21
+ else
22
+ parentTemplate = el.closest('[templateid]')
23
+ }
24
+
25
+ if (parentTemplate) {
26
+ do {
27
+ if (parentTemplate.renderedData)
28
+ value = getValueFromObject(parentTemplate.renderedData, result[1].trim());
29
+ if (!value && parentTemplate.parentElement)
30
+ parentTemplate = parentTemplate.parentElement.closest('[templateid]')
31
+ else
32
+ parentTemplate = ""
33
+ } while (!value && parentTemplate)
34
+ }
35
+ }
36
+ return value;
37
+ }
38
+ return false;
39
+ },
40
+
41
+ __createObject: function (data, path) {
42
+ try {
43
+ if (!path) return data;
44
+
45
+ let keys = path.split('.');
46
+ let newObject = data;
47
+
48
+ for (var i = keys.length - 1; i >= 0; i--) {
49
+ newObject = {[keys[i]]: newObject};
50
+ }
51
+ return newObject;
52
+
53
+ } catch (error) {
54
+ console.log("Error in getValueFromObject", error);
55
+ return false;
56
+ }
57
+ },
58
+
59
+ __replaceValue: function(data, inputValue, renderKey, el) {
60
+ let outputValue = inputValue;
61
+ let placeholders = inputValue.match(/{{([A-Za-z0-9_.,\[\]\- ]*)}}/g);
62
+ if (placeholders) {
63
+ for (let placeholder of placeholders) {
64
+ let value = this.__getValue(data, placeholder, el);
65
+
66
+ if (value || value === "") {
67
+ if (typeof(value) == "object")
68
+ value = this.generateString(value)
69
+
70
+ outputValue = outputValue.replace(placeholder, value);
71
+ } else if (renderKey && placeholder.includes(`{{${renderKey}.`)) {
72
+ outputValue = '';
73
+ }
74
+ }
75
+ }
76
+ return outputValue;
77
+ },
78
+
79
+ generateString: function(value, str = ''){
80
+ // let str = '';
81
+ // do {
82
+ let flag = true;
83
+ if (str)
84
+ flag = false;
85
+ for (const key of Object.keys(value)) {
86
+ let val = value[key]
87
+ if (typeof(val) == "object") {
88
+ str += `${key}: \n`;
89
+ this.generateString(val, str)
90
+ }
91
+ else
92
+ str += `${key}: ${val}\n`;
93
+ }
94
+ // } while()
95
+ if (flag)
96
+ return str
97
+ },
98
+
99
+ render: function(template, data) {
100
+ const self = this;
101
+ let type = '';
102
+ let arrayData = data;
103
+
104
+ let exclude = template.getAttribute('render-exclude') || ''
105
+ if (exclude) {
106
+ exclude = exclude.replace(/ /g, '').split(",")
107
+ if (!Array.isArray(exclude))
108
+ exclude = [exclude]
109
+ }
110
+
111
+ const isRenderObject = template.hasAttribute('render-object');
112
+ if (isRenderObject) {
113
+ const renderObject = template.getAttribute('render-object');
114
+ type = renderObject || ''
115
+ }
116
+
117
+ const isRenderArray = template.hasAttribute('render-array');
118
+ if (isRenderArray){
119
+ var renderArray = template.getAttribute('render-array');
120
+ if (renderArray)
121
+ arrayData = data[renderArray];
122
+ type = renderArray || '';
123
+ }
124
+
125
+ let renderKey = template.getAttribute('render-key') || type;
126
+
127
+ if (!template.renderedKeys)
128
+ template.renderedKeys = new Map()
129
+
130
+ if (isRenderObject && type) {
131
+ let Data = getValueFromObject(arrayData, type);
132
+ let array = self.renderObject(Data, renderKey, exclude)
133
+ for (let item of array) {
134
+ if (!template.renderedKeys.has(item[renderKey].key)){
135
+ template.renderedKeys.set(item[renderKey].key, '')
136
+ let cloneEl = this.cloneEl(template);
137
+ cloneEl.setAttribute('renderedKey', item[renderKey].key)
138
+ self.setValue([cloneEl], item, renderArray, renderKey);
139
+ template.insertAdjacentElement('beforebegin', cloneEl);
140
+ }
141
+ }
142
+ } else {
143
+
144
+ if (!Array.isArray(arrayData))
145
+ arrayData = getValueFromObject(data, type);
146
+
147
+ if (!arrayData) {
148
+ let cloneEl = this.cloneEl(template);
149
+ self.setValue([cloneEl], data, renderArray, renderKey);
150
+ template.insertAdjacentElement('beforebegin', cloneEl);
151
+ }
152
+
153
+ if (!Array.isArray(arrayData))
154
+ arrayData = [arrayData]
155
+
156
+ if (type && Array.isArray(arrayData)) {
157
+ arrayData.forEach((item) => {
158
+ if (!template.renderedKeys.has(item)){
159
+ template.renderedKeys.set(item, '')
160
+
161
+ let cloneEl = this.cloneEl(template);
162
+ let object = self.__createObject(item, renderKey);
163
+ self.setValue([cloneEl], object, renderArray, renderKey);
164
+ template.insertAdjacentElement('beforebegin', cloneEl);
165
+ }
166
+ });
167
+ }
168
+ }
169
+ },
170
+
171
+ renderObject: function(data, renderKey, exclude) {
172
+ let array = []
173
+ if (!data)
174
+ return array
175
+ for (const key of Object.keys(data)) {
176
+ let value = data[key]
177
+ if (!exclude.includes(key)) {
178
+ let type = 'string';
179
+ if (typeof(value) == "object")
180
+ if (Array.isArray(value))
181
+ type = 'array'
182
+ else
183
+ type = 'object'
184
+ array.push({[renderKey]: {key, value, type}})
185
+ }
186
+ }
187
+ return array
188
+ },
189
+
190
+ cloneEl: function(template) {
191
+ let cloneEl = template.cloneNode(true);
192
+
193
+ let templateId = cloneEl.getAttribute('template_id');
194
+ if (!templateId)
195
+ templateId = cloneEl.getAttribute('template');
196
+
197
+ if (templateId) {
198
+ cloneEl.setAttribute('templateId', templateId);
199
+ cloneEl.removeAttribute('template_id');
200
+ cloneEl.removeAttribute('template');
201
+ }
202
+
203
+ if (cloneEl.tagName == 'TEMPLATE'){
204
+ cloneEl = template.content.firstElementChild
205
+ for (let attribute of template.attributes){
206
+ let attrName = attribute.name;
207
+ let attrValue = attribute.value || '';
208
+ cloneEl.setAttribute(attrName, attrValue);
209
+ }
210
+ }
211
+ else {
212
+ cloneEl.classList.remove('template');
213
+ cloneEl.removeAttribute('template');
214
+ }
215
+ cloneEl.setAttribute('render-clone', '');
216
+
217
+ return cloneEl;
218
+ },
219
+
220
+ document_id: '',
221
+ setValue: function(els, data, renderArray, renderKey){
222
+ if (!data) return;
223
+ let isRenderKey
224
+ if (data.renderKey)
225
+ isRenderKey = true
226
+
227
+ const that = this;
228
+ Array.from(els).forEach(el => {
229
+ let updateData;
230
+
231
+ if (el.nodeType == 1) {
232
+ if (el.hasAttribute('render-clone')) {
233
+ if (!el.renderedData)
234
+ el.renderedData = {...data}
235
+ else if (Object.keys(el.renderedData)[0] == Object.keys(data)[0]) {
236
+ el.renderedData = {...data}
237
+ }
238
+
239
+ }
240
+
241
+ if (el.renderMap && !isRenderKey) {
242
+ let placeholder = el.renderMap.get(el)
243
+ if (placeholder){
244
+ renderKey = placeholder.renderKey
245
+ renderArray = placeholder.renderArray
246
+ if (renderArray && Array.isArray(data[renderArray]))
247
+ updateData = data[renderArray][0]
248
+ else if (data[renderArray])
249
+ updateData = data[renderArray]
250
+
251
+ if (renderKey) {
252
+ if (updateData)
253
+ updateData = {[renderKey]: updateData}
254
+ else
255
+ updateData = {[renderKey]: data}
256
+ }
257
+
258
+ let textContent = placeholder.placeholder
259
+ let text = that.__replaceValue(updateData, textContent, renderKey, el);
260
+ if (text && text != el.renderedValue)
261
+ el.innerHTML = placeholder.placeholder
262
+ }
263
+ }
264
+
265
+ Array.from(el.attributes).forEach(attr=>{
266
+ let attr_name = attr.name.toLowerCase();
267
+ let attrValue = attr.value;
268
+ let placeholder
269
+ if (attr.renderMap)
270
+ placeholder = attr.renderMap.get(attr)
271
+ else
272
+ that.renderMap(attr, attr.value, renderArray, renderKey)
273
+
274
+ if (placeholder && !isRenderKey){
275
+ let temp = placeholder.placeholder;
276
+ // let updateData
277
+ // renderKey = placeholder.renderKey
278
+ // renderArray = placeholder.renderArray
279
+ // if (renderArray && Array.isArray(data[renderArray]))
280
+ // updateData = data[renderArray][0]
281
+ // else if (data[renderArray])
282
+ // updateData = data[renderArray]
283
+
284
+ // if (renderKey) {
285
+ // if (updateData)
286
+ // updateData = {[renderKey]: updateData}
287
+ // else
288
+ // updateData = {[renderKey]: data}
289
+ // }
290
+ if (updateData)
291
+ attrValue = that.__replaceValue(updateData, temp, renderKey, el);
292
+ if (attrValue == attr.value)
293
+ attrValue = undefined
294
+ }
295
+ else
296
+ attrValue = that.__replaceValue(data, attrValue, renderKey, el);
297
+
298
+ // TODO: support attibute name replace if has {{}}
299
+ // attr_name = that.__replaceValue(data, attr_name, renderKey, el);
300
+
301
+ if (attrValue || attrValue == "") {
302
+ el.setAttribute(attr_name, attrValue);
303
+ }
304
+ });
305
+
306
+ if (CoCreate.pass) {
307
+ if (el.hasAttribute('[pass_id]'))
308
+ CoCreate.pass.initElement(el)
309
+ }
310
+
311
+ if (el.tagName === 'SCRIPT' && el.src) {
312
+ if (el.src.includes('CoCreate.js') || el.src.includes('CoCreate.min.js')) {
313
+ el.remove()
314
+ return
315
+ }
316
+ }
317
+
318
+ if (el.tagName === 'LINK' && el.href) {
319
+ if (el.href.includes('CoCreate.css') || el.href.includes('CoCreate.min.css')) {
320
+ el.remove()
321
+ return
322
+ }
323
+ }
324
+
325
+ if (el.childNodes.length > 0) {
326
+ that.setValue(el.childNodes, updateData || data, renderArray, renderKey);
327
+ }
328
+
329
+ if ((el.tagName == 'TEMPLATE' || el.hasAttribute('template') || el.classList.contains('template')) && !el.hasAttribute('template_id')) {
330
+ if (el.getAttribute('render-object') || el.getAttribute('render-array'))
331
+ that.render(el, data);
332
+ }
333
+
334
+ }
335
+
336
+ if (el.nodeType == 3) {
337
+ let valueType = el.parentElement.getAttribute('value-type')
338
+
339
+ let textContent, placeholder, text;
340
+ if (el.renderMap)
341
+ placeholder = el.renderMap.get(el)
342
+ if (placeholder && !isRenderKey) {
343
+ let updateData = data;
344
+ textContent = placeholder.placeholder
345
+ renderKey = placeholder.renderKey
346
+ renderArray = placeholder.renderArray
347
+ if (renderArray && Array.isArray(data[renderArray]))
348
+ updateData = data[renderArray][0]
349
+ else
350
+ updateData = data[renderArray]
351
+ if (renderKey)
352
+ updateData = {[renderKey]: updateData}
353
+ text = that.__replaceValue(updateData, textContent, renderKey, el);
354
+ }
355
+
356
+ if (!placeholder && !text) {
357
+ textContent = el.textContent;
358
+ if (!el.renderMap)
359
+ that.renderMap(el, textContent, renderArray, renderKey)
360
+ text = that.__replaceValue(data, textContent, renderKey, el);
361
+ }
362
+
363
+ if (text || text == "") {
364
+ if (text != el.renderedValue) {
365
+ el.renderedValue = text
366
+ if (valueType == 'text' || valueType == 'string'){
367
+ el.renderedValue = text
368
+ el.textContent = text;
369
+ } else {
370
+ const newNode = document.createElement('div');
371
+ newNode.innerHTML = text;
372
+ let parentElement = el.parentElement
373
+ parentElement.renderedValue = text
374
+ if (!parentElement.renderMap) {
375
+ that.renderMap(parentElement, textContent, renderArray, renderKey)
376
+ } else if (!parentElement['renderMap'].has(parentElement))
377
+ that.renderMap(parentElement, textContent, renderArray, renderKey)
378
+ el.replaceWith(...newNode.childNodes)
379
+
380
+ if (el.childNodes.length > 0) {
381
+ that.setValue(el.childNodes, updateData || data, renderArray, renderKey);
382
+ }
383
+ }
384
+ }
385
+ }
386
+ }
387
+ });
388
+ },
389
+
390
+ renderMap: function(node, placeholder, renderArray, renderKey) {
391
+ if (!node.renderMap) {
392
+ node['renderMap'] = new Map();
393
+ }
394
+ if (placeholder && renderKey)
395
+ node['renderMap'].set(node, {placeholder, renderArray, renderKey})
396
+ },
397
+
398
+ data: function({selector, data, elements}) {
399
+ if (selector) {
400
+ let template = queryDocumentSelector(selector);
401
+ if (!template) return;
402
+ if (template.tagName == 'TEMPLATE' || template.hasAttribute('template') || template.classList.contains('template')) {
403
+ template.renderedKeys = undefined
404
+ this.render(template, data);
405
+ }
406
+ else
407
+ this.setValue([template], data);
408
+ } else if (elements) {
409
+ if (elements.length == 1 && (elements[0].tagName == 'TEMPLATE' || elements[0].hasAttribute('template') || elements[0].classList.contains('template'))){
410
+ this.render(elements[0], data);
411
+ }
412
+ else
413
+ this.setValue(elements, data);
414
+ }
415
+
416
+ }
417
+
418
+ };
419
+
420
+ function renderKey(element, params) {
421
+ // TODO: custom render-keys
422
+ const form = element.closest("form") || document;
423
+ if (!params)
424
+ params = 'render-key'
425
+
426
+ let data = {}
427
+ let selector = `[${params}]`
428
+ let elements = form.querySelectorAll(selector);
429
+ for (let el of elements) {
430
+ let attribute = el.getAttribute(params)
431
+ if (attribute)
432
+ data[attribute] = el.getValue()
433
+ }
434
+ data = dotNotationToObject(data)
435
+ let renderData = {data: {[params]: data}}
436
+
437
+ let templateSelector = `[template_id='${params}']`
438
+ let template = document.querySelectorAll(templateSelector);
439
+ if (template)
440
+ renderData.elements = template
441
+ else
442
+ renderData.selector = `[template='${params}']`
443
+
444
+ CoCreateRender.data(renderData);
445
+
446
+ document.dispatchEvent(new CustomEvent('renderKey', {
447
+ detail: { data }
448
+ }));
449
+ }
450
+
451
+ action.init({
452
+ name: "renderKey",
453
+ callback: (btn, params) => {
454
+ renderKey(btn, params);
455
+ }
456
+ });
457
+
458
+ observer.init({
459
+ name: 'render',
460
+ observe: ['addedNodes'],
461
+ target: '[render]',
462
+ callback: function(mutation) {
463
+ let element = mutation.target
464
+ element.removeAttribute('render')
465
+
466
+ let parentElement = element.parentElement
467
+ if (parentElement) {
468
+ let el = element
469
+ let parentKeys = [];
470
+ let renderedData = new Map();
471
+ do {
472
+ let data;
473
+ el = el.parentElement
474
+ if (el) {
475
+ if (el.hasAttribute('render-clone'))
476
+ data = el.renderedData
477
+ if (data) {
478
+ renderedData.set(data, '')
479
+ }
480
+ let parentKey = el.getAttribute('parentKey')
481
+ if (parentKey && parentKey != null) {
482
+ if (/^\d+$/.test(parentKey))
483
+ parentKey = `[${parentKey}]`
484
+ parentKeys.push(parentKey)
485
+ }
486
+ }
487
+ } while (el)
488
+
489
+ let renderKey = element.getAttribute('render-key')
490
+
491
+ let parentKey;
492
+ parentKey = parentElement.getAttribute('parentKey')
493
+ if (renderKey == '$auto' || parentKey || parentKeys) {
494
+ let template = element.outerHTML
495
+ if (renderKey) {
496
+ template = template.replace(/\$auto/g, uuid.generate(6));
497
+ }
498
+ if (parentKeys.length > 0) {
499
+ let string = ''
500
+ if (parentKeys.length == 1){
501
+ string = parentKeys[0]
502
+ }
503
+ else
504
+ string = parentKeys.reverse().join('.')
505
+ string = string.replace(/.\[/g, '[');
506
+ template = template.replace(/\$parents/g, string);
507
+ }
508
+ if (parentKey) {
509
+ template = template.replace(/\$parent/g, parentKey);
510
+ }
511
+
512
+ parentElement.innerHTML = template
513
+
514
+ }
515
+
516
+ element = parentElement.firstElementChild
517
+ let obj = {}
518
+ let array = Array.from(renderedData.keys())
519
+ for (let data of array.reverse()){
520
+ obj = {...obj, ...data}
521
+ }
522
+
523
+ CoCreateRender.data({
524
+ elements: [element],
525
+ data: obj
526
+ });
527
+ }
528
+ }
529
+ });
530
+
531
531
  export default CoCreateRender;