@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
@@ -15,7 +15,7 @@ import {ATTRIBUTE_THEME_NAME, DEFAULT_THEME} from "./constants.js";
15
15
  *
16
16
  * ```
17
17
  * <script type="module">
18
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/theme.js';
18
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
19
19
  * console.log(new Monster.DOM.Theme())
20
20
  * </script>
21
21
  * ```
@@ -24,14 +24,14 @@ import {ATTRIBUTE_THEME_NAME, DEFAULT_THEME} from "./constants.js";
24
24
  *
25
25
  * ```
26
26
  * <script type="module">
27
- * import {Theme} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/theme.js';
27
+ * import {Theme} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/theme.js';
28
28
  * console.log(new Theme())
29
29
  * </script>
30
30
  * ```
31
31
  *
32
32
  * @example
33
33
  *
34
- * import {getDocumentTheme} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/theme.js';
34
+ * import {getDocumentTheme} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/theme.js';
35
35
  *
36
36
  * const theme = getDocumentTheme();
37
37
  * console.log(theme.getName());
@@ -1,9 +1,14 @@
1
1
  'use strict';
2
2
 
3
- import {Diff} from "../data/diff.js";
3
+ /**
4
+ * @author schukai GmbH
5
+ */
6
+
7
+ import {diff} from "../data/diff.js";
4
8
  import {Pathfinder} from "../data/pathfinder.js";
5
9
  import {Pipe} from "../data/pipe.js";
