@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.
Files changed (151) hide show
  1. package/CHANGELOG +38 -0
  2. package/README.md +5 -5
  3. package/dist/modules/constants.js +2 -2
  4. package/dist/modules/constraints/abstract.js +2 -2
  5. package/dist/modules/constraints/abstractoperator.js +2 -2
  6. package/dist/modules/constraints/andoperator.js +2 -2
  7. package/dist/modules/constraints/invalid.js +2 -2
  8. package/dist/modules/constraints/isarray.js +2 -2
  9. package/dist/modules/constraints/isobject.js +2 -2
  10. package/dist/modules/constraints/namespace.js +1 -1
  11. package/dist/modules/constraints/oroperator.js +2 -2
  12. package/dist/modules/constraints/valid.js +2 -2
  13. package/dist/modules/data/buildmap.js +2 -2
  14. package/dist/modules/data/diff.js +2 -2
  15. package/dist/modules/data/extend.js +2 -2
  16. package/dist/modules/data/namespace.js +1 -1
  17. package/dist/modules/data/pathfinder.js +2 -2
  18. package/dist/modules/data/pipe.js +2 -2
  19. package/dist/modules/data/transformer.js +2 -2
  20. package/dist/modules/dom/assembler.js +2 -2
  21. package/dist/modules/dom/attributes.js +2 -2
  22. package/dist/modules/dom/constants.js +1 -1
  23. package/dist/modules/dom/customcontrol.js +2 -2
  24. package/dist/modules/dom/customelement.js +2 -2
  25. package/dist/modules/dom/events.js +2 -2
  26. package/dist/modules/dom/locale.js +2 -2
  27. package/dist/modules/dom/namespace.js +1 -1
  28. package/dist/modules/dom/template.js +2 -2
  29. package/dist/modules/dom/theme.js +2 -2
  30. package/dist/modules/dom/updater.js +2 -2
  31. package/dist/modules/dom/util.js +2 -2
  32. package/dist/modules/i18n/locale.js +2 -2
  33. package/dist/modules/i18n/namespace.js +1 -1
  34. package/dist/modules/i18n/provider.js +2 -2
  35. package/dist/modules/i18n/providers/fetch.js +2 -2
  36. package/dist/modules/i18n/providers/namespace.js +1 -1
  37. package/dist/modules/i18n/translations.js +2 -2
  38. package/dist/modules/logging/handler/console.js +2 -2
  39. package/dist/modules/logging/handler/namespace.js +1 -1
  40. package/dist/modules/logging/handler.js +2 -2
  41. package/dist/modules/logging/logentry.js +2 -2
  42. package/dist/modules/logging/logger.js +2 -2
  43. package/dist/modules/logging/namespace.js +1 -1
  44. package/dist/modules/math/namespace.js +1 -1
  45. package/dist/modules/math/random.js +2 -2
  46. package/dist/modules/monster.js +2 -2
  47. package/dist/modules/namespace.js +2 -2
  48. package/dist/modules/text/formatter.js +2 -2
  49. package/dist/modules/text/namespace.js +1 -1
  50. package/dist/modules/types/base.js +2 -2
  51. package/dist/modules/types/basewithoptions.js +2 -2
  52. package/dist/modules/types/global.js +2 -2
  53. package/dist/modules/types/id.js +2 -2
  54. package/dist/modules/types/is.js +2 -2
  55. package/dist/modules/types/namespace.js +1 -1
  56. package/dist/modules/types/observer.js +2 -2
  57. package/dist/modules/types/observerlist.js +2 -2
  58. package/dist/modules/types/proxyobserver.js +2 -2
  59. package/dist/modules/types/queue.js +2 -2
  60. package/dist/modules/types/randomid.js +2 -2
  61. package/dist/modules/types/stack.js +2 -2
  62. package/dist/modules/types/tokenlist.js +2 -2
  63. package/dist/modules/types/typeof.js +2 -2
  64. package/dist/modules/types/uniquequeue.js +2 -2
  65. package/dist/modules/types/validate.js +2 -2
  66. package/dist/modules/types/version.js +2 -2
  67. package/dist/modules/util/clone.js +2 -2
  68. package/dist/modules/util/comparator.js +2 -2
  69. package/dist/modules/util/freeze.js +2 -2
  70. package/dist/modules/util/namespace.js +1 -1
  71. package/dist/monster.dev.js +8263 -7501
  72. package/dist/monster.dev.js.map +1 -1
  73. package/dist/monster.js +2 -9
  74. package/package.json +1 -1
  75. package/source/constants.js +6 -5
  76. package/source/constraints/abstract.js +2 -2
  77. package/source/constraints/abstractoperator.js +4 -4
  78. package/source/constraints/andoperator.js +8 -8
  79. package/source/constraints/invalid.js +6 -6
  80. package/source/constraints/isarray.js +7 -7
  81. package/source/constraints/isobject.js +7 -7
  82. package/source/constraints/namespace.js +2 -2
  83. package/source/constraints/oroperator.js +8 -8
  84. package/source/constraints/valid.js +7 -7
  85. package/source/data/buildmap.js +15 -15
  86. package/source/data/diff.js +9 -9
  87. package/source/data/extend.js +55 -13
  88. package/source/data/namespace.js +2 -2
  89. package/source/data/pathfinder.js +13 -14
  90. package/source/data/pipe.js +8 -8
  91. package/source/data/transformer.js +10 -11
  92. package/source/dom/assembler.js +7 -7
  93. package/source/dom/attributes.js +27 -28
  94. package/source/dom/constants.js +1 -2
  95. package/source/dom/customcontrol.js +90 -128
  96. package/source/dom/customelement.js +166 -71
  97. package/source/dom/events.js +9 -9
  98. package/source/dom/locale.js +5 -5
  99. package/source/dom/namespace.js +2 -2
  100. package/source/dom/template.js +30 -19
  101. package/source/dom/theme.js +8 -9
  102. package/source/dom/updater.js +43 -26
  103. package/source/dom/util.js +11 -11
  104. package/source/i18n/locale.js +7 -7
  105. package/source/i18n/namespace.js +1 -1
  106. package/source/i18n/provider.js +6 -6
  107. package/source/i18n/providers/fetch.js +10 -10
  108. package/source/i18n/translations.js +5 -5
  109. package/source/logging/handler/console.js +5 -5
  110. package/source/logging/handler/namespace.js +1 -1
  111. package/source/logging/handler.js +8 -8
  112. package/source/logging/logentry.js +5 -5
  113. package/source/logging/logger.js +5 -5
  114. package/source/logging/namespace.js +2 -2
  115. package/source/math/namespace.js +2 -2
  116. package/source/math/random.js +5 -5
  117. package/source/monster.js +48 -44
  118. package/source/namespace.js +2 -2
  119. package/source/text/formatter.js +6 -7
  120. package/source/text/namespace.js +1 -1
  121. package/source/types/base.js +4 -5
  122. package/source/types/basewithoptions.js +10 -9
  123. package/source/types/global.js +7 -7
  124. package/source/types/id.js +7 -7
  125. package/source/types/is.js +22 -22
  126. package/source/types/namespace.js +2 -2
  127. package/source/types/observer.js +7 -7
  128. package/source/types/observerlist.js +4 -4
  129. package/source/types/proxyobserver.js +32 -26
  130. package/source/types/queue.js +13 -7
  131. package/source/types/randomid.js +6 -6
  132. package/source/types/stack.js +11 -4
  133. package/source/types/tokenlist.js +9 -9
  134. package/source/types/typeof.js +5 -5
  135. package/source/types/uniquequeue.js +14 -7
  136. package/source/types/validate.js +27 -27
  137. package/source/types/version.js +9 -9
  138. package/source/util/clone.js +6 -6
  139. package/source/util/comparator.js +7 -7
  140. package/source/util/freeze.js +7 -7
  141. package/source/util/namespace.js +2 -2
  142. package/test/cases/data/extend.js +66 -13
  143. package/test/cases/dom/customcontrol.js +17 -3
  144. package/test/cases/dom/customelement.js +65 -7
  145. package/test/cases/dom/template.js +40 -1
  146. package/test/cases/monster.js +1 -1
  147. package/test/cases/types/proxyobserver.js +9 -0
  148. package/test/web/monster-dev.html +3 -3
  149. package/test/web/monster.html +2 -2
  150. package/test/web/test.html +3 -3
  151. 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 {extend} from "../data/extend.js";
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.14.0/dist/modules/dom/customcontrol.js';
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.14.0/dist/modules/dom/customcontrol.js';
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' && this.getOption('formAssociated') === true) {
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
- * | option | description |
71
- * |----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
72
- * | formAssociated | Adding a static formAssociated property, with a true value, makes an autonomous custom element a form-associated custom element. |
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 Object.assign({}, super.defaults, {
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 {{shadowMode: string, delegatesFocus: boolean}}
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('the ElementInternals is not supported and a polyfill is necessary');
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
- Monster.assignToNamespace('Monster.DOM', CustomControl);
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 {PROPERTY_KEY_OPTIONS} from "../constants.js";
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 optionsSymbol = Symbol.for(PROPERTY_KEY_OPTIONS);
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.14.0/dist/modules/dom/customelement.js';
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.14.0/dist/modules/dom/customelement.js';
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[optionsSymbol] = extend({}, this.defaults, getOptionsFromAttributes.call(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[optionsSymbol]).getVia(path);
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
- // inform every element
225
- const updaters = getLinkedObjects(this, Symbol.for(OBJECTLINK_KEY_UPDATER));
310
+ /**
311
+ * @since 1.15.0
312
+ * @param {string|object} options
313
+ * @return {CustomElement}
314
+ */
315
+ setOptions(options) {
226
316
 
227
- for (const list of updaters) {
228
- for (const updater of list) {
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
- return this;
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, this[optionsSymbol])
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
- setTimeout(() => {
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 property will receive this callback.
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.7.0
423
+ * @since 1.15.0
336
424
  */
337
425
  attributeChangedCallback(attrName, oldVal, newVal) {
338
- }
426
+ const self = this;
339
427
 
340
- /**
341
- * There is no check on the name by this class. the developer is responsible for assigning an appropriate tag.
342
- * if the name is not valid, registerCustomElement() will issue an erro
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
- let obj = JSON.parse(this.getAttribute(ATTRIBUTE_OPTIONS))
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 attribute ' + ATTRIBUTE_OPTIONS + ' does not contain a valid json definition (actual: ' + this.getAttribute(ATTRIBUTE_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
- Monster.assignToNamespace('Monster.DOM', CustomElement, registerCustomElement);
574
+ assignToNamespace('Monster.DOM', CustomElement, registerCustomElement);
480
575
  export {Monster, registerCustomElement, CustomElement, initMethodSymbol, assembleMethodSymbol}