@cocreate/elements 1.36.2 → 1.37.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 +23 -0
- package/package.json +1 -1
- package/src/fetchSrc.js +4 -3
- package/src/form.js +37 -24
- package/src/index.js +33 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
## [1.37.1](https://github.com/CoCreate-app/CoCreate-elements/compare/v1.37.0...v1.37.1) (2024-11-02)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* checkValue(key) prior to excutuing element.setValue() ([8234c96](https://github.com/CoCreate-app/CoCreate-elements/commit/8234c96ff445b7a9bbc4d7171c07ae1b189fb9ee))
|
|
7
|
+
* element.getValue() ([7009f70](https://github.com/CoCreate-app/CoCreate-elements/commit/7009f70d7a18d0e79100da8c25788db1a1c4c2e2))
|
|
8
|
+
* handling contenteditable iframes ([11b6819](https://github.com/CoCreate-app/CoCreate-elements/commit/11b6819089e2b3ab2bbbcb47aa4f6134a036ad92))
|
|
9
|
+
* if form has attribute object set as empty on reset ([29c1b6d](https://github.com/CoCreate-app/CoCreate-elements/commit/29c1b6d469afbaecd8e760288961726a2d9cd49b))
|
|
10
|
+
* init if observer ol attribute value not the same as new ([456913c](https://github.com/CoCreate-app/CoCreate-elements/commit/456913c6d4a13279aad08a40732efd91e272add0))
|
|
11
|
+
* observer taget has been renamed to selector ([239974c](https://github.com/CoCreate-app/CoCreate-elements/commit/239974ca9316607f28ce9fa1440b18b4e60735a0))
|
|
12
|
+
* removed comsole.log ([d0b6fe3](https://github.com/CoCreate-app/CoCreate-elements/commit/d0b6fe314ab9532df479e955d243d3ef242bbc89))
|
|
13
|
+
* removed dead code ([3929b76](https://github.com/CoCreate-app/CoCreate-elements/commit/3929b76d6a7d5bd71b5973f3ff4b2a8061954d7a))
|
|
14
|
+
* removed test console.log ([4fea18d](https://github.com/CoCreate-app/CoCreate-elements/commit/4fea18d4f32c604b2666d92a384dce6bfe53dfc7))
|
|
15
|
+
* resetType support ([2ce141e](https://github.com/CoCreate-app/CoCreate-elements/commit/2ce141e832f97c8df7a68a7bdfc5206d98cf66da))
|
|
16
|
+
|
|
17
|
+
# [1.37.0](https://github.com/CoCreate-app/CoCreate-elements/compare/v1.36.2...v1.37.0) (2024-09-21)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* update="" attribute support. improved data type handling ([fa478b0](https://github.com/CoCreate-app/CoCreate-elements/commit/fa478b008c85a78014f16f4800270af933767615))
|
|
23
|
+
|
|
1
24
|
## [1.36.2](https://github.com/CoCreate-app/CoCreate-elements/compare/v1.36.1...v1.36.2) (2024-08-24)
|
|
2
25
|
|
|
3
26
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/elements",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.37.1",
|
|
4
4
|
"description": "Fetch content into any html element by using html5 attributes to query data stored in CoCreate headless CMS. If data is changed it will instantly reflect in html tags as changes are broadcasted in realtime",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"elements",
|
package/src/fetchSrc.js
CHANGED
|
@@ -208,7 +208,7 @@ function base64ToArrayBuffer(base64) {
|
|
|
208
208
|
observer.init({
|
|
209
209
|
name: 'CoCreateSrc',
|
|
210
210
|
observe: ['addedNodes'],
|
|
211
|
-
|
|
211
|
+
selector: selector,
|
|
212
212
|
callback: function (mutation) {
|
|
213
213
|
init(mutation.target);
|
|
214
214
|
}
|
|
@@ -218,9 +218,10 @@ observer.init({
|
|
|
218
218
|
name: 'CoCreateSrcAttributes',
|
|
219
219
|
observe: ['attributes'],
|
|
220
220
|
attributeName: ['src'],
|
|
221
|
-
|
|
221
|
+
selector: selector,
|
|
222
222
|
callback: function (mutation) {
|
|
223
|
-
|
|
223
|
+
if (mutation.oldValue !== mutation.target.getAttribute(mutation.attributeName))
|
|
224
|
+
init(mutation.target);
|
|
224
225
|
}
|
|
225
226
|
});
|
|
226
227
|
|
package/src/form.js
CHANGED
|
@@ -23,7 +23,7 @@ function init(elements) {
|
|
|
23
23
|
Observer.init({
|
|
24
24
|
name: 'CoCreateFormElements',
|
|
25
25
|
observe: ['addedNodes'],
|
|
26
|
-
|
|
26
|
+
selector: '[storage], [database], [array], [index], [object], [key]',
|
|
27
27
|
callback: function (mutation) {
|
|
28
28
|
if (element == mutation.target.form)
|
|
29
29
|
setAttribute(element, [mutation.target])
|
|
@@ -74,8 +74,9 @@ function setAttribute(form, elements) {
|
|
|
74
74
|
if (variable) {
|
|
75
75
|
for (let el of elements) {
|
|
76
76
|
// Set the value of the attribute.
|
|
77
|
+
// TODO: skip-attribute naming convention, perhaps skip by defualt if storage, database, array not the same and use attribute to apply for cases where one _id will be used across 2 arrays
|
|
77
78
|
if (!el.getAttribute(attribute.name) && !el.hasAttribute('skip-attribute')) {
|
|
78
|
-
el.setAttribute(attribute.name,
|
|
79
|
+
el.setAttribute(attribute.name, attribute.value);
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
}
|
|
@@ -101,32 +102,44 @@ function disableAutoFill(element) {
|
|
|
101
102
|
* @param form
|
|
102
103
|
*/
|
|
103
104
|
function reset(form) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
for
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
// Convert the form elements collection to an array
|
|
106
|
+
const formElementsArray = Array.from(form.elements);
|
|
107
|
+
|
|
108
|
+
// Query for additional elements with [object] or [key] attributes that are not already part of form controls
|
|
109
|
+
const customElements = Array.from(form.querySelectorAll('[object], [key]:not(input):not(select):not(textarea):not(button)'));
|
|
110
|
+
|
|
111
|
+
// Merge form elements and custom elements using the spread operator
|
|
112
|
+
const allElements = [...formElementsArray, ...customElements];
|
|
113
|
+
|
|
114
|
+
// Store the elements and their values in a map for restoration
|
|
115
|
+
const elementStates = new Map();
|
|
116
|
+
|
|
117
|
+
// Iterate over all elements and store their current state based on the 'reset' attribute
|
|
118
|
+
for (const element of allElements) {
|
|
119
|
+
if (['BUTTON', 'FIELDSET'].includes(element.tagName))
|
|
120
|
+
continue
|
|
121
|
+
// Get the reset attribute value, if any
|
|
122
|
+
const resetType = element.getAttribute('reset');
|
|
123
|
+
if (element.hasAttribute('object') && (!resetType || resetType === 'object'))
|
|
111
124
|
element.setAttribute('object', '');
|
|
112
|
-
|
|
113
|
-
|
|
125
|
+
if (resetType === 'false' || resetType === 'object')
|
|
126
|
+
elementStates.set(element, element.getValue() || element.value || element.getAttribute('value'));
|
|
127
|
+
if (!resetType || resetType !== 'object')
|
|
114
128
|
element.setValue('')
|
|
115
129
|
}
|
|
116
130
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// Set the object id attribute of the element to the object id if it has not yet been set.
|
|
120
|
-
if (!formElements.has(element)) {
|
|
121
|
-
// Set object attribute to object if it exists
|
|
122
|
-
if (element.hasAttribute('object'))
|
|
123
|
-
element.setAttribute('object', '');
|
|
124
|
-
element.setValue('')
|
|
125
|
-
}
|
|
126
|
-
}
|
|
131
|
+
if (form.hasAttribute('object'))
|
|
132
|
+
form.setAttribute('object', '');
|
|
127
133
|
|
|
134
|
+
// Perform the default form reset
|
|
128
135
|
form.reset();
|
|
129
|
-
|
|
136
|
+
|
|
137
|
+
// Restore values based on the 'reset' attribute
|
|
138
|
+
elementStates.forEach((value, element) => {
|
|
139
|
+
element.setValue(value)
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Dispatch a custom reset event
|
|
130
143
|
document.dispatchEvent(new CustomEvent('reset', {
|
|
131
144
|
detail: {}
|
|
132
145
|
}));
|
|
@@ -152,7 +165,7 @@ function setValue(form) {
|
|
|
152
165
|
Observer.init({
|
|
153
166
|
name: 'CoCreateForm',
|
|
154
167
|
observe: ['addedNodes'],
|
|
155
|
-
|
|
168
|
+
selector: 'form',
|
|
156
169
|
callback: mutation => init(mutation.target)
|
|
157
170
|
});
|
|
158
171
|
|
|
@@ -160,7 +173,7 @@ Observer.init({
|
|
|
160
173
|
name: 'CoCreateForm',
|
|
161
174
|
observe: ['attributes'],
|
|
162
175
|
attributeName: getAttributeNames(['storage', 'database', 'array', 'object', 'index']),
|
|
163
|
-
|
|
176
|
+
selector: 'form',
|
|
164
177
|
callback: mutation => mutation.target.tagName === "FORM" &&
|
|
165
178
|
setAttribute(mutation.target)
|
|
166
179
|
});
|
package/src/index.js
CHANGED
|
@@ -85,8 +85,6 @@ async function init(element) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
async function initElement(el) {
|
|
88
|
-
// if (el.closest('.template')) return;
|
|
89
|
-
|
|
90
88
|
let data = getObject(el);
|
|
91
89
|
if (!data || !data.type)
|
|
92
90
|
return
|
|
@@ -97,14 +95,20 @@ async function initElement(el) {
|
|
|
97
95
|
if (!elements.has(el)) {
|
|
98
96
|
elements.set(el, '')
|
|
99
97
|
|
|
100
|
-
if (el.tagName === "EDITOR")
|
|
101
|
-
console.log('editor event added')
|
|
102
98
|
if (!el.elementsInputEvent) {
|
|
103
99
|
el.elementsInputEvent = true;
|
|
104
100
|
|
|
105
101
|
if (['INPUT', 'TEXTAREA', 'SELECT'].includes(el.tagName)
|
|
106
102
|
|| (el.hasAttribute('contenteditable') && el.getAttribute('contenteditable') !== 'false')
|
|
107
103
|
|| el.contenteditable) {
|
|
104
|
+
|
|
105
|
+
if (el.tagName == 'IFRAME') {
|
|
106
|
+
// ToDo: saving on contenteditable elements when an objectId does not exist in order to crud or crdt
|
|
107
|
+
el = el.contentDocument.documentElement
|
|
108
|
+
el.setAttribute('contenteditable', 'true')
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
108
112
|
el.addEventListener('input', function (e) {
|
|
109
113
|
if (el.pendingObject) return
|
|
110
114
|
|
|
@@ -121,6 +125,7 @@ async function initElement(el) {
|
|
|
121
125
|
}
|
|
122
126
|
// let attributes = ['filter-key', 'filter-search', 'filter-sort-key', 'filter-on', 'filter-limit']
|
|
123
127
|
// if (el.getFilter || attributes.some(attr => el.hasAttribute(attr))) {
|
|
128
|
+
|
|
124
129
|
await filter.init()
|
|
125
130
|
if (el.getFilter) {
|
|
126
131
|
data.$filter = await el.getFilter();
|
|
@@ -373,14 +378,14 @@ async function setData(element, data) {
|
|
|
373
378
|
let action = el.getAttribute('actions')
|
|
374
379
|
if (action && ['database', 'array', 'object', 'key'].includes(action)) continue;
|
|
375
380
|
|
|
376
|
-
const { key, isRead, isListen, isCrdt } = getAttributes(el);
|
|
381
|
+
const { key, isRead, isUpdate, isListen, isCrdt } = getAttributes(el);
|
|
377
382
|
if (el.getFilter || el.renderValue)
|
|
378
383
|
await filterData(el, data, type, key)
|
|
379
384
|
else {
|
|
380
385
|
if (!data[type] || !data[type].length)
|
|
381
386
|
continue;
|
|
382
387
|
|
|
383
|
-
if (key) {
|
|
388
|
+
if (key && checkValue(key)) {
|
|
384
389
|
let value
|
|
385
390
|
if (key.includes('$length')) {
|
|
386
391
|
value = CRUD.getValueFromObject(data[type][0], key.replace(/\.\$length$/, ''))
|
|
@@ -398,11 +403,10 @@ async function setData(element, data) {
|
|
|
398
403
|
}
|
|
399
404
|
|
|
400
405
|
if (!data[type].length) continue;
|
|
401
|
-
if (isRead
|
|
402
|
-
if (isListen
|
|
406
|
+
if (isRead === "false" || isCrdt === "true") continue;
|
|
407
|
+
if (isUpdate === "false" || isListen === "false" && !data.method.endsWith('.read')) continue;
|
|
403
408
|
// TODO: object.update data returned from server will not include $operator
|
|
404
409
|
el.setValue(value);
|
|
405
|
-
|
|
406
410
|
}
|
|
407
411
|
}
|
|
408
412
|
}
|
|
@@ -411,8 +415,7 @@ async function setData(element, data) {
|
|
|
411
415
|
async function filterData(element, data, type, key) {
|
|
412
416
|
let operator = '', value
|
|
413
417
|
|
|
414
|
-
|
|
415
|
-
if (key && !key.includes('$length')) {
|
|
418
|
+
if (key && !key.includes('$length') && key !== '{}') {
|
|
416
419
|
if (!data || !type) return
|
|
417
420
|
|
|
418
421
|
if (key.startsWith('$')) {
|
|
@@ -465,7 +468,6 @@ async function filterData(element, data, type, key) {
|
|
|
465
468
|
}
|
|
466
469
|
|
|
467
470
|
let isRendered = element.querySelector('[render-clone]');
|
|
468
|
-
|
|
469
471
|
if (operator) {
|
|
470
472
|
element.setValue(value);
|
|
471
473
|
} else if (element.renderValue && data.method && data.method.endsWith('.read') && data.$filter && (data.$filter.overwrite || !isRendered)) {
|
|
@@ -481,6 +483,8 @@ async function filterData(element, data, type, key) {
|
|
|
481
483
|
} else if (key && key.includes('$length')) {
|
|
482
484
|
let value = CRUD.getValueFromObject(data[type][0], key.replace(/\.\$length$/, ''))
|
|
483
485
|
element.setValue(value.length);
|
|
486
|
+
} else if (key === '{}') {
|
|
487
|
+
element.setValue(data[type])
|
|
484
488
|
} else if (data)
|
|
485
489
|
element.setValue(data)
|
|
486
490
|
|
|
@@ -527,7 +531,8 @@ async function checkFilters(element, data, type) {
|
|
|
527
531
|
// TODO: fix: getObject as this is related to render or form, but filter could exist on an input which does not have getObject
|
|
528
532
|
// TODO: generate an object of current element key: value to use with filter. because filter is used object is not defined
|
|
529
533
|
Data = getObject(element)
|
|
530
|
-
|
|
534
|
+
if (Array.isArray(Data[type]))
|
|
535
|
+
Data = Data[type][0]
|
|
531
536
|
} else
|
|
532
537
|
Data = await element.getData()
|
|
533
538
|
|
|
@@ -569,9 +574,20 @@ async function checkFilters(element, data, type) {
|
|
|
569
574
|
primaryKey = 'name';
|
|
570
575
|
}
|
|
571
576
|
|
|
572
|
-
if (
|
|
577
|
+
if (Array.isArray(newData)) {
|
|
578
|
+
for (let i = 0; i < newData.length; i++) {
|
|
579
|
+
if (typeof Data === 'string' && Data === newData[i][primaryKey]) {
|
|
580
|
+
Data = newData[i]
|
|
581
|
+
} else if (Data[primaryKey] === newData[i][primaryKey]) {
|
|
582
|
+
Data = dotNotationToObject(newData[i], Data)
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
} else if (typeof Data === 'string' && Data === newData[primaryKey]) {
|
|
586
|
+
Data = newData
|
|
587
|
+
} else if (Data[primaryKey] === newData[primaryKey]) {
|
|
573
588
|
Data = dotNotationToObject(newData, Data)
|
|
574
589
|
}
|
|
590
|
+
|
|
575
591
|
if (element.renderValue)
|
|
576
592
|
element.renderValue(data);
|
|
577
593
|
// render({ element, data, key: type });
|
|
@@ -1165,7 +1181,7 @@ function initSocket() {
|
|
|
1165
1181
|
Observer.init({
|
|
1166
1182
|
name: 'render',
|
|
1167
1183
|
observe: ['addedNodes'],
|
|
1168
|
-
|
|
1184
|
+
selector: '[render-clone]',
|
|
1169
1185
|
callback: function (mutation) {
|
|
1170
1186
|
if (!mutation.parentElement.hasAttribute('dnd'))
|
|
1171
1187
|
return
|
|
@@ -1315,7 +1331,7 @@ function dndCrudSend(data, crudType) {
|
|
|
1315
1331
|
Observer.init({
|
|
1316
1332
|
name: 'CoCreateElementsChildList',
|
|
1317
1333
|
observe: ['childList'],
|
|
1318
|
-
|
|
1334
|
+
selector: selector,
|
|
1319
1335
|
callback: function (mutation) {
|
|
1320
1336
|
init(mutation.addedNodes);
|
|
1321
1337
|
}
|
|
@@ -1324,7 +1340,7 @@ Observer.init({
|
|
|
1324
1340
|
Observer.init({
|
|
1325
1341
|
name: 'CoCreateElementsRemovedNodes',
|
|
1326
1342
|
observe: ['removedNodes'],
|
|
1327
|
-
|
|
1343
|
+
selector: selector,
|
|
1328
1344
|
callback: function (mutation) {
|
|
1329
1345
|
// if (mutation.target.parentElement) return
|
|
1330
1346
|
// if (mutation.target.parentElement) {
|