@schukai/monster 1.23.0 → 1.26.1
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 +53 -0
- package/README.md +4 -4
- package/dist/modules/constants.js +2 -2
- package/dist/modules/constraints/abstract.js +1 -1
- package/dist/modules/constraints/abstractoperator.js +1 -1
- package/dist/modules/constraints/andoperator.js +1 -1
- package/dist/modules/constraints/invalid.js +1 -1
- package/dist/modules/constraints/isarray.js +1 -1
- package/dist/modules/constraints/isobject.js +1 -1
- package/dist/modules/constraints/namespace.js +1 -1
- package/dist/modules/constraints/oroperator.js +1 -1
- package/dist/modules/constraints/valid.js +1 -1
- package/dist/modules/data/buildmap.js +2 -2
- package/dist/modules/data/buildtree.js +2 -0
- package/dist/modules/data/datasource/namespace.js +1 -1
- package/dist/modules/data/datasource/restapi/writeerror.js +2 -0
- package/dist/modules/data/datasource/restapi.js +2 -2
- package/dist/modules/data/datasource/storage/localstorage.js +2 -2
- package/dist/modules/data/datasource/storage/namespace.js +1 -1
- package/dist/modules/data/datasource/storage/sessionstorage.js +2 -2
- package/dist/modules/data/datasource/storage.js +2 -2
- package/dist/modules/data/datasource.js +2 -2
- package/dist/modules/data/diff.js +2 -2
- package/dist/modules/data/extend.js +1 -1
- package/dist/modules/data/namespace.js +1 -1
- package/dist/modules/data/pathfinder.js +2 -2
- package/dist/modules/data/pipe.js +1 -1
- package/dist/modules/data/transformer.js +2 -2
- package/dist/modules/dom/assembler.js +1 -1
- package/dist/modules/dom/attributes.js +1 -1
- package/dist/modules/dom/constants.js +2 -2
- package/dist/modules/dom/customcontrol.js +2 -2
- package/dist/modules/dom/customelement.js +2 -2
- package/dist/modules/dom/events.js +1 -1
- package/dist/modules/dom/focusmanager.js +2 -0
- package/dist/modules/dom/locale.js +1 -1
- package/dist/modules/dom/namespace.js +1 -1
- package/dist/modules/dom/resource/data.js +2 -0
- package/dist/modules/dom/resource/link/stylesheet.js +2 -0
- package/dist/modules/dom/resource/link.js +2 -0
- package/dist/modules/dom/resource/script.js +2 -0
- package/dist/modules/dom/resource.js +2 -0
- package/dist/modules/dom/resourcemanager.js +2 -0
- package/dist/modules/dom/template.js +2 -2
- package/dist/modules/dom/theme.js +1 -1
- package/dist/modules/dom/updater.js +2 -2
- package/dist/modules/dom/util.js +1 -1
- package/dist/modules/dom/worker/factory.js +2 -0
- package/dist/modules/i18n/formatter.js +2 -0
- package/dist/modules/i18n/locale.js +1 -1
- package/dist/modules/i18n/namespace.js +1 -1
- package/dist/modules/i18n/provider.js +1 -1
- package/dist/modules/i18n/providers/fetch.js +2 -2
- package/dist/modules/i18n/providers/namespace.js +1 -1
- package/dist/modules/i18n/translations.js +1 -1
- package/dist/modules/logging/handler/console.js +1 -1
- package/dist/modules/logging/handler/namespace.js +1 -1
- package/dist/modules/logging/handler.js +1 -1
- package/dist/modules/logging/logentry.js +1 -1
- package/dist/modules/logging/logger.js +1 -1
- package/dist/modules/logging/namespace.js +1 -1
- package/dist/modules/math/namespace.js +1 -1
- package/dist/modules/math/random.js +2 -2
- package/dist/modules/monster.js +1 -1
- package/dist/modules/namespace.js +1 -1
- package/dist/modules/text/formatter.js +2 -2
- package/dist/modules/text/namespace.js +1 -1
- package/dist/modules/types/base.js +1 -1
- package/dist/modules/types/basewithoptions.js +2 -2
- package/dist/modules/types/binary.js +1 -1
- package/dist/modules/types/dataurl.js +1 -1
- package/dist/modules/types/global.js +1 -1
- package/dist/modules/types/id.js +1 -1
- package/dist/modules/types/is.js +2 -2
- package/dist/modules/types/mediatype.js +1 -1
- package/dist/modules/types/namespace.js +1 -1
- package/dist/modules/types/node.js +2 -0
- package/dist/modules/types/nodelist.js +2 -0
- package/dist/modules/types/noderecursiveiterator.js +2 -0
- package/dist/modules/types/observer.js +1 -1
- package/dist/modules/types/observerlist.js +2 -2
- package/dist/modules/types/proxyobserver.js +2 -2
- package/dist/modules/types/queue.js +1 -1
- package/dist/modules/types/randomid.js +1 -1
- package/dist/modules/types/regex.js +2 -0
- package/dist/modules/types/stack.js +1 -1
- package/dist/modules/types/tokenlist.js +2 -2
- package/dist/modules/types/typeof.js +1 -1
- package/dist/modules/types/uniquequeue.js +1 -1
- package/dist/modules/types/uuid.js +2 -0
- package/dist/modules/types/validate.js +1 -1
- package/dist/modules/types/version.js +2 -2
- package/dist/modules/util/clone.js +1 -1
- package/dist/modules/util/comparator.js +2 -2
- package/dist/modules/util/freeze.js +1 -1
- package/dist/modules/util/namespace.js +1 -1
- package/dist/modules/util/processing.js +2 -2
- package/dist/modules/util/trimspaces.js +2 -0
- package/dist/monster.dev.js +1684 -696
- package/dist/monster.dev.js.map +1 -1
- package/dist/monster.js +2 -2
- package/package.json +13 -2
- package/source/constants.js +16 -7
- package/source/constraints/abstract.js +5 -0
- package/source/constraints/abstractoperator.js +5 -0
- package/source/constraints/andoperator.js +10 -5
- package/source/constraints/invalid.js +8 -3
- package/source/constraints/isarray.js +9 -4
- package/source/constraints/isobject.js +8 -3
- package/source/constraints/oroperator.js +10 -5
- package/source/constraints/valid.js +8 -3
- package/source/data/buildmap.js +27 -11
- package/source/data/buildtree.js +95 -0
- package/source/data/datasource/restapi/writeerror.js +49 -0
- package/source/data/datasource/restapi.js +87 -20
- package/source/data/datasource/storage/localstorage.js +4 -10
- package/source/data/datasource/storage/sessionstorage.js +4 -12
- package/source/data/datasource/storage.js +7 -14
- package/source/data/datasource.js +55 -17
- package/source/data/diff.js +8 -8
- package/source/data/extend.js +5 -5
- package/source/data/pathfinder.js +12 -6
- package/source/data/pipe.js +6 -5
- package/source/data/transformer.js +131 -24
- package/source/dom/assembler.js +2 -2
- package/source/dom/attributes.js +24 -24
- package/source/dom/constants.js +305 -12
- package/source/dom/customcontrol.js +40 -19
- package/source/dom/customelement.js +121 -92
- package/source/dom/events.js +6 -6
- package/source/dom/focusmanager.js +250 -0
- package/source/dom/locale.js +10 -5
- package/source/dom/resource/data.js +170 -0
- package/source/dom/resource/link/stylesheet.js +54 -0
- package/source/dom/resource/link.js +125 -0
- package/source/dom/resource/script.js +112 -0
- package/source/dom/resource.js +268 -0
- package/source/dom/resourcemanager.js +214 -0
- package/source/dom/template.js +52 -12
- package/source/dom/theme.js +3 -3
- package/source/dom/updater.js +47 -33
- package/source/dom/util.js +6 -6
- package/source/dom/worker/factory.js +134 -0
- package/source/i18n/formatter.js +140 -0
- package/source/i18n/locale.js +10 -8
- package/source/i18n/provider.js +4 -4
- package/source/i18n/providers/fetch.js +24 -14
- package/source/i18n/translations.js +20 -10
- package/source/logging/handler/console.js +2 -2
- package/source/logging/handler.js +2 -2
- package/source/logging/logentry.js +2 -2
- package/source/logging/logger.js +4 -4
- package/source/math/random.js +11 -5
- package/source/namespace.js +1 -1
- package/source/text/formatter.js +244 -27
- package/source/types/base.js +4 -4
- package/source/types/basewithoptions.js +10 -15
- package/source/types/binary.js +4 -4
- package/source/types/dataurl.js +6 -6
- package/source/types/global.js +9 -7
- package/source/types/id.js +6 -3
- package/source/types/is.js +103 -85
- package/source/types/mediatype.js +4 -4
- package/source/types/node.js +179 -0
- package/source/types/nodelist.js +125 -0
- package/source/types/noderecursiveiterator.js +126 -0
- package/source/types/observer.js +3 -3
- package/source/types/observerlist.js +3 -3
- package/source/types/proxyobserver.js +24 -7
- package/source/types/queue.js +6 -6
- package/source/types/randomid.js +2 -2
- package/source/types/regex.js +49 -0
- package/source/types/stack.js +2 -2
- package/source/types/tokenlist.js +8 -9
- package/source/types/typeof.js +3 -3
- package/source/types/uniquequeue.js +4 -4
- package/source/types/uuid.js +102 -0
- package/source/types/validate.js +20 -20
- package/source/types/version.js +6 -6
- package/source/util/clone.js +4 -5
- package/source/util/comparator.js +5 -5
- package/source/util/freeze.js +5 -5
- package/source/util/processing.js +33 -36
- package/source/util/trimspaces.js +85 -0
- package/test/cases/data/buildtree.js +149 -0
- package/test/cases/data/datasource/restapi.js +1 -1
- package/test/cases/data/datasource.js +4 -4
- package/test/cases/data/diff.js +4 -4
- package/test/cases/data/pathfinder.js +18 -9
- package/test/cases/data/pipe.js +26 -2
- package/test/cases/data/transformer.js +41 -10
- package/test/cases/dom/attributes.js +18 -14
- package/test/cases/dom/customcontrol.js +6 -5
- package/test/cases/dom/customelement.js +14 -16
- package/test/cases/dom/focusmanager.js +111 -0
- package/test/cases/dom/locale.js +1 -4
- package/test/cases/dom/resource/data.js +129 -0
- package/test/cases/dom/resource/link/stylesheet.js +101 -0
- package/test/cases/dom/resource/link.js +101 -0
- package/test/cases/dom/resource/script.js +115 -0
- package/test/cases/dom/resourcemanager.js +118 -0
- package/test/cases/dom/updater.js +28 -4
- package/test/cases/dom/worker/factory.js +63 -0
- package/test/cases/i18n/formatter.js +66 -0
- package/test/cases/monster.js +1 -1
- package/test/cases/text/formatter.js +71 -8
- package/test/cases/types/node.js +196 -0
- package/test/cases/types/nodelist.js +64 -0
- package/test/cases/types/noderecursiveiterator.js +54 -0
- package/test/cases/types/proxyobserver.js +55 -11
- package/test/cases/types/regex.js +32 -0
- package/test/cases/types/uuid.js +42 -0
- package/test/cases/util/freeze.js +30 -4
- package/test/cases/util/trimspaces.js +24 -0
- package/test/util/cleanupdom.js +48 -0
- package/test/util/jsdom.js +22 -9
- package/test/web/import.js +15 -0
- package/test/web/monster-dev.html +3 -3
- package/test/web/monster.html +2 -2
- package/test/web/test.html +3 -3
- package/test/web/tests.js +7 -7
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @author schukai GmbH
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {extend} from "../../data/extend.js";
|
|
8
|
+
import {assignToNamespace, Monster} from "../../namespace.js";
|
|
9
|
+
import {
|
|
10
|
+
ATTRIBUTE_CLASS,
|
|
11
|
+
ATTRIBUTE_ID,
|
|
12
|
+
ATTRIBUTE_NONCE,
|
|
13
|
+
ATTRIBUTE_SRC,
|
|
14
|
+
ATTRIBUTE_TITLE,
|
|
15
|
+
ATTRIBUTE_TYPE,
|
|
16
|
+
TAG_SCRIPT
|
|
17
|
+
} from "../constants.js";
|
|
18
|
+
import {KEY_DOCUMENT, referenceSymbol, Resource} from "../resource.js";
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* This class is used by the resource manager to embed scripts.
|
|
23
|
+
*
|
|
24
|
+
* You can call the method via the monster namespace `new Monster.DOM.Resource.Script()`.
|
|
25
|
+
*
|
|
26
|
+
* ```
|
|
27
|
+
* <script type="module">
|
|
28
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.1/dist/monster.js';
|
|
29
|
+
* new Monster.DOM.Resource.Script()
|
|
30
|
+
* </script>
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Alternatively, you can also integrate this function individually.
|
|
34
|
+
*
|
|
35
|
+
* ```
|
|
36
|
+
* <script type="module">
|
|
37
|
+
* import {Script} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.1/dist/modules/dom/resource/script.js';
|
|
38
|
+
* new Script()
|
|
39
|
+
* </script>
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @since 1.25.0
|
|
43
|
+
* @copyright schukai GmbH
|
|
44
|
+
* @memberOf Monster.DOM.Resource
|
|
45
|
+
* @summary A Resource class
|
|
46
|
+
*/
|
|
47
|
+
class Script extends Resource {
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @property {boolean} async=true {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-async}
|
|
51
|
+
* @property {string} crossOrigin=anonymous {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-crossorigin}
|
|
52
|
+
* @property {boolean} defer=false {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer}
|
|
53
|
+
* @property {string} integrity {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-integrity}
|
|
54
|
+
* @property {boolean} nomodule {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nomodule}
|
|
55
|
+
* @property {string} nonce {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-nonce}
|
|
56
|
+
* @property {string} referrerpolicy {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-referrerpolicy}
|
|
57
|
+
* @property {string} type {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type}
|
|
58
|
+
*/
|
|
59
|
+
get defaults() {
|
|
60
|
+
return extend({}, super.defaults, {
|
|
61
|
+
async: true,
|
|
62
|
+
crossOrigin: 'anonymous',
|
|
63
|
+
defer: false,
|
|
64
|
+
integrity: undefined,
|
|
65
|
+
nomodule: false,
|
|
66
|
+
nonce: undefined,
|
|
67
|
+
referrerpolicy: undefined,
|
|
68
|
+
type: 'text/javascript',
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
*
|
|
74
|
+
* @return {Monster.DOM.Resource.Script}
|
|
75
|
+
*/
|
|
76
|
+
create() {
|
|
77
|
+
createElement.call(this);
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @return {string}
|
|
83
|
+
*/
|
|
84
|
+
static getURLAttribute() {
|
|
85
|
+
return ATTRIBUTE_SRC
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @private
|
|
92
|
+
* @return {Monster.DOM.Resource.Script}
|
|
93
|
+
*/
|
|
94
|
+
function createElement() {
|
|
95
|
+
const self = this;
|
|
96
|
+
|
|
97
|
+
const document = self.getOption(KEY_DOCUMENT);
|
|
98
|
+
self[referenceSymbol] = document.createElement(TAG_SCRIPT);
|
|
99
|
+
|
|
100
|
+
for (let key of ['crossOrigin', 'defer', 'async', 'integrity', 'nomodule', ATTRIBUTE_NONCE, 'referrerpolicy', ATTRIBUTE_TYPE, ATTRIBUTE_SRC, ATTRIBUTE_ID, ATTRIBUTE_CLASS, ATTRIBUTE_TITLE]) {
|
|
101
|
+
if (self.getOption(key) !== undefined) {
|
|
102
|
+
self[referenceSymbol][key] = self.getOption(key);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
return self;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
assignToNamespace('Monster.DOM.Resource', Script);
|
|
112
|
+
export {Monster, Script}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @author schukai GmbH
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {internalStateSymbol, internalSymbol,} from "../constants.js";
|
|
8
|
+
import {extend} from "../data/extend.js";
|
|
9
|
+
import {assignToNamespace, Monster} from "../namespace.js";
|
|
10
|
+
import {BaseWithOptions} from "../types/basewithoptions.js";
|
|
11
|
+
import {getGlobalObject} from "../types/global.js";
|
|
12
|
+
import {ID} from "../types/id.js";
|
|
13
|
+
import {isString} from "../types/is.js";
|
|
14
|
+
import {Observer} from "../types/observer.js";
|
|
15
|
+
import {ProxyObserver} from "../types/proxyobserver.js";
|
|
16
|
+
import {ATTRIBUTE_CLASS, ATTRIBUTE_ID, ATTRIBUTE_TITLE} from "./constants.js";
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @private
|
|
21
|
+
* @type {string}
|
|
22
|
+
*/
|
|
23
|
+
export const KEY_DOCUMENT = 'document';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
* @type {string}
|
|
28
|
+
*/
|
|
29
|
+
export const KEY_QUERY = 'query';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @private
|
|
33
|
+
* @type {string}
|
|
34
|
+
*/
|
|
35
|
+
export const KEY_TIMEOUT = 'timeout';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @private
|
|
39
|
+
* @type {symbol}
|
|
40
|
+
*/
|
|
41
|
+
export const referenceSymbol = Symbol('reference');
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* This class is the base class for all resources to be loaded.
|
|
45
|
+
*
|
|
46
|
+
* You can call the method via the monster namespace `new Monster.DOM.Resource()`.
|
|
47
|
+
*
|
|
48
|
+
* ```
|
|
49
|
+
* <script type="module">
|
|
50
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.1/dist/monster.js';
|
|
51
|
+
* new Monster.DOM.Resource()
|
|
52
|
+
* </script>
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* Alternatively, you can also integrate this function individually.
|
|
56
|
+
*
|
|
57
|
+
* ```
|
|
58
|
+
* <script type="module">
|
|
59
|
+
* import {Resource} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.1/dist/modules/dom/resource.js';
|
|
60
|
+
* new Resource()
|
|
61
|
+
* </script>
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @since 1.25.0
|
|
65
|
+
* @copyright schukai GmbH
|
|
66
|
+
* @memberOf Monster.DOM
|
|
67
|
+
* @summary A Resource class
|
|
68
|
+
*/
|
|
69
|
+
class Resource extends BaseWithOptions {
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @param {Object|undefined} options
|
|
74
|
+
*/
|
|
75
|
+
constructor(options) {
|
|
76
|
+
super(options);
|
|
77
|
+
|
|
78
|
+
let uri = this.getOption(this.constructor.getURLAttribute());
|
|
79
|
+
|
|
80
|
+
if (uri === undefined) {
|
|
81
|
+
throw new Error('missing source')
|
|
82
|
+
} else if (uri instanceof URL) {
|
|
83
|
+
uri = uri.toString();
|
|
84
|
+
} else if (!isString(uri)) {
|
|
85
|
+
throw new Error('unsupported url type')
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this[internalSymbol][this.constructor.getURLAttribute()] = uri;
|
|
89
|
+
this[internalStateSymbol] = new ProxyObserver({
|
|
90
|
+
loaded: false,
|
|
91
|
+
error: undefined,
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
this[referenceSymbol] = undefined;
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @return {boolean}
|
|
100
|
+
*/
|
|
101
|
+
isConnected() {
|
|
102
|
+
|
|
103
|
+
if (this[referenceSymbol] instanceof HTMLElement) {
|
|
104
|
+
return this[referenceSymbol].isConnected;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* This method is overridden by the special classes and creates the DOM object.
|
|
112
|
+
* This method is also called implicitly, if not yet done explicitly, by calling `connect()`.
|
|
113
|
+
*
|
|
114
|
+
* @throws {Error} this method must be implemented by derived classes
|
|
115
|
+
* @return {Monster.DOM.Resource}
|
|
116
|
+
*/
|
|
117
|
+
create() {
|
|
118
|
+
throw new Error("this method must be implemented by derived classes");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* This method appends the HTMLElement to the specified document.
|
|
123
|
+
* If the element has not yet been created, `create()` is called implicitly.
|
|
124
|
+
*
|
|
125
|
+
* throws {Error} target not found
|
|
126
|
+
* @return {Monster.DOM.Resource}
|
|
127
|
+
*/
|
|
128
|
+
connect() {
|
|
129
|
+
|
|
130
|
+
if (!(this[referenceSymbol] instanceof HTMLElement)) {
|
|
131
|
+
this.create();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
appendToDocument.call(this);
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @property {Document} document the document object into which the node is to be appended
|
|
140
|
+
* @property {string} src/href url to the corresponding resource
|
|
141
|
+
* @property {string} query defines the location where the resource is to be hooked into the dom.
|
|
142
|
+
* @property {string} id element attribute id
|
|
143
|
+
* @property {string} title element attribute title
|
|
144
|
+
* @property {string} class element attribute class
|
|
145
|
+
* @property {int} timeout timeout
|
|
146
|
+
*/
|
|
147
|
+
get defaults() {
|
|
148
|
+
return extend({}, super.defaults, {
|
|
149
|
+
[this.constructor.getURLAttribute()]: undefined,
|
|
150
|
+
[KEY_DOCUMENT]: getGlobalObject('document'),
|
|
151
|
+
[KEY_QUERY]: 'head',
|
|
152
|
+
[KEY_TIMEOUT]: 10000,
|
|
153
|
+
[ATTRIBUTE_ID]: (new ID('resource')).toString(),
|
|
154
|
+
[ATTRIBUTE_CLASS]: undefined,
|
|
155
|
+
[ATTRIBUTE_TITLE]: undefined
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* With `available()` you can check if a resource is available.
|
|
161
|
+
* This is the case when the tag is included and the resource is loaded.
|
|
162
|
+
*
|
|
163
|
+
* @return {Promise}
|
|
164
|
+
*/
|
|
165
|
+
available() {
|
|
166
|
+
const self = this;
|
|
167
|
+
if (!(self[referenceSymbol] instanceof HTMLElement)) {
|
|
168
|
+
return Promise.reject('no element')
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!self.isConnected()) {
|
|
172
|
+
return Promise.reject('element not connected')
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (self[internalStateSymbol].getSubject()['loaded'] === true) {
|
|
176
|
+
|
|
177
|
+
if (self[internalStateSymbol].getSubject()['error'] !== undefined) {
|
|
178
|
+
return Promise.reject(self[internalStateSymbol].getSubject()['error']);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return Promise.resolve();
|
|
182
|
+
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return new Promise(function (resolve, reject) {
|
|
186
|
+
|
|
187
|
+
const timeout = setTimeout(() => {
|
|
188
|
+
reject('timeout');
|
|
189
|
+
}, self.getOption('timeout'))
|
|
190
|
+
|
|
191
|
+
const observer = new Observer(() => {
|
|
192
|
+
clearTimeout(timeout);
|
|
193
|
+
self[internalStateSymbol].detachObserver(observer);
|
|
194
|
+
resolve();
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
self[internalStateSymbol].attachObserver(observer);
|
|
198
|
+
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @return {string}
|
|
205
|
+
*/
|
|
206
|
+
static getURLAttribute() {
|
|
207
|
+
throw new Error("this method must be implemented by derived classes");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @private
|
|
215
|
+
* @return {Promise}
|
|
216
|
+
* throws {Error} target not found
|
|
217
|
+
*/
|
|
218
|
+
function appendToDocument() {
|
|
219
|
+
const self = this;
|
|
220
|
+
|
|
221
|
+
const targetNode = document.querySelector(self.getOption(KEY_QUERY, 'head'))
|
|
222
|
+
if (!(targetNode instanceof HTMLElement)) {
|
|
223
|
+
throw new Error('target not found')
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
addEvents.call(self);
|
|
227
|
+
targetNode.appendChild(self[referenceSymbol]);
|
|
228
|
+
|
|
229
|
+
return self;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @private
|
|
234
|
+
* @return {addEvents}
|
|
235
|
+
*/
|
|
236
|
+
function addEvents() {
|
|
237
|
+
const self = this;
|
|
238
|
+
|
|
239
|
+
const onError = () => {
|
|
240
|
+
|
|
241
|
+
self[referenceSymbol].removeEventListener('error', onError);
|
|
242
|
+
self[referenceSymbol].removeEventListener('load', onLoad);
|
|
243
|
+
|
|
244
|
+
self[internalStateSymbol].setSubject({
|
|
245
|
+
loaded: true,
|
|
246
|
+
error: self[referenceSymbol][self.constructor.getURLAttribute()] + ' is not available',
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const onLoad = () => {
|
|
253
|
+
self[referenceSymbol].removeEventListener('error', onError);
|
|
254
|
+
self[referenceSymbol].removeEventListener('load', onLoad);
|
|
255
|
+
self[internalStateSymbol].getSubject()['loaded'] = true;
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
self[referenceSymbol].addEventListener('load', onLoad, false);
|
|
260
|
+
self[referenceSymbol].addEventListener('error', onError, false);
|
|
261
|
+
|
|
262
|
+
return self;
|
|
263
|
+
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
assignToNamespace('Monster.DOM', Resource);
|
|
268
|
+
export {Monster, Resource}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @author schukai GmbH
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {extend} from "../data/extend.js";
|
|
8
|
+
import {assignToNamespace, Monster} from "../namespace.js";
|
|
9
|
+
import {BaseWithOptions} from "../types/basewithoptions.js";
|
|
10
|
+
import {getGlobalObject} from "../types/global.js";
|
|
11
|
+
import {isArray} from "../types/is.js";
|
|
12
|
+
import {ATTRIBUTE_HREF, ATTRIBUTE_SRC} from "./constants.js";
|
|
13
|
+
import {Resource} from "./resource.js";
|
|
14
|
+
import {Data} from "./resource/data.js";
|
|
15
|
+
import {Stylesheet} from "./resource/link/stylesheet.js";
|
|
16
|
+
import {Script} from "./resource/script.js";
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* You can call the method via the monster namespace `new Monster.DOM.ResourceManager()`.
|
|
21
|
+
*
|
|
22
|
+
* ```
|
|
23
|
+
* <script type="module">
|
|
24
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.1/dist/monster.js';
|
|
25
|
+
* new Monster.DOM.ResourceManager()
|
|
26
|
+
* </script>
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* Alternatively, you can also integrate this function individually.
|
|
30
|
+
*
|
|
31
|
+
* ```
|
|
32
|
+
* <script type="module">
|
|
33
|
+
* import {Resource} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.1/dist/modules/dom/resourcemanager.js';
|
|
34
|
+
* new ResourceManager()
|
|
35
|
+
* </script>
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @since 1.25.0
|
|
39
|
+
* @copyright schukai GmbH
|
|
40
|
+
* @memberOf Monster.DOM
|
|
41
|
+
* @summary A Resource class
|
|
42
|
+
*/
|
|
43
|
+
class ResourceManager extends BaseWithOptions {
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param {Object} options
|
|
48
|
+
* throw {Error} unsupported document type
|
|
49
|
+
*/
|
|
50
|
+
constructor(options) {
|
|
51
|
+
super(options);
|
|
52
|
+
|
|
53
|
+
if (!(this.getOption('document') instanceof Document)) {
|
|
54
|
+
throw new Error('unsupported document type')
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @property {string} baseurl
|
|
62
|
+
*/
|
|
63
|
+
getBaseURL() {
|
|
64
|
+
this.getOption('document')?.baseURL;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
*
|
|
69
|
+
* @property {HTMLDocument} document=document Document
|
|
70
|
+
* @property {Object} resources
|
|
71
|
+
* @property {Array} resources.scripts=[] array with {@link Monster.DOM.Resource.Script} objects
|
|
72
|
+
* @property {Array} resources.stylesheets=[] array with {@link Monster.DOM.Resource.Link.Stylesheet} objects
|
|
73
|
+
* @property {Array} resources.data=[] array with {@link Monster.DOM.Resource.Data} objects
|
|
74
|
+
*/
|
|
75
|
+
get defaults() {
|
|
76
|
+
return Object.assign({}, super.defaults, {
|
|
77
|
+
document: getGlobalObject('document'),
|
|
78
|
+
resources: {
|
|
79
|
+
scripts: [],
|
|
80
|
+
stylesheets: [],
|
|
81
|
+
data: []
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Append Tags to DOM
|
|
88
|
+
*
|
|
89
|
+
* @return {Monster.DOM.ResourceManager}
|
|
90
|
+
* @throws {Error} unsupported resource definition
|
|
91
|
+
*/
|
|
92
|
+
connect() {
|
|
93
|
+
runResourceMethod.call(this, 'connect');
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Check if available
|
|
99
|
+
*
|
|
100
|
+
* @return {Promise}
|
|
101
|
+
* @throws {Error} unsupported resource definition
|
|
102
|
+
*/
|
|
103
|
+
available() {
|
|
104
|
+
return Promise.all(runResourceMethod.call(this, 'available'));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Add a script
|
|
109
|
+
*
|
|
110
|
+
* @param {string|URL} url
|
|
111
|
+
* @param [Object|undefined} options
|
|
112
|
+
* @return {Monster.DOM.ResourceManager}
|
|
113
|
+
* @see Monster.DOM.Resource.Script
|
|
114
|
+
*/
|
|
115
|
+
addScript(url, options) {
|
|
116
|
+
return addResource.call(this, 'scripts', url, options);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Add Stylesheet
|
|
122
|
+
*
|
|
123
|
+
* @param {string|URL} url
|
|
124
|
+
* @param [Object|undefined} options
|
|
125
|
+
* @return {Monster.DOM.ResourceManager}
|
|
126
|
+
* @see Monster.DOM.Resource.Link.Stylesheet
|
|
127
|
+
*/
|
|
128
|
+
addStylesheet(url, options) {
|
|
129
|
+
return addResource.call(this, 'stylesheets', url, options);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Add Data Tag
|
|
134
|
+
*
|
|
135
|
+
* @param {string|URL} url
|
|
136
|
+
* @param [Object|undefined} options
|
|
137
|
+
* @return {Monster.DOM.ResourceManager}
|
|
138
|
+
* @see Monster.DOM.Resource.Data
|
|
139
|
+
*/
|
|
140
|
+
addData(url, options) {
|
|
141
|
+
return addResource.call(this, 'data', url, options);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @private
|
|
149
|
+
* @param {string} method
|
|
150
|
+
* @return {Array}
|
|
151
|
+
*/
|
|
152
|
+
function runResourceMethod(method) {
|
|
153
|
+
const self = this;
|
|
154
|
+
|
|
155
|
+
const result = [];
|
|
156
|
+
|
|
157
|
+
for (const type of ['scripts', 'stylesheets', 'data']) {
|
|
158
|
+
const resources = self.getOption('resources.' + type);
|
|
159
|
+
if (!isArray(resources)) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
for (const resource of resources) {
|
|
164
|
+
if (!(resource instanceof Resource)) {
|
|
165
|
+
throw new Error('unsupported resource definition')
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
result.push(resource[method]());
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
*
|
|
178
|
+
* @param {string} type
|
|
179
|
+
* @param {string|URL} url
|
|
180
|
+
* @param [Object|undefined} options
|
|
181
|
+
* @return {Monster.DOM.ResourceManager}
|
|
182
|
+
* @private
|
|
183
|
+
*/
|
|
184
|
+
function addResource(type, url, options) {
|
|
185
|
+
const self = this;
|
|
186
|
+
|
|
187
|
+
if (url instanceof URL) {
|
|
188
|
+
url = url.toString();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
options = options || {}
|
|
192
|
+
|
|
193
|
+
let resource;
|
|
194
|
+
switch (type) {
|
|
195
|
+
case 'scripts':
|
|
196
|
+
resource = new Script(extend({}, options, {[ATTRIBUTE_SRC]: url}))
|
|
197
|
+
break;
|
|
198
|
+
case 'stylesheets':
|
|
199
|
+
resource = new Stylesheet(extend({}, options, {[ATTRIBUTE_HREF]: url}))
|
|
200
|
+
break;
|
|
201
|
+
case 'data':
|
|
202
|
+
resource = new Data(extend({}, options, {[ATTRIBUTE_SRC]: url}))
|
|
203
|
+
break;
|
|
204
|
+
default:
|
|
205
|
+
throw new Error('unsupported type ' + type)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
(self.getOption('resources')?.[type]).push(resource);
|
|
209
|
+
return self;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
assignToNamespace('Monster.DOM', ResourceManager);
|
|
214
|
+
export {Monster, ResourceManager}
|