@cocreate/render 1.9.2 → 1.12.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 +32 -0
- package/demo/render.html +42 -0
- package/package.json +1 -1
- package/src/index.js +223 -39
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
# [1.12.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.11.0...v1.12.0) (2022-07-29)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* replace attribute value if new and old value are not equal ([3dc25d8](https://github.com/CoCreate-app/CoCreate-render/commit/3dc25d884510a6ad14455b232d9068eb5e1302a8))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* if oldValues same as new value will not update text, html or attributes ([9cfe3f0](https://github.com/CoCreate-app/CoCreate-render/commit/9cfe3f017e706a5a7211449c294158d60fa2098c))
|
|
12
|
+
|
|
13
|
+
# [1.11.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.10.0...v1.11.0) (2022-07-25)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* if templateId setAttribute ([41e30b3](https://github.com/CoCreate-app/CoCreate-render/commit/41e30b3a748aa8900d9f9397584f14052d637197))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* getValueFromObject supports deeply nested array and objects ([db7fefd](https://github.com/CoCreate-app/CoCreate-render/commit/db7fefd81a908ba6f68dbf4c43d62639aa73e3f8))
|
|
24
|
+
* observe new elements with atrribute render, if elements detected replace placholders with values ([90d7d98](https://github.com/CoCreate-app/CoCreate-render/commit/90d7d982eedf83b194cfae0704d06e110914ca52))
|
|
25
|
+
|
|
26
|
+
# [1.10.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.2...v1.10.0) (2022-07-14)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
|
|
31
|
+
* renderMap function to apply map containing placeholder to node object in order to render new values ([7afffa0](https://github.com/CoCreate-app/CoCreate-render/commit/7afffa07b2cc1dd562e96d1ee558433d3f6d043a))
|
|
32
|
+
|
|
1
33
|
## [1.9.2](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.1...v1.9.2) (2022-07-10)
|
|
2
34
|
|
|
3
35
|
|
package/demo/render.html
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Render | CoCreateJS</title>
|
|
4
|
+
|
|
5
|
+
<!-- CoCreate Favicon -->
|
|
6
|
+
<link rel="icon" href="https://cdn.cocreate.app/favicon.ico" type="image/ico" sizes="16x16">
|
|
7
|
+
</head>
|
|
8
|
+
<style>
|
|
9
|
+
.template{display:none}
|
|
10
|
+
</style>
|
|
11
|
+
<body>
|
|
12
|
+
|
|
13
|
+
<body>
|
|
14
|
+
|
|
15
|
+
<div class="template" template_id="abc1">
|
|
16
|
+
<h3>{{collection}}</h3>
|
|
17
|
+
<h3>{{data._id}}</h3>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<pre>
|
|
21
|
+
<h1>Paste in your browser console</h1>
|
|
22
|
+
|
|
23
|
+
/** Example **/
|
|
24
|
+
CoCreate.render.data({
|
|
25
|
+
selector: '[template_id=abc1]',
|
|
26
|
+
data: {
|
|
27
|
+
collection: 'dededede',
|
|
28
|
+
data: {
|
|
29
|
+
_id : '123kijfhgfkel45',
|
|
30
|
+
current_org: ['test1', 'test2', 'test31', 'test3'],
|
|
31
|
+
current: [{name: 'test1w'}, {name: 'test2'}, {name: 'test31'}, {name: 'test3'}]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
</pre>
|
|
38
|
+
|
|
39
|
+
<!-- CoCreate JS CDN -->
|
|
40
|
+
<script src="../../../CoCreateJS/dist/CoCreate.js" ></script>
|
|
41
|
+
</body>
|
|
42
|
+
</html>
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
/*globals CustomEvent*/
|
|
2
2
|
import action from '@cocreate/actions';
|
|
3
|
+
import observer from '@cocreate/observer';
|
|
4
|
+
import uuid from '@cocreate/uuid';
|
|
3
5
|
import { queryDocumentSelector } from '@cocreate/utils';
|
|
4
6
|
// import { getValue } from '../../CoCreate-elements/src/getValue';
|
|
5
7
|
// import api from '@cocreate/api';
|
|
6
8
|
|
|
7
9
|
const CoCreateRender = {
|
|
8
|
-
|
|
10
|
+
// Can be called from crud getObjectValueByPath
|
|
9
11
|
__getValueFromObject : function(json, path) {
|
|
10
12
|
try {
|
|
11
13
|
if(typeof json == 'undefined' || !path)
|
|
12
14
|
return false;
|
|
13
15
|
if (path.indexOf('.') == -1 && path.includes('collection'))
|
|
14
16
|
json = this.dataOriginal
|
|
17
|
+
if (/\[([0-9]*)\]/g.test(path)) {
|
|
18
|
+
path = path.replace(/\[/g, '.');
|
|
19
|
+
if (path.endsWith(']'))
|
|
20
|
+
path = path.slice(0, -1)
|
|
21
|
+
path = path.replace(/\]./g, '.');
|
|
22
|
+
path = path.replace(/\]/g, '.');
|
|
23
|
+
}
|
|
15
24
|
let jsonData = json, subpath = path.split('.');
|
|
16
25
|
|
|
17
26
|
for (let i = 0; i < subpath.length; i++) {
|
|
@@ -52,7 +61,7 @@ const CoCreateRender = {
|
|
|
52
61
|
}
|
|
53
62
|
},
|
|
54
63
|
|
|
55
|
-
__replaceValue: function(data, inputValue, renderKey) {
|
|
64
|
+
__replaceValue: function(data, inputValue, renderKey, valueType) {
|
|
56
65
|
let isPass = false;
|
|
57
66
|
let self = this;
|
|
58
67
|
let resultValue = null;
|
|
@@ -103,32 +112,33 @@ const CoCreateRender = {
|
|
|
103
112
|
},
|
|
104
113
|
|
|
105
114
|
render: function(template, data) {
|
|
106
|
-
let type = template.getAttribute('render-array') || "data";
|
|
107
|
-
const renderKey = template.getAttribute('render-key') || type;
|
|
108
115
|
const self = this;
|
|
109
|
-
|
|
116
|
+
let type = '';
|
|
110
117
|
let arrayData = data;
|
|
111
118
|
|
|
112
119
|
const isRenderObject = template.hasAttribute('render-object');
|
|
113
120
|
if (isRenderObject){
|
|
114
|
-
const renderObject = template.getAttribute('render-object');
|
|
115
|
-
type = renderObject || '
|
|
121
|
+
const renderObject = template.getAttribute('render-object');
|
|
122
|
+
type = renderObject || ''
|
|
116
123
|
}
|
|
117
124
|
|
|
118
125
|
const isRenderArray = template.hasAttribute('render-array');
|
|
119
126
|
if (isRenderArray){
|
|
120
|
-
|
|
127
|
+
var renderArray = template.getAttribute('render-array');
|
|
121
128
|
if (renderArray)
|
|
122
129
|
arrayData = data[renderArray];
|
|
123
|
-
type = renderArray || '
|
|
130
|
+
type = renderArray || '';
|
|
124
131
|
}
|
|
132
|
+
|
|
133
|
+
let renderKey = template.getAttribute('render-key') || type;
|
|
134
|
+
|
|
125
135
|
if (isRenderObject && type) {
|
|
126
|
-
let
|
|
127
|
-
|
|
136
|
+
let Data = self.__getValueFromObject(arrayData, type);
|
|
137
|
+
let array = self.isRenderObject(Data, renderKey)
|
|
138
|
+
for (let item of array) {
|
|
128
139
|
let cloneEl = this.cloneEl(template);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
template.insertAdjacentHTML('beforebegin', cloneEl.outerHTML);
|
|
140
|
+
self.setValue([cloneEl], item, renderArray, renderKey);
|
|
141
|
+
template.insertAdjacentElement('beforebegin', cloneEl);
|
|
132
142
|
}
|
|
133
143
|
} else {
|
|
134
144
|
|
|
@@ -137,18 +147,16 @@ const CoCreateRender = {
|
|
|
137
147
|
|
|
138
148
|
if (!arrayData) {
|
|
139
149
|
let cloneEl = this.cloneEl(template);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
template.insertAdjacentHTML('beforebegin', cloneEl.outerHTML);
|
|
150
|
+
self.setValue([cloneEl], data, renderArray, renderKey);
|
|
151
|
+
template.insertAdjacentElement('beforebegin', cloneEl);
|
|
143
152
|
}
|
|
144
153
|
|
|
145
154
|
if(type && Array.isArray(arrayData)) {
|
|
146
155
|
arrayData.forEach((item) => {
|
|
147
156
|
let cloneEl = this.cloneEl(template);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
template.insertAdjacentHTML('beforebegin', cloneEl.outerHTML);
|
|
157
|
+
let object = self.__createObject(item, renderKey);
|
|
158
|
+
self.setValue([cloneEl], object, renderArray, renderKey);
|
|
159
|
+
template.insertAdjacentElement('beforebegin', cloneEl);
|
|
152
160
|
});
|
|
153
161
|
}
|
|
154
162
|
}
|
|
@@ -156,6 +164,8 @@ const CoCreateRender = {
|
|
|
156
164
|
|
|
157
165
|
isRenderObject: function(data, renderKey) {
|
|
158
166
|
let array = []
|
|
167
|
+
if (!data)
|
|
168
|
+
return array
|
|
159
169
|
for (const [key, value] of Object.entries(data)) {
|
|
160
170
|
let type = 'string';
|
|
161
171
|
if (typeof(value) == "object")
|
|
@@ -170,68 +180,167 @@ const CoCreateRender = {
|
|
|
170
180
|
|
|
171
181
|
cloneEl: function(template) {
|
|
172
182
|
let cloneEl = template.cloneNode(true);
|
|
173
|
-
|
|
183
|
+
|
|
174
184
|
let templateId = cloneEl.getAttribute('template_id');
|
|
185
|
+
if (templateId)
|
|
186
|
+
cloneEl.setAttribute('templateId', templateId);
|
|
187
|
+
|
|
175
188
|
cloneEl.removeAttribute('template_id');
|
|
176
|
-
cloneEl.setAttribute('
|
|
189
|
+
cloneEl.setAttribute('render-clone', '');
|
|
190
|
+
cloneEl.classList.remove('template');
|
|
191
|
+
|
|
192
|
+
if (template.dataOriginal)
|
|
193
|
+
cloneEl.dataOriginal = template.dataOriginal
|
|
194
|
+
|
|
177
195
|
return cloneEl;
|
|
178
196
|
},
|
|
179
197
|
|
|
180
|
-
setValue: function(els, data, renderKey){
|
|
198
|
+
setValue: function(els, data, renderArray, renderKey){
|
|
181
199
|
if (!data) return;
|
|
182
200
|
const that = this;
|
|
183
201
|
Array.from(els).forEach(el => {
|
|
202
|
+
let updateData;
|
|
203
|
+
|
|
184
204
|
if (el.nodeType == 1) {
|
|
205
|
+
if (el.hasAttribute('render-clone')) {
|
|
206
|
+
el.renderData = {...data}
|
|
207
|
+
}
|
|
208
|
+
if (el.renderMap) {
|
|
209
|
+
let placeholder = el.renderMap.get(el)
|
|
210
|
+
if (placeholder){
|
|
211
|
+
let valueType = el.getAttribute('value-type')
|
|
212
|
+
renderKey = placeholder.renderKey
|
|
213
|
+
renderArray = placeholder.renderArray
|
|
214
|
+
if (renderArray)
|
|
215
|
+
updateData = data[renderArray][0]
|
|
216
|
+
if (renderKey)
|
|
217
|
+
updateData = {[renderKey]: updateData}
|
|
218
|
+
let textContent = placeholder.placeholder
|
|
219
|
+
let text = that.__replaceValue(updateData, textContent, renderKey, valueType);
|
|
220
|
+
if (text && text != el.renderedValue)
|
|
221
|
+
el.innerHTML = placeholder.placeholder
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
185
225
|
Array.from(el.attributes).forEach(attr=>{
|
|
186
226
|
let attr_name = attr.name.toLowerCase();
|
|
187
227
|
let attrValue = attr.value;
|
|
188
|
-
|
|
228
|
+
|
|
229
|
+
let placeholder
|
|
230
|
+
if (attr.renderMap)
|
|
231
|
+
placeholder = attr.renderMap.get(attr)
|
|
232
|
+
else
|
|
233
|
+
that.renderMap(attr, attr.value, renderArray, renderKey)
|
|
234
|
+
|
|
235
|
+
if(placeholder){
|
|
236
|
+
let updateData = data;
|
|
237
|
+
// let oldValue = attrValue
|
|
238
|
+
let temp = placeholder.placeholder;
|
|
239
|
+
renderKey = placeholder.renderKey
|
|
240
|
+
renderArray = placeholder.renderArray
|
|
241
|
+
if (renderArray)
|
|
242
|
+
updateData = data[renderArray][0]
|
|
243
|
+
if (renderKey)
|
|
244
|
+
updateData = {[renderKey]: updateData}
|
|
245
|
+
|
|
246
|
+
attrValue = that.__replaceValue(updateData, temp, renderKey);
|
|
247
|
+
if (attrValue == attr.value)
|
|
248
|
+
attrValue = undefined
|
|
249
|
+
}
|
|
250
|
+
else
|
|
251
|
+
attrValue = that.__replaceValue(data, attrValue, renderKey);
|
|
189
252
|
|
|
253
|
+
// ToDo support attibute name replace if has {{}}
|
|
254
|
+
// attr_name = that.__replaceValue(data, attr_name, renderKey);
|
|
255
|
+
|
|
190
256
|
if (attrValue || attrValue == "") {
|
|
191
257
|
el.setAttribute(attr_name, attrValue);
|
|
192
258
|
}
|
|
193
259
|
});
|
|
194
260
|
|
|
195
|
-
if(el.childNodes.length > 0) {
|
|
196
|
-
that.setValue(el.childNodes, data, renderKey);
|
|
261
|
+
if(el.childNodes.length > 0) {
|
|
262
|
+
that.setValue(el.childNodes, updateData || data, renderArray, renderKey);
|
|
197
263
|
}
|
|
198
264
|
if (el.classList.contains('template') && !el.hasAttribute('template_id')) {
|
|
199
265
|
that.render(el, data);
|
|
200
266
|
}
|
|
201
267
|
}
|
|
202
|
-
|
|
268
|
+
|
|
203
269
|
if (el.nodeType == 3) {
|
|
204
270
|
let valueType = el.parentElement.getAttribute('value-type')
|
|
205
|
-
|
|
206
|
-
let
|
|
271
|
+
|
|
272
|
+
let textContent, placeholder, text;
|
|
273
|
+
if (el.renderMap)
|
|
274
|
+
placeholder = el.renderMap.get(el)
|
|
275
|
+
if (placeholder) {
|
|
276
|
+
let updateData = data;
|
|
277
|
+
textContent = placeholder.placeholder
|
|
278
|
+
renderKey = placeholder.renderKey
|
|
279
|
+
renderArray = placeholder.renderArray
|
|
280
|
+
if (renderArray)
|
|
281
|
+
updateData = data[renderArray][0]
|
|
282
|
+
if (renderKey)
|
|
283
|
+
updateData = {[renderKey]: updateData}
|
|
284
|
+
text = that.__replaceValue(updateData, textContent, renderKey, valueType);
|
|
285
|
+
}
|
|
286
|
+
if (!placeholder && !text) {
|
|
287
|
+
textContent = el.textContent;
|
|
288
|
+
that.renderMap(el, textContent, renderArray, renderKey)
|
|
289
|
+
text = that.__replaceValue(data, textContent, renderKey, valueType);
|
|
290
|
+
}
|
|
291
|
+
|
|
207
292
|
if (text || text == "") {
|
|
208
|
-
if (
|
|
209
|
-
el.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
293
|
+
if (text != el.renderedValue) {
|
|
294
|
+
el.renderedValue = text
|
|
295
|
+
if (valueType == 'text' || valueType == 'string'){
|
|
296
|
+
el.renderedValue = text
|
|
297
|
+
el.textContent = text;
|
|
298
|
+
} else {
|
|
299
|
+
const newNode = document.createElement('div');
|
|
300
|
+
newNode.innerHTML = text;
|
|
301
|
+
let parentElement = el.parentElement
|
|
302
|
+
parentElement.renderedValue = text
|
|
303
|
+
if (!parentElement.renderMap) {
|
|
304
|
+
that.renderMap(parentElement, textContent, renderArray, renderKey)
|
|
305
|
+
} else if (!parentElement['renderMap'].has(parentElement))
|
|
306
|
+
that.renderMap(parentElement, textContent, renderArray, renderKey)
|
|
307
|
+
el.replaceWith(...newNode.childNodes)
|
|
308
|
+
}
|
|
214
309
|
}
|
|
215
310
|
}
|
|
216
311
|
}
|
|
217
|
-
|
|
218
312
|
});
|
|
219
313
|
},
|
|
314
|
+
|
|
315
|
+
renderMap: function(node, placeholder, renderArray, renderKey) {
|
|
316
|
+
if (!node.renderMap) {
|
|
317
|
+
node['renderMap'] = new Map();
|
|
318
|
+
}
|
|
319
|
+
if (placeholder && renderKey)
|
|
320
|
+
node['renderMap'].set(node, {placeholder, renderArray, renderKey})
|
|
321
|
+
},
|
|
220
322
|
|
|
221
323
|
dataOriginal: {},
|
|
222
324
|
data: function({selector, data, elements}) {
|
|
223
|
-
this.dataOriginal = data;
|
|
325
|
+
this.dataOriginal = {...data};
|
|
326
|
+
delete this.dataOriginal.data
|
|
327
|
+
|
|
328
|
+
for (let element of elements)
|
|
329
|
+
element.dataOriginal = {...this.dataOriginal};
|
|
330
|
+
|
|
224
331
|
if (selector) {
|
|
225
332
|
let template = queryDocumentSelector(selector);
|
|
226
333
|
if (!template) return;
|
|
334
|
+
template.dataOriginal = {...data}
|
|
227
335
|
if (template.classList.contains('template')) {
|
|
228
336
|
this.render(template, data);
|
|
229
337
|
}
|
|
230
338
|
else
|
|
231
339
|
this.setValue([template], data);
|
|
232
340
|
} else if (elements) {
|
|
233
|
-
if (elements.length == 1 && elements[0].classList.contains('template'))
|
|
341
|
+
if (elements.length == 1 && elements[0].classList.contains('template')){
|
|
234
342
|
this.render(elements[0], data);
|
|
343
|
+
}
|
|
235
344
|
else
|
|
236
345
|
this.setValue(elements, data);
|
|
237
346
|
}
|
|
@@ -262,4 +371,79 @@ action.init({
|
|
|
262
371
|
}
|
|
263
372
|
});
|
|
264
373
|
|
|
374
|
+
observer.init({
|
|
375
|
+
name: 'render',
|
|
376
|
+
observe: ['addedNodes'],
|
|
377
|
+
target: '[render]',
|
|
378
|
+
callback: function(mutation) {
|
|
379
|
+
let element = mutation.target
|
|
380
|
+
element.removeAttribute('render')
|
|
381
|
+
|
|
382
|
+
let parentElement = element.parentElement
|
|
383
|
+
if (parentElement) {
|
|
384
|
+
let el = element
|
|
385
|
+
let parentKeys = [];
|
|
386
|
+
let renderData = new Map();
|
|
387
|
+
do {
|
|
388
|
+
let data;
|
|
389
|
+
el = el.parentElement
|
|
390
|
+
if (el) {
|
|
391
|
+
if (el.dataOriginal)
|
|
392
|
+
renderData.set(el.dataOriginal, '')
|
|
393
|
+
if (el.hasAttribute('render-clone'))
|
|
394
|
+
data = el.renderData
|
|
395
|
+
if (data)
|
|
396
|
+
renderData.set(data, '')
|
|
397
|
+
|
|
398
|
+
let parentKey = el.getAttribute('parentKey')
|
|
399
|
+
if(parentKey && parentKey != null) {
|
|
400
|
+
if (/^\d+$/.test(parentKey))
|
|
401
|
+
parentKey = `[${parentKey}]`
|
|
402
|
+
parentKeys.push(parentKey)
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
} while (el)
|
|
406
|
+
|
|
407
|
+
let renderKey = element.getAttribute('render-key')
|
|
408
|
+
|
|
409
|
+
let parentKey;
|
|
410
|
+
parentKey = parentElement.getAttribute('parentKey')
|
|
411
|
+
if(renderKey == '$auto' || parentKey || parentKeys) {
|
|
412
|
+
let template = element.outerHTML
|
|
413
|
+
if (renderKey) {
|
|
414
|
+
template = template.replace(/\$auto/g, uuid.generate(6));
|
|
415
|
+
}
|
|
416
|
+
if (parentKeys.length > 0) {
|
|
417
|
+
let string = ''
|
|
418
|
+
if (parentKeys.length == 1){
|
|
419
|
+
string = parentKeys[0]
|
|
420
|
+
}
|
|
421
|
+
else
|
|
422
|
+
string = parentKeys.reverse().join('.')
|
|
423
|
+
string = string.replace(/.\[/g, '[');
|
|
424
|
+
template = template.replace(/\$parents/g, string);
|
|
425
|
+
}
|
|
426
|
+
if (parentKey) {
|
|
427
|
+
template = template.replace(/\$parent/g, parentKey);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
parentElement.innerHTML = template
|
|
431
|
+
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
element = parentElement.firstElementChild
|
|
435
|
+
let obj = {}
|
|
436
|
+
let array = Array.from(renderData.keys())
|
|
437
|
+
for (let data of array.reverse()){
|
|
438
|
+
obj = {...obj, ...data}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
CoCreateRender.data({
|
|
442
|
+
elements: [element],
|
|
443
|
+
data: obj
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
|
|
265
449
|
export default CoCreateRender;
|