@schukai/monster 1.14.0 → 1.15.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.
- package/CHANGELOG +38 -0
- package/README.md +5 -5
- package/dist/modules/constants.js +2 -2
- package/dist/modules/constraints/abstract.js +2 -2
- package/dist/modules/constraints/abstractoperator.js +2 -2
- package/dist/modules/constraints/andoperator.js +2 -2
- package/dist/modules/constraints/invalid.js +2 -2
- package/dist/modules/constraints/isarray.js +2 -2
- package/dist/modules/constraints/isobject.js +2 -2
- package/dist/modules/constraints/namespace.js +1 -1
- package/dist/modules/constraints/oroperator.js +2 -2
- package/dist/modules/constraints/valid.js +2 -2
- package/dist/modules/data/buildmap.js +2 -2
- package/dist/modules/data/diff.js +2 -2
- package/dist/modules/data/extend.js +2 -2
- package/dist/modules/data/namespace.js +1 -1
- package/dist/modules/data/pathfinder.js +2 -2
- package/dist/modules/data/pipe.js +2 -2
- package/dist/modules/data/transformer.js +2 -2
- package/dist/modules/dom/assembler.js +2 -2
- package/dist/modules/dom/attributes.js +2 -2
- package/dist/modules/dom/constants.js +1 -1
- package/dist/modules/dom/customcontrol.js +2 -2
- package/dist/modules/dom/customelement.js +2 -2
- package/dist/modules/dom/events.js +2 -2
- package/dist/modules/dom/locale.js +2 -2
- package/dist/modules/dom/namespace.js +1 -1
- package/dist/modules/dom/template.js +2 -2
- package/dist/modules/dom/theme.js +2 -2
- package/dist/modules/dom/updater.js +2 -2
- package/dist/modules/dom/util.js +2 -2
- package/dist/modules/i18n/locale.js +2 -2
- package/dist/modules/i18n/namespace.js +1 -1
- package/dist/modules/i18n/provider.js +2 -2
- package/dist/modules/i18n/providers/fetch.js +2 -2
- package/dist/modules/i18n/providers/namespace.js +1 -1
- package/dist/modules/i18n/translations.js +2 -2
- package/dist/modules/logging/handler/console.js +2 -2
- package/dist/modules/logging/handler/namespace.js +1 -1
- package/dist/modules/logging/handler.js +2 -2
- package/dist/modules/logging/logentry.js +2 -2
- package/dist/modules/logging/logger.js +2 -2
- 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 +2 -2
- package/dist/modules/namespace.js +2 -2
- package/dist/modules/text/formatter.js +2 -2
- package/dist/modules/text/namespace.js +1 -1
- package/dist/modules/types/base.js +2 -2
- package/dist/modules/types/basewithoptions.js +2 -2
- package/dist/modules/types/global.js +2 -2
- package/dist/modules/types/id.js +2 -2
- package/dist/modules/types/is.js +2 -2
- package/dist/modules/types/namespace.js +1 -1
- package/dist/modules/types/observer.js +2 -2
- package/dist/modules/types/observerlist.js +2 -2
- package/dist/modules/types/proxyobserver.js +2 -2
- package/dist/modules/types/queue.js +2 -2
- package/dist/modules/types/randomid.js +2 -2
- package/dist/modules/types/stack.js +2 -2
- package/dist/modules/types/tokenlist.js +2 -2
- package/dist/modules/types/typeof.js +2 -2
- package/dist/modules/types/uniquequeue.js +2 -2
- package/dist/modules/types/validate.js +2 -2
- package/dist/modules/types/version.js +2 -2
- package/dist/modules/util/clone.js +2 -2
- package/dist/modules/util/comparator.js +2 -2
- package/dist/modules/util/freeze.js +2 -2
- package/dist/modules/util/namespace.js +1 -1
- package/dist/monster.dev.js +8263 -7501
- package/dist/monster.dev.js.map +1 -1
- package/dist/monster.js +2 -9
- package/package.json +1 -1
- package/source/constants.js +6 -5
- package/source/constraints/abstract.js +2 -2
- package/source/constraints/abstractoperator.js +4 -4
- package/source/constraints/andoperator.js +8 -8
- package/source/constraints/invalid.js +6 -6
- package/source/constraints/isarray.js +7 -7
- package/source/constraints/isobject.js +7 -7
- package/source/constraints/namespace.js +2 -2
- package/source/constraints/oroperator.js +8 -8
- package/source/constraints/valid.js +7 -7
- package/source/data/buildmap.js +15 -15
- package/source/data/diff.js +9 -9
- package/source/data/extend.js +55 -13
- package/source/data/namespace.js +2 -2
- package/source/data/pathfinder.js +13 -14
- package/source/data/pipe.js +8 -8
- package/source/data/transformer.js +10 -11
- package/source/dom/assembler.js +7 -7
- package/source/dom/attributes.js +27 -28
- package/source/dom/constants.js +1 -2
- package/source/dom/customcontrol.js +90 -128
- package/source/dom/customelement.js +166 -71
- package/source/dom/events.js +9 -9
- package/source/dom/locale.js +5 -5
- package/source/dom/namespace.js +2 -2
- package/source/dom/template.js +30 -19
- package/source/dom/theme.js +8 -9
- package/source/dom/updater.js +43 -26
- package/source/dom/util.js +11 -11
- package/source/i18n/locale.js +7 -7
- package/source/i18n/namespace.js +1 -1
- package/source/i18n/provider.js +6 -6
- package/source/i18n/providers/fetch.js +10 -10
- package/source/i18n/translations.js +5 -5
- package/source/logging/handler/console.js +5 -5
- package/source/logging/handler/namespace.js +1 -1
- package/source/logging/handler.js +8 -8
- package/source/logging/logentry.js +5 -5
- package/source/logging/logger.js +5 -5
- package/source/logging/namespace.js +2 -2
- package/source/math/namespace.js +2 -2
- package/source/math/random.js +5 -5
- package/source/monster.js +48 -44
- package/source/namespace.js +2 -2
- package/source/text/formatter.js +6 -7
- package/source/text/namespace.js +1 -1
- package/source/types/base.js +4 -5
- package/source/types/basewithoptions.js +10 -9
- package/source/types/global.js +7 -7
- package/source/types/id.js +7 -7
- package/source/types/is.js +22 -22
- package/source/types/namespace.js +2 -2
- package/source/types/observer.js +7 -7
- package/source/types/observerlist.js +4 -4
- package/source/types/proxyobserver.js +32 -26
- package/source/types/queue.js +13 -7
- package/source/types/randomid.js +6 -6
- package/source/types/stack.js +11 -4
- package/source/types/tokenlist.js +9 -9
- package/source/types/typeof.js +5 -5
- package/source/types/uniquequeue.js +14 -7
- package/source/types/validate.js +27 -27
- package/source/types/version.js +9 -9
- package/source/util/clone.js +6 -6
- package/source/util/comparator.js +7 -7
- package/source/util/freeze.js +7 -7
- package/source/util/namespace.js +2 -2
- package/test/cases/data/extend.js +66 -13
- package/test/cases/dom/customcontrol.js +17 -3
- package/test/cases/dom/customelement.js +65 -7
- package/test/cases/dom/template.js +40 -1
- package/test/cases/monster.js +1 -1
- package/test/cases/types/proxyobserver.js +9 -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 +3 -3
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
import {extend} from "../data/extend.js";
|
|
3
4
|
/**
|
|
4
5
|
* @author schukai GmbH
|
|
5
6
|
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
import {isArray} from "../types/is.js";
|
|
9
|
-
import {OBJECTLINK_KEY_UPDATER} from "./constants.js";
|
|
10
|
-
import {Monster, CustomElement} from "./customelement.js";
|
|
7
|
+
import {assignToNamespace, Monster} from '../namespace.js';
|
|
8
|
+
import {CustomElement} from "./customelement.js";
|
|
11
9
|
|
|
12
10
|
|
|
13
11
|
/**
|
|
@@ -29,7 +27,7 @@ const internalSymbol = Symbol('internalSymbol');
|
|
|
29
27
|
*
|
|
30
28
|
* ```
|
|
31
29
|
* <script type="module">
|
|
32
|
-
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.
|
|
30
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.3/dist/modules/dom/customcontrol.js';
|
|
33
31
|
* console.log(new Monster.DOM.CustomControl())
|
|
34
32
|
* </script>
|
|
35
33
|
* ```
|
|
@@ -38,7 +36,7 @@ const internalSymbol = Symbol('internalSymbol');
|
|
|
38
36
|
*
|
|
39
37
|
* ```
|
|
40
38
|
* <script type="module">
|
|
41
|
-
* import {CustomControl} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.
|
|
39
|
+
* import {CustomControl} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.3/dist/modules/dom/customcontrol.js';
|
|
42
40
|
* console.log(new CustomControl())
|
|
43
41
|
* </script>
|
|
44
42
|
* ```
|
|
@@ -59,7 +57,7 @@ class CustomControl extends CustomElement {
|
|
|
59
57
|
constructor() {
|
|
60
58
|
super();
|
|
61
59
|
|
|
62
|
-
if (typeof this['attachInternals'] === 'function'
|
|
60
|
+
if (typeof this['attachInternals'] === 'function') {
|
|
63
61
|
// currently only supported by chrome
|
|
64
62
|
this[internalSymbol] = this.attachInternals();
|
|
65
63
|
}
|
|
@@ -67,15 +65,25 @@ class CustomControl extends CustomElement {
|
|
|
67
65
|
}
|
|
68
66
|
|
|
69
67
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
68
|
+
*
|
|
69
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals
|
|
70
|
+
* @since 1.14.0
|
|
71
|
+
* @return {boolean}
|
|
72
|
+
*/
|
|
73
|
+
static get formAssociated() {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* | option | description |
|
|
79
|
+
* |----------------|---------------------------------|
|
|
80
|
+
* | | |
|
|
73
81
|
*
|
|
74
82
|
* Derived classes can override and extend this method as follows.
|
|
75
83
|
*
|
|
76
84
|
* ```
|
|
77
85
|
* get defaults() {
|
|
78
|
-
* return
|
|
86
|
+
* return extends{}, super.defaults, {
|
|
79
87
|
* myValue:true
|
|
80
88
|
* });
|
|
81
89
|
* }
|
|
@@ -83,55 +91,11 @@ class CustomControl extends CustomElement {
|
|
|
83
91
|
*
|
|
84
92
|
* @see https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example
|
|
85
93
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals
|
|
86
|
-
* @return {
|
|
94
|
+
* @return {object}
|
|
87
95
|
* @since 1.14.0
|
|
88
96
|
*/
|
|
89
97
|
get defaults() {
|
|
90
|
-
|
|
91
|
-
return Object.assign({}, super.defaults, {
|
|
92
|
-
formAssociated: true
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* This method determines which attributes are to be monitored by `attributeChangedCallback()`.
|
|
99
|
-
*
|
|
100
|
-
* @return {string[]}
|
|
101
|
-
* @since 1.14.0
|
|
102
|
-
*/
|
|
103
|
-
static get observedAttributes() {
|
|
104
|
-
return [];
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* This method can be implemented in a derived class. The attributes must be defined in `observedAttributes()`.
|
|
109
|
-
*
|
|
110
|
-
* @param {string} name
|
|
111
|
-
* @param {string} oldValue
|
|
112
|
-
* @param {string} newValue
|
|
113
|
-
* @since 1.14.0
|
|
114
|
-
* @throws {Error} attributes but no handles have been defined
|
|
115
|
-
*/
|
|
116
|
-
attributeChangedCallback(name, oldValue, newValue) {
|
|
117
|
-
|
|
118
|
-
const a = this.constructor.observedAttributes();
|
|
119
|
-
|
|
120
|
-
if (!a || (isArray(a) && a.length > 0)) {
|
|
121
|
-
throw new Error('attributes but no handles have been defined');
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
*
|
|
129
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals
|
|
130
|
-
* @since 1.14.0
|
|
131
|
-
* @return {boolean}
|
|
132
|
-
*/
|
|
133
|
-
static get formAssociated() {
|
|
134
|
-
return true;
|
|
98
|
+
return extend({}, super.defaults);
|
|
135
99
|
}
|
|
136
100
|
|
|
137
101
|
/**
|
|
@@ -159,73 +123,6 @@ class CustomControl extends CustomElement {
|
|
|
159
123
|
throw Error('the value setter must be overwritten by the derived class');
|
|
160
124
|
}
|
|
161
125
|
|
|
162
|
-
/**
|
|
163
|
-
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
164
|
-
*
|
|
165
|
-
* ```
|
|
166
|
-
* // Use the control's name as the base name for submitted data
|
|
167
|
-
* const n = this.getAttribute('name');
|
|
168
|
-
* const entries = new FormData();
|
|
169
|
-
* entries.append(n + '-first-name', this.firstName_);
|
|
170
|
-
* entries.append(n + '-last-name', this.lastName_);
|
|
171
|
-
* this.setFormValue(entries);
|
|
172
|
-
* ```
|
|
173
|
-
*
|
|
174
|
-
* @param {File|string|FormData} value
|
|
175
|
-
* @param {File|string|FormData} state
|
|
176
|
-
* @since 1.14.0
|
|
177
|
-
* @return {undefined}
|
|
178
|
-
* @throws {DOMException} NotSupportedError
|
|
179
|
-
* @throws {Error} the ElementInternals is not supported and a polyfill is necessary
|
|
180
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setFormValue
|
|
181
|
-
*/
|
|
182
|
-
setFormValue(value, state) {
|
|
183
|
-
getInternal.call(this).setFormValue(value, state);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
*
|
|
188
|
-
* @param {object} flags
|
|
189
|
-
* @param {string|undefined} message
|
|
190
|
-
* @param {HTMLElement} anchor
|
|
191
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setValidity
|
|
192
|
-
* @since 1.14.0
|
|
193
|
-
* @return {undefined}
|
|
194
|
-
* @throws {DOMException} NotSupportedError
|
|
195
|
-
* @throws {Error} the ElementInternals is not supported and a polyfill is necessary
|
|
196
|
-
*/
|
|
197
|
-
setValidity(flags, message, anchor) {
|
|
198
|
-
getInternal.call(this).setValidity(flags, message, anchor);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
204
|
-
*
|
|
205
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity
|
|
206
|
-
* @since 1.14.0
|
|
207
|
-
* @return {boolean}
|
|
208
|
-
* @throws {DOMException} NotSupportedError
|
|
209
|
-
* @throws {Error} the ElementInternals is not supported and a polyfill is necessary
|
|
210
|
-
*/
|
|
211
|
-
checkValidity() {
|
|
212
|
-
return getInternal.call(this)?.checkValidity();
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
218
|
-
*
|
|
219
|
-
* @return {boolean}
|
|
220
|
-
* @since 1.14.0
|
|
221
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity
|
|
222
|
-
* @throws {Error} the ElementInternals is not supported and a polyfill is necessary
|
|
223
|
-
* @throws {DOMException} NotSupportedError
|
|
224
|
-
*/
|
|
225
|
-
reportValidity() {
|
|
226
|
-
return getInternal.call(this)?.reportValidity();
|
|
227
|
-
}
|
|
228
|
-
|
|
229
126
|
/**
|
|
230
127
|
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
231
128
|
*
|
|
@@ -316,6 +213,71 @@ class CustomControl extends CustomElement {
|
|
|
316
213
|
return getInternal.call(this)?.form;
|
|
317
214
|
}
|
|
318
215
|
|
|
216
|
+
/**
|
|
217
|
+
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
218
|
+
*
|
|
219
|
+
* ```
|
|
220
|
+
* // Use the control's name as the base name for submitted data
|
|
221
|
+
* const n = this.getAttribute('name');
|
|
222
|
+
* const entries = new FormData();
|
|
223
|
+
* entries.append(n + '-first-name', this.firstName_);
|
|
224
|
+
* entries.append(n + '-last-name', this.lastName_);
|
|
225
|
+
* this.setFormValue(entries);
|
|
226
|
+
* ```
|
|
227
|
+
*
|
|
228
|
+
* @param {File|string|FormData} value
|
|
229
|
+
* @param {File|string|FormData} state
|
|
230
|
+
* @since 1.14.0
|
|
231
|
+
* @return {undefined}
|
|
232
|
+
* @throws {DOMException} NotSupportedError
|
|
233
|
+
* @throws {Error} the ElementInternals is not supported and a polyfill is necessary
|
|
234
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setFormValue
|
|
235
|
+
*/
|
|
236
|
+
setFormValue(value, state) {
|
|
237
|
+
getInternal.call(this).setFormValue(value, state);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
*
|
|
242
|
+
* @param {object} flags
|
|
243
|
+
* @param {string|undefined} message
|
|
244
|
+
* @param {HTMLElement} anchor
|
|
245
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setValidity
|
|
246
|
+
* @since 1.14.0
|
|
247
|
+
* @return {undefined}
|
|
248
|
+
* @throws {DOMException} NotSupportedError
|
|
249
|
+
* @throws {Error} the ElementInternals is not supported and a polyfill is necessary
|
|
250
|
+
*/
|
|
251
|
+
setValidity(flags, message, anchor) {
|
|
252
|
+
getInternal.call(this).setValidity(flags, message, anchor);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
257
|
+
*
|
|
258
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity
|
|
259
|
+
* @since 1.14.0
|
|
260
|
+
* @return {boolean}
|
|
261
|
+
* @throws {DOMException} NotSupportedError
|
|
262
|
+
* @throws {Error} the ElementInternals is not supported and a polyfill is necessary
|
|
263
|
+
*/
|
|
264
|
+
checkValidity() {
|
|
265
|
+
return getInternal.call(this)?.checkValidity();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
270
|
+
*
|
|
271
|
+
* @return {boolean}
|
|
272
|
+
* @since 1.14.0
|
|
273
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity
|
|
274
|
+
* @throws {Error} the ElementInternals is not supported and a polyfill is necessary
|
|
275
|
+
* @throws {DOMException} NotSupportedError
|
|
276
|
+
*/
|
|
277
|
+
reportValidity() {
|
|
278
|
+
return getInternal.call(this)?.reportValidity();
|
|
279
|
+
}
|
|
280
|
+
|
|
319
281
|
}
|
|
320
282
|
|
|
321
283
|
/**
|
|
@@ -325,13 +287,13 @@ class CustomControl extends CustomElement {
|
|
|
325
287
|
*/
|
|
326
288
|
function getInternal() {
|
|
327
289
|
const self = this;
|
|
328
|
-
|
|
290
|
+
|
|
329
291
|
if (!(internalSymbol in this)) {
|
|
330
|
-
throw new Error('
|
|
292
|
+
throw new Error('ElementInternals is not supported and a polyfill is necessary');
|
|
331
293
|
}
|
|
332
294
|
|
|
333
295
|
return this[internalSymbol];
|
|
334
296
|
}
|
|
335
297
|
|
|
336
|
-
|
|
298
|
+
assignToNamespace('Monster.DOM', CustomControl);
|
|
337
299
|
export {Monster, CustomControl}
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
import {PROPERTY_KEY_INTERNALDATA} from "../constants.js";
|
|
4
|
+
import {extend} from "../data/extend.js";
|
|
5
|
+
import {Pathfinder} from "../data/pathfinder.js";
|
|
3
6
|
/**
|
|
4
7
|
* @author schukai GmbH
|
|
5
8
|
*/
|
|
6
|
-
|
|
7
|
-
import {Monster, Updater} from "./updater.js";
|
|
8
|
-
import {extend} from "../data/extend.js";
|
|
9
|
-
import {Pathfinder} from "../data/pathfinder.js";
|
|
10
|
-
import {ATTRIBUTE_OPTIONS, OBJECTLINK_KEY_UPDATER} from "./constants.js";
|
|
11
|
-
import {findDocumentTemplate, Template} from "./template.js";
|
|
12
|
-
import {addToObjectLink,getLinkedObjects, hasObjectLink} from "./attributes.js";
|
|
9
|
+
import {assignToNamespace, Monster} from '../namespace.js';
|
|
13
10
|
import {getGlobalObject} from "../types/global.js";
|
|
14
|
-
import {validateFunction, validateObject} from "../types/validate.js";
|
|
15
11
|
import {isString} from "../types/is.js";
|
|
16
|
-
import {
|
|
12
|
+
import {Observer} from "../types/observer.js";
|
|
13
|
+
import {ProxyObserver} from "../types/proxyobserver.js";
|
|
14
|
+
import {validateFunction, validateObject} from "../types/validate.js";
|
|
15
|
+
import {clone} from "../util/clone.js";
|
|
16
|
+
import {addToObjectLink, getLinkedObjects, hasObjectLink} from "./attributes.js";
|
|
17
|
+
import {ATTRIBUTE_OPTIONS, OBJECTLINK_KEY_UPDATER} from "./constants.js";
|
|
18
|
+
import {findDocumentTemplate, Template} from "./template.js";
|
|
19
|
+
import {Updater} from "./updater.js";
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* @private
|
|
20
23
|
* @type {symbol}
|
|
21
24
|
*/
|
|
22
|
-
const
|
|
25
|
+
const internalDataSymbol = Symbol.for(PROPERTY_KEY_INTERNALDATA);
|
|
23
26
|
|
|
24
27
|
/**
|
|
25
28
|
* @private
|
|
@@ -37,7 +40,6 @@ const initMethodSymbol = Symbol('initMethodSymbol');
|
|
|
37
40
|
*/
|
|
38
41
|
const assembleMethodSymbol = Symbol('assembleMethodSymbol');
|
|
39
42
|
|
|
40
|
-
|
|
41
43
|
/**
|
|
42
44
|
* To define a new HTML element we need the power of CustomElement
|
|
43
45
|
*
|
|
@@ -48,7 +50,7 @@ const assembleMethodSymbol = Symbol('assembleMethodSymbol');
|
|
|
48
50
|
*
|
|
49
51
|
* ```
|
|
50
52
|
* <script type="module">
|
|
51
|
-
* import {CustomElement} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.
|
|
53
|
+
* import {CustomElement} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.3/dist/modules/dom/customelement.js';
|
|
52
54
|
* console.log(new Monster.DOM.CustomElement())
|
|
53
55
|
* </script>
|
|
54
56
|
* ```
|
|
@@ -57,7 +59,7 @@ const assembleMethodSymbol = Symbol('assembleMethodSymbol');
|
|
|
57
59
|
*
|
|
58
60
|
* ```
|
|
59
61
|
* <script type="module">
|
|
60
|
-
* import {CustomElement} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.
|
|
62
|
+
* import {CustomElement} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.3/dist/modules/dom/customelement.js';
|
|
61
63
|
* console.log(new CustomElement())
|
|
62
64
|
* </script>
|
|
63
65
|
* ```
|
|
@@ -155,10 +157,21 @@ class CustomElement extends HTMLElement {
|
|
|
155
157
|
*/
|
|
156
158
|
constructor() {
|
|
157
159
|
super();
|
|
158
|
-
this[
|
|
160
|
+
this[internalDataSymbol] = new ProxyObserver({'options': extend({}, this.defaults, getOptionsFromAttributes.call(this))});
|
|
161
|
+
initOptionObserver.call(this);
|
|
159
162
|
this[initMethodSymbol]();
|
|
160
163
|
}
|
|
161
164
|
|
|
165
|
+
/**
|
|
166
|
+
* This method determines which attributes are to be monitored by `attributeChangedCallback()`.
|
|
167
|
+
*
|
|
168
|
+
* @return {string[]}
|
|
169
|
+
* @since 1.15.0
|
|
170
|
+
*/
|
|
171
|
+
static get observedAttributes() {
|
|
172
|
+
return [ATTRIBUTE_OPTIONS];
|
|
173
|
+
}
|
|
174
|
+
|
|
162
175
|
/**
|
|
163
176
|
* | option | description |
|
|
164
177
|
* |----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
@@ -190,6 +203,75 @@ class CustomElement extends HTMLElement {
|
|
|
190
203
|
};
|
|
191
204
|
}
|
|
192
205
|
|
|
206
|
+
/**
|
|
207
|
+
* There is no check on the name by this class. the developer is responsible for assigning an appropriate tag.
|
|
208
|
+
* if the name is not valid, registerCustomElement() will issue an error
|
|
209
|
+
*
|
|
210
|
+
* @link https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
|
|
211
|
+
* @return {string}
|
|
212
|
+
* @throws {Error} the method getTag must be overwritten by the derived class.
|
|
213
|
+
* @since 1.7.0
|
|
214
|
+
*/
|
|
215
|
+
static getTag() {
|
|
216
|
+
throw new Error("the method getTag must be overwritten by the derived class.");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* At this point a `CSSStyleSheet` object can be returned. If the environment does not
|
|
221
|
+
* support a constructor, then an object can also be built using the following detour.
|
|
222
|
+
*
|
|
223
|
+
* If `undefined` is returned then the shadowRoot does not get a stylesheet.
|
|
224
|
+
*
|
|
225
|
+
* ```
|
|
226
|
+
* const doc = document.implementation.createHTMLDocument('title');
|
|
227
|
+
*
|
|
228
|
+
* let style = doc.createElement("style");
|
|
229
|
+
* style.innerHTML="p{color:red;}";
|
|
230
|
+
*
|
|
231
|
+
* // WebKit Hack
|
|
232
|
+
* style.appendChild(document.createTextNode(""));
|
|
233
|
+
* // Add the <style> element to the page
|
|
234
|
+
* doc.head.appendChild(style);
|
|
235
|
+
* return doc.styleSheets[0];
|
|
236
|
+
* ;
|
|
237
|
+
* ```
|
|
238
|
+
*
|
|
239
|
+
* @return {CSSStyleSheet|undefined}
|
|
240
|
+
*/
|
|
241
|
+
static getCSSStyleSheet() {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* attach a new observer
|
|
247
|
+
*
|
|
248
|
+
* @param {Observer} observer
|
|
249
|
+
* @returns {CustomElement}
|
|
250
|
+
*/
|
|
251
|
+
attachObserver(observer) {
|
|
252
|
+
this[internalDataSymbol].attachObserver(observer)
|
|
253
|
+
return this;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* detach a observer
|
|
258
|
+
*
|
|
259
|
+
* @param {Observer} observer
|
|
260
|
+
* @returns {CustomElement}
|
|
261
|
+
*/
|
|
262
|
+
detachObserver(observer) {
|
|
263
|
+
this[internalDataSymbol].detachObserver(observer)
|
|
264
|
+
return this;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @param {Observer} observer
|
|
269
|
+
* @returns {ProxyObserver}
|
|
270
|
+
*/
|
|
271
|
+
containsObserver(observer) {
|
|
272
|
+
return this[internalDataSymbol].containsObserver(observer)
|
|
273
|
+
}
|
|
274
|
+
|
|
193
275
|
/**
|
|
194
276
|
* nested options can be specified by path `a.b.c`
|
|
195
277
|
*
|
|
@@ -202,7 +284,7 @@ class CustomElement extends HTMLElement {
|
|
|
202
284
|
let value;
|
|
203
285
|
|
|
204
286
|
try {
|
|
205
|
-
value = new Pathfinder(this[
|
|
287
|
+
value = new Pathfinder(this[internalDataSymbol].getRealSubject()['options']).getVia(path);
|
|
206
288
|
} catch (e) {
|
|
207
289
|
|
|
208
290
|
}
|
|
@@ -220,20 +302,27 @@ class CustomElement extends HTMLElement {
|
|
|
220
302
|
* @since 1.14.0
|
|
221
303
|
*/
|
|
222
304
|
setOption(path, value) {
|
|
305
|
+
new Pathfinder(this[internalDataSymbol].getSubject()['options']).setVia(path, value);
|
|
306
|
+
//this[internalDataSymbol].notifyObservers();
|
|
307
|
+
return this;
|
|
308
|
+
}
|
|
223
309
|
|
|
224
|
-
|
|
225
|
-
|
|
310
|
+
/**
|
|
311
|
+
* @since 1.15.0
|
|
312
|
+
* @param {string|object} options
|
|
313
|
+
* @return {CustomElement}
|
|
314
|
+
*/
|
|
315
|
+
setOptions(options) {
|
|
226
316
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
// reset value so that a change occurs
|
|
230
|
-
new Pathfinder(this[optionsSymbol]).setVia(path, false);
|
|
231
|
-
new Pathfinder(updater.getSubject()).setVia(path, value);
|
|
232
|
-
}
|
|
317
|
+
if (isString(options)) {
|
|
318
|
+
options = parseOptionsJSON(options)
|
|
233
319
|
}
|
|
234
320
|
|
|
235
|
-
|
|
321
|
+
const self = this;
|
|
322
|
+
extend(self[internalDataSymbol].getSubject()['options'], self.defaults, options);
|
|
323
|
+
//this[internalDataSymbol].notifyObservers();
|
|
236
324
|
|
|
325
|
+
return self;
|
|
237
326
|
}
|
|
238
327
|
|
|
239
328
|
/**
|
|
@@ -275,8 +364,8 @@ class CustomElement extends HTMLElement {
|
|
|
275
364
|
for (const [, element] of Object.entries(elements)) {
|
|
276
365
|
|
|
277
366
|
if (!(element instanceof HTMLElement)) continue;
|
|
278
|
-
|
|
279
|
-
const u = new Updater(element,
|
|
367
|
+
if ((element instanceof HTMLTemplateElement)) continue;
|
|
368
|
+
const u = new Updater(element, clone(self[internalDataSymbol].getRealSubject()['options']))
|
|
280
369
|
updater.add(u);
|
|
281
370
|
|
|
282
371
|
u.run().then(() => {
|
|
@@ -298,9 +387,7 @@ class CustomElement extends HTMLElement {
|
|
|
298
387
|
connectedCallback() {
|
|
299
388
|
let self = this;
|
|
300
389
|
if (!hasObjectLink(self, objectLinkSymbol)) {
|
|
301
|
-
|
|
302
|
-
self[assembleMethodSymbol]()
|
|
303
|
-
}, 0);
|
|
390
|
+
self[assembleMethodSymbol]()
|
|
304
391
|
}
|
|
305
392
|
}
|
|
306
393
|
|
|
@@ -326,58 +413,53 @@ class CustomElement extends HTMLElement {
|
|
|
326
413
|
|
|
327
414
|
/**
|
|
328
415
|
* Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial
|
|
329
|
-
* values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes
|
|
416
|
+
* values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes
|
|
417
|
+
* property will receive this callback.
|
|
330
418
|
*
|
|
331
419
|
* @param {string} attrName
|
|
332
420
|
* @param {string} oldVal
|
|
333
421
|
* @param {string} newVal
|
|
334
422
|
* @return {void}
|
|
335
|
-
* @since 1.
|
|
423
|
+
* @since 1.15.0
|
|
336
424
|
*/
|
|
337
425
|
attributeChangedCallback(attrName, oldVal, newVal) {
|
|
338
|
-
|
|
426
|
+
const self = this;
|
|
339
427
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
*
|
|
344
|
-
* @link https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
|
|
345
|
-
* @return {string}
|
|
346
|
-
* @throws {Error} the method getTag must be overwritten by the derived class.
|
|
347
|
-
* @since 1.7.0
|
|
348
|
-
*/
|
|
349
|
-
static getTag() {
|
|
350
|
-
throw new Error("the method getTag must be overwritten by the derived class.");
|
|
351
|
-
}
|
|
428
|
+
if (attrName === ATTRIBUTE_OPTIONS) {
|
|
429
|
+
self.setOptions(newVal);
|
|
430
|
+
}
|
|
352
431
|
|
|
353
|
-
/**
|
|
354
|
-
* At this point a `CSSStyleSheet` object can be returned. If the environment does not
|
|
355
|
-
* support a constructor, then an object can also be built using the following detour.
|
|
356
|
-
*
|
|
357
|
-
* If `undefined` is returned then the shadowRoot does not get a stylesheet.
|
|
358
|
-
*
|
|
359
|
-
* ```
|
|
360
|
-
* const doc = document.implementation.createHTMLDocument('title');
|
|
361
|
-
*
|
|
362
|
-
* let style = doc.createElement("style");
|
|
363
|
-
* style.innerHTML="p{color:red;}";
|
|
364
|
-
*
|
|
365
|
-
* // WebKit Hack
|
|
366
|
-
* style.appendChild(document.createTextNode(""));
|
|
367
|
-
* // Add the <style> element to the page
|
|
368
|
-
* doc.head.appendChild(style);
|
|
369
|
-
* return doc.styleSheets[0];
|
|
370
|
-
* ;
|
|
371
|
-
* ```
|
|
372
|
-
*
|
|
373
|
-
* @return {CSSStyleSheet|undefined}
|
|
374
|
-
*/
|
|
375
|
-
static getCSSStyleSheet() {
|
|
376
|
-
return undefined;
|
|
377
432
|
}
|
|
378
433
|
|
|
379
434
|
}
|
|
380
435
|
|
|
436
|
+
/**
|
|
437
|
+
* @since 1.15.0
|
|
438
|
+
* @private
|
|
439
|
+
*/
|
|
440
|
+
function initOptionObserver() {
|
|
441
|
+
const self = this;
|
|
442
|
+
|
|
443
|
+
self.attachObserver(new Observer(function () {
|
|
444
|
+
|
|
445
|
+
// not initialised
|
|
446
|
+
if (!hasObjectLink(self, Symbol.for(OBJECTLINK_KEY_UPDATER))) {
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
// inform every element
|
|
450
|
+
const updaters = getLinkedObjects(self, Symbol.for(OBJECTLINK_KEY_UPDATER));
|
|
451
|
+
|
|
452
|
+
for (const list of updaters) {
|
|
453
|
+
for (const updater of list) {
|
|
454
|
+
let d = clone(self[internalDataSymbol].getRealSubject()['options']);
|
|
455
|
+
Object.assign(updater.getSubject(), d);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
}));
|
|
460
|
+
|
|
461
|
+
}
|
|
462
|
+
|
|
381
463
|
/**
|
|
382
464
|
* @private
|
|
383
465
|
* @return {object}
|
|
@@ -386,11 +468,24 @@ class CustomElement extends HTMLElement {
|
|
|
386
468
|
function getOptionsFromAttributes() {
|
|
387
469
|
if (this.hasAttribute(ATTRIBUTE_OPTIONS)) {
|
|
388
470
|
try {
|
|
389
|
-
|
|
471
|
+
return parseOptionsJSON(this.getAttribute(ATTRIBUTE_OPTIONS))
|
|
472
|
+
} catch (e) {
|
|
473
|
+
throw new Error('the options attribute ' + ATTRIBUTE_OPTIONS + ' does not contain a valid json definition (actual: ' + this.getAttribute(ATTRIBUTE_OPTIONS) + ').');
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
return {};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
function parseOptionsJSON(data) {
|
|
482
|
+
if (isString(data)) {
|
|
483
|
+
try {
|
|
484
|
+
let obj = JSON.parse(data);
|
|
390
485
|
validateObject(obj);
|
|
391
486
|
return obj;
|
|
392
487
|
} catch (e) {
|
|
393
|
-
throw new Error('the options
|
|
488
|
+
throw new Error('the options does not contain a valid json definition (actual: ' + data + ').');
|
|
394
489
|
}
|
|
395
490
|
}
|
|
396
491
|
|
|
@@ -476,5 +571,5 @@ function registerCustomElement(element) {
|
|
|
476
571
|
getGlobalObject('customElements').define(element.getTag(), element);
|
|
477
572
|
}
|
|
478
573
|
|
|
479
|
-
|
|
574
|
+
assignToNamespace('Monster.DOM', CustomElement, registerCustomElement);
|
|
480
575
|
export {Monster, registerCustomElement, CustomElement, initMethodSymbol, assembleMethodSymbol}
|