@schukai/monster 3.102.5 → 3.103.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 +49 -0
- package/package.json +1 -1
- package/source/components/datatable/dataset.mjs +1 -1
- package/source/components/datatable/filter/select.mjs +3 -3
- package/source/components/datatable/filter.mjs +21 -2
- package/source/components/datatable/save-button.mjs +1 -0
- package/source/components/form/select.mjs +2221 -2193
- package/source/dom/customcontrol.mjs +318 -321
- package/source/dom/updater.mjs +146 -89
- package/source/types/version.mjs +1 -1
- package/test/cases/monster.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +503 -456
package/source/dom/updater.mjs
CHANGED
@@ -29,20 +29,33 @@ import {
|
|
29
29
|
} from "./constants.mjs";
|
30
30
|
|
31
31
|
import {Base} from "../types/base.mjs";
|
32
|
-
import {isArray, isString, isInstance, isIterable} from "../types/is.mjs";
|
32
|
+
import {isArray, isInteger, isString, isInstance, isIterable} from "../types/is.mjs";
|
33
33
|
import {Observer} from "../types/observer.mjs";
|
34
34
|
import {ProxyObserver} from "../types/proxyobserver.mjs";
|
35
35
|
import {validateArray, validateInstance} from "../types/validate.mjs";
|
36
36
|
import {clone} from "../util/clone.mjs";
|
37
37
|
import {trimSpaces} from "../util/trimspaces.mjs";
|
38
38
|
import {addAttributeToken, addToObjectLink} from "./attributes.mjs";
|
39
|
-
import {
|
39
|
+
import {
|
40
|
+
CustomElement,
|
41
|
+
updaterTransformerMethodsSymbol,
|
42
|
+
} from "./customelement.mjs";
|
40
43
|
import {findTargetElementFromEvent} from "./events.mjs";
|
41
44
|
import {findDocumentTemplate} from "./template.mjs";
|
42
45
|
import {getWindow} from "./util.mjs";
|
46
|
+
import {DeadMansSwitch} from "../util/deadmansswitch.mjs";
|
47
|
+
import {addErrorAttribute, removeErrorAttribute} from "./error.mjs";
|
48
|
+
|
43
49
|
|
44
50
|
export {Updater, addObjectWithUpdaterToElement};
|
45
51
|
|
52
|
+
|
53
|
+
/**
|
54
|
+
* @private
|
55
|
+
* @type {symbol}
|
56
|
+
*/
|
57
|
+
const timerElementEventHandlerSymbol = Symbol("timerElementEventHandler");
|
58
|
+
|
46
59
|
/**
|
47
60
|
* The updater class connects an object with the DOM. In this way, structures and contents in the DOM can be
|
48
61
|
* programmatically adapted via attributes.
|
@@ -306,11 +319,20 @@ function getControlEventHandler() {
|
|
306
319
|
return;
|
307
320
|
}
|
308
321
|
|
309
|
-
|
322
|
+
if (this[timerElementEventHandlerSymbol] instanceof DeadMansSwitch) {
|
323
|
+
try {
|
324
|
+
this[timerElementEventHandlerSymbol].touch();
|
325
|
+
return;
|
326
|
+
} catch (e) {
|
327
|
+
delete this[timerElementEventHandlerSymbol];
|
328
|
+
}
|
329
|
+
}
|
330
|
+
|
331
|
+
this[timerElementEventHandlerSymbol] = new DeadMansSwitch(50, () => {
|
310
332
|
try {
|
311
333
|
retrieveAndSetValue.call(this, element);
|
312
334
|
} catch (e) {
|
313
|
-
|
335
|
+
addErrorAttribute(element, e);
|
314
336
|
}
|
315
337
|
});
|
316
338
|
};
|
@@ -380,62 +402,109 @@ function retrieveAndSetValue(element) {
|
|
380
402
|
throw new Error("unsupported object");
|
381
403
|
}
|
382
404
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
405
|
+
const type = element.getAttribute(ATTRIBUTE_UPDATER_BIND_TYPE);
|
406
|
+
switch (type) {
|
407
|
+
case "number":
|
408
|
+
case "int":
|
409
|
+
case "float":
|
410
|
+
case "integer":
|
411
|
+
value = Number(value);
|
412
|
+
if (isNaN(value)) {
|
413
|
+
value = 0;
|
414
|
+
}
|
415
|
+
break;
|
416
|
+
case "boolean":
|
417
|
+
case "bool":
|
418
|
+
case "checkbox":
|
419
|
+
value = value === "true" || value === "1" || value === "on" || value === true;
|
420
|
+
break;
|
421
|
+
|
422
|
+
case "string[]":
|
423
|
+
if (isString(value)) {
|
424
|
+
|
425
|
+
if (value.trim() === "") {
|
426
|
+
value = [];
|
427
|
+
} else {
|
428
|
+
value = value.split(",").map((v) => `${v}`);
|
393
429
|
}
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
430
|
+
} else if (isInteger(value)) {
|
431
|
+
value = [`${value}`];
|
432
|
+
} else if (value === undefined || value === null) {
|
433
|
+
value = [];
|
434
|
+
} else if (isArray(value)) {
|
435
|
+
value = value.map((v) => `${v}`);
|
436
|
+
} else {
|
437
|
+
throw new Error("unsupported value");
|
438
|
+
}
|
439
|
+
|
440
|
+
break;
|
400
441
|
|
401
|
-
|
402
|
-
|
442
|
+
case "int[]":
|
443
|
+
case "integer[]":
|
444
|
+
|
445
|
+
if (isString(value)) {
|
446
|
+
|
447
|
+
if (value.trim() === "") {
|
403
448
|
value = [];
|
449
|
+
} else {
|
450
|
+
value = value.split(",").map((v) => {
|
451
|
+
try {
|
452
|
+
return parseInt(v, 10);
|
453
|
+
} catch (e) {
|
454
|
+
}
|
455
|
+
return -1;
|
456
|
+
}).filter((v) => v !== -1);
|
404
457
|
}
|
405
458
|
|
406
|
-
|
407
|
-
|
459
|
+
} else if (isInteger(value)) {
|
460
|
+
value = [value];
|
461
|
+
} else if (value === undefined || value === null) {
|
462
|
+
value = [];
|
463
|
+
} else if (isArray(value)) {
|
464
|
+
value = value.split(",").map((v) => {
|
465
|
+
try {
|
466
|
+
return parseInt(v, 10);
|
467
|
+
} catch (e) {
|
468
|
+
}
|
469
|
+
return -1;
|
470
|
+
}).filter((v) => v !== -1);
|
471
|
+
} else {
|
472
|
+
throw new Error("unsupported value");
|
473
|
+
}
|
474
|
+
|
475
|
+
break;
|
476
|
+
case "[]":
|
477
|
+
case "array":
|
478
|
+
case "list":
|
408
479
|
|
409
|
-
|
410
|
-
|
411
|
-
if (value === "") {
|
480
|
+
if (isString(value)) {
|
481
|
+
if (value.trim() === "") {
|
412
482
|
value = [];
|
413
483
|
} else {
|
414
|
-
value = value
|
415
|
-
.split(",")
|
416
|
-
.map((v) => {
|
417
|
-
try {
|
418
|
-
return parseInt(v, 10);
|
419
|
-
} catch (e) {
|
420
|
-
}
|
421
|
-
return -1;
|
422
|
-
})
|
423
|
-
.filter((v) => v !== -1);
|
484
|
+
value = value.split(",");
|
424
485
|
}
|
486
|
+
} else if (isInteger(value)) {
|
487
|
+
value = [value];
|
488
|
+
} else if (value === undefined || value === null) {
|
489
|
+
value = [];
|
490
|
+
} else if (isArray(value)) {
|
491
|
+
// nothing to do
|
492
|
+
} else {
|
493
|
+
throw new Error("unsupported value for array");
|
494
|
+
}
|
495
|
+
break;
|
496
|
+
case "object":
|
497
|
+
case "json":
|
425
498
|
|
426
|
-
|
427
|
-
case "[]":
|
428
|
-
case "array":
|
429
|
-
case "list":
|
430
|
-
value = value.split(",");
|
431
|
-
break;
|
432
|
-
case "object":
|
433
|
-
case "json":
|
499
|
+
if (isString(value)) {
|
434
500
|
value = JSON.parse(value);
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
501
|
+
} else {
|
502
|
+
throw new Error("unsupported value for object");
|
503
|
+
}
|
504
|
+
|
505
|
+
break;
|
506
|
+
default:
|
507
|
+
break;
|
439
508
|
}
|
440
509
|
|
441
510
|
const copy = clone(this[internalSymbol].subject.getRealSubject());
|
@@ -558,7 +627,7 @@ function insertElement(change) {
|
|
558
627
|
containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
|
559
628
|
value = pipe.run(subject);
|
560
629
|
} catch (e) {
|
561
|
-
containerElement
|
630
|
+
addErrorAttribute(containerElement, e);
|
562
631
|
}
|
563
632
|
|
564
633
|
const dataPath = cmd.split(":").pop();
|
@@ -604,12 +673,7 @@ function insertElement(change) {
|
|
604
673
|
try {
|
605
674
|
containerElement.removeChild(node);
|
606
675
|
} catch (e) {
|
607
|
-
containerElement
|
608
|
-
ATTRIBUTE_ERRORMESSAGE,
|
609
|
-
`${containerElement.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${
|
610
|
-
e.message
|
611
|
-
}`.trim(),
|
612
|
-
);
|
676
|
+
addErrorAttribute(containerElement, e);
|
613
677
|
}
|
614
678
|
}
|
615
679
|
}
|
@@ -660,27 +724,32 @@ function appendNewDocumentFragment(container, key, ref, path) {
|
|
660
724
|
* @return {void}
|
661
725
|
*/
|
662
726
|
function applyRecursive(node, key, path) {
|
663
|
-
if (node instanceof HTMLElement) {
|
664
|
-
|
665
|
-
|
666
|
-
node.setAttribute(
|
667
|
-
ATTRIBUTE_UPDATER_REPLACE,
|
668
|
-
value.replaceAll(`path:${key}`, `path:${path}`),
|
669
|
-
);
|
670
|
-
}
|
727
|
+
if (!(node instanceof HTMLElement)) {
|
728
|
+
return
|
729
|
+
}
|
671
730
|
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
731
|
+
if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) {
|
732
|
+
const value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
|
733
|
+
node.setAttribute(
|
734
|
+
ATTRIBUTE_UPDATER_REPLACE,
|
735
|
+
value.replaceAll(`path:${key}`, `path:${path}`),
|
736
|
+
);
|
737
|
+
}
|
679
738
|
|
680
|
-
|
739
|
+
if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
|
740
|
+
const value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
|
741
|
+
node.setAttribute(
|
742
|
+
ATTRIBUTE_UPDATER_ATTRIBUTES,
|
743
|
+
value.replaceAll(`path:${key}`, `path:${path}`),
|
744
|
+
);
|
745
|
+
}
|
746
|
+
|
747
|
+
for (const [, child] of Object.entries(node.childNodes)) {
|
748
|
+
if (child instanceof HTMLElement) {
|
681
749
|
applyRecursive(child, key, path);
|
682
750
|
}
|
683
751
|
}
|
752
|
+
|
684
753
|
}
|
685
754
|
|
686
755
|
/**
|
@@ -768,12 +837,7 @@ function runUpdateContent(container, parts, subject) {
|
|
768
837
|
try {
|
769
838
|
element.appendChild(value);
|
770
839
|
} catch (e) {
|
771
|
-
element
|
772
|
-
ATTRIBUTE_ERRORMESSAGE,
|
773
|
-
`${element.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${
|
774
|
-
e.message
|
775
|
-
}`.trim(),
|
776
|
-
);
|
840
|
+
addErrorAttribute(element, e);
|
777
841
|
}
|
778
842
|
} else {
|
779
843
|
element.innerHTML = value;
|
@@ -854,7 +918,7 @@ function runUpdateAttributes(container, parts, subject) {
|
|
854
918
|
element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
|
855
919
|
value = pipe.run(subject);
|
856
920
|
} catch (e) {
|
857
|
-
element
|
921
|
+
addErrorAttribute(element, e);
|
858
922
|
}
|
859
923
|
|
860
924
|
if (value === undefined) {
|
@@ -879,7 +943,6 @@ function runUpdateAttributes(container, parts, subject) {
|
|
879
943
|
*/
|
880
944
|
|
881
945
|
function handleInputControlAttributeUpdate(element, name, value) {
|
882
|
-
|
883
946
|
if (element instanceof HTMLSelectElement) {
|
884
947
|
switch (element.type) {
|
885
948
|
case "select-multiple":
|
@@ -920,7 +983,6 @@ function handleInputControlAttributeUpdate(element, name, value) {
|
|
920
983
|
element.value = value === undefined ? "" : value;
|
921
984
|
}
|
922
985
|
break;
|
923
|
-
|
924
986
|
}
|
925
987
|
} else if (element instanceof HTMLTextAreaElement) {
|
926
988
|
if (name === "value") {
|
@@ -979,18 +1041,13 @@ function addObjectWithUpdaterToElement(elements, symbol, object, config = {}) {
|
|
979
1041
|
if (typeof callback === "function") {
|
980
1042
|
updaterCallbacks.push([name, callback]);
|
981
1043
|
} else {
|
982
|
-
|
983
|
-
this,
|
984
|
-
ATTRIBUTE_ERRORMESSAGE,
|
985
|
-
`onUpdaterPipeCallbacks: ${name} is not a function`,
|
986
|
-
);
|
1044
|
+
addErrorAttribute(this, `onUpdaterPipeCallbacks: ${name} is not a function`);
|
987
1045
|
}
|
988
1046
|
}
|
989
1047
|
} else {
|
990
|
-
|
1048
|
+
addErrorAttribute(
|
991
1049
|
this,
|
992
|
-
|
993
|
-
`onUpdaterPipeCallbacks do not return an object with functions`,
|
1050
|
+
`onUpdaterPipeCallbacks do not return an object with functions`
|
994
1051
|
);
|
995
1052
|
}
|
996
1053
|
}
|
package/source/types/version.mjs
CHANGED
package/test/cases/monster.mjs
CHANGED
package/test/web/test.html
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
</head>
|
10
10
|
<body>
|
11
11
|
<div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
|
12
|
-
<h1 style='margin-bottom: 0.1em;'>Monster 3.102.
|
13
|
-
<div id="lastupdate" style='font-size:0.7em'>last update
|
12
|
+
<h1 style='margin-bottom: 0.1em;'>Monster 3.102.6</h1>
|
13
|
+
<div id="lastupdate" style='font-size:0.7em'>last update So 2. Feb 23:18:18 CET 2025</div>
|
14
14
|
</div>
|
15
15
|
<div id="mocha-errors"
|
16
16
|
style="color: red;font-weight: bold;display: flex;align-items: center;justify-content: center;flex-direction: column;margin:20px;"></div>
|