@cocreate/render 1.10.0 → 1.12.1

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 CHANGED
@@ -1,3 +1,35 @@
1
+ ## [1.12.1](https://github.com/CoCreate-app/CoCreate-render/compare/v1.12.0...v1.12.1) (2022-07-31)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * moved the of loop that adds dataOriginal to inside if elements ([a1db516](https://github.com/CoCreate-app/CoCreate-render/commit/a1db516d6c4739581ab59db5ab5e746e8f409985))
7
+
8
+ # [1.12.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.11.0...v1.12.0) (2022-07-29)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * replace attribute value if new and old value are not equal ([3dc25d8](https://github.com/CoCreate-app/CoCreate-render/commit/3dc25d884510a6ad14455b232d9068eb5e1302a8))
14
+
15
+
16
+ ### Features
17
+
18
+ * if oldValues same as new value will not update text, html or attributes ([9cfe3f0](https://github.com/CoCreate-app/CoCreate-render/commit/9cfe3f017e706a5a7211449c294158d60fa2098c))
19
+
20
+ # [1.11.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.10.0...v1.11.0) (2022-07-25)
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * if templateId setAttribute ([41e30b3](https://github.com/CoCreate-app/CoCreate-render/commit/41e30b3a748aa8900d9f9397584f14052d637197))
26
+
27
+
28
+ ### Features
29
+
30
+ * getValueFromObject supports deeply nested array and objects ([db7fefd](https://github.com/CoCreate-app/CoCreate-render/commit/db7fefd81a908ba6f68dbf4c43d62639aa73e3f8))
31
+ * observe new elements with atrribute render, if elements detected replace placholders with values ([90d7d98](https://github.com/CoCreate-app/CoCreate-render/commit/90d7d982eedf83b194cfae0704d06e110914ca52))
32
+
1
33
  # [1.10.0](https://github.com/CoCreate-app/CoCreate-render/compare/v1.9.2...v1.10.0) (2022-07-14)
2
34
 
3
35
 
@@ -19,7 +19,7 @@
19
19
  </cc-options>
20
20
 
21
21
  <div class="template" template_id="abc1">
22
- <div class="template" render-array="data.current" render-key="current_org" value="{{current_org.name}}">
22
+ <div class="template" render-array="data[0].current" render-key="current_org" value="{{current_org.name}}">
23
23
  <h3>{{current_org.name}}</h3>
24
24
  </div>
25
25
  </div>
@@ -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>
@@ -16,7 +16,7 @@
16
16
  <div class="template" render-object="" render-key="one">
17
17
  <h5>{{one.key}}: {{one.value}}</h5>
18
18
  </div>
19
- <div class="template" render-array="data.current_org" render-key="current_org" value="{{current_org}}">
19
+ <div class="template" render-array="data[0].current_org" render-key="current_org" value="{{current_org}}">
20
20
  <h3>{{current_org}}</h3>
21
21
  </div>
22
22
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/render",
3
- "version": "1.10.0",
3
+ "version": "1.12.1",
4
4
  "description": "A simple render component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "render",
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++) {
@@ -103,31 +112,32 @@ 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 || 'data'
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
- const renderArray = template.getAttribute('render-array');
127
+ var renderArray = template.getAttribute('render-array');
121
128
  if (renderArray)
122
129
  arrayData = data[renderArray];
123
- type = renderArray || 'data';
130
+ type = renderArray || '';
124
131
  }
132
+
133
+ let renderKey = template.getAttribute('render-key') || type;
134
+
125
135
  if (isRenderObject && type) {
126
- let r_data = self.isRenderObject(arrayData[type], renderKey)
127
- for (let sdata of r_data) {
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
- cloneEl.classList.add('clone_' + type);
130
- self.setValue([cloneEl], sdata, renderKey);
140
+ self.setValue([cloneEl], item, renderArray, renderKey);
131
141
  template.insertAdjacentElement('beforebegin', cloneEl);
132
142
  }
133
143
  } else {
@@ -137,17 +147,15 @@ const CoCreateRender = {
137
147
 
138
148
  if (!arrayData) {
139
149
  let cloneEl = this.cloneEl(template);
140
- cloneEl.classList.add('cloned');
141
- self.setValue([cloneEl], data, renderKey);
150
+ self.setValue([cloneEl], data, renderArray, renderKey);
142
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
- cloneEl.classList.add('clone_' + type);
149
- let r_data = self.__createObject(item, renderKey);
150
- self.setValue([cloneEl], r_data, renderKey);
157
+ let object = self.__createObject(item, renderKey);
158
+ self.setValue([cloneEl], object, renderArray, renderKey);
151
159
  template.insertAdjacentElement('beforebegin', cloneEl);
152
160
  });
153
161
  }
@@ -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,26 +180,45 @@ const CoCreateRender = {
170
180
 
171
181
  cloneEl: function(template) {
172
182
  let cloneEl = template.cloneNode(true);
173
- cloneEl.classList.remove('template');
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('templateId', templateId);
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;
184
203
 
185
204
  if (el.nodeType == 1) {
205
+ if (el.hasAttribute('render-clone')) {
206
+ el.renderData = {...data}
207
+ }
186
208
  if (el.renderMap) {
187
209
  let placeholder = el.renderMap.get(el)
188
210
  if (placeholder){
189
- el.innerHTML = placeholder.placeholder
211
+ let valueType = el.getAttribute('value-type')
190
212
  renderKey = placeholder.renderKey
191
- if (data[renderKey][0])
192
- data = {[renderKey]: data[renderKey][0]}
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
193
222
  }
194
223
  }
195
224
 
@@ -197,100 +226,127 @@ const CoCreateRender = {
197
226
  let attr_name = attr.name.toLowerCase();
198
227
  let attrValue = attr.value;
199
228
 
200
- // get placeholder
201
229
  let placeholder
202
230
  if (attr.renderMap)
203
231
  placeholder = attr.renderMap.get(attr)
204
232
  else
205
- that.renderMap(attr, attr.value, renderKey)
233
+ that.renderMap(attr, attr.value, renderArray, renderKey)
206
234
 
207
235
  if(placeholder){
208
- attrValue = placeholder.placeholder;
209
- renderKey = placeholder.renderKey
210
236
  let updateData = data;
211
- if (data[renderKey][0])
212
- updateData = {[renderKey]: data[renderKey][0]}
213
- attrValue = that.__replaceValue(updateData, attrValue, renderKey);
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
214
249
  }
215
250
  else
216
251
  attrValue = that.__replaceValue(data, attrValue, renderKey);
217
252
 
253
+ // ToDo support attibute name replace if has {{}}
254
+ // attr_name = that.__replaceValue(data, attr_name, renderKey);
255
+
218
256
  if (attrValue || attrValue == "") {
219
257
  el.setAttribute(attr_name, attrValue);
220
258
  }
221
259
  });
222
260
 
223
261
  if(el.childNodes.length > 0) {
224
- that.setValue(el.childNodes, data, renderKey);
262
+ that.setValue(el.childNodes, updateData || data, renderArray, renderKey);
225
263
  }
226
264
  if (el.classList.contains('template') && !el.hasAttribute('template_id')) {
227
265
  that.render(el, data);
228
- }
266
+ }
267
+ // if (el.hasAttribute('render-array') || el.hasAttribute('render-object')) {
268
+ // if (!el.dataOriginal) {
269
+ // that.render(el, data);
270
+ // }
271
+ // }
272
+
229
273
  }
230
274
 
231
275
  if (el.nodeType == 3) {
232
276
  let valueType = el.parentElement.getAttribute('value-type')
233
277
 
234
- // get placeholder
235
278
  let textContent, placeholder, text;
236
279
  if (el.renderMap)
237
280
  placeholder = el.renderMap.get(el)
238
281
  if (placeholder) {
282
+ let updateData = data;
239
283
  textContent = placeholder.placeholder
240
284
  renderKey = placeholder.renderKey
241
- let updateData = data;
242
- if (data[renderKey][0])
243
- updateData = {[renderKey]: data[renderKey][0]}
285
+ renderArray = placeholder.renderArray
286
+ if (renderArray)
287
+ updateData = data[renderArray][0]
288
+ if (renderKey)
289
+ updateData = {[renderKey]: updateData}
244
290
  text = that.__replaceValue(updateData, textContent, renderKey, valueType);
245
291
  }
246
- if (!text) {
292
+ if (!placeholder && !text) {
247
293
  textContent = el.textContent;
248
- that.renderMap(el, textContent, renderKey)
294
+ that.renderMap(el, textContent, renderArray, renderKey)
249
295
  text = that.__replaceValue(data, textContent, renderKey, valueType);
250
296
  }
251
297
 
252
- // let textContent = el.textContent;
253
- // let text = that.__replaceValue(data, textContent, renderKey, valueType);
254
298
  if (text || text == "") {
255
- if (valueType == 'text' || valueType == 'string'){
256
- el.textContent = text;
257
- } else {
258
- const newNode = document.createElement('div');
259
- newNode.innerHTML = text;
260
- let parentElement = el.parentElement
261
- if (!parentElement.renderMap) {
262
- that.renderMap(parentElement, textContent, renderKey)
263
- } else if (!parentElement['renderMap'].has(parentElement))
264
- that.renderMap(parentElement, textContent, renderKey)
265
- el.replaceWith(...newNode.childNodes)
299
+ if (text != el.renderedValue) {
300
+ el.renderedValue = text
301
+ if (valueType == 'text' || valueType == 'string'){
302
+ el.renderedValue = text
303
+ el.textContent = text;
304
+ } else {
305
+ const newNode = document.createElement('div');
306
+ newNode.innerHTML = text;
307
+ let parentElement = el.parentElement
308
+ parentElement.renderedValue = text
309
+ if (!parentElement.renderMap) {
310
+ that.renderMap(parentElement, textContent, renderArray, renderKey)
311
+ } else if (!parentElement['renderMap'].has(parentElement))
312
+ that.renderMap(parentElement, textContent, renderArray, renderKey)
313
+ el.replaceWith(...newNode.childNodes)
314
+ }
266
315
  }
267
316
  }
268
317
  }
269
318
  });
270
319
  },
271
320
 
272
- renderMap: function(node, placeholder, renderKey) {
321
+ renderMap: function(node, placeholder, renderArray, renderKey) {
273
322
  if (!node.renderMap) {
274
323
  node['renderMap'] = new Map();
275
324
  }
276
325
  if (placeholder && renderKey)
277
- node['renderMap'].set(node, {placeholder, renderKey})
326
+ node['renderMap'].set(node, {placeholder, renderArray, renderKey})
278
327
  },
279
328
 
280
329
  dataOriginal: {},
281
330
  data: function({selector, data, elements}) {
282
- this.dataOriginal = data;
331
+ this.dataOriginal = {...data};
332
+ delete this.dataOriginal.data
333
+
283
334
  if (selector) {
284
335
  let template = queryDocumentSelector(selector);
285
336
  if (!template) return;
337
+ template.dataOriginal = {...data}
286
338
  if (template.classList.contains('template')) {
287
339
  this.render(template, data);
288
340
  }
289
341
  else
290
342
  this.setValue([template], data);
291
343
  } else if (elements) {
292
- if (elements.length == 1 && elements[0].classList.contains('template'))
344
+ for (let element of elements)
345
+ element.dataOriginal = {...this.dataOriginal};
346
+
347
+ if (elements.length == 1 && elements[0].classList.contains('template')){
293
348
  this.render(elements[0], data);
349
+ }
294
350
  else
295
351
  this.setValue(elements, data);
296
352
  }
@@ -321,4 +377,79 @@ action.init({
321
377
  }
322
378
  });
323
379
 
380
+ observer.init({
381
+ name: 'render',
382
+ observe: ['addedNodes'],
383
+ target: '[render]',
384
+ callback: function(mutation) {
385
+ let element = mutation.target
386
+ element.removeAttribute('render')
387
+
388
+ let parentElement = element.parentElement
389
+ if (parentElement) {
390
+ let el = element
391
+ let parentKeys = [];
392
+ let renderData = new Map();
393
+ do {
394
+ let data;
395
+ el = el.parentElement
396
+ if (el) {
397
+ if (el.dataOriginal)
398
+ renderData.set(el.dataOriginal, '')
399
+ if (el.hasAttribute('render-clone'))
400
+ data = el.renderData
401
+ if (data)
402
+ renderData.set(data, '')
403
+
404
+ let parentKey = el.getAttribute('parentKey')
405
+ if(parentKey && parentKey != null) {
406
+ if (/^\d+$/.test(parentKey))
407
+ parentKey = `[${parentKey}]`
408
+ parentKeys.push(parentKey)
409
+ }
410
+ }
411
+ } while (el)
412
+
413
+ let renderKey = element.getAttribute('render-key')
414
+
415
+ let parentKey;
416
+ parentKey = parentElement.getAttribute('parentKey')
417
+ if(renderKey == '$auto' || parentKey || parentKeys) {
418
+ let template = element.outerHTML
419
+ if (renderKey) {
420
+ template = template.replace(/\$auto/g, uuid.generate(6));
421
+ }
422
+ if (parentKeys.length > 0) {
423
+ let string = ''
424
+ if (parentKeys.length == 1){
425
+ string = parentKeys[0]
426
+ }
427
+ else
428
+ string = parentKeys.reverse().join('.')
429
+ string = string.replace(/.\[/g, '[');
430
+ template = template.replace(/\$parents/g, string);
431
+ }
432
+ if (parentKey) {
433
+ template = template.replace(/\$parent/g, parentKey);
434
+ }
435
+
436
+ parentElement.innerHTML = template
437
+
438
+ }
439
+
440
+ element = parentElement.firstElementChild
441
+ let obj = {}
442
+ let array = Array.from(renderData.keys())
443
+ for (let data of array.reverse()){
444
+ obj = {...obj, ...data}
445
+ }
446
+
447
+ CoCreateRender.data({
448
+ elements: [element],
449
+ data: obj
450
+ });
451
+ }
452
+ }
453
+ });
454
+
324
455
  export default CoCreateRender;