@schukai/monster 3.96.1 → 3.96.3

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +20 -5
  2. package/package.json +1 -1
  3. package/source/components/datatable/change-button.mjs +39 -41
  4. package/source/components/datatable/dataset.mjs +335 -325
  5. package/source/components/datatable/datasource/rest.mjs +33 -29
  6. package/source/components/datatable/embedded-pagination.mjs +3 -1
  7. package/source/components/datatable/filter.mjs +164 -63
  8. package/source/components/datatable/pagination.mjs +13 -6
  9. package/source/components/datatable/save-button.mjs +25 -3
  10. package/source/components/datatable/status.mjs +21 -26
  11. package/source/components/datatable/style/status.pcss +12 -2
  12. package/source/components/datatable/stylesheet/status.mjs +1 -1
  13. package/source/components/datatable/util.mjs +1 -2
  14. package/source/components/form/form.mjs +5 -4
  15. package/source/components/form/select.mjs +2008 -2013
  16. package/source/components/form/style/field-set.pcss +28 -7
  17. package/source/components/form/style/toggle-switch.pcss +13 -2
  18. package/source/components/form/stylesheet/field-set.mjs +14 -7
  19. package/source/components/form/stylesheet/toggle-switch.mjs +14 -7
  20. package/source/components/form/toggle-switch.mjs +372 -380
  21. package/source/components/layout/tabs.mjs +1 -2
  22. package/source/constants.mjs +14 -1
  23. package/source/data/extend.mjs +2 -1
  24. package/source/data/transformer.mjs +2 -0
  25. package/source/dom/constants.mjs +0 -1
  26. package/source/dom/customelement.mjs +7 -3
  27. package/source/dom/updater.mjs +5 -1
  28. package/source/monster.mjs +1 -1
  29. package/source/text/formatter.mjs +5 -3
  30. package/source/types/is.mjs +13 -0
  31. package/source/types/proxyobserver.mjs +7 -2
  32. package/source/types/version.mjs +1 -1
  33. package/source/util/clone.mjs +9 -14
  34. package/test/cases/data/pathfinder.mjs +18 -0
  35. package/test/cases/monster.mjs +1 -1
  36. package/test/cases/text/formatter.mjs +21 -1
  37. package/test/web/test.html +2 -2
  38. package/test/web/tests.js +266 -176
