@schukai/monster 2.2.1 → 3.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/README.md CHANGED
@@ -73,7 +73,7 @@ We do try to work around some browser bugs, but on the whole we don't use polyfi
73
73
  However, many functions can be mapped via [polyfill.io](https://polyfill.io/) and thus the compatibility can be increased.
74
74
 
75
75
  ```html
76
- <script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getOwnPropertySymbols,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet"
76
+ <script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet"
77
77
  crossorigin="anonymous"
78
78
  referrerpolicy="no-referrer"></script>
79
79
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schukai/monster",
3
- "version": "2.2.1",
3
+ "version": "3.0.0",
4
4
  "description": "Monster is a simple library for creating fast, robust and lightweight websites.",
5
5
  "keywords": [
6
6
  "framework",
@@ -59,6 +59,7 @@ export {
59
59
  ATTRIBUTE_EXPORTPARTS,
60
60
  ATTRIBUTE_HIDDEN,
61
61
  objectUpdaterLinkSymbol,
62
+ customElementUpdaterLinkSymbol
62
63
 
63
64
  }
64
65
 
@@ -223,6 +224,14 @@ const ATTRIBUTE_ERRORMESSAGE = ATTRIBUTE_PREFIX + 'error';
223
224
  */
224
225
  const objectUpdaterLinkSymbol = Symbol.for('@schukai/monster/dom/@@object-updater-link');
225
226
 
227
+ /**
228
+ * @memberOf Monster.DOM
229
+ * @type {symbol}
230
+ * @license AGPLv3
231
+ * @since 1.24.0
232
+ */
233
+ const customElementUpdaterLinkSymbol = Symbol.for('@schukai/monster/dom/custom-element@@options-updater-link');
234
+
226
235
  /**
227
236
  * @memberOf Monster.DOM
228
237
  * @type {string}
@@ -22,13 +22,20 @@ import {
22
22
  ATTRIBUTE_ERRORMESSAGE,
23
23
  ATTRIBUTE_OPTIONS,
24
24
  ATTRIBUTE_OPTIONS_SELECTOR,
25
- objectUpdaterLinkSymbol
25
+ customElementUpdaterLinkSymbol
26
26
  } from "./constants.mjs";
27
27
  import {findDocumentTemplate, Template} from "./template.mjs";
28
- import {Updater} from "./updater.mjs";
28
+ import {addObjectWithUpdaterToElement} from "./updater.mjs";
29
29
  import {instanceSymbol} from '../constants.mjs';
30
30
 
31
- export {CustomElement, initMethodSymbol, assembleMethodSymbol, attributeObserverSymbol, registerCustomElement, assignUpdaterToElement, getSlottedElements}
31
+ export {
32
+ CustomElement,
33
+ initMethodSymbol,
34
+ assembleMethodSymbol,
35
+ attributeObserverSymbol,
36
+ registerCustomElement,
37
+ getSlottedElements
38
+ }
32
39
 
33
40
  /**
34
41
  * @memberOf Monster.DOM
@@ -460,7 +467,8 @@ class CustomElement extends HTMLElement {
460
467
  nodeList = elements
461
468
  }
462
469
 
463
- assignUpdaterToElement.call(self, nodeList, clone(self[internalSymbol].getRealSubject()['options']));
470
+ addObjectWithUpdaterToElement.call(self, nodeList, customElementUpdaterLinkSymbol, clone(self[internalSymbol].getRealSubject()['options']))
471
+ //assignUpdaterToElement.call(self, nodeList, clone(self[internalSymbol].getRealSubject()['options']));
464
472
  return self;
465
473
  }
466
474
 
@@ -473,7 +481,7 @@ class CustomElement extends HTMLElement {
473
481
  */
474
482
  connectedCallback() {
475
483
  let self = this;
476
- if (!hasObjectLink(self, objectUpdaterLinkSymbol)) {
484
+ if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
477
485
  self[assembleMethodSymbol]()
478
486
  }
479
487
  }
@@ -673,11 +681,11 @@ function initOptionObserver() {
673
681
  self.attachObserver(new Observer(function () {
674
682
 
675
683
  // not initialised
676
- if (!hasObjectLink(self, objectUpdaterLinkSymbol)) {
684
+ if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) {
677
685
  return;
678
686
  }
679
687
  // inform every element
680
- const updaters = getLinkedObjects(self, objectUpdaterLinkSymbol);
688
+ const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol);
681
689
 
682
690
  for (const list of updaters) {
683
691
  for (const updater of list) {
@@ -935,44 +943,3 @@ function registerCustomElement(element) {
935
943
  getGlobalObject('customElements').define(element.getTag(), element);
936
944
  }
937
945
 
938
-
939
- /**
940
- *
941
- * @param element
942
- * @param object
943
- * @return {Promise[]}
944
- * @license AGPLv3
945
- * @since 1.23.0
946
- * @memberOf Monster.DOM
947
- */
948
- function assignUpdaterToElement(elements, object) {
949
-
950
- const updaters = new Set;
951
-
952
- if (elements instanceof NodeList) {
953
- elements = new Set([
954
- ...elements
955
- ])
956
- }
957
-
958
- let result = [];
959
-
960
- elements.forEach((element) => {
961
- if (!(element instanceof HTMLElement)) return;
962
- if ((element instanceof HTMLTemplateElement)) return;
963
-
964
- const u = new Updater(element, object)
965
- updaters.add(u);
966
-
967
- result.push(u.run().then(() => {
968
- return u.enableEventProcessing();
969
- }));
970
-
971
- });
972
-
973
- if (updaters.size > 0) {
974
- addToObjectLink(this, objectUpdaterLinkSymbol, updaters);
975
- }
976
-
977
- return result;
978
- }
@@ -17,7 +17,7 @@ import {
17
17
  ATTRIBUTE_UPDATER_INSERT_REFERENCE,
18
18
  ATTRIBUTE_UPDATER_REMOVE,
19
19
  ATTRIBUTE_UPDATER_REPLACE,
20
- ATTRIBUTE_UPDATER_SELECT_THIS
20
+ ATTRIBUTE_UPDATER_SELECT_THIS, customElementUpdaterLinkSymbol
21
21
  } from "../dom/constants.mjs";
22
22
 
23
23
  import {Base} from "../types/base.mjs";
@@ -27,11 +27,12 @@ import {ProxyObserver} from "../types/proxyobserver.mjs";
27
27
  import {validateArray, validateInstance} from "../types/validate.mjs";
28
28
  import {clone} from "../util/clone.mjs";
29
29
  import {trimSpaces} from "../util/trimspaces.mjs";
30
+ import {addToObjectLink} from "./attributes.mjs";
30
31
  import {findTargetElementFromEvent} from "./events.mjs";
31
32
  import {findDocumentTemplate} from "./template.mjs";
32
33
  import {getDocument} from "./util.mjs";
33
34
 
34
- export {Updater}
35
+ export {Updater, addObjectWithUpdaterToElement}
35
36
 
36
37
  /**
37
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.
@@ -252,7 +253,7 @@ function getCheckStateCallback() {
252
253
  /**
253
254
  * @private
254
255
  */
255
- const symbol = Symbol('EventHandler');
256
+ const symbol = Symbol('@schukai/monster/updater@@EventHandler');
256
257
 
257
258
  /**
258
259
  * @private
@@ -308,7 +309,7 @@ function retrieveAndSetValue(element) {
308
309
  throw new Error('the bind argument must start as a value with a path');
309
310
  }
310
311
 
311
- path = path.substr(5);
312
+ path = path.substring(5);
312
313
 
313
314
  let value;
314
315
 
@@ -525,8 +526,6 @@ function insertElement(change) {
525
526
  }
526
527
 
527
528
  }
528
-
529
-
530
529
  }
531
530
 
532
531
  /**
@@ -608,8 +607,6 @@ function updateContent(change) {
608
607
  }
609
608
  }
610
609
  }
611
-
612
-
613
610
  }
614
611
 
615
612
  /**
@@ -869,3 +866,64 @@ function handleInputControlAttributeUpdate(element, name, value) {
869
866
  }
870
867
 
871
868
  }
869
+
870
+
871
+
872
+ /**
873
+ * @param {NodeList|HTMLElement|Set<HTMLElement>} elements
874
+ * @param {Symbol} symbol
875
+ * @param {object} object
876
+ * @return {Promise[]}
877
+ * @license AGPLv3
878
+ * @since 1.23.0
879
+ * @memberOf Monster.DOM
880
+ * @throws {TypeError} elements is not an instance of NodeList, HTMLElement or Set
881
+ * @throws {TypeError} the context of the function is not an instance of HTMLElement
882
+ * @throws {TypeError} symbol must be an instance of Symbol
883
+ */
884
+ function addObjectWithUpdaterToElement (elements,symbol, object) {
885
+ const self = this;
886
+ if (!(self instanceof HTMLElement)) {
887
+ throw new TypeError('the context of this function must be an instance of HTMLElement');
888
+ }
889
+
890
+ if (!(typeof symbol === 'symbol')) {
891
+ throw new TypeError('symbol must be an instance of Symbol');
892
+ }
893
+
894
+ const updaters = new Set;
895
+
896
+ if (elements instanceof NodeList) {
897
+ elements = new Set([
898
+ ...elements
899
+ ])
900
+ } else if (elements instanceof HTMLElement) {
901
+ elements = new Set([
902
+ elements
903
+ ])
904
+ } else if (elements instanceof Set) {
905
+ } else {
906
+ throw new TypeError('elements is not a valid type. (actual: ' + typeof elements + ')');
907
+ }
908
+
909
+ let result = [];
910
+
911
+ elements.forEach((element) => {
912
+ if (!(element instanceof HTMLElement)) return;
913
+ if ((element instanceof HTMLTemplateElement)) return;
914
+
915
+ const u = new Updater(element, object)
916
+ updaters.add(u);
917
+
918
+ result.push(u.run().then(() => {
919
+ return u.enableEventProcessing();
920
+ }));
921
+
922
+ });
923
+
924
+ if (updaters.size > 0) {
925
+ addToObjectLink(self, symbol, updaters);
926
+ }
927
+
928
+ return result;
929
+ }
@@ -99,7 +99,6 @@ export {
99
99
  assembleMethodSymbol,
100
100
  attributeObserverSymbol,
101
101
  registerCustomElement,
102
- assignUpdaterToElement,
103
102
  getSlottedElements
104
103
  } from "./dom/customelement.mjs"
105
104
  export {
@@ -149,7 +149,7 @@ function getMonsterVersion() {
149
149
  }
150
150
 
151
151
  /** don't touch, replaced by make with package.json version */
152
- monsterVersion = new Version('2.2.1')
152
+ monsterVersion = new Version('3.0.0')
153
153
 
154
154
  return monsterVersion;
155
155
 
@@ -2,8 +2,10 @@
2
2
 
3
3
  import chai from "chai"
4
4
  import {internalSymbol} from "../../../../application/source/constants.mjs";
5
- import {ATTRIBUTE_OPTIONS} from "../../../../application/source/dom/constants.mjs";
5
+ import {ATTRIBUTE_OPTIONS, customElementUpdaterLinkSymbol} from "../../../../application/source/dom/constants.mjs";
6
6
  import {getDocument} from "../../../../application/source/dom/util.mjs";
7
+ import {ProxyObserver} from "../../../../application/source/types/proxyobserver.mjs";
8
+ import {addObjectWithUpdaterToElement} from "../../../../application/source/dom/updater.mjs";
7
9
  import {chaiDom} from "../../util/chai-dom.mjs";
8
10
  import {initJSDOM} from "../../util/jsdom.mjs";
9
11
 
@@ -16,10 +18,164 @@ let html1 = `
16
18
  </div>
17
19
  `;
18
20
 
21
+ let html2 = `
22
+ <input data-monster-bind="path:a" id="test2" data-monster-attributes="value path:a">
23
+ `;
24
+
25
+ // defined in constants.mjs
26
+ const updaterSymbolKey = "@schukai/monster/dom/custom-element@@options-updater-link"
27
+ const updaterSymbolSymbol = Symbol.for(updaterSymbolKey);
28
+
29
+
19
30
 
20
31
  describe('DOM', function () {
21
32
 
22
- let CustomElement, registerCustomElement, TestComponent, document, TestComponent2;
33
+ let CustomElement, registerCustomElement, TestComponent, document, TestComponent2,assignUpdaterToElement;
34
+
35
+ // This allows us to inspect the addEventListener calls
36
+
37
+ // let addEventListener = EventTarget.prototype.addEventListener;
38
+ // let removeEventListener = EventTarget.prototype.removeEventListener;
39
+ //
40
+ // before(function (done) {
41
+ // initJSDOM().then(() => {
42
+ //
43
+ // EventTarget.prototype.addEventListener = function (type, callback, options) {
44
+ // /* store args and then… */
45
+ // // callback = (e) => {
46
+ // // console.log("event fired" + e);
47
+ // // callback(e);
48
+ // // };
49
+ //
50
+ // addEventListener.call(this, type, callback, options);
51
+ // };
52
+ //
53
+ // EventTarget.prototype.removeEventListener = function (type, callback, options) {
54
+ // /* remove from stored args and then… */
55
+ // removeEventListener.call(this, type, callback, options);
56
+ // };
57
+ //
58
+ // done(e);
59
+ //
60
+ //
61
+ // });
62
+ //
63
+ //
64
+ // })
65
+ //
66
+ // after(function () {
67
+ // EventTarget.prototype.addEventListener = addEventListener;
68
+ // EventTarget.prototype.removeEventListener = removeEventListener;
69
+ // });
70
+
71
+
72
+ describe("assignUpdaterToElement", function () {
73
+
74
+ before(function (done) {
75
+ initJSDOM().then(() => {
76
+ import("../../../../application/source/dom/customelement.mjs").then((m) => {
77
+ try {
78
+ CustomElement = m['CustomElement'];
79
+ assignUpdaterToElement= function (elements, object) {
80
+ return addObjectWithUpdaterToElement.call(this, elements, updaterSymbolSymbol, object);
81
+ }
82
+
83
+
84
+ document = getDocument();
85
+
86
+ done()
87
+ } catch (e) {
88
+ done(e);
89
+ }
90
+
91
+
92
+ });
93
+
94
+ });
95
+ })
96
+
97
+ beforeEach(() => {
98
+ let mocks = document.getElementById('mocks');
99
+ mocks.innerHTML = html2;
100
+ })
101
+
102
+ afterEach(() => {
103
+ let mocks = document.getElementById('mocks');
104
+ mocks.innerHTML = "";
105
+ })
106
+
107
+ /**
108
+ * this test try to simulate the bug that was found in the assignUpdaterToElement function.
109
+ * The bug was that the updater was not assigned to the element when the element was created.
110
+ *
111
+ * unfortunately, this test does not reproduce the bug.
112
+ */
113
+ it("should assign an updater to an element", function (done) {
114
+ let element = document.getElementById('test2');
115
+
116
+ expect(document.getElementById("mocks").innerHTML).to.equal(html2);
117
+
118
+ const a = {a: 1};
119
+ const b = {b: 2};
120
+
121
+ const ap = new ProxyObserver(a);
122
+ const bp = new ProxyObserver(b);
123
+
124
+ const x = ap.getSubject()
125
+ const y = bp.getSubject()
126
+
127
+ const set = new Set();
128
+ set.add(element);
129
+
130
+ assignUpdaterToElement.call(element, set, ap);
131
+ assignUpdaterToElement.call(element, set, bp);
132
+
133
+ expect(JSON.stringify(x)).to.equal('{"a":1}');
134
+ expect(JSON.stringify(y)).to.equal('{"b":2}');
135
+
136
+ const sy = updaterSymbolSymbol;
137
+
138
+ let v = element.getAttribute("data-monster-objectlink");
139
+ expect(v).to.equal('Symbol('+updaterSymbolKey+')');
140
+
141
+ const updater = element[sy];
142
+
143
+ for (const v of updater) {
144
+ for (const u of v) {
145
+ u.run().then(() => {
146
+ u.enableEventProcessing();
147
+ });
148
+ }
149
+ }
150
+
151
+ expect(updater).to.be.an.instanceof(Set);
152
+ expect(updater).to.be.a("Set");
153
+
154
+ x.a = 3;
155
+ bp.getSubject().b = 4;
156
+
157
+ setTimeout(() => {
158
+
159
+ let mockHTML = document.getElementById("mocks");
160
+
161
+ // html expexted:
162
+ // <input data-monster-bind="path:a" id="test2" data-monster-attributes="value path:a" data-monster-objectlink="Symbol(@schukai/monster/dom/@@object-updater-link)" value="3">
163
+
164
+ expect(mockHTML.querySelector("#test2")).to.have.value('3')
165
+ expect(mockHTML.querySelector("#test2")).to.have.attribute('data-monster-objectlink', 'Symbol('+updaterSymbolKey+')')
166
+ //expect(mockHTML).to.have.html(resultHTML);
167
+
168
+ expect(element.value).to.equal("3");
169
+
170
+ expect(JSON.stringify(ap.getRealSubject())).to.equal('{"a":3}');
171
+ expect(JSON.stringify(bp.getRealSubject())).to.equal('{"b":4}');
172
+ done()
173
+ }, 10)
174
+
175
+ })
176
+
177
+ })
178
+
23
179
 
24
180
  describe('CustomElement()', function () {
25
181
 
@@ -102,7 +258,7 @@ describe('DOM', function () {
102
258
 
103
259
  let monster = document.getElementById('thisisatest');
104
260
  expect(monster.getOption('demotest')).is.eql(1425);
105
-
261
+
106
262
  });
107
263
  });
108
264
 
@@ -133,7 +289,7 @@ describe('DOM', function () {
133
289
  try {
134
290
  expect(document.getElementsByTagName('monster-testclass2').length).is.equal(1);
135
291
  expect(document.getElementsByTagName('monster-testclass2').item(0).shadowRoot.innerHTML).is.equal('<h1></h1><article><p>test</p><div id="container"></div></article>');
136
- expect(document.getElementById('test1')).contain.html('<monster-testclass2 data-monster-objectlink="Symbol(@schukai/monster/dom/@@object-updater-link)"></monster-testclass2>');
292
+ expect(document.getElementById('test1')).contain.html('<monster-testclass2 data-monster-objectlink="Symbol('+updaterSymbolKey+')"></monster-testclass2>');
137
293
  return done();
138
294
  } catch (e) {
139
295
  done(e);
@@ -514,6 +670,4 @@ describe('DOM', function () {
514
670
  })
515
671
 
516
672
  });
517
- });
518
-
519
-
673
+ })
@@ -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('2.2.1')
10
+ monsterVersion = new Version('3.0.0')
11
11
 
12
12
  let m = getMonsterVersion();
13
13
 
@@ -54,6 +54,7 @@ function initJSDOM(options) {
54
54
  'Document',
55
55
  'Node',
56
56
  'ShadowRoot',
57
+ 'EventTarget',
57
58
  'Event',
58
59
  'CustomEvent',
59
60
  'Element',
@@ -62,6 +63,7 @@ function initJSDOM(options) {
62
63
  'customElements',
63
64
  'DocumentFragment',
64
65
  'DOMParser',
66
+ 'KeyboardEvent',
65
67
  'CSSStyleSheet',
66
68
  'HTMLScriptElement',
67
69
  'MutationObserver',
@@ -14,6 +14,7 @@ import "../cases/dom/updater.mjs";
14
14
  import "../cases/dom/customcontrol.mjs";
15
15
  import "../cases/dom/locale.mjs";
16
16
  import "../cases/dom/theme.mjs";
17
+ import "../cases/dom/resource.mjs";
17
18
  import "../cases/dom/resourcemanager.mjs";
18
19
  import "../cases/dom/util.mjs";
19
20
  import "../cases/dom/customelement.mjs";
@@ -58,6 +59,7 @@ import "../cases/constraint/invalid.mjs";
58
59
  import "../cases/constraint/andoperator.mjs";
59
60
  import "../cases/constraint/oroperator.mjs";
60
61
  import "../cases/constraint/isarray.mjs";
62
+ import "../cases/constraint/abstractoperator.mjs";
61
63
  import "../cases/constraint/valid.mjs";
62
64
  import "../cases/util/trimspaces.mjs";
63
65
  import "../cases/util/deadmansswitch.mjs";
@@ -5,7 +5,7 @@
5
5
  <title>Mocha Monster</title>
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
7
7
  <link rel="stylesheet" href="mocha.css"/>
8
- <script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getOwnPropertySymbols,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet"
8
+ <script id="polyfill" src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.filter,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,CustomEvent,DataView,document,Document,DocumentFragment,Element,Event,fetch,globalThis,HTMLDocument,HTMLTemplateElement,Intl,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.freeze,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.for,Symbol.hasInstance,Symbol.iterator,Uint16Array,Uint8Array,URL,WeakMap,WeakSet"
9
9
  src="https://polyfill.io/v3/polyfill.min.js?features=Array.from,Array.isArray,Array.prototype.entries,Array.prototype.fill,Array.prototype.forEach,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,DataView,document,DocumentFragment,Element,Event,globalThis,HTMLDocument,HTMLTemplateElement,JSON,Map,Math.log2,Number.isInteger,Object.assign,Object.defineProperty,Object.entries,Object.getOwnPropertyDescriptor,Object.getPrototypeOf,Object.keys,Promise,Reflect,Reflect.defineProperty,Reflect.get,Reflect.getOwnPropertyDescriptor,Reflect.setPrototypeOf,Set,String.prototype.endsWith,String.prototype.matchAll,String.prototype.padStart,String.prototype.startsWith,String.prototype.trim,Symbol,Symbol.iterator,WeakMap,WeakSet"
10
10
  crossorigin="anonymous"
11
11
  referrerpolicy="no-referrer"></script>
@@ -14,8 +14,8 @@
14
14
  </head>
15
15
  <body>
16
16
  <div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
17
- <h1 style='margin-bottom: 0.1em;'>Monster 2.0.16</h1>
18
- <div id="lastupdate" style='font-size:0.7em'>last update Do 29. Dez 14:29:19 CET 2022</div>
17
+ <h1 style='margin-bottom: 0.1em;'>Monster 2.2.1</h1>
18
+ <div id="lastupdate" style='font-size:0.7em'>last update Mi 4. Jan 15:51:44 CET 2023</div>
19
19
  </div>
20
20
  <div id="mocks"></div>
21
21
  <div id="mocha"></div>