@schukai/monster 1.22.0 → 1.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/CHANGELOG +56 -0
  2. package/README.md +4 -4
  3. package/dist/modules/constants.js +2 -2
  4. package/dist/modules/constraints/abstract.js +1 -1
  5. package/dist/modules/constraints/abstractoperator.js +1 -1
  6. package/dist/modules/constraints/andoperator.js +1 -1
  7. package/dist/modules/constraints/invalid.js +1 -1
  8. package/dist/modules/constraints/isarray.js +1 -1
  9. package/dist/modules/constraints/isobject.js +1 -1
  10. package/dist/modules/constraints/namespace.js +1 -1
  11. package/dist/modules/constraints/oroperator.js +1 -1
  12. package/dist/modules/constraints/valid.js +1 -1
  13. package/dist/modules/data/buildmap.js +2 -2
  14. package/dist/modules/data/buildtree.js +2 -0
  15. package/dist/modules/data/datasource/namespace.js +1 -1
  16. package/dist/modules/data/datasource/restapi/writeerror.js +2 -0
  17. package/dist/modules/data/datasource/restapi.js +2 -2
  18. package/dist/modules/data/datasource/storage/localstorage.js +2 -2
  19. package/dist/modules/data/datasource/storage/namespace.js +1 -1
  20. package/dist/modules/data/datasource/storage/sessionstorage.js +2 -2
  21. package/dist/modules/data/datasource/storage.js +2 -2
  22. package/dist/modules/data/datasource.js +2 -2
  23. package/dist/modules/data/diff.js +2 -2
  24. package/dist/modules/data/extend.js +1 -1
  25. package/dist/modules/data/namespace.js +1 -1
  26. package/dist/modules/data/pathfinder.js +2 -2
  27. package/dist/modules/data/pipe.js +1 -1
  28. package/dist/modules/data/transformer.js +2 -2
  29. package/dist/modules/dom/assembler.js +1 -1
  30. package/dist/modules/dom/attributes.js +1 -1
  31. package/dist/modules/dom/constants.js +2 -2
  32. package/dist/modules/dom/customcontrol.js +2 -2
  33. package/dist/modules/dom/customelement.js +2 -2
  34. package/dist/modules/dom/events.js +1 -1
  35. package/dist/modules/dom/focusmanager.js +2 -0
  36. package/dist/modules/dom/locale.js +1 -1
  37. package/dist/modules/dom/namespace.js +1 -1
  38. package/dist/modules/dom/resource/data.js +2 -0
  39. package/dist/modules/dom/resource/link/stylesheet.js +2 -0
  40. package/dist/modules/dom/resource/link.js +2 -0
  41. package/dist/modules/dom/resource/script.js +2 -0
  42. package/dist/modules/dom/resource.js +2 -0
  43. package/dist/modules/dom/resourcemanager.js +2 -0
  44. package/dist/modules/dom/template.js +1 -1
  45. package/dist/modules/dom/theme.js +1 -1
  46. package/dist/modules/dom/updater.js +2 -2
  47. package/dist/modules/dom/util.js +1 -1
  48. package/dist/modules/dom/worker/factory.js +2 -0
  49. package/dist/modules/i18n/formatter.js +2 -0
  50. package/dist/modules/i18n/locale.js +1 -1
  51. package/dist/modules/i18n/namespace.js +1 -1
  52. package/dist/modules/i18n/provider.js +1 -1
  53. package/dist/modules/i18n/providers/fetch.js +2 -2
  54. package/dist/modules/i18n/providers/namespace.js +1 -1
  55. package/dist/modules/i18n/translations.js +1 -1
  56. package/dist/modules/logging/handler/console.js +1 -1
  57. package/dist/modules/logging/handler/namespace.js +1 -1
  58. package/dist/modules/logging/handler.js +1 -1
  59. package/dist/modules/logging/logentry.js +1 -1
  60. package/dist/modules/logging/logger.js +1 -1
  61. package/dist/modules/logging/namespace.js +1 -1
  62. package/dist/modules/math/namespace.js +1 -1
  63. package/dist/modules/math/random.js +2 -2
  64. package/dist/modules/monster.js +1 -1
  65. package/dist/modules/namespace.js +1 -1
  66. package/dist/modules/text/formatter.js +2 -2
  67. package/dist/modules/text/namespace.js +1 -1
  68. package/dist/modules/types/base.js +1 -1
  69. package/dist/modules/types/basewithoptions.js +2 -2
  70. package/dist/modules/types/binary.js +1 -1
  71. package/dist/modules/types/dataurl.js +1 -1
  72. package/dist/modules/types/global.js +1 -1
  73. package/dist/modules/types/id.js +1 -1
  74. package/dist/modules/types/is.js +2 -2
  75. package/dist/modules/types/mediatype.js +1 -1
  76. package/dist/modules/types/namespace.js +1 -1
  77. package/dist/modules/types/node.js +2 -0
  78. package/dist/modules/types/nodelist.js +2 -0
  79. package/dist/modules/types/noderecursiveiterator.js +2 -0
  80. package/dist/modules/types/observer.js +1 -1
  81. package/dist/modules/types/observerlist.js +2 -2
  82. package/dist/modules/types/proxyobserver.js +2 -2
  83. package/dist/modules/types/queue.js +1 -1
  84. package/dist/modules/types/randomid.js +1 -1
  85. package/dist/modules/types/regex.js +2 -0
  86. package/dist/modules/types/stack.js +1 -1
  87. package/dist/modules/types/tokenlist.js +2 -2
  88. package/dist/modules/types/typeof.js +1 -1
  89. package/dist/modules/types/uniquequeue.js +1 -1
  90. package/dist/modules/types/uuid.js +2 -0
  91. package/dist/modules/types/validate.js +1 -1
  92. package/dist/modules/types/version.js +2 -2
  93. package/dist/modules/util/clone.js +2 -2
  94. package/dist/modules/util/comparator.js +2 -2
  95. package/dist/modules/util/freeze.js +1 -1
  96. package/dist/modules/util/namespace.js +1 -1
  97. package/dist/modules/util/processing.js +2 -2
  98. package/dist/modules/util/trimspaces.js +2 -0
  99. package/dist/monster.dev.js +1838 -792
  100. package/dist/monster.dev.js.map +1 -1
  101. package/dist/monster.js +2 -2
  102. package/package.json +13 -2
  103. package/source/constants.js +16 -7
  104. package/source/constraints/abstract.js +5 -0
  105. package/source/constraints/abstractoperator.js +5 -0
  106. package/source/constraints/andoperator.js +10 -5
  107. package/source/constraints/invalid.js +8 -3
  108. package/source/constraints/isarray.js +9 -4
  109. package/source/constraints/isobject.js +8 -3
  110. package/source/constraints/oroperator.js +10 -5
  111. package/source/constraints/valid.js +8 -3
  112. package/source/data/buildmap.js +27 -11
  113. package/source/data/buildtree.js +95 -0
  114. package/source/data/datasource/restapi/writeerror.js +49 -0
  115. package/source/data/datasource/restapi.js +95 -11
  116. package/source/data/datasource/storage/localstorage.js +15 -8
  117. package/source/data/datasource/storage/sessionstorage.js +16 -12
  118. package/source/data/datasource/storage.js +16 -7
  119. package/source/data/datasource.js +60 -16
  120. package/source/data/diff.js +8 -8
  121. package/source/data/extend.js +5 -5
  122. package/source/data/pathfinder.js +12 -6
  123. package/source/data/pipe.js +6 -5
  124. package/source/data/transformer.js +131 -24
  125. package/source/dom/assembler.js +2 -2
  126. package/source/dom/attributes.js +24 -24
  127. package/source/dom/constants.js +305 -12
  128. package/source/dom/customcontrol.js +40 -19
  129. package/source/dom/customelement.js +182 -102
  130. package/source/dom/events.js +6 -6
  131. package/source/dom/focusmanager.js +250 -0
  132. package/source/dom/locale.js +10 -5
  133. package/source/dom/resource/data.js +170 -0
  134. package/source/dom/resource/link/stylesheet.js +54 -0
  135. package/source/dom/resource/link.js +125 -0
  136. package/source/dom/resource/script.js +112 -0
  137. package/source/dom/resource.js +268 -0
  138. package/source/dom/resourcemanager.js +214 -0
  139. package/source/dom/template.js +40 -10
  140. package/source/dom/theme.js +3 -3
  141. package/source/dom/updater.js +115 -39
  142. package/source/dom/util.js +6 -6
  143. package/source/dom/worker/factory.js +134 -0
  144. package/source/i18n/formatter.js +140 -0
  145. package/source/i18n/locale.js +10 -8
  146. package/source/i18n/provider.js +4 -4
  147. package/source/i18n/providers/fetch.js +24 -14
  148. package/source/i18n/translations.js +20 -10
  149. package/source/logging/handler/console.js +2 -2
  150. package/source/logging/handler.js +2 -2
  151. package/source/logging/logentry.js +2 -2
  152. package/source/logging/logger.js +4 -4
  153. package/source/math/random.js +11 -5
  154. package/source/namespace.js +1 -1
  155. package/source/text/formatter.js +244 -27
  156. package/source/types/base.js +4 -4
  157. package/source/types/basewithoptions.js +10 -15
  158. package/source/types/binary.js +8 -8
  159. package/source/types/dataurl.js +6 -6
  160. package/source/types/global.js +9 -7
  161. package/source/types/id.js +6 -3
  162. package/source/types/is.js +103 -85
  163. package/source/types/mediatype.js +4 -4
  164. package/source/types/node.js +179 -0
  165. package/source/types/nodelist.js +125 -0
  166. package/source/types/noderecursiveiterator.js +126 -0
  167. package/source/types/observer.js +3 -3
  168. package/source/types/observerlist.js +3 -3
  169. package/source/types/proxyobserver.js +24 -7
  170. package/source/types/queue.js +6 -6
  171. package/source/types/randomid.js +2 -2
  172. package/source/types/regex.js +49 -0
  173. package/source/types/stack.js +2 -2
  174. package/source/types/tokenlist.js +8 -9
  175. package/source/types/typeof.js +3 -3
  176. package/source/types/uniquequeue.js +4 -4
  177. package/source/types/uuid.js +102 -0
  178. package/source/types/validate.js +20 -20
  179. package/source/types/version.js +6 -6
  180. package/source/util/clone.js +5 -6
  181. package/source/util/comparator.js +5 -5
  182. package/source/util/freeze.js +5 -5
  183. package/source/util/processing.js +33 -36
  184. package/source/util/trimspaces.js +85 -0
  185. package/test/cases/data/buildtree.js +149 -0
  186. package/test/cases/data/datasource/restapi.js +1 -1
  187. package/test/cases/data/datasource.js +4 -4
  188. package/test/cases/data/diff.js +4 -4
  189. package/test/cases/data/pathfinder.js +18 -9
  190. package/test/cases/data/pipe.js +26 -2
  191. package/test/cases/data/transformer.js +41 -10
  192. package/test/cases/dom/attributes.js +18 -14
  193. package/test/cases/dom/customcontrol.js +6 -5
  194. package/test/cases/dom/customelement.js +25 -26
  195. package/test/cases/dom/focusmanager.js +111 -0
  196. package/test/cases/dom/locale.js +1 -4
  197. package/test/cases/dom/resource/data.js +129 -0
  198. package/test/cases/dom/resource/link/stylesheet.js +101 -0
  199. package/test/cases/dom/resource/link.js +101 -0
  200. package/test/cases/dom/resource/script.js +115 -0
  201. package/test/cases/dom/resourcemanager.js +118 -0
  202. package/test/cases/dom/updater.js +42 -19
  203. package/test/cases/dom/worker/factory.js +63 -0
  204. package/test/cases/i18n/formatter.js +66 -0
  205. package/test/cases/monster.js +1 -1
  206. package/test/cases/text/formatter.js +71 -8
  207. package/test/cases/types/node.js +196 -0
  208. package/test/cases/types/nodelist.js +64 -0
  209. package/test/cases/types/noderecursiveiterator.js +54 -0
  210. package/test/cases/types/proxyobserver.js +55 -11
  211. package/test/cases/types/regex.js +32 -0
  212. package/test/cases/types/uuid.js +42 -0
  213. package/test/cases/util/freeze.js +30 -4
  214. package/test/cases/util/trimspaces.js +24 -0
  215. package/test/util/cleanupdom.js +48 -0
  216. package/test/util/jsdom.js +22 -9
  217. package/test/web/import.js +15 -0
  218. package/test/web/monster-dev.html +3 -3
  219. package/test/web/monster.html +2 -2
  220. package/test/web/test.html +3 -3
  221. package/test/web/tests.js +7 -7