@@ -921,8 +921,7 @@ function initTabButtons() {
921
921
  this.setOption("marker", random());
922
922
 
923
923
  return adjustButtonVisibility.call(this).then(() => {
924
-
925
- if (!activeReference&& this.getOption("features.openFirst") === true) {
924
+ if (!activeReference && this.getOption("features.openFirst") === true) {
926
925
  const firstButton = this.getOption("buttons.standard").find(
927
926
  (button) => button.disabled !== true,
928
927
  );
@@ -12,7 +12,12 @@
12
12
  * SPDX-License-Identifier: AGPL-3.0
13
13
  */
14
14
 
15
- export { internalSymbol, internalStateSymbol, instanceSymbol };
15
+ export {
16
+ internalSymbol,
17
+ internalStateSymbol,
18
+ instanceSymbol,
19
+ proxyInstanceMarker,
20
+ };
16
21
 
17
22
  /**
18
23
  * @private
@@ -35,3 +40,11 @@ const internalStateSymbol = Symbol.for("@schukai/monster/state");
35
40
  * @type {symbol}
36
41
  */
37
42
  const instanceSymbol = Symbol.for("@schukai/monster/instance");
43
+
44
+ /**
45
+ * @private
46
+ * @type {symbol}
47
+ */
48
+ const proxyInstanceMarker = Symbol.for(
49
+ "@schukai/monster/proxy-instance-marker",
50
+ );
@@ -53,7 +53,8 @@ function extend(...args) {
53
53
  for (const k in a) {
54
54
  const v = a?.[k];
55
55
 
56
- if (v === o?.[k]) {
56
+ if (k in o && v === o?.[k]) {
57
+ // k in o is for the case of undefined
57
58
  continue;
58
59
  }
59
60
 
@@ -265,9 +265,11 @@ function transform(value) {
265
265
  validateString(value);
266
266
  return value.toUpperCase();
267
267
 
268
+ case "to-string":
268
269
  case "tostring":
269
270
  return `${value}`;
270
271
 
272
+ case "to-integer":
271
273
  case "tointeger":
272
274
  const n = parseInt(value);
273
275
  validateInteger(n);
@@ -216,7 +216,6 @@ const ATTRIBUTE_FORM_BIND = `${ATTRIBUTE_PREFIX}form-bind`;
216
216
  */
217
217
  const ATTRIBUTE_FORM_BIND_TYPE = `${ATTRIBUTE_PREFIX}form-bind-type`;
218
218
 
219
-
220
219
  /**
221
220
  * @type {string}
222
221
  * @license AGPLv3
@@ -610,9 +610,13 @@ class CustomElement extends HTMLElement {
610
610
  nodeList = elements;
611
611
  }
612
612
 
613
- this[updateCloneDataSymbol] = clone(
614
- this[internalSymbol].getRealSubject()["options"],
615
- );
613
+ try {
614
+ this[updateCloneDataSymbol] = clone(
615
+ this[internalSymbol].getRealSubject()["options"],
616
+ );
617
+ } catch (e) {
618
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e?.messages || `${e}`);
619
+ }
616
620
 
617
621
  const cfg = {};
618
622
  if (this.getOption("eventProcessing") === true) {
@@ -307,7 +307,11 @@ function getControlEventHandler() {
307
307
  }
308
308
 
309
309
  queueMicrotask(() => {
310
- retrieveAndSetValue.call(this, element);
310
+ try {
311
+ retrieveAndSetValue.call(this, element);
312
+ } catch (e) {
313
+ addAttributeToken(element, ATTRIBUTE_ERRORMESSAGE, e.message || `${e}`);
314
+ }
311
315
  });
312
316
  };
313
317
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
2
+ * Copyright © schukai GmbH and all contributing authors, 2025. All rights reserved.
3
3
  * Node module: @schukai/monster
4
4
  *
5
5
  * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
@@ -276,7 +276,10 @@ function format(text) {
276
276
  * @private
277
277
  * @license AGPLv3
278
278
  * @since 1.12.0
279
- * @param text
279
+ *
280
+ * @param {string} text
281
+ * @param {string} openMarker
282
+ * @param {string} closeMarker
280
283
  * @return {string}
281
284
  */
282
285
  function tokenize(text, openMarker, closeMarker) {
@@ -339,7 +342,7 @@ function tokenize(text, openMarker, closeMarker) {
339
342
  const t1 = key.split("|").shift().trim(); // pipe symbol
340
343
  const t2 = t1.split("::").shift().trim(); // key value delimiter
341
344
  const t3 = t2.split(".").shift().trim(); // path delimiter
342
- const prefix = this[workingDataSymbol]?.[t3] ? "path:" : "static:";
345
+ const prefix = t3 in this[workingDataSymbol] ? "path:" : "static:";
343
346
 
344
347
  let command = "";
345
348
  if (
@@ -362,7 +365,6 @@ function tokenize(text, openMarker, closeMarker) {
362
365
  }
363
366
 
364
367
  formatted.push(validateString(pipe.run(this[workingDataSymbol])));
365
-
366
368
  text = text.substring(endIndex + closeMarker.length);
367
369
  }
368
370
 
@@ -12,6 +12,8 @@
12
12
  * SPDX-License-Identifier: AGPL-3.0
13
13
  */
14
14
 
15
+ import { proxyInstanceMarker } from "../constants.mjs";
16
+
15
17
  export {
16
18
  isIterable,
17
19
  isPrimitive,
@@ -23,8 +25,19 @@ export {
23
25
  isArray,
24
26
  isFunction,
25
27
  isInteger,
28
+ isProxy,
26
29
  };
27
30
 
31
+ /**
32
+ * Checks whether the value passed is a Proxy.
33
+ *
34
+ * @param {*} value
35
+ * @returns {boolean}
36
+ */
37
+ function isProxy(value) {
38
+ return value?.[proxyInstanceMarker] === proxyInstanceMarker;
39
+ }
40
+
28
41
  /**
29
42
  * With this function you can check if a value is iterable.
30
43
  *
@@ -18,7 +18,7 @@ import { Observer } from "./observer.mjs";
18
18
  import { ObserverList } from "./observerlist.mjs";
19
19
  import { validateObject } from "./validate.mjs";
20
20
  import { extend } from "../data/extend.mjs";
21
- import { instanceSymbol } from "../constants.mjs";
21
+ import { instanceSymbol, proxyInstanceMarker } from "../constants.mjs";
22
22
  import { clone } from "../util/clone.mjs";
23
23
  export { ProxyObserver };
24
24
 
@@ -74,7 +74,7 @@ class ProxyObserver extends Base {
74
74
  /**
75
75
  * @since 1.24.0
76
76
  * @param {Object} obj
77
- * @return {Monster.Types.ProxyObserver}
77
+ * @return {ProxyObserver}
78
78
  */
79
79
  setSubject(obj) {
80
80
  let i;
@@ -152,6 +152,11 @@ function getHandler() {
152
152
  const handler = {
153
153
  // https://262.ecma-international.org/9.0/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
154
154
  get: function (target, key, receiver) {
155
+ // this is an internal hack to identify proxy
156
+ if (key === proxyInstanceMarker) {
157
+ return proxyInstanceMarker;
158
+ }
159
+
155
160
  const value = Reflect.get(target, key, receiver);
156
161
 
157
162
  if (typeof key === "symbol") {
@@ -156,7 +156,7 @@ function getMonsterVersion() {
156
156
  }
157
157
 
158
158
  /** don't touch, replaced by make with package.json version */
159
- monsterVersion = new Version("3.95.2");
159
+ monsterVersion = new Version("3.96.2");
160
160
 
161
161
  return monsterVersion;
162
162
  }
@@ -13,7 +13,13 @@
13
13
  */
14
14
 
15
15
  import { getGlobal } from "../types/global.mjs";
16
- import { isArray, isFunction, isObject, isPrimitive } from "../types/is.mjs";
16
+ import {
17
+ isArray,
18
+ isFunction,
19
+ isObject,
20
+ isPrimitive,
21
+ isProxy,
22
+ } from "../types/is.mjs";
17
23
  import { typeOf } from "../types/typeof.mjs";
18
24
  import { validateObject } from "../types/validate.mjs";
19
25
 
@@ -71,8 +77,7 @@ function clone(obj) {
71
77
 
72
78
  /** Do not clone DOM nodes */
73
79
  if (typeof Element !== "undefined" && obj instanceof Element) return obj;
74
- if (typeof HTMLDocument !== "undefined" && obj instanceof HTMLDocument)
75
- return obj;
80
+ if (typeof Document !== "undefined" && obj instanceof Document) return obj;
76
81
  if (
77
82
  typeof DocumentFragment !== "undefined" &&
78
83
  obj instanceof DocumentFragment
@@ -81,21 +86,11 @@ function clone(obj) {
81
86
 
82
87
  /** Do not clone global objects */
83
88
  if (obj === getGlobal()) return obj;
84
- if (typeof globalContext !== "undefined" && obj === globalContext)
85
- return obj;
86
89
  if (typeof window !== "undefined" && obj === window) return obj;
87
90
  if (typeof document !== "undefined" && obj === document) return obj;
88
91
  if (typeof navigator !== "undefined" && obj === navigator) return obj;
89
92
  if (typeof JSON !== "undefined" && obj === JSON) return obj;
90
-
91
- // Handle Proxy-Object
92
- try {
93
- // try/catch because possible: TypeError: Function has non-object prototype 'undefined' in instanceof check
94
- if (obj instanceof Proxy) {
95
- return obj;
96
- }
97
- } catch (e) {}
98
-
93
+ if (isProxy(obj)) return obj; // Handle Proxy-Object
99
94
  return cloneObject(obj);
100
95
  }
101
96
 
@@ -22,6 +22,24 @@ describe('Pathfinder', function () {
22
22
  return r;
23
23
  }
24
24
 
25
+ describe("value is not an integer issue #274", function () {
26
+ it("should not be fail with", function () {
27
+
28
+ const pf = new Pathfinder({
29
+ data: {}
30
+ });
31
+
32
+ try {
33
+ pf.setVia("data.age", 10);
34
+ } catch (e) {
35
+ expect(e).to.be.null;
36
+ }
37
+
38
+ expect(pf.getVia("data.age")).to.be.equal(10);
39
+
40
+ });
41
+ });
42
+
25
43
 
26
44
  describe('with Wildcard and Iterations', function () {
27
45
  let pf, obj;
@@ -7,7 +7,7 @@ describe('Monster', function () {
7
7
  let monsterVersion
8
8
 
9
9
  /** don´t touch, replaced by make with package.json version */
10
- monsterVersion = new Version("3.95.2")
10
+ monsterVersion = new Version("3.96.2")
11
11
 
12
12
  let m = getMonsterVersion();
13
13
 
@@ -4,7 +4,27 @@ import {Formatter} from "../../../source/text/formatter.mjs";
4
4
 
5
5
  describe('Formatter', function () {
6
6
 
7
- // https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/47
7
+ // https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/275
8
+ describe('change empty handling', function () {
9
+
10
+ it('modification 1', function () {
11
+
12
+ const formatter = new Formatter({
13
+
14
+ a: null,
15
+ b: undefined,
16
+ c : 0
17
+
18
+
19
+ })
20
+
21
+ expect(formatter.format("${a | tostring}")).to.be.equal('null');
22
+ expect(formatter.format("${b | tostring}")).to.be.equal('undefined');
23
+ expect(formatter.format("${c | tostring}")).to.be.equal('0');
24
+ })
25
+ })
26
+
27
+ // https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/47
8
28
  describe('examples', function () {
9
29
 
10
30
  it('rfc example should run', function () {
@@ -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.95.2</h1>
13
- <div id="lastupdate" style='font-size:0.7em'>last update So 29. Dez 11:41:55 CET 2024</div>
12
+ <h1 style='margin-bottom: 0.1em;'>Monster 3.96.2</h1>
13
+ <div id="lastupdate" style='font-size:0.7em'>last update Fr 3. Jan 15:17:06 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>