@cocreate/elements 1.46.0 → 2.0.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/.github/FUNDING.yml +1 -1
- package/.github/workflows/automated.yml +18 -7
- package/CHANGELOG.md +753 -700
- package/CONTRIBUTING.md +6 -6
- package/README.md +469 -46
- package/demo/index.html +1 -1
- package/docs/index.html +7 -7
- package/package.json +12 -11
- package/src/crudHandler.js +153 -47
- package/src/dataHandler.js +7 -0
- package/src/dataObject.js +54 -0
- package/src/formHandler.js +226 -170
- package/src/formSelectors.js +1 -0
- package/src/getDataHandler.js +97 -94
- package/src/hrefHandler.js +104 -0
- package/src/iframeHandler.js +90 -0
- package/src/index.js +446 -12
- package/src/initHandler.js +96 -46
- package/src/mapRegistry.js +10 -1
- package/src/setDataHandler.js +171 -87
- package/src/socketHandler.js +328 -0
- package/src/socketSelectors.js +3 -0
- package/src/srcHandler.js +69 -32
- package/src/subscribeHandler.js +64 -64
- package/src/valueQuery.js +3 -4
- package/src/valueQuerySelector.js +1 -0
- package/test/deferred-src.test.cjs +11 -0
- package/test/form-enter.test.cjs +48 -0
- package/test/get-data.test.cjs +100 -0
- package/test/href-handler.test.cjs +132 -0
- package/test/init-read.test.cjs +145 -0
- package/test/lazy-loading.test.cjs +168 -0
- package/test/load-more.test.cjs +19 -0
- package/test/save-array.test.cjs +31 -0
- package/test/save-completion.test.cjs +36 -0
- package/test/set-data-type.test.cjs +119 -0
- package/test/ssr-response.test.cjs +108 -0
- package/webpack.config.js +1 -0
- package/src/dndHandler.js +0 -155
package/src/index.js
CHANGED
|
@@ -19,35 +19,469 @@
|
|
|
19
19
|
* Commercial Licensing Information:
|
|
20
20
|
* For commercial use of this software without the copyleft provisions of the AGPLv3,
|
|
21
21
|
* you must obtain a commercial license from CoCreate LLC.
|
|
22
|
-
* For details, visit <https://
|
|
22
|
+
* For details, visit <https://CoCreateJS.com/licenses/> or contact us at sales@CoCreateJS.com.
|
|
23
23
|
*/
|
|
24
24
|
import {
|
|
25
25
|
getAttributes
|
|
26
26
|
} from "@cocreate/utils";
|
|
27
|
-
import
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
import "./
|
|
35
|
-
import "./
|
|
36
|
-
import "./valueQuery.js";
|
|
27
|
+
import Observer from "@cocreate/observer";
|
|
28
|
+
import { getDataObject } from "./dataObject.js";
|
|
29
|
+
import {
|
|
30
|
+
socketActionSelector,
|
|
31
|
+
socketOnSelector,
|
|
32
|
+
socketStatusSelector
|
|
33
|
+
} from "./socketSelectors.js";
|
|
34
|
+
import { formSelector } from "./formSelectors.js";
|
|
35
|
+
import { valueQuerySelector } from "./valueQuerySelector.js";
|
|
37
36
|
|
|
38
37
|
import { elements, forms, keys, debounce } from "./mapRegistry.js"
|
|
39
38
|
|
|
39
|
+
let hrefHandlerLoading;
|
|
40
|
+
let dataHandlerLoading;
|
|
41
|
+
let srcHandlerLoading;
|
|
42
|
+
let socketHandlerLoading;
|
|
43
|
+
let formHandlerLoading;
|
|
44
|
+
let iframeHandlerLoading;
|
|
45
|
+
let valueQueryHandlerLoading;
|
|
46
|
+
const socketSelectors = [socketOnSelector, socketStatusSelector, socketActionSelector].join(", ");
|
|
47
|
+
|
|
48
|
+
if (document.clickedElement === undefined) {
|
|
49
|
+
document.clickedElement = null;
|
|
50
|
+
document.addEventListener("click", event => {
|
|
51
|
+
document.clickedElement = event.target;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const hrefSelector = "[href], [target]";
|
|
56
|
+
const dataSelector = "[storage], [database], [array], [render-json]";
|
|
57
|
+
const srcSelector = "img, [src], [source], [stream]";
|
|
58
|
+
|
|
59
|
+
function loadHrefHandler() {
|
|
60
|
+
if (!hrefHandlerLoading) {
|
|
61
|
+
hrefHandlerLoading = import(/* webpackChunkName: "elements-href-handler" */ "./hrefHandler.js")
|
|
62
|
+
.catch(error => {
|
|
63
|
+
hrefHandlerLoading = undefined;
|
|
64
|
+
throw error;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
hrefHandlerLoading.catch(error => console.error("CoCreate: unable to load href handler.", error));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function loadDataHandler() {
|
|
71
|
+
if (!dataHandlerLoading) {
|
|
72
|
+
dataHandlerLoading = import(/* webpackChunkName: "elements-data-handler" */ "./dataHandler.js")
|
|
73
|
+
.catch(error => {
|
|
74
|
+
dataHandlerLoading = undefined;
|
|
75
|
+
throw error;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return dataHandlerLoading;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function initializeDataHandler() {
|
|
82
|
+
loadDataHandler().catch(error => console.error("CoCreate: unable to load data handler.", error));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function loadSrcHandler() {
|
|
86
|
+
if (!srcHandlerLoading) {
|
|
87
|
+
srcHandlerLoading = import(/* webpackChunkName: "elements-src-handler" */ "./srcHandler.js")
|
|
88
|
+
.catch(error => {
|
|
89
|
+
srcHandlerLoading = undefined;
|
|
90
|
+
throw error;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
srcHandlerLoading.catch(error => console.error("CoCreate: unable to load source handler.", error));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function loadIframeHandler() {
|
|
97
|
+
if (!iframeHandlerLoading) {
|
|
98
|
+
iframeHandlerLoading = import(/* webpackChunkName: "elements-iframe-handler" */ "./iframeHandler.js")
|
|
99
|
+
.catch(error => {
|
|
100
|
+
iframeHandlerLoading = undefined;
|
|
101
|
+
throw error;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
iframeHandlerLoading.catch(error => console.error("CoCreate: unable to load iframe handler.", error));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function loadValueQueryHandler() {
|
|
108
|
+
if (!valueQueryHandlerLoading) {
|
|
109
|
+
valueQueryHandlerLoading = import(/* webpackChunkName: "elements-value-query" */ "./valueQuery.js")
|
|
110
|
+
.catch(error => {
|
|
111
|
+
valueQueryHandlerLoading = undefined;
|
|
112
|
+
throw error;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
valueQueryHandlerLoading.catch(error => console.error("CoCreate: unable to load value query handler.", error));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function loadFormHandler() {
|
|
119
|
+
if (!formHandlerLoading) {
|
|
120
|
+
formHandlerLoading = import(/* webpackChunkName: "elements-form-handler" */ "./formHandler.js")
|
|
121
|
+
.catch(error => {
|
|
122
|
+
formHandlerLoading = undefined;
|
|
123
|
+
throw error;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return formHandlerLoading;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function initializeFormHandler() {
|
|
130
|
+
loadFormHandler().catch(error => console.error("CoCreate: unable to load form handler.", error));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function usesSocket(element) {
|
|
134
|
+
if (element.matches(socketOnSelector) || element.matches(socketStatusSelector)) return true;
|
|
135
|
+
return (element.getAttribute("actions") || "").split(",").some(action =>
|
|
136
|
+
action.trim().split("(", 1)[0].trim() === "send"
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function loadSocketHandler(element) {
|
|
141
|
+
if (!usesSocket(element)) return;
|
|
142
|
+
if (!socketHandlerLoading) {
|
|
143
|
+
socketHandlerLoading = import(/* webpackChunkName: "elements-socket-handler" */ "./socketHandler.js")
|
|
144
|
+
.catch(error => {
|
|
145
|
+
socketHandlerLoading = undefined;
|
|
146
|
+
throw error;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
socketHandlerLoading.catch(error => {
|
|
150
|
+
element.dispatchEvent(new CustomEvent("socketerror", {
|
|
151
|
+
bubbles: true, detail: { error, element }
|
|
152
|
+
}));
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
Observer.init([
|
|
157
|
+
{
|
|
158
|
+
name: "CoCreateElementsHrefLoaderAddedNodes",
|
|
159
|
+
types: ["addedNodes"],
|
|
160
|
+
selector: hrefSelector,
|
|
161
|
+
callback: loadHrefHandler
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "CoCreateElementsHrefLoaderAttributes",
|
|
165
|
+
types: ["attributes"],
|
|
166
|
+
attributeFilter: ["href", "target"],
|
|
167
|
+
selector: hrefSelector,
|
|
168
|
+
callback: loadHrefHandler
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: "CoCreateElementsDataLoaderAddedNodes",
|
|
172
|
+
types: ["addedNodes"],
|
|
173
|
+
selector: dataSelector,
|
|
174
|
+
callback: initializeDataHandler
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "CoCreateElementsDataLoaderAttributes",
|
|
178
|
+
types: ["attributes"],
|
|
179
|
+
attributeFilter: ["storage", "database", "array", "render-json"],
|
|
180
|
+
selector: dataSelector,
|
|
181
|
+
callback: initializeDataHandler
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "CoCreateElementsSrcLoaderAddedNodes",
|
|
185
|
+
types: ["addedNodes"],
|
|
186
|
+
selector: srcSelector,
|
|
187
|
+
callback: loadSrcHandler
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "CoCreateElementsSrcLoaderAttributes",
|
|
191
|
+
types: ["attributes"],
|
|
192
|
+
attributeFilter: ["src", "source", "stream"],
|
|
193
|
+
selector: srcSelector,
|
|
194
|
+
callback: loadSrcHandler
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "CoCreateElementsActionLoaderAddedNodes",
|
|
198
|
+
types: ["addedNodes"],
|
|
199
|
+
selector: "[actions]",
|
|
200
|
+
callback: mutation => loadActionHandler(mutation.target)
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: "CoCreateElementsActionLoaderAttributes",
|
|
204
|
+
types: ["attributes"],
|
|
205
|
+
attributeFilter: ["actions"],
|
|
206
|
+
selector: "[actions]",
|
|
207
|
+
callback: mutation => loadActionHandler(mutation.target)
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: "CoCreateElementsFormLoader",
|
|
211
|
+
types: ["addedNodes"],
|
|
212
|
+
selector: formSelector,
|
|
213
|
+
callback: initializeFormHandler
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: "CoCreateElementsSocketLoaderAddedNodes",
|
|
217
|
+
types: ["addedNodes"],
|
|
218
|
+
selector: socketSelectors,
|
|
219
|
+
callback: mutation => loadSocketHandler(mutation.target)
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: "CoCreateElementsSocketLoaderAttributes",
|
|
223
|
+
types: ["attributes"],
|
|
224
|
+
attributeFilter: ["socket-on", "socket-status", "actions"],
|
|
225
|
+
selector: socketSelectors,
|
|
226
|
+
callback: mutation => loadSocketHandler(mutation.target)
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
name: "CoCreateElementsIframeLoader",
|
|
230
|
+
types: ["addedNodes"],
|
|
231
|
+
selector: "iframe",
|
|
232
|
+
callback: loadIframeHandler
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "CoCreateElementsValueQueryLoaderAddedNodes",
|
|
236
|
+
types: ["addedNodes"],
|
|
237
|
+
selector: valueQuerySelector,
|
|
238
|
+
callback: loadValueQueryHandler
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: "CoCreateElementsValueQueryLoaderAttributes",
|
|
242
|
+
types: ["attributes"],
|
|
243
|
+
attributeFilter: ["value-query"],
|
|
244
|
+
selector: valueQuerySelector,
|
|
245
|
+
callback: loadValueQueryHandler
|
|
246
|
+
}
|
|
247
|
+
]);
|
|
248
|
+
|
|
249
|
+
function loadActionHandler(element) {
|
|
250
|
+
const actions = (element.getAttribute("actions") || "").split(",");
|
|
251
|
+
for (const action of actions) {
|
|
252
|
+
const name = action.trim().split("(", 1)[0].trim();
|
|
253
|
+
if (name === "save" || name === "delete") initializeDataHandler();
|
|
254
|
+
if (name === "reset") initializeFormHandler();
|
|
255
|
+
if (name === "disableHref" || name === "enableHref") loadHrefHandler();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
document.querySelectorAll("[actions]").forEach(loadActionHandler);
|
|
260
|
+
if (document.querySelector(hrefSelector)) loadHrefHandler();
|
|
261
|
+
if (document.querySelector(dataSelector)) initializeDataHandler();
|
|
262
|
+
if (document.querySelector(srcSelector)) loadSrcHandler();
|
|
263
|
+
document.querySelectorAll(socketSelectors).forEach(loadSocketHandler);
|
|
264
|
+
if (document.querySelector(formSelector)) initializeFormHandler();
|
|
265
|
+
if (document.querySelector("iframe")) loadIframeHandler();
|
|
266
|
+
if (document.querySelector(valueQuerySelector)) loadValueQueryHandler();
|
|
267
|
+
|
|
268
|
+
// Preserve the asynchronous public APIs while loading their implementation on demand.
|
|
269
|
+
const callDataHandler = (name, args) => loadDataHandler().then(module => module[name](...args));
|
|
270
|
+
/**
|
|
271
|
+
*
|
|
272
|
+
* @public
|
|
273
|
+
* @environment client
|
|
274
|
+
*/
|
|
275
|
+
const init = (...args) => callDataHandler("init", args);
|
|
276
|
+
/**
|
|
277
|
+
*
|
|
278
|
+
* @public
|
|
279
|
+
* @environment client
|
|
280
|
+
*/
|
|
281
|
+
const read = (...args) => callDataHandler("read", args);
|
|
282
|
+
/**
|
|
283
|
+
*
|
|
284
|
+
* @public
|
|
285
|
+
* @environment client
|
|
286
|
+
*/
|
|
287
|
+
const save = (...args) => callDataHandler("save", args);
|
|
288
|
+
/**
|
|
289
|
+
*
|
|
290
|
+
* @public
|
|
291
|
+
* @environment client
|
|
292
|
+
*/
|
|
293
|
+
const getData = (...args) => callDataHandler("getData", args);
|
|
294
|
+
/**
|
|
295
|
+
*
|
|
296
|
+
* @public
|
|
297
|
+
* @environment client
|
|
298
|
+
*/
|
|
299
|
+
const setDataType = (...args) => callDataHandler("setDataType", args);
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
*
|
|
303
|
+
* @public
|
|
304
|
+
* @environment client
|
|
305
|
+
*/
|
|
306
|
+
export function reset(action) {
|
|
307
|
+
return loadFormHandler().then(module => module.reset(action));
|
|
308
|
+
}
|
|
309
|
+
|
|
40
310
|
export default {
|
|
41
311
|
init,
|
|
42
312
|
read,
|
|
43
313
|
save,
|
|
44
314
|
getData,
|
|
315
|
+
/**
|
|
316
|
+
*
|
|
317
|
+
* @public
|
|
318
|
+
* @environment client
|
|
319
|
+
*/
|
|
45
320
|
getDataObject,
|
|
46
321
|
reset,
|
|
322
|
+
/**
|
|
323
|
+
*
|
|
324
|
+
* @public
|
|
325
|
+
* @environment client
|
|
326
|
+
*/
|
|
47
327
|
elements,
|
|
328
|
+
/**
|
|
329
|
+
*
|
|
330
|
+
* @public
|
|
331
|
+
* @environment client
|
|
332
|
+
*/
|
|
48
333
|
keys,
|
|
334
|
+
/**
|
|
335
|
+
*
|
|
336
|
+
* @public
|
|
337
|
+
* @environment client
|
|
338
|
+
*/
|
|
49
339
|
forms,
|
|
340
|
+
/**
|
|
341
|
+
*
|
|
342
|
+
* @public
|
|
343
|
+
* @environment client
|
|
344
|
+
*/
|
|
50
345
|
debounce,
|
|
346
|
+
/**
|
|
347
|
+
*
|
|
348
|
+
* @public
|
|
349
|
+
* @environment client
|
|
350
|
+
*/
|
|
51
351
|
getAttributes,
|
|
52
352
|
setDataType
|
|
53
|
-
};
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
*
|
|
357
|
+
* @name actions
|
|
358
|
+
* @kind member
|
|
359
|
+
* @attribute
|
|
360
|
+
* @environment client
|
|
361
|
+
*/
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
*
|
|
365
|
+
* @name array
|
|
366
|
+
* @kind member
|
|
367
|
+
* @attribute
|
|
368
|
+
* @environment client
|
|
369
|
+
*/
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
*
|
|
373
|
+
* @name database
|
|
374
|
+
* @kind member
|
|
375
|
+
* @attribute
|
|
376
|
+
* @environment client
|
|
377
|
+
*/
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
*
|
|
381
|
+
* @name href
|
|
382
|
+
* @kind member
|
|
383
|
+
* @attribute
|
|
384
|
+
* @environment client
|
|
385
|
+
*/
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
*
|
|
389
|
+
* @name render-json
|
|
390
|
+
* @kind member
|
|
391
|
+
* @attribute
|
|
392
|
+
* @environment client
|
|
393
|
+
*/
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
*
|
|
397
|
+
* @name socket-on
|
|
398
|
+
* @kind member
|
|
399
|
+
* @attribute
|
|
400
|
+
* @environment client
|
|
401
|
+
*/
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
*
|
|
405
|
+
* @name socket-status
|
|
406
|
+
* @kind member
|
|
407
|
+
* @attribute
|
|
408
|
+
* @environment client
|
|
409
|
+
*/
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
*
|
|
413
|
+
* @name source
|
|
414
|
+
* @kind member
|
|
415
|
+
* @attribute
|
|
416
|
+
* @environment client
|
|
417
|
+
*/
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
*
|
|
421
|
+
* @name src
|
|
422
|
+
* @kind member
|
|
423
|
+
* @attribute
|
|
424
|
+
* @environment client
|
|
425
|
+
*/
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
*
|
|
429
|
+
* @name storage
|
|
430
|
+
* @kind member
|
|
431
|
+
* @attribute
|
|
432
|
+
* @environment client
|
|
433
|
+
*/
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
*
|
|
437
|
+
* @name stream
|
|
438
|
+
* @kind member
|
|
439
|
+
* @attribute
|
|
440
|
+
* @environment client
|
|
441
|
+
*/
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
*
|
|
445
|
+
* @name target
|
|
446
|
+
* @kind member
|
|
447
|
+
* @attribute
|
|
448
|
+
* @environment client
|
|
449
|
+
*/
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
*
|
|
453
|
+
* @name value-query
|
|
454
|
+
* @kind member
|
|
455
|
+
* @attribute
|
|
456
|
+
* @environment client
|
|
457
|
+
*/
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* 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
|
|
461
|
+
*
|
|
462
|
+
* @module elements
|
|
463
|
+
* @environment client
|
|
464
|
+
*/
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Declarative selectors recognized by this module.
|
|
468
|
+
*
|
|
469
|
+
* @name declarative-selectors
|
|
470
|
+
* @kind member
|
|
471
|
+
* @selectors
|
|
472
|
+
* @environment client
|
|
473
|
+
* @example
|
|
474
|
+
* ```json
|
|
475
|
+
* [
|
|
476
|
+
* "[actions]",
|
|
477
|
+
* "iframe",
|
|
478
|
+
* "[href], [target]",
|
|
479
|
+
* "[storage], [database], [array], [render-json]",
|
|
480
|
+
* "img, [src], [source], [stream]",
|
|
481
|
+
* "[value-query]",
|
|
482
|
+
* "form, fieldset",
|
|
483
|
+
* "[socket-on]",
|
|
484
|
+
* "[socket-status]"
|
|
485
|
+
* ]
|
|
486
|
+
* ```
|
|
487
|
+
*/
|