@@ -1,47 +1,43 @@
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";
6
3
  /**
7
4
  * @author schukai GmbH
8
5
  */
6
+
7
+ import {internalSymbol} from "../constants.js";
8
+ import {extend} from "../data/extend.js";
9
+ import {Pathfinder} from "../data/pathfinder.js";
9
10
  import {assignToNamespace, Monster} from '../namespace.js';
10
11
  import {parseDataURL} from "../types/dataurl.js";
11
12
  import {getGlobalObject} from "../types/global.js";
12
- import {isArray, isObject, isString} from "../types/is.js";
13
+ import {isArray, isFunction, isObject, isString} from "../types/is.js";
13
14
  import {Observer} from "../types/observer.js";
14
15
  import {ProxyObserver} from "../types/proxyobserver.js";
15
16
  import {validateFunction, validateInstance, validateObject} from "../types/validate.js";
16
17
  import {clone} from "../util/clone.js";
17
18
  import {addToObjectLink, getLinkedObjects, hasObjectLink} from "./attributes.js";
18
- import {ATTRIBUTE_OPTIONS, OBJECTLINK_KEY_UPDATER} from "./constants.js";
19
+ import {ATTRIBUTE_DISABLED, ATTRIBUTE_OPTIONS, objectUpdaterLinkSymbol} from "./constants.js";
19
20
  import {findDocumentTemplate, Template} from "./template.js";