6
10
  import {
11
+ ATTRIBUTE_ERRORMESSAGE,
7
12
  ATTRIBUTE_UPDATER_ATTRIBUTES,
8
13
  ATTRIBUTE_UPDATER_BIND,
9
14
  ATTRIBUTE_UPDATER_INSERT,
@@ -11,9 +16,6 @@ import {
11
16
  ATTRIBUTE_UPDATER_REMOVE,
12
17
  ATTRIBUTE_UPDATER_REPLACE
13
18
  } from "../dom/constants.js";
14
- /**
15
- * @author schukai GmbH
16
- */
17
19
  import {assignToNamespace, Monster} from '../namespace.js';
18
20
  import {Base} from "../types/base.js";
19
21
  import {isArray, isInstance, isIterable} from "../types/is.js";
@@ -21,6 +23,7 @@ import {Observer} from "../types/observer.js";
21
23
  import {ProxyObserver} from "../types/proxyobserver.js";
22
24
  import {validateArray, validateInstance} from "../types/validate.js";
23
25
  import {clone} from "../util/clone.js";
26
+ import {trimSpaces} from "../util/trimspaces.js";
24
27
  import {findDocumentTemplate} from "./template.js";
25
28
  import {getDocument} from "./util.js";
26
29
 
@@ -28,15 +31,15 @@ import {getDocument} from "./util.js";
28
31
  /**
29
32
  * The updater class connects an object with the dom. In this way, structures and contents in the DOM can be programmatically adapted via attributes.
30
33
  *
31
- * For example, to include a string from an object, the attribute `data-monster-replace` can be used.
34
+ * For example, to include a string from an object, the attribute `data-monster-replace` can be used.
32
35
  * a further explanation can be found under {@tutorial dom-based-templating-implementation}.
33
36
  *
34
37
  * You can create an object of this class using the monster namespace `new Monster.DOM.Updater()`.
35
38
  *
36
39
  * ```
37
40
  * <script type="module">
38
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/updater.js';
39
- * console.log(new Monster.DOM.Updater())
41
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
42
+ * new Monster.DOM.Updater()
40
43
  * </script>
41
44
  * ```
42
45
  *
@@ -44,14 +47,14 @@ import {getDocument} from "./util.js";
44
47
  *
45
48
  * ```
46
49
  * <script type="module">
47
- * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/updater.js';
48
- * console.log(new Updater())
50
+ * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/updater.js';
51
+ * new Updater()
49
52
  * </script>
50
53
  * ```
51
54
  *
52
55
  * @example
53
56
  *
54
- * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/updater.js';
57
+ * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/updater.js';
55
58
  *
56
59
  * // First we prepare the html document.
57
60
  * // This is done here via script, but can also be inserted into the document as pure html.
@@ -65,7 +68,7 @@ import {getDocument} from "./util.js";
65
68
  * let obj = {
66
69
  * headline: "Hello World",
67
70
  * };
68
- *
71
+ *
69
72
  * // Now comes the real magic. we pass the updater the parent HTMLElement
70
73
  * // and the desired data structure.
71
74
  * const updater = new Updater(body, obj);
@@ -121,10 +124,10 @@ class Updater extends Base {
121
124
 
122
125
  const s = this.subject.getRealSubject();
123
126
 
124
- const diff = Diff(this.last, s)
127
+ const diffResult = diff(this.last, s)
125
128
  this.last = clone(s);
126
129
 
127
- for (const [, change] of Object.entries(diff)) {
130
+ for (const [, change] of Object.entries(diffResult)) {
128
131
  removeElement.call(this, change);
129
132
  insertElement.call(this, change);
130
133
  updateContent.call(this, change);
@@ -150,6 +153,13 @@ class Updater extends Base {
150
153
  }
151
154
 
152
155
  /**
156
+ * With this method, the eventlisteners are hooked in and the magic begins.
157
+ *
158
+ * ```
159
+ * updater.run().then(() => {
160
+ * updater.enableEventProcessing();
161
+ * });
162
+ * ```
153
163
  *
154
164
  * @since 1.9.0
155
165
  * @return {Updater}
@@ -166,6 +176,7 @@ class Updater extends Base {
166
176
  }
167
177
 
168
178
  /**
179
+ * This method turns off the magic or who loves it more profane it removes the eventListener.
169
180
  *
170
181
  * @since 1.9.0
171
182
  * @return {Updater}
@@ -181,10 +192,16 @@ class Updater extends Base {
181
192
  }
182
193
 
183
194
  /**
184
- * Let the magic begin
185
- *
186
195
  * The run method must be called for the update to start working.
196
+ * The method ensures that changes are detected.
187
197
  *
198
+ * ```
199
+ * updater.run().then(() => {
200
+ * updater.enableEventProcessing();
201
+ * });
202
+ * ```
203
+ *
204
+ * @summary Let the magic begin
188
205
  * @return {Promise}
189
206
  */
190
207
  run() {
@@ -195,13 +212,13 @@ class Updater extends Base {
195
212
  }
196
213
 
197
214
  /**
198
- * If you have passed a ProxyObserver in the constructor, you will get the same object here.
199
- * However, if you have passed a simple object, you will get the ProxyObserver here.
215
+ * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here.
216
+ * However, if you passed a simple object, here you will get a proxy for that object.
200
217
  *
201
218
  * For changes the ProxyObserver must be used.
202
219
  *
203
220
  * @since 1.8.0
204
- * @return {ProxyObserver}
221
+ * @return {Proxy}
205
222
  */
206
223
  getSubject() {
207
224
  return this.subject.getSubject();
@@ -336,9 +353,9 @@ function getControlEventHandler() {
336
353
  const pf = new Pathfinder(copy);
337
354
  pf.setVia(path, value);
338
355
 
339
- const diff = new Diff(copy, self.subject.getRealSubject());
356
+ const diffResult = diff(copy, self.subject.getRealSubject());
340
357
 
341
- if (diff.length > 0) {
358
+ if (diffResult.length > 0) {
342
359
  pathfinder.setVia(path, value);
343
360
  }
344
361
 
@@ -400,11 +417,11 @@ function insertElement(change) {
400
417
  found = true;
401
418
 
402
419
  const attributes = containerElement.getAttribute(ATTRIBUTE_UPDATER_INSERT);
403
- let def = attributes.trim();
420
+ let def = trimSpaces(attributes);
404
421
  let i = def.indexOf(' ');
405
- let key = def.substr(0, i).trim();
422
+ let key = trimSpaces(def.substr(0, i));
406
423
  let refPrefix = key + '-';
407
- let cmd = def.substr(i).trim();
424
+ let cmd = trimSpaces(def.substr(i));
408
425
 
409
426
  // this case is actually excluded by the query but is nevertheless checked again here
410
427
  if (cmd.indexOf('|') > 0) {
@@ -416,7 +433,14 @@ function insertElement(change) {
416
433
  pipe.setCallback(n, f);
417
434
  })
418
435
 
419
- let value = pipe.run(subject)
436
+ let value
437
+ try {
438
+ containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
439
+ value = pipe.run(subject)
440
+ } catch (e) {
441
+ containerElement.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
442
+ }
443
+
420
444
  let dataPath = cmd.split(':').pop();
421
445
 
422
446
  let insertPoint;
@@ -506,12 +530,12 @@ function applyRecursive(node, key, path) {
506
530
 
507
531
  if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) {
508
532
  let value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
509
- node.setAttribute(ATTRIBUTE_UPDATER_REPLACE, value.replace("path:" + key, "path:" + path));
533
+ node.setAttribute(ATTRIBUTE_UPDATER_REPLACE, value.replaceAll("path:" + key, "path:" + path));
510
534
  }
511
535
 
512
536
  if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
513
537
  let value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
514
- node.setAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES, value.replace("path:" + key, "path:" + path));
538
+ node.setAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES, value.replaceAll("path:" + key, "path:" + path));
515
539
  }
516
540
 
517
541
  for (const [, child] of Object.entries(node.childNodes)) {
@@ -533,6 +557,17 @@ function updateContent(change) {
533
557
 
534
558
  let p = clone(change?.['path']);
535
559
  runUpdateContent.call(this, this.element, p, subject);
560
+
561
+ const slots = this.element.querySelectorAll('slot');
562
+ if (slots.length > 0) {
563
+ for (const [, slot] of Object.entries(slots)) {
564
+ for (const [, element] of Object.entries(slot.assignedNodes())) {
565
+ runUpdateContent.call(this, element, p, subject);
566
+ }
567
+ }
568
+ }
569
+
570
+
536
571
  }
537
572
 
538
573
  /**
@@ -545,6 +580,7 @@ function updateContent(change) {
545
580
  */
546
581
  function runUpdateContent(container, parts, subject) {
547
582
  if (!isArray(parts)) return;
583
+ if (!(container instanceof HTMLElement)) return;
548
584
  parts = clone(parts);
549
585
 
550
586
  let mem = new WeakSet;
@@ -554,20 +590,37 @@ function runUpdateContent(container, parts, subject) {
554
590
  parts.pop();
555
591
 
556
592
  // Unfortunately, static data is always changed as well, since it is not possible to react to changes here.
557
- for (const [, element] of container.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_REPLACE + '^="path:' + current + '"], [' + ATTRIBUTE_UPDATER_REPLACE + '^="static:"]').entries()) {
593
+ const query = '[' + ATTRIBUTE_UPDATER_REPLACE + '^="path:' + current + '"], [' + ATTRIBUTE_UPDATER_REPLACE + '^="static:"]';
594
+ const e = container.querySelectorAll('' + query);
558
595
 
559
- if (mem.has(element)) continue;
596
+ const iterator = new Set([
597
+ ...e
598
+ ])
599
+
600
+ if (container.matches(query)) {
601
+ iterator.add(container);
602
+ }
603
+
604
+ iterator.forEach((key, element) => {
605
+
606
+ if (mem.has(element)) return;
560
607
  mem.add(element)
561
608
 
562
609
  const attributes = element.getAttribute(ATTRIBUTE_UPDATER_REPLACE)
563
- let cmd = attributes.trim();
610
+ let cmd = trimSpaces(attributes);
564
611
 
565
612
  let pipe = new Pipe(cmd);
566
613
  this.callbacks.forEach((f, n) => {
567
614
  pipe.setCallback(n, f);
568
615
  })
569
616
 
570
- let value = pipe.run(subject)
617
+ let value
618
+ try {
619
+ element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
620
+ value = pipe.run(subject)
621
+ } catch (e) {
622
+ element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
623
+ }
571
624
 
572
625
  if (value instanceof HTMLElement) {
573
626
  while (element.firstChild) {
@@ -578,7 +631,9 @@ function runUpdateContent(container, parts, subject) {
578
631
  element.innerHTML = value;
579
632
  }
580
633
 
581
- }
634
+ })
635
+
636
+
582
637
  }
583
638
 
584
639
  }
@@ -617,18 +672,33 @@ function runUpdateAttributes(container, parts, subject) {
617
672
  const current = parts.join('.');
618
673
  parts.pop();
619
674
 
620
- for (const [, element] of container.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_ATTRIBUTES + '*="path:' + current + '"]').entries()) {
675
+ let iterator = new Set;
676
+
677
+ const query = '[' + ATTRIBUTE_UPDATER_ATTRIBUTES + '*="path:' + current + '"], [' + ATTRIBUTE_UPDATER_ATTRIBUTES + '^="static:"]';
678
+ const e = container.querySelectorAll(query);
621
679
 
622
- if (mem.has(element)) continue;
680
+ if (e.length > 0) {
681
+ iterator = new Set(
682
+ [...e]
683
+ )
684
+ }
685
+
686
+ if (container.matches(query)) {
687
+ iterator.add(container);
688
+ }
689
+
690
+ iterator.forEach((key, element) => {
691
+
692
+ if (mem.has(element)) return;
623
693
  mem.add(element)
624
694
 
625
695
  const attributes = element.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)
626
696
 
627
697
  for (let [, def] of Object.entries(attributes.split(','))) {
628
- def = def.trim();
698
+ def = trimSpaces(def);
629
699
  let i = def.indexOf(' ');
630
- let name = def.substr(0, i).trim();
631
- let cmd = def.substr(i).trim();
700
+ let name = trimSpaces(def.substr(0, i));
701
+ let cmd = trimSpaces(def.substr(i));
632
702
 
633
703
  let pipe = new Pipe(cmd);
634
704
 
@@ -636,7 +706,14 @@ function runUpdateAttributes(container, parts, subject) {
636
706
  pipe.setCallback(n, f, element);
637
707
  })
638
708
 
639
- let value = pipe.run(subject)
709
+ let value
710
+ try {
711
+ element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
712
+ value = pipe.run(subject)
713
+ } catch (e) {
714
+ element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
715
+ }
716
+
640
717
 
641
718
  if (value === undefined) {
642
719
  element.removeAttribute(name)
@@ -647,9 +724,8 @@ function runUpdateAttributes(container, parts, subject) {
647
724
 
648
725
  handleInputControlAttributeUpdate.call(this, element, name, value);
649
726
 
650
-
651
727
  }
652
- }
728
+ });
653
729
 
654
730
  }
655
731
 
@@ -13,7 +13,7 @@ import {validateString} from "../types/validate.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/util.js';
16
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
17
17
  * console.log(Monster.DOM.getDocument())
18
18
  * </script>
19
19
  * ```
@@ -22,7 +22,7 @@ import {validateString} from "../types/validate.js";
22
22
  *
23
23
  * ```
24
24
  * <script type="module">
25
- * import {getDocument} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/util.js';
25
+ * import {getDocument} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/util.js';
26
26
  * console.log(getDocument())
27
27
  * </script>
28
28
  * ```
@@ -74,7 +74,7 @@ function getDocument() {
74
74
  *
75
75
  * ```
76
76
  * <script type="module">
77
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/util.js';
77
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
78
78
  * console.log(Monster.DOM.getWindow())
79
79
  * </script>
80
80
  * ```
@@ -83,7 +83,7 @@ function getDocument() {
83
83
  *
84
84
  * ```
85
85
  * <script type="module">
86
- * import {getWindow} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/util.js';
86
+ * import {getWindow} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/util.js';
87
87
  * console.log(getWindow(null))
88
88
  * </script>
89
89
  * ```
@@ -140,7 +140,7 @@ function getWindow() {
140
140
  *
141
141
  * ```
142
142
  * <script type="module">
143
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/util.js';
143
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
144
144
  * console.log(Monster.DOM.getDocumentFragmentFromString())
145
145
  * </script>
146
146
  * ```
@@ -149,7 +149,7 @@ function getWindow() {
149
149
  *
150
150
  * ```
151
151
  * <script type="module">
152
- * import {getDocumentFragmentFromString} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/dom/util.js';
152
+ * import {getDocumentFragmentFromString} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/util.js';
153
153
  * console.log(getDocumentFragmentFromString('<div></div>'))
154
154
  * </script>
155
155
  * ```
@@ -0,0 +1,134 @@
1
+ 'use strict';
2
+
3
+
4
+ /**
5
+ * @author schukai GmbH
6
+ */
7
+
8
+
9
+ import {internalSymbol} from "../../constants.js";
10
+ import {assignToNamespace, Monster} from "../../namespace.js";
11
+ import {Base} from "../../types/base.js";
12
+ import {getGlobal, getGlobalFunction} from "../../types/global.js";
13
+ import {isFunction} from "../../types/is.js";
14
+ import {validateInstance, validateString} from "../../types/validate.js";
15
+
16
+
17
+
18
+ /**
19
+ * You can call the function via the monster namespace `new Monster.DOM.Worker.getLocaleOfDocument()`.
20
+ *
21
+ * ```
22
+ * <script type="module">
23
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
24
+ * console.log(new Monster.DOM.Worker.Factory())
25
+ * </script>
26
+ * ```
27
+ *
28
+ * Alternatively, you can also integrate this function individually.
29
+ *
30
+ * ```
31
+ * <script type="module">
32
+ * import {Factory} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/worker/factory.js';
33
+ * console.log(new Factory())
34
+ * </script>
35
+ * ```
36
+ *
37
+ * @since 1.25.0
38
+ * @copyright schukai GmbH
39
+ * @memberOf Monster.DOM.Worker
40
+ * @summary A small factory to create worker
41
+ */
42
+ class Factory extends Base {
43
+
44
+
45
+ /**
46
+ *
47
+ */
48
+ constructor() {
49
+ super();
50
+ this[internalSymbol] = {
51
+ worker: new WeakMap
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Creates a worker from a URL
57
+ *
58
+ * @param {string|URL} url
59
+ * @param {function} messageHandler
60
+ * @param {function} errorHandler
61
+ * @return {Worker}
62
+ */
63
+ createFromURL = function (url, messageHandler, errorHandler) {
64
+
65
+ if (url instanceof URL) {
66
+ url = url.toString();
67
+ }
68
+
69
+ const workerClass = getGlobalFunction('Worker');
70
+ var worker = new workerClass(validateString(url));
71
+
72
+ if (isFunction(messageHandler)) {
73
+ worker.onmessage = (event) => {
74
+ messageHandler.call(worker, event);
75
+ }
76
+ }
77
+
78
+ if (isFunction(errorHandler)) {
79
+ worker.onerror = (event) => {
80
+ errorHandler.call(worker, event);
81
+ }
82
+ }
83
+
84
+ return worker;
85
+ };
86
+
87
+ /**
88
+ * Creates a worker from a script
89
+ *
90
+ * @param {string} content
91
+ * @param {function} messageHandler
92
+ * @param {function} errorHandler
93
+ * @return {Worker}
94
+ * @see https://developer.mozilla.org/de/docs/Web/API/URL/createObjectURL
95
+ */
96
+ createFromScript = function (content, messageHandler, errorHandler) {
97
+ const blobFunction = new getGlobalFunction('Blob')
98
+ const blob = new blobFunction([validateString(content)], {type: 'script/javascript'});
99
+
100
+ const url = getGlobalFunction('URL').createObjectURL(blob);
101
+ const worker = this.createFromURL(url, messageHandler, errorHandler);
102
+
103
+ this[internalSymbol]['worker'].set(worker, url);
104
+
105
+ return worker;
106
+
107
+ };
108
+
109
+ /**
110
+ * Terminate the worker and call revokeObjectURL if necessary.
111
+ *
112
+ * @param worker
113
+ * @return {Monster.DOM.Worker.Factory}
114
+ */
115
+ terminate(worker) {
116
+
117
+ const workerClass = getGlobalFunction('Worker');
118
+ validateInstance(worker, workerClass);
119
+
120
+ worker.terminate();
121
+
122
+ if (this[internalSymbol]['worker'].has(worker)) {
123
+ const url = this[internalSymbol]['worker'].get(worker);
124
+ URL.revokeObjectURL(url);
125
+ }
126
+
127
+ return this;
128
+ }
129
+
130
+
131
+ }
132
+
133
+ assignToNamespace('Monster.DOM.Worker', Factory);
134
+ export {Monster, Factory}