@schukai/monster 3.19.0 → 3.21.0

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schukai/monster",
3
- "version": "3.19.0",
3
+ "version": "3.21.0",
4
4
  "description": "Monster is a simple library for creating fast, robust and lightweight websites.",
5
5
  "keywords": [
6
6
  "framework",
@@ -186,33 +186,33 @@ function transform(value) {
186
186
  case "tolowercase":
187
187
  validateString(value);
188
188
  return value.toLowerCase();
189
-
189
+
190
190
  case "contains":
191
191
  if (isString(value)) {
192
- return value.includes(args[0]);
192
+ return value.includes(args[0]);
193
193
  }
194
-
194
+
195
195
  if (isArray(value)) {
196
196
  return value.includes(args[0]);
197
197
  }
198
-
198
+
199
199
  if (isObject(value)) {
200
200
  return value.hasOwnProperty(args[0]);
201
201
  }
202
-
202
+
203
+ return false;
204
+
205
+ case "has-entries":
206
+ case "hasentries":
207
+ if (isObject(value)) {
208
+ return Object.keys(value).length > 0;
209
+ }
210
+
211
+ if (isArray(value)) {
212
+ return value.length > 0;
213
+ }
214
+
203
215
  return false;
204
-
205
- case "has-entries":
206
- case "hasentries":
207
- if (isObject(value)) {
208
- return Object.keys(value).length > 0;
209
- }
210
-
211
- if (isArray(value)) {
212
- return value.length > 0;
213
- }
214
-
215
- return false;
216
216
 
217
217
  case "isundefined":
218
218
  case "is-undefined":
@@ -576,7 +576,45 @@ function transform(value) {
576
576
 
577
577
  return map.get(value);
578
578
 
579
- case "money":
579
+ case "equals":
580
+
581
+ if (args.length === 0) {
582
+ throw new Error("missing value parameter");
583
+ }
584
+
585
+ validatePrimitive(value);
586
+
587
+ const equalsValue = args.shift();
588
+
589
+ /**
590
+ * The history of “typeof null”
591
+ * https://2ality.com/2013/10/typeof-null.html
592
+ * In JavaScript, typeof null is 'object', which incorrectly suggests
593
+ * that null is an object.
594
+ */
595
+ if (value === null) {
596
+ if (equalsValue === "null") {
597
+ return true;
598
+ }
599
+ return false;
600
+ }
601
+
602
+ const typeOfValue = typeof value;
603
+
604
+ switch (typeOfValue) {
605
+ case "string":
606
+ return value === equalsValue;
607
+ case "number":
608
+ return value === parseFloat(equalsValue);
609
+ case "boolean":
610
+ return value === (equalsValue === "true" || equalsValue === "on");
611
+ case "undefined":
612
+ return equalsValue === "undefined";
613
+ default:
614
+ throw new Error("type not supported");
615
+ }
616
+
617
+ case "money":
580
618
  case "currency":
581
619
 
582
620
  try {
@@ -584,24 +622,24 @@ function transform(value) {
584
622
  } catch (e) {
585
623
  throw new Error("unsupported locale or missing format (" + e.message + ")");
586
624
  }
587
-
625
+
588
626
  const currency = value.substring(0, 3);
589
- if(!currency) {
627
+ if (!currency) {
590
628
  throw new Error("missing currency parameter");
591
629
  }
592
-
630
+
593
631
  const maximumFractionDigits = args?.[0] || 2;
594
632
  const roundingIncrement = args?.[1] || 5;
595
-
633
+
596
634
  const nf = new Intl.NumberFormat(locale, {
597
635
  style: "currency",
598
636
  currency: currency,
599
637
  maximumFractionDigits: maximumFractionDigits,
600
638
  roundingIncrement: roundingIncrement,
601
639
  });
602
-
640
+
603
641
  return nf.format(value.substring(3));
604
-
642
+
605
643
  case "timestamp":
606
644
  date = new Date(value);
607
645
  timestamp = date.getTime();
@@ -637,7 +675,7 @@ function transform(value) {
637
675
  } catch (e) {
638
676
  throw new Error("unsupported locale or missing format (" + e.message + ")");
639
677
  }
640
-
678
+
641
679
  case "date":
642
680
  date = new Date(value);
643
681
  if (isNaN(date.getTime())) {
@@ -651,7 +689,7 @@ function transform(value) {
651
689
  } catch (e) {
652
690
  throw new Error("unsupported locale or missing format (" + e.message + ")");
653
691
  }
654
-
692
+
655
693
 
656
694
  case "year":
657
695
  date = new Date(value);
@@ -16,6 +16,7 @@ export {
16
16
  ATTRIBUTE_UPDATER_SELECT_THIS,
17
17
  ATTRIBUTE_UPDATER_REPLACE,
18
18
  ATTRIBUTE_UPDATER_INSERT,
19
+ ATTRIBUTE_UPDATER_INSERT_TEMPLATE_ID,
19
20
  ATTRIBUTE_UPDATER_INSERT_REFERENCE,
20
21
  ATTRIBUTE_UPDATER_REMOVE,
21
22
  ATTRIBUTE_UPDATER_BIND,
@@ -142,6 +143,14 @@ const ATTRIBUTE_UPDATER_REPLACE = `${ATTRIBUTE_PREFIX}replace`;
142
143
  */
143
144
  const ATTRIBUTE_UPDATER_INSERT = `${ATTRIBUTE_PREFIX}insert`;
144
145
 
146
+ /**
147
+ * @memberOf Monster.DOM
148
+ * @type {string}
149
+ * @license AGPLv3
150
+ * @since 3.21.0
151
+ */
152
+ const ATTRIBUTE_UPDATER_INSERT_TEMPLATE_ID = `${ATTRIBUTE_UPDATER_INSERT}-template-id`;
153
+
145
154
  /**
146
155
  * @memberOf Monster.DOM
147
156
  * @type {string}
@@ -5,10 +5,10 @@
5
5
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
6
  */
7
7
 
8
- import { internalSymbol } from "../constants.mjs";
9
- import { diff } from "../data/diff.mjs";
10
- import { Pathfinder } from "../data/pathfinder.mjs";
11
- import { Pipe } from "../data/pipe.mjs";
8
+ import {internalSymbol} from "../constants.mjs";
9
+ import {diff} from "../data/diff.mjs";
10
+ import {Pathfinder} from "../data/pathfinder.mjs";
11
+ import {Pipe} from "../data/pipe.mjs";
12
12
  import {
13
13
  ATTRIBUTE_ERRORMESSAGE,
14
14
  ATTRIBUTE_UPDATER_ATTRIBUTES,
@@ -18,22 +18,21 @@ import {
18
18
  ATTRIBUTE_UPDATER_REMOVE,
19
19
  ATTRIBUTE_UPDATER_REPLACE,
20
20
  ATTRIBUTE_UPDATER_SELECT_THIS,
21
- customElementUpdaterLinkSymbol,
21
+ ATTRIBUTE_UPDATER_INSERT_TEMPLATE_ID
22
22
  } from "../dom/constants.mjs";
23
23
 
24
- import { Base } from "../types/base.mjs";
25
- import { isArray, isInstance, isIterable } from "../types/is.mjs";
26
- import { Observer } from "../types/observer.mjs";
27
- import { ProxyObserver } from "../types/proxyobserver.mjs";
28
- import { validateArray, validateInstance } from "../types/validate.mjs";
29
- import { clone } from "../util/clone.mjs";
30
- import { trimSpaces } from "../util/trimspaces.mjs";
31
- import { addToObjectLink } from "./attributes.mjs";
32
- import { findTargetElementFromEvent } from "./events.mjs";
33
- import { findDocumentTemplate } from "./template.mjs";
34
- import { getDocument } from "./util.mjs";
24
+ import {Base} from "../types/base.mjs";
25
+ import {isArray, isInstance, isIterable} from "../types/is.mjs";
26
+ import {Observer} from "../types/observer.mjs";
27
+ import {ProxyObserver} from "../types/proxyobserver.mjs";
28
+ import {validateArray, validateInstance} from "../types/validate.mjs";
29
+ import {clone} from "../util/clone.mjs";
30
+ import {trimSpaces} from "../util/trimspaces.mjs";
31
+ import {addToObjectLink} from "./attributes.mjs";
32
+ import {findTargetElementFromEvent} from "./events.mjs";
33
+ import {findDocumentTemplate} from "./template.mjs";
35
34
 
36
- export { Updater, addObjectWithUpdaterToElement };
35
+ export {Updater, addObjectWithUpdaterToElement};
37
36
 
38
37
  /**
39
38
  * The updater class connects an object with the dom. In this way, structures and contents in the DOM can be programmatically adapted via attributes.
@@ -174,7 +173,7 @@ class Updater extends Base {
174
173
  run() {
175
174
  // the key __init__has no further meaning and is only
176
175
  // used to create the diff for empty objects.
177
- this[internalSymbol].last = { __init__: true };
176
+ this[internalSymbol].last = {__init__: true};
178
177
  return this[internalSymbol].subject.notifyObservers();
179
178
  }
180
179
 
@@ -323,7 +322,7 @@ function retrieveAndSetValue(element) {
323
322
 
324
323
  let options = element?.selectedOptions;
325
324
  if (options === undefined) options = element.querySelectorAll(":scope option:checked");
326
- value = Array.from(options).map(({ value }) => value);
325
+ value = Array.from(options).map(({value}) => value);
327
326
 
328
327
  break;
329
328
  }
@@ -400,7 +399,6 @@ function removeElement(change) {
400
399
  function insertElement(change) {
401
400
  const self = this;
402
401
  const subject = self[internalSymbol].subject.getRealSubject();
403
- const document = getDocument();
404
402
 
405
403
  let mem = new WeakSet();
406
404
  let wd = 0;
@@ -516,6 +514,30 @@ function insertElement(change) {
516
514
  }
517
515
  }
518
516
 
517
+ function findTemplate(container, key, ref, path) {
518
+
519
+ let templateID = key;
520
+ let template;
521
+
522
+ if (container.hasAttribute(ATTRIBUTE_UPDATER_INSERT_TEMPLATE_ID)) {
523
+ templateID = container.getAttribute(ATTRIBUTE_UPDATER_INSERT_TEMPLATE_ID);
524
+ template = findDocumentTemplate(templateID, container);
525
+ if (template instanceof HTMLTemplateElement) {
526
+ return template;
527
+ }
528
+ }
529
+
530
+ if (container.closest(`[${ATTRIBUTE_UPDATER_INSERT_TEMPLATE_ID}]`)) {
531
+ templateID = container.closest(`[${ATTRIBUTE_UPDATER_INSERT_TEMPLATE_ID}]`).getAttribute(ATTRIBUTE_UPDATER_INSERT_TEMPLATE_ID);
532
+ template = findDocumentTemplate(templateID, container);
533
+ if (template instanceof HTMLTemplateElement) {
534
+ return template;
535
+ }
536
+ }
537
+
538
+ return findDocumentTemplate(templateID, container);
539
+ }
540
+
519
541
  /**
520
542
  *
521
543
  * @private
@@ -528,8 +550,9 @@ function insertElement(change) {
528
550
  * @throws {Error} no template was found with the specified key.
529
551
  */
530
552
  function appendNewDocumentFragment(container, key, ref, path) {
531
- let template = findDocumentTemplate(key, container);
532
553
 
554
+ let template = findTemplate(container, key, ref, path);
555
+ console.log(template);
533
556
  let nodes = template.createDocumentFragment();
534
557
  for (const [, node] of Object.entries(nodes.childNodes)) {
535
558
  if (node instanceof HTMLElement) {
@@ -142,7 +142,7 @@ function getMonsterVersion() {
142
142
  }
143
143
 
144
144
  /** don't touch, replaced by make with package.json version */
145
- monsterVersion = new Version("3.19.0");
145
+ monsterVersion = new Version("3.21.0");
146
146
 
147
147
  return monsterVersion;
148
148
  }
@@ -28,6 +28,26 @@ describe('Transformer', function () {
28
28
  describe('Transformer.run()', function () {
29
29
 
30
30
  [
31
+ ['equals:a', "a", true],
32
+ ['equals:a', "b", false],
33
+ ['equals:3', 3, true],
34
+ ['equals:3', 6, false],
35
+ ['equals:on', true, true],
36
+ ['equals:true', true, true],
37
+ ['equals:on', false, false],
38
+ ['equals:true', false, false],
39
+ ['equals:off', false, true],
40
+ ['equals:false', false, true],
41
+ ['equals:off', false, true],
42
+ ['equals:false', true, false],
43
+ ['equals:3', 3, true],
44
+ ['equals:3', 6, false],
45
+ ['equals:undefined', undefined, true],
46
+ ['equals:undefined', 3, false],
47
+ ['equals:null', null, true],
48
+ ['equals:null', 3, false],
49
+ ['equals:3', 6, false],
50
+ ['currency', "EUR0", "0,00 €"],
31
51
  ['currency:1:2', "EUR14.25", "14,2 €"],
32
52
  ['currency', "EUR14.25", "14,25 €"],
33
53
  ['datetime', "2023-02-14 14:12:10", "14.2.2023, 14:12:10"],
@@ -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.19.0")
10
+ monsterVersion = new Version("3.21.0")
11
11
 
12
12
  let m = getMonsterVersion();
13
13