20
21
  import {Updater} from "./updater.js";
21
22
 
22
23
  /**
23
- * @private
24
- * @type {symbol}
25
- */
26
- const internalDataSymbol = Symbol.for(PROPERTY_KEY_INTERNALDATA);
27
-
28
- /**
29
- * @private
24
+ * @memberOf Monster.DOM
30
25
  * @type {symbol}
31
26
  */
32
- const objectLinkSymbol = Symbol.for(OBJECTLINK_KEY_UPDATER);
27
+ const initMethodSymbol = Symbol('initMethodSymbol');
33
28
 
34
29
  /**
35
30
  * @memberOf Monster.DOM
36
31
  * @type {symbol}
37
32
  */
38
- const initMethodSymbol = Symbol('initMethodSymbol');
33
+ const assembleMethodSymbol = Symbol('assembleMethodSymbol');
39
34
 
40
35
  /**
36
+ * this symbol holds the attribute observer callbacks. The key is the attribute name.
41
37
  * @memberOf Monster.DOM
42
38
  * @type {symbol}
43
39
  */
44
- const assembleMethodSymbol = Symbol('assembleMethodSymbol');
40
+ const attributeObserverSymbol = Symbol('attributeObserver');
45
41
 
46
42
 
47
43
  /**
@@ -96,21 +92,12 @@ const assembleMethodSymbol = Symbol('assembleMethodSymbol');
96
92
  *
97
93
  * <img src="./images/customelement-class.png">
98
94
  *
99
- * You can create the object via the monster namespace `new Monster.DOM.CustomElement()`.
100
- *
101
- * ```
102
- * <script type="module">
103
- * import {CustomElement} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/customelement.js';
104
- * console.log(new Monster.DOM.CustomElement())
105
- * </script>
106
- * ```
107
- *
108
- * Alternatively, you can also integrate this function individually.
95
+ * You can create the object via the function `document.createElement()`.
109
96
  *
110
97
  * ```
111
98
  * <script type="module">
112
- * import {CustomElement} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/customelement.js';
113
- * console.log(new CustomElement())
99
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
100
+ * document.createElement('monster-')
114
101
  * </script>
115
102
  * ```
116
103
  *
@@ -213,7 +200,8 @@ class CustomElement extends HTMLElement {
213
200
  */
