@schukai/monster 3.32.0 → 3.33.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +1 -1
- package/package.json +1 -1
- package/source/dom/customelement.mjs +1 -52
- package/source/dom/slotted.mjs +111 -0
- package/source/types/version.mjs +1 -1
- package/test/cases/dom/customelement.mjs +1 -37
- package/test/cases/dom/find.mjs +16 -25
- package/test/cases/dom/slotted-nodes.mjs +14 -0
- package/test/cases/monster.mjs +1 -1
- package/test/util/chai-dom.mjs +2 -2
- package/test/web/import.js +5 -0
- package/test/web/test.html +4 -4
- package/test/web/tests.js +3408 -2163
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,Blob,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"
|
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.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,Blob,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.includes,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
@@ -29,6 +29,7 @@ import {findDocumentTemplate, Template} from "./template.mjs";
|
|
29
29
|
import {addObjectWithUpdaterToElement} from "./updater.mjs";
|
30
30
|
import {instanceSymbol} from "../constants.mjs";
|
31
31
|
import {getDocumentTranslations, Translations} from "../i18n/translations.mjs";
|
32
|
+
import {getSlottedElements} from "./slotted.mjs";
|
32
33
|
|
33
34
|
export {
|
34
35
|
CustomElement,
|
@@ -599,58 +600,6 @@ class CustomElement extends HTMLElement {
|
|
599
600
|
}
|
600
601
|
}
|
601
602
|
|
602
|
-
/**
|
603
|
-
* @private
|
604
|
-
* @param {String|undefined} query
|
605
|
-
* @param {String|undefined|null} name name of the slot (if the parameter is undefined, all slots are searched, if the parameter has the value null, all slots without a name are searched. if a string is specified, the slots with this name are searched.)
|
606
|
-
* @return {*}
|
607
|
-
* @this CustomElement
|
608
|
-
* @license AGPLv3
|
609
|
-
* @since 1.23.0
|
610
|
-
* @throws {Error} query must be a string
|
611
|
-
*/
|
612
|
-
function getSlottedElements(query, name) {
|
613
|
-
const self = this;
|
614
|
-
const result = new Set();
|
615
|
-
|
616
|
-
if (!(self.shadowRoot instanceof ShadowRoot)) {
|
617
|
-
return result;
|
618
|
-
}
|
619
|
-
|
620
|
-
let selector = "slot";
|
621
|
-
if (name !== undefined) {
|
622
|
-
if (name === null) {
|
623
|
-
selector += ":not([name])";
|
624
|
-
} else {
|
625
|
-
selector += `[name=${validateString(name)}]`;
|
626
|
-
}
|
627
|
-
}
|
628
|
-
|
629
|
-
const slots = self.shadowRoot.querySelectorAll(selector);
|
630
|
-
|
631
|
-
for (const [, slot] of Object.entries(slots)) {
|
632
|
-
slot.assignedElements().forEach(function (node) {
|
633
|
-
if (!(node instanceof HTMLElement)) return;
|
634
|
-
|
635
|
-
if (isString(query)) {
|
636
|
-
node.querySelectorAll(query).forEach(function (n) {
|
637
|
-
result.add(n);
|
638
|
-
});
|
639
|
-
|
640
|
-
if (node.matches(query)) {
|
641
|
-
result.add(node);
|
642
|
-
}
|
643
|
-
} else if (query !== undefined) {
|
644
|
-
throw new Error("query must be a string");
|
645
|
-
} else {
|
646
|
-
result.add(node);
|
647
|
-
}
|
648
|
-
});
|
649
|
-
}
|
650
|
-
|
651
|
-
return result;
|
652
|
-
}
|
653
|
-
|
654
603
|
/**
|
655
604
|
* @this CustomElement
|
656
605
|
* @private
|
@@ -0,0 +1,111 @@
|
|
1
|
+
import {isString} from "../types/is.mjs";
|
2
|
+
import {validateString} from "../types/validate.mjs";
|
3
|
+
|
4
|
+
export {getSlottedElements, getSlottedNodes};
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @private
|
8
|
+
* @param {String|undefined} query
|
9
|
+
* @param {String|undefined|null} name name of the slot (if the parameter is undefined, all slots are searched, if the parameter has the value null, all slots without a name are searched. if a string is specified, the slots with this name are searched.)
|
10
|
+
* @return {*}
|
11
|
+
* @this CustomElement
|
12
|
+
* @license AGPLv3
|
13
|
+
* @since 3.33.0
|
14
|
+
* @throws {Error} query must be a string
|
15
|
+
*/
|
16
|
+
function getSlottedNodes(query, name) {
|
17
|
+
const self = this;
|
18
|
+
const result = new Set();
|
19
|
+
|
20
|
+
if (!self.shadowRoot) {
|
21
|
+
return result;
|
22
|
+
}
|
23
|
+
|
24
|
+
let selector = "slot";
|
25
|
+
if (name !== undefined) {
|
26
|
+
if (name === null) {
|
27
|
+
selector += ":not([name])";
|
28
|
+
} else {
|
29
|
+
selector += `[name=${validateString(name)}]`;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
const slots = self.shadowRoot.querySelectorAll(selector);
|
34
|
+
|
35
|
+
for (const [, slot] of Object.entries(slots)) {
|
36
|
+
slot.assignedNodes().forEach(function (node) {
|
37
|
+
if (node === null || node === undefined) {
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
|
41
|
+
if (isString(query)) {
|
42
|
+
node.querySelectorAll(query).forEach(function (n) {
|
43
|
+
result.add(n);
|
44
|
+
});
|
45
|
+
|
46
|
+
if (node.matches(query)) {
|
47
|
+
result.add(node);
|
48
|
+
}
|
49
|
+
} else if (query !== undefined) {
|
50
|
+
throw new Error("query must be a string");
|
51
|
+
} else {
|
52
|
+
result.add(node);
|
53
|
+
}
|
54
|
+
});
|
55
|
+
}
|
56
|
+
|
57
|
+
return result;
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
/**
|
62
|
+
* @private
|
63
|
+
* @param {String|undefined} query
|
64
|
+
* @param {String|undefined|null} name name of the slot (if the parameter is undefined, all slots are searched, if the parameter has the value null, all slots without a name are searched. if a string is specified, the slots with this name are searched.)
|
65
|
+
* @return {*}
|
66
|
+
* @this CustomElement
|
67
|
+
* @license AGPLv3
|
68
|
+
* @since 1.23.0
|
69
|
+
* @throws {Error} query must be a string
|
70
|
+
*/
|
71
|
+
function getSlottedElements(query, name) {
|
72
|
+
const self = this;
|
73
|
+
const result = new Set();
|
74
|
+
|
75
|
+
if (!(self.shadowRoot instanceof ShadowRoot)) {
|
76
|
+
return result;
|
77
|
+
}
|
78
|
+
|
79
|
+
let selector = "slot";
|
80
|
+
if (name !== undefined) {
|
81
|
+
if (name === null) {
|
82
|
+
selector += ":not([name])";
|
83
|
+
} else {
|
84
|
+
selector += `[name=${validateString(name)}]`;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
const slots = self.shadowRoot.querySelectorAll(selector);
|
89
|
+
|
90
|
+
for (const [, slot] of Object.entries(slots)) {
|
91
|
+
slot.assignedElements().forEach(function (node) {
|
92
|
+
if (!(node instanceof HTMLElement)) return;
|
93
|
+
|
94
|
+
if (isString(query)) {
|
95
|
+
node.querySelectorAll(query).forEach(function (n) {
|
96
|
+
result.add(n);
|
97
|
+
});
|
98
|
+
|
99
|
+
if (node.matches(query)) {
|
100
|
+
result.add(node);
|
101
|
+
}
|
102
|
+
} else if (query !== undefined) {
|
103
|
+
throw new Error("query must be a string");
|
104
|
+
} else {
|
105
|
+
result.add(node);
|
106
|
+
}
|
107
|
+
});
|
108
|
+
}
|
109
|
+
|
110
|
+
return result;
|
111
|
+
}
|
package/source/types/version.mjs
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
import chai from "chai"
|
4
4
|
import {internalSymbol} from "../../../../application/source/constants.mjs";
|
5
|
-
import {ATTRIBUTE_OPTIONS
|
5
|
+
import {ATTRIBUTE_OPTIONS} from "../../../../application/source/dom/constants.mjs";
|
6
6
|
import {getDocument} from "../../../../application/source/dom/util.mjs";
|
7
7
|
import {ProxyObserver} from "../../../../application/source/types/proxyobserver.mjs";
|
8
8
|
import {addObjectWithUpdaterToElement} from "../../../../application/source/dom/updater.mjs";
|
@@ -32,42 +32,6 @@ describe('DOM', function () {
|
|
32
32
|
|
33
33
|
let CustomElement, registerCustomElement, TestComponent, document, TestComponent2,assignUpdaterToElement;
|
34
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
35
|
|
72
36
|
describe("assignUpdaterToElement", function () {
|
73
37
|
|
package/test/cases/dom/find.mjs
CHANGED
@@ -2,30 +2,16 @@ import {
|
|
2
2
|
findElementWithIdUpwards
|
3
3
|
} from "../../../../application/source/dom/util.mjs";
|
4
4
|
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
|
8
|
-
let originalEnvironment;
|
5
|
+
import {expect} from 'chai';
|
6
|
+
import {initJSDOM} from "../../util/jsdom.mjs";
|
9
7
|
|
10
8
|
function setupTestEnvironment() {
|
11
|
-
const { window } = new JSDOM('<!DOCTYPE html>', { pretendToBeVisual: true });
|
12
9
|
|
13
|
-
const { document, customElements, HTMLElement } = window;
|
14
|
-
originalEnvironment = {
|
15
|
-
document: globalThis.document,
|
16
|
-
customElements: globalThis.customElements,
|
17
|
-
HTMLElement: globalThis.HTMLElement,
|
18
|
-
ShadowRoot: globalThis.ShadowRoot,
|
19
|
-
};
|
20
|
-
globalThis.document = document;
|
21
|
-
globalThis.customElements = customElements;
|
22
|
-
globalThis.HTMLElement = HTMLElement;
|
23
|
-
globalThis.ShadowRoot = window.ShadowRoot || class ShadowRoot {}; // Fallback for JSDOM
|
24
10
|
|
25
11
|
class TestComponent extends HTMLElement {
|
26
12
|
constructor() {
|
27
13
|
super();
|
28
|
-
this.attachShadow({
|
14
|
+
this.attachShadow({mode: 'open'});
|
29
15
|
}
|
30
16
|
}
|
31
17
|
|
@@ -35,12 +21,16 @@ function setupTestEnvironment() {
|
|
35
21
|
}
|
36
22
|
|
37
23
|
function cleanupTestEnvironment() {
|
38
|
-
|
24
|
+
let mocks = document.getElementById('mocks');
|
25
|
+
mocks.innerHTML = "";
|
39
26
|
}
|
40
27
|
|
41
28
|
describe('findElementWithIdUpwards', () => {
|
42
|
-
before(() => {
|
43
|
-
|
29
|
+
before((done) => {
|
30
|
+
initJSDOM().then(() => {
|
31
|
+
setupTestEnvironment();
|
32
|
+
done()
|
33
|
+
});
|
44
34
|
});
|
45
35
|
|
46
36
|
after(() => {
|
@@ -49,17 +39,18 @@ describe('findElementWithIdUpwards', () => {
|
|
49
39
|
|
50
40
|
beforeEach(() => {
|
51
41
|
// Set up the DOM
|
52
|
-
|
53
|
-
|
42
|
+
|
43
|
+
let mocks = document.getElementById('mocks');
|
44
|
+
mocks.innerHTML = `
|
45
|
+
<div id="container">
|
54
46
|
<div id="parent">
|
55
47
|
<div id="child"></div>
|
56
48
|
</div>
|
57
|
-
</div
|
58
|
-
`;
|
49
|
+
</div>`;
|
59
50
|
|
60
51
|
const shadowHost = document.createElement('div');
|
61
52
|
document.body.appendChild(shadowHost);
|
62
|
-
const shadowRoot = shadowHost.attachShadow({
|
53
|
+
const shadowRoot = shadowHost.attachShadow({mode: 'open'});
|
63
54
|
const innerElement = document.createElement('div');
|
64
55
|
innerElement.id = 'inner';
|
65
56
|
shadowRoot.appendChild(innerElement);
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import {expect} from 'chai';
|
2
|
+
import {getSlottedNodes} from "../../../../application/source/dom/slotted.mjs";
|
3
|
+
|
4
|
+
|
5
|
+
describe('getSlottedNodes', () => {
|
6
|
+
|
7
|
+
|
8
|
+
it('should return an empty Set if there is no ShadowRoot', () => {
|
9
|
+
expect(getSlottedNodes).is.a('function');
|
10
|
+
});
|
11
|
+
|
12
|
+
|
13
|
+
});
|
14
|
+
|
package/test/cases/monster.mjs
CHANGED
package/test/util/chai-dom.mjs
CHANGED
@@ -15,10 +15,10 @@
|
|
15
15
|
**********/
|
16
16
|
|
17
17
|
export function chaiDom(chai, utils) {
|
18
|
-
|
18
|
+
let flag = utils.flag,
|
19
19
|
|
20
20
|
elToString = function(el) {
|
21
|
-
|
21
|
+
let desc
|
22
22
|
if (isNodeList(el)) {
|
23
23
|
if (el.length === 0) return 'empty NodeList'
|
24
24
|
desc = Array.prototype.slice.call(el, 0, 5).map(elToString).join(', ')
|
package/test/web/import.js
CHANGED
@@ -6,6 +6,8 @@ import "../cases/logging/logentry.mjs";
|
|
6
6
|
import "../cases/logging/handler/console.mjs";
|
7
7
|
import "../cases/logging/handler.mjs";
|
8
8
|
import "../cases/text/formatter.mjs";
|
9
|
+
import "../cases/text/util.mjs";
|
10
|
+
import "../cases/dom/slotted-nodes.mjs";
|
9
11
|
import "../cases/dom/resource/link/stylesheet.mjs";
|
10
12
|
import "../cases/dom/resource/data.mjs";
|
11
13
|
import "../cases/dom/resource/link.mjs";
|
@@ -17,6 +19,7 @@ import "../cases/dom/theme.mjs";
|
|
17
19
|
import "../cases/dom/resource.mjs";
|
18
20
|
import "../cases/dom/resourcemanager.mjs";
|
19
21
|
import "../cases/dom/util.mjs";
|
22
|
+
import "../cases/dom/find.mjs";
|
20
23
|
import "../cases/dom/customelement.mjs";
|
21
24
|
import "../cases/dom/attributes.mjs";
|
22
25
|
import "../cases/dom/events.mjs";
|
@@ -40,6 +43,7 @@ import "../cases/types/randomid.mjs";
|
|
40
43
|
import "../cases/types/observablequeue.mjs";
|
41
44
|
import "../cases/types/uuid.mjs";
|
42
45
|
import "../cases/types/observer.mjs";
|
46
|
+
import "../cases/types/internal.mjs";
|
43
47
|
import "../cases/types/tokenlist.mjs";
|
44
48
|
import "../cases/types/queue.mjs";
|
45
49
|
import "../cases/types/stack.mjs";
|
@@ -82,6 +86,7 @@ import "../cases/data/diff.mjs";
|
|
82
86
|
import "../cases/data/datasource/server.mjs";
|
83
87
|
import "../cases/data/datasource/storage/sessionstorage.mjs";
|
84
88
|
import "../cases/data/datasource/storage/localstorage.mjs";
|
89
|
+
import "../cases/data/datasource/dom.mjs";
|
85
90
|
import "../cases/data/datasource/server/restapi.mjs";
|
86
91
|
import "../cases/data/datasource/server/websocket.mjs";
|
87
92
|
import "../cases/math/random.mjs";
|
package/test/web/test.html
CHANGED
@@ -5,17 +5,17 @@
|
|
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,Blob,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"
|
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.includes,Array.prototype.indexOf,Array.prototype.keys,Array.prototype.lastIndexOf,Array.prototype.map,Array.prototype.reduce,Array.prototype.sort,ArrayBuffer,atob,Blob,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.includes,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>
|
12
|
-
<script src="https://cdn.jsdelivr.net/npm/element-internals-polyfill
|
12
|
+
<script src="https://cdn.jsdelivr.net/npm/element-internals-polyfill"></script>
|
13
13
|
|
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 3.
|
18
|
-
<div id="lastupdate" style='font-size:0.7em'>last update
|
17
|
+
<h1 style='margin-bottom: 0.1em;'>Monster 3.32.0</h1>
|
18
|
+
<div id="lastupdate" style='font-size:0.7em'>last update So 26. Mär 17:02:25 CEST 2023</div>
|
19
19
|
</div>
|
20
20
|
<div id="mocks"></div>
|
21
21
|
<div id="mocha"></div>
|