214
201
  constructor() {
215
202
  super();
216
- this[internalDataSymbol] = new ProxyObserver({'options': extend({}, this.defaults, getOptionsFromAttributes.call(this))});
203
+ this[internalSymbol] = new ProxyObserver({'options': extend({}, this.defaults, getOptionsFromAttributes.call(this))});
204
+ this[attributeObserverSymbol] = {};
217
205
  initOptionObserver.call(this);
218
206
  this[initMethodSymbol]();
219
207
  }
@@ -225,7 +213,7 @@ class CustomElement extends HTMLElement {
225
213
  * @since 1.15.0
226
214
  */
227
215
  static get observedAttributes() {
228
- return [ATTRIBUTE_OPTIONS];
216
+ return [ATTRIBUTE_OPTIONS, ATTRIBUTE_DISABLED];
229
217
  }
230
218
 
231
219
  /**
@@ -265,7 +253,7 @@ class CustomElement extends HTMLElement {
265
253
  */
266
254
  get defaults() {
267
255
  return {
268
- disabled: false,
256
+ ATTRIBUTE_DISABLED: this.getAttribute(ATTRIBUTE_DISABLED),
269
257
  shadowMode: 'open',
270
258
  delegatesFocus: true,
271
259
  templates: {
@@ -320,7 +308,7 @@ class CustomElement extends HTMLElement {
320
308
  * @returns {CustomElement}
321
309
  */
322
310
  attachObserver(observer) {
323
- this[internalDataSymbol].attachObserver(observer)
311
+ this[internalSymbol].attachObserver(observer)
324
312
  return this;
325
313
  }
326
314
 
@@ -331,7 +319,7 @@ class CustomElement extends HTMLElement {
331
319
  * @returns {CustomElement}
332
320
  */
333
321
  detachObserver(observer) {
334
- this[internalDataSymbol].detachObserver(observer)
322
+ this[internalSymbol].detachObserver(observer)
335
323
  return this;
336
324
  }
337
325
 
@@ -340,7 +328,7 @@ class CustomElement extends HTMLElement {
340
328
  * @returns {ProxyObserver}
341
329
  */
342
330
  containsObserver(observer) {
343
- return this[internalDataSymbol].containsObserver(observer)
331
+ return this[internalSymbol].containsObserver(observer)
344
332
  }
345
333
 
346
334
  /**
@@ -355,7 +343,7 @@ class CustomElement extends HTMLElement {
355
343
  let value;
356
344
 
357
345
  try {
358
- value = new Pathfinder(this[internalDataSymbol].getRealSubject()['options']).getVia(path);
346
+ value = new Pathfinder(this[internalSymbol].getRealSubject()['options']).getVia(path);
359
347
  } catch (e) {
360
348
 
361
349
  }
@@ -373,7 +361,7 @@ class CustomElement extends HTMLElement {
373
361
  * @since 1.14.0
374
362
  */
375
363
  setOption(path, value) {
376
- new Pathfinder(this[internalDataSymbol].getSubject()['options']).setVia(path, value);
364
+ new Pathfinder(this[internalSymbol].getSubject()['options']).setVia(path, value);
377
365
  return this;
378
366
  }
379
367
 
@@ -389,7 +377,7 @@ class CustomElement extends HTMLElement {
389
377
  }
390
378
 
391
379
  const self = this;
392
- extend(self[internalDataSymbol].getSubject()['options'], self.defaults, options);
380
+ extend(self[internalSymbol].getSubject()['options'], self.defaults, options);
393
381
 
394
382
  return self;
395
383
  }
@@ -413,15 +401,17 @@ class CustomElement extends HTMLElement {
413
401
  [assembleMethodSymbol]() {
414
402
 
415
403
  const self = this;
416
- let elements;
404
+ let elements, nodeList;
417
405
 
418
- if (this.getOption('shadowMode', false) !== false) {
406
+ if (self.getOption('shadowMode', false) !== false) {
419
407
  try {
420
- initShadowRoot.call(this);
421
- elements = this.shadowRoot.childNodes;
408
+ initShadowRoot.call(self);
409
+ elements = self.shadowRoot.childNodes;
410
+
422
411
  } catch (e) {
423
412
 
424
413
  }
414
+
425
415
  try {
426
416
  initCSSStylesheet.call(this);
427
417
  } catch (e) {
@@ -430,34 +420,25 @@ class CustomElement extends HTMLElement {
430
420
  }
431
421
 
432
422
  if (!(elements instanceof NodeList)) {
433
- initHtmlContent.call(this);
434
- elements = this.childNodes;
435
- }
436
-
437
- const updater = new Set;
438
- addToObjectLink(this, objectLinkSymbol, updater);
439
-
440
- for (const [, element] of Object.entries(elements)) {
441
-
442
- if (!(element instanceof HTMLElement)) continue;
443
- if ((element instanceof HTMLTemplateElement)) continue;
444
- const u = new Updater(element, clone(self[internalDataSymbol].getRealSubject()['options']))
445
- updater.add(u);
446
-
447
- u.run().then(() => {
448
- u.enableEventProcessing();
449
- });
450
-
423
+ if (!(elements instanceof NodeList)) {
424
+ initHtmlContent.call(this);
425
+ elements = this.childNodes;
426
+ }
451
427
  }
452
428
 
453
- if (this.hasAttribute('disabled')) {
454
- self.setOption('disabled', true);
429
+ try {
430
+ nodeList = new Set([
431
+ ...elements,
432
+ ...getSlottedElements.call(self)
433
+ ])
434
+ } catch (e) {
435
+ nodeList = elements
455
436
  }
456
437
 
457
- return this;
438
+ assignUpdaterToElement.call(self, nodeList, clone(self[internalSymbol].getRealSubject()['options']));
439
+ return self;
458
440
  }
459
441
 
460
-
461
442
  /**
462
443
  * Called every time the element is inserted into the DOM. Useful for running setup code, such as
463
444
  * fetching resources or rendering. Generally, you should try to delay work until this time.
@@ -467,7 +448,7 @@ class CustomElement extends HTMLElement {
467
448
  */
468
449
  connectedCallback() {
469
450
  let self = this;
470
- if (!hasObjectLink(self, objectLinkSymbol)) {
451
+ if (!hasObjectLink(self, objectUpdaterLinkSymbol)) {
471
452
  self[assembleMethodSymbol]()
472
453
  }
473
454
  }
@@ -506,8 +487,10 @@ class CustomElement extends HTMLElement {
506
487
  attributeChangedCallback(attrName, oldVal, newVal) {
507
488
  const self = this;
508
489
 
509
- if (attrName === ATTRIBUTE_OPTIONS) {
510
- self.setOptions(newVal);
490
+ const callback = self[attributeObserverSymbol]?.[attrName];
491
+
492
+ if (isFunction(callback)) {
493
+ callback.call(self, newVal, oldVal);
511
494
  }
512
495
 
513
496
  }
@@ -522,7 +505,6 @@ class CustomElement extends HTMLElement {
522
505
  hasNode(node) {
523
506
  const self = this;
524
507
 
525
-
526
508
  if (containChildNode.call(self, validateInstance(node, Node))) {
527
509
  return true;
528
510
  }
@@ -538,6 +520,48 @@ class CustomElement extends HTMLElement {
538
520
  }
539
521
 
540
522
  /**
523
+ * @private
524
+ * @param {String} filter
525
+ * @return {*}
526
+ * @this CustomElement
527
+ * @since 1.23.0
528
+ */
529
+ function getSlottedElements(filter) {
530
+ const self = this;
531
+ const result = new Set;
532
+
533
+
534
+ if (!(self.shadowRoot instanceof ShadowRoot)) {
535
+ return result;
536
+ }
537
+
538
+ const slots = self.shadowRoot.querySelectorAll('slot');
539
+
540
+ for (const [, slot] of Object.entries(slots)) {
541
+ slot.assignedElements().forEach(function (node) {
542
+
543
+ if (!(node instanceof HTMLElement)) return;
544
+
545
+ if (filter !== undefined) {
546
+ node.querySelectorAll(filter).forEach(function (n) {
547
+ result.add(n);
548
+ });
549
+
550
+ if (node.matches(filter)) {
551
+ result.add(node);
552
+ }
553
+
554
+ } else {
555
+ result.add(node);
556
+ }
557
+ })
558
+ }
559
+
560
+ return result;
561
+ }
562
+
563
+ /**
564
+ * @this CustomElement
541
565
  * @private
542
566
  * @param {Node} node
543
567
  * @return {boolean}
@@ -577,63 +601,70 @@ function initOptionObserver() {
577
601
  return;
578
602
  }
579
603
 
580
- if (self.shadowRoot instanceof ShadowRoot) {
581
- const found = self.shadowRoot.querySelectorAll('button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]');
582
- for (const [, element] of Object.entries(found)) {
583
- if (flag === true) {
584
- element.setAttribute('disabled', '');
585
- } else {
586
- element.removeAttribute('disabled');
587
- }
604
+ lastDisabledValue = flag;
588
605
 
589
- }
606
+ if (!(self.shadowRoot instanceof ShadowRoot)) {
607
+ return;
590
608
  }
591
609
 
592
- lastDisabledValue = flag;
610
+ const query = 'button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]';
611
+ const elements = self.shadowRoot.querySelectorAll(query);
612
+
613
+ let nodeList;
614
+ try {
615
+ nodeList = new Set([
616
+ ...elements,
617
+ ...getSlottedElements.call(self, query)
618
+ ])
619
+ } catch (e) {
620
+ nodeList = elements
621
+ }
622
+
623
+ for (const element of [...nodeList]) {
624
+ if (flag === true) {
625
+ element.setAttribute(ATTRIBUTE_DISABLED, '');
626
+ } else {
627
+ element.removeAttribute(ATTRIBUTE_DISABLED);
628
+ }
629
+ }
593
630
 
594
631
  }));
595
-
632
+
596
633
  self.attachObserver(new Observer(function () {
597
634
 
598
635
  // not initialised
599
- if (!hasObjectLink(self, Symbol.for(OBJECTLINK_KEY_UPDATER))) {
636
+ if (!hasObjectLink(self, objectUpdaterLinkSymbol)) {
600
637
  return;
601
638
  }
602
639
  // inform every element
603
- const updaters = getLinkedObjects(self, Symbol.for(OBJECTLINK_KEY_UPDATER));
640
+ const updaters = getLinkedObjects(self, objectUpdaterLinkSymbol);
604
641
 
605
642
  for (const list of updaters) {
606
643
  for (const updater of list) {
607
- let d = clone(self[internalDataSymbol].getRealSubject()['options']);
644
+ let d = clone(self[internalSymbol].getRealSubject()['options']);
608
645
  Object.assign(updater.getSubject(), d);
609
646
  }
610
647
  }
611
648
 
612
649
  }));
613
650
 
614
- const observer = new MutationObserver(function (mutationsList, observer) {
615
-
616
- for (const mutation of mutationsList) {
617
- if (mutation.type === 'attributes') {
618
-
619
- switch (mutation?.attributeName) {
620
- case 'disabled':
621
- self.setOption('disabled', self.hasAttribute('disabled') ? true : undefined);
622
- break;
623
- case ATTRIBUTE_OPTIONS:
624
- const options = getOptionsFromAttributes.call(self);
625
- if (isObject(options)) {
626
- self.setOptions(options);
627
- }
628
-
629
- break;
630
- }
651
+ // disabled
652
+ self[attributeObserverSymbol][ATTRIBUTE_DISABLED] = (newVal) => {
653
+ if (self.hasAttribute(ATTRIBUTE_DISABLED)) {
654
+ self.setOption(ATTRIBUTE_DISABLED, true);
655
+ } else {
656
+ self.setOption(ATTRIBUTE_DISABLED, undefined);
657
+ }
658
+ }
631
659
 
632
- }
660
+ // data-monster-options
661
+ self[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => {
662
+ const options = getOptionsFromAttributes.call(self);
663
+ if (isObject(options)) {
664
+ self.setOptions(options);
633
665
  }
634
- });
666
+ }
635
667
 
636
- observer.observe(this, {attributes: true, attributeOldValue: true, childList: false, subtree: false});
637
668
 
638
669
  }
639
670
 
@@ -786,5 +817,54 @@ function registerCustomElement(element) {
786
817
  getGlobalObject('customElements').define(element.getTag(), element);
787
818
  }
788
819
 
789
- assignToNamespace('Monster.DOM', CustomElement, registerCustomElement);
790
- export {Monster, registerCustomElement, CustomElement, initMethodSymbol, assembleMethodSymbol}
820
+
821
+ /**
822
+ *
823
+ * @param element
824
+ * @param object
825
+ * @return {Promise[]}
826
+ * @since 1.23.0
827
+ * @memberOf Monster.DOM
828
+ */
829
+ function assignUpdaterToElement(elements, object) {
830
+
831
+ const updaters = new Set;
832
+
833
+ if (elements instanceof NodeList) {
834
+ elements = new Set([
835
+ ...elements
836
+ ])
837
+ }
838
+
839
+ let result = [];
840
+
841
+ elements.forEach((element) => {
842
+ if (!(element instanceof HTMLElement)) return;
843
+ if ((element instanceof HTMLTemplateElement)) return;
844
+
845
+ const u = new Updater(element, object)
846
+ updaters.add(u);
847
+
848
+ result.push(u.run().then(() => {
849
+ return u.enableEventProcessing();
850
+ }));
851
+
852
+ });
853
+
854
+ if (updaters.size > 0) {
855
+ addToObjectLink(this, objectUpdaterLinkSymbol, updaters);
856
+ }
857
+
858
+ return result;
859
+ }
860
+
861
+ assignToNamespace('Monster.DOM', CustomElement, registerCustomElement, assignUpdaterToElement);
862
+ export {
863
+ Monster,
864
+ registerCustomElement,
865
+ CustomElement,
866
+ initMethodSymbol,
867
+ assembleMethodSymbol,
868
+ assignUpdaterToElement,
869
+ attributeObserverSymbol
870
+ }
@@ -13,7 +13,7 @@ import {getDocument} from "./util.js";
13
13
  *
14
14
  * ```
15
15
  * <script type="module">
16
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/events.js';
16
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
17
17
  * console.log(new Monster.DOM.fireEvent())
18
18
  * </script>
19
19
  * ```
@@ -22,7 +22,7 @@ import {getDocument} from "./util.js";
22
22
  *
23
23
  * ```
24
24
  * <script type="module">
25
- * import {fireEvent} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/events.js';
25
+ * import {fireEvent} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/events.js';
26
26
  * console.log(fireEvent())
27
27
  * </script>
28
28
  * ```
@@ -66,14 +66,14 @@ function fireEvent(element, type) {
66
66
 
67
67
  /**
68
68
  * This function gets the path `Event.composedPath()` from an event and tries to find the next element
69
- * up the tree `element.closest()` with the attribute and value. If no value, or a value that is undefined or null,
69
+ * up the tree `element.closest()` with the attribute and value. If no value, or a value that is undefined or null,
70
70
  * is specified, only the attribute is searched.
71
71
  *
72
72
  * You can call the function via the monster namespace `new Monster.DOM.findTargetElementFromEvent()`.
73
73
  *
74
74
  * ```
75
75
  * <script type="module">
76
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/events.js';
76
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
77
77
  * console.log(new Monster.DOM.findTargetElementFromEvent())
78
78
  * </script>
79
79
  * ```
@@ -82,7 +82,7 @@ function fireEvent(element, type) {
82
82
  *
83
83
  * ```
84
84
  * <script type="module">
85
- * import {findTargetElementFromEvent} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/events.js';
85
+ * import {findTargetElementFromEvent} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/events.js';
86
86
  * console.log(findTargetElementFromEvent())
87
87
  * </script>
88
88
  * ```
@@ -114,7 +114,7 @@ function findTargetElementFromEvent(event, attributeName, attributeValue) {
114
114
 
115
115
  if (o instanceof HTMLElement &&
116
116
  o.hasAttribute(attributeName)
117
- && (attributeValue===undefined || o.getAttribute(attributeName) === attributeValue)) {
117
+ && (attributeValue === undefined || o.getAttribute(attributeName) === attributeValue)) {
118
118
  return o;
119
119
  }
120
120
  }