@schukai/monster 1.24.0 → 1.27.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 (214) hide show
  1. package/CHANGELOG +47 -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 +1 -1
  17. package/dist/modules/data/datasource/restapi.js +1 -1
  18. package/dist/modules/data/datasource/storage/localstorage.js +1 -1
  19. package/dist/modules/data/datasource/storage/namespace.js +1 -1
  20. package/dist/modules/data/datasource/storage/sessionstorage.js +1 -1
  21. package/dist/modules/data/datasource/storage.js +1 -1
  22. package/dist/modules/data/datasource.js +1 -1
  23. package/dist/modules/data/diff.js +1 -1
  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 +1 -1
  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 +2 -2
  31. package/dist/modules/dom/constants.js +2 -2
  32. package/dist/modules/dom/customcontrol.js +1 -1
  33. package/dist/modules/dom/customelement.js +1 -1
  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 +2 -2
  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 +1 -1
  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 +1 -1
  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 +1 -1
  82. package/dist/modules/types/proxyobserver.js +1 -1
  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 +1 -1
  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 +1 -1
  94. package/dist/modules/util/comparator.js +1 -1
  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 +1 -1
  98. package/dist/modules/util/trimspaces.js +1 -1
  99. package/dist/monster.dev.js +1528 -770
  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 +11 -2
  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 +25 -9
  113. package/source/data/buildtree.js +95 -0
  114. package/source/data/datasource/restapi.js +3 -3
  115. package/source/data/datasource/storage/localstorage.js +2 -2
  116. package/source/data/datasource/storage/sessionstorage.js +2 -2
  117. package/source/data/datasource/storage.js +3 -3
  118. package/source/data/datasource.js +3 -3
  119. package/source/data/diff.js +3 -3
  120. package/source/data/extend.js +2 -2
  121. package/source/data/pathfinder.js +4 -4
  122. package/source/data/pipe.js +3 -3
  123. package/source/data/transformer.js +7 -5
  124. package/source/dom/assembler.js +2 -2
  125. package/source/dom/attributes.js +111 -28
  126. package/source/dom/constants.js +287 -10
  127. package/source/dom/customcontrol.js +1 -1
  128. package/source/dom/customelement.js +1 -1
  129. package/source/dom/events.js +6 -7
  130. package/source/dom/focusmanager.js +250 -0
  131. package/source/dom/locale.js +10 -5
  132. package/source/dom/resource/data.js +170 -0
  133. package/source/dom/resource/link/stylesheet.js +54 -0
  134. package/source/dom/resource/link.js +125 -0
  135. package/source/dom/resource/script.js +112 -0
  136. package/source/dom/resource.js +268 -0
  137. package/source/dom/resourcemanager.js +214 -0
  138. package/source/dom/template.js +86 -16
  139. package/source/dom/theme.js +3 -3
  140. package/source/dom/updater.js +138 -90
  141. package/source/dom/util.js +6 -6
  142. package/source/dom/worker/factory.js +134 -0
  143. package/source/i18n/formatter.js +140 -0
  144. package/source/i18n/locale.js +6 -4
  145. package/source/i18n/provider.js +2 -2
  146. package/source/i18n/providers/fetch.js +18 -3
  147. package/source/i18n/translations.js +18 -9
  148. package/source/logging/handler/console.js +2 -2
  149. package/source/logging/handler.js +2 -2
  150. package/source/logging/logentry.js +2 -2
  151. package/source/logging/logger.js +2 -2
  152. package/source/math/random.js +9 -5
  153. package/source/namespace.js +1 -1
  154. package/source/text/formatter.js +190 -48
  155. package/source/types/base.js +4 -4
  156. package/source/types/basewithoptions.js +2 -2
  157. package/source/types/binary.js +4 -4
  158. package/source/types/dataurl.js +4 -4
  159. package/source/types/global.js +4 -4
  160. package/source/types/id.js +6 -3
  161. package/source/types/is.js +103 -85
  162. package/source/types/mediatype.js +4 -4
  163. package/source/types/node.js +179 -0
  164. package/source/types/nodelist.js +125 -0
  165. package/source/types/noderecursiveiterator.js +126 -0
  166. package/source/types/observer.js +3 -3
  167. package/source/types/observerlist.js +2 -2
  168. package/source/types/proxyobserver.js +5 -5
  169. package/source/types/queue.js +4 -4
  170. package/source/types/randomid.js +2 -2
  171. package/source/types/regex.js +49 -0
  172. package/source/types/stack.js +2 -2
  173. package/source/types/tokenlist.js +2 -2
  174. package/source/types/typeof.js +3 -3
  175. package/source/types/uniquequeue.js +2 -2
  176. package/source/types/uuid.js +102 -0
  177. package/source/types/validate.js +20 -20
  178. package/source/types/version.js +6 -6
  179. package/source/util/clone.js +2 -2
  180. package/source/util/comparator.js +4 -4
  181. package/source/util/freeze.js +5 -5
  182. package/source/util/processing.js +3 -3
  183. package/source/util/trimspaces.js +3 -3
  184. package/test/cases/data/buildtree.js +149 -0
  185. package/test/cases/data/datasource/restapi.js +1 -1
  186. package/test/cases/data/transformer.js +2 -0
  187. package/test/cases/dom/attributes.js +46 -19
  188. package/test/cases/dom/customelement.js +0 -3
  189. package/test/cases/dom/focusmanager.js +111 -0
  190. package/test/cases/dom/locale.js +1 -4
  191. package/test/cases/dom/resource/data.js +129 -0
  192. package/test/cases/dom/resource/link/stylesheet.js +101 -0
  193. package/test/cases/dom/resource/link.js +101 -0
  194. package/test/cases/dom/resource/script.js +115 -0
  195. package/test/cases/dom/resourcemanager.js +118 -0
  196. package/test/cases/dom/template.js +72 -14
  197. package/test/cases/dom/updater.js +102 -75
  198. package/test/cases/dom/worker/factory.js +63 -0
  199. package/test/cases/i18n/formatter.js +66 -0
  200. package/test/cases/monster.js +1 -1
  201. package/test/cases/text/formatter.js +36 -5
  202. package/test/cases/types/node.js +196 -0
  203. package/test/cases/types/nodelist.js +64 -0
  204. package/test/cases/types/noderecursiveiterator.js +54 -0
  205. package/test/cases/types/regex.js +32 -0
  206. package/test/cases/types/uuid.js +42 -0
  207. package/test/cases/util/freeze.js +30 -4
  208. package/test/util/cleanupdom.js +48 -0
  209. package/test/util/jsdom.js +22 -9
  210. package/test/web/import.js +14 -0
  211. package/test/web/monster-dev.html +3 -3
  212. package/test/web/monster.html +2 -2
  213. package/test/web/test.html +3 -3
  214. package/test/web/tests.js +7 -7
@@ -4,6 +4,7 @@
4
4
  * @author schukai GmbH
5
5
  */
6
6
 
7
+ import {internalSymbol} from "../constants.js";
7
8
  import {diff} from "../data/diff.js";
8
9
  import {Pathfinder} from "../data/pathfinder.js";
9
10
  import {Pipe} from "../data/pipe.js";
@@ -24,6 +25,7 @@ import {ProxyObserver} from "../types/proxyobserver.js";
24
25
  import {validateArray, validateInstance} from "../types/validate.js";
25
26
  import {clone} from "../util/clone.js";
26
27
  import {trimSpaces} from "../util/trimspaces.js";
28
+ import {findTargetElementFromEvent} from "./events.js";
27
29
  import {findDocumentTemplate} from "./template.js";
28
30
  import {getDocument} from "./util.js";
29
31
 
@@ -38,7 +40,7 @@ import {getDocument} from "./util.js";
38
40
  *
39
41
  * ```
40
42
  * <script type="module">
41
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/dom/updater.js';
43
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
42
44
  * new Monster.DOM.Updater()
43
45
  * </script>
44
46
  * ```
@@ -47,14 +49,14 @@ import {getDocument} from "./util.js";
47
49
  *
48
50
  * ```
49
51
  * <script type="module">
50
- * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/dom/updater.js';
52
+ * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/dom/updater.js';
51
53
  * new Updater()
52
54
  * </script>
53
55
  * ```
54
56
  *
55
57
  * @example
56
58
  *
57
- * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/dom/updater.js';
59
+ * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/dom/updater.js';
58
60
  *
59
61
  * // First we prepare the html document.
60
62
  * // This is done here via script, but can also be inserted into the document as pure html.
@@ -105,27 +107,27 @@ class Updater extends Base {
105
107
  /**
106
108
  * @type {HTMLElement}
107
109
  */
108
- this.element = validateInstance(element, HTMLElement);
109
-
110
110
  if (subject === undefined) subject = {}
111
- let a = subject;
112
111
  if (!isInstance(subject, ProxyObserver)) {
113
112
  subject = new ProxyObserver(subject);
114
113
  }
115
114
 
116
- this.last = {};
117
- this.callbacks = new Map();
118
- this.callbacks.set('checkstate', getCheckStateCallback.call(this));
115
+ this[internalSymbol] = {
116
+ element: validateInstance(element, HTMLElement),
117
+ last: {},
118
+ callbacks: new Map(),
119
+ eventTypes: ['keyup', 'click', 'change', 'drop', 'touchend', 'input'],
120
+ subject: subject
121
+ }
119
122
 
120
- /**
121
- * @type {object}
122
- */
123
- this.subject = subject.attachObserver(new Observer(() => {
123
+ this[internalSymbol].callbacks.set('checkstate', getCheckStateCallback.call(this));
124
124
 
125
- const s = this.subject.getRealSubject();
125
+ this[internalSymbol].subject.attachObserver(new Observer(() => {
126
126
 
127
- const diffResult = diff(this.last, s)
128
- this.last = clone(s);
127
+ const s = this[internalSymbol].subject.getRealSubject();
128
+
129
+ const diffResult = diff(this[internalSymbol].last, s)
130
+ this[internalSymbol].last = clone(s);
129
131
 
130
132
  for (const [, change] of Object.entries(diffResult)) {
131
133
  removeElement.call(this, change);
@@ -135,8 +137,6 @@ class Updater extends Base {
135
137
  }
136
138
  }));
137
139
 
138
- this.eventTypes = ['keyup', 'click', 'change', 'drop', 'touchend', 'input'];
139
-
140
140
  }
141
141
 
142
142
  /**
@@ -148,7 +148,7 @@ class Updater extends Base {
148
148
  * @return {Updater}
149
149
  */
150
150
  setEventTypes(types) {
151
- this.eventTypes = validateArray(types);
151
+ this[internalSymbol].eventTypes = validateArray(types);
152
152
  return this;
153
153
  }
154
154
 
@@ -163,12 +163,17 @@ class Updater extends Base {
163
163
  *
164
164
  * @since 1.9.0
165
165
  * @return {Updater}
166
+ * @throws {Error} the bind argument must start as a value with a path
166
167
  */
167
168
  enableEventProcessing() {
168
169
  this.disableEventProcessing();
169
170
 
170
- for (const type of this.eventTypes) {
171
- this.element.addEventListener(type, getControlEventHandler.call(this));
171
+ for (const type of this[internalSymbol].eventTypes) {
172
+ // @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
173
+ this[internalSymbol].element.addEventListener(type, getControlEventHandler.call(this), {
174
+ capture: true,
175
+ passive: true
176
+ });
172
177
  }
173
178
 
174
179
  return this;
@@ -183,8 +188,8 @@ class Updater extends Base {
183
188
  */
184
189
  disableEventProcessing() {
185
190
 
186
- for (const type of this.eventTypes) {
187
- this.element.removeEventListener(type, getControlEventHandler.call(this));
191
+ for (const type of this[internalSymbol].eventTypes) {
192
+ this[internalSymbol].element.removeEventListener(type, getControlEventHandler.call(this));
188
193
  }
189
194
 
190
195
  return this;
@@ -207,21 +212,32 @@ class Updater extends Base {
207
212
  run() {
208
213
  // the key __init__has no further meaning and is only
209
214
  // used to create the diff for empty objects.
210
- this.last = {'__init__': true};
211
- return this.subject.notifyObservers();
215
+ this[internalSymbol].last = {'__init__': true};
216
+ return this[internalSymbol].subject.notifyObservers();
217
+ }
218
+
219
+ /**
220
+ * Gets the values of bound elements and changes them in subject
221
+ *
222
+ * @since 1.27.0
223
+ * @return {Monster.DOM.Updater}
224
+ */
225
+ retrieve() {
226
+ retrieveFromBindings.call(this);
227
+ return this;
212
228
  }
213
229
 
214
230
  /**
215
- * If you have passed a ProxyObserver in the constructor, you will get the same object here.
216
- * However, if you have passed a simple object, you will get the ProxyObserver here.
231
+ * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here.
232
+ * However, if you passed a simple object, here you will get a proxy for that object.
217
233
  *
218
234
  * For changes the ProxyObserver must be used.
219
235
  *
220
236
  * @since 1.8.0
221
- * @return {ProxyObserver}
237
+ * @return {Proxy}
222
238
  */
223
239
  getSubject() {
224
- return this.subject.getSubject();
240
+ return this[internalSymbol].subject.getSubject();
225
241
  }
226
242
 
227
243
  /**
@@ -235,7 +251,7 @@ class Updater extends Base {
235
251
  * @throws {TypeError} value is not a function
236
252
  */
237
253
  setCallback(name, callback) {
238
- this.callbacks.set(name, callback);
254
+ this[internalSymbol].callbacks.set(name, callback);
239
255
  return this;
240
256
  }
241
257
 
@@ -252,6 +268,7 @@ function getCheckStateCallback() {
252
268
 
253
269
  return function (current) {
254
270
 
271
+ // this is a reference to the current object (therefore no array function here)
255
272
  if (this instanceof HTMLInputElement) {
256
273
  if (['radio', 'checkbox'].indexOf(this.type) !== -1) {
257
274
  return (this.value + "" === current + "") ? 'true' : undefined
@@ -261,9 +278,8 @@ function getCheckStateCallback() {
261
278
  if (isArray(current) && current.indexOf(this.value) !== -1) {
262
279
  return 'true'
263
280
  }
264
- return undefined;
265
-
266
281
 
282
+ return undefined;
267
283
  }
268
284
  }
269
285
  }
@@ -277,6 +293,7 @@ const symbol = Symbol('EventHandler');
277
293
  * @private
278
294
  * @return {function}
279
295
  * @this Updater
296
+ * @throws {Error} the bind argument must start as a value with a path
280
297
  */
281
298
  function getControlEventHandler() {
282
299
 
@@ -286,83 +303,112 @@ function getControlEventHandler() {
286
303
  return self[symbol];
287
304
  }
288
305
 
289
- const pathfinder = new Pathfinder(this.subject.getSubject());
290
-
291
306
  /**
292
307
  * @throws {Error} the bind argument must start as a value with a path.
293
308
  * @throws {Error} unsupported object
294
309
  * @param {Event} event
295
310
  */
296
311
  self[symbol] = (event) => {
297
- const element = event.target;
312
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND);
298
313
 
299
- if (!element.hasAttribute(ATTRIBUTE_UPDATER_BIND)) {
314
+ if (element === undefined) {
300
315
  return;
301
316
  }
302
317
 
303
- let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND);
318
+ retrieveAndSetValue.call(self, element);
304
319
 
305
- if (path.indexOf('path:') !== 0) {
306
- throw new Error('the bind argument must start as a value with a path.');
307
- }
320
+ }
308
321
 
309
- path = path.substr(5);
322
+ return self[symbol];
310
323
 
311
- let value;
312
324
 
313
- if (element instanceof HTMLInputElement) {
314
- switch (element.type) {
325
+ }
315
326
 
316
- case 'checkbox':
317
- value = element.checked ? element.value : undefined;
318
- break;
319
- default:
320
- value = element.value;
321
- break;
327
+ /**
328
+ * @throws {Error} the bind argument must start as a value with a path
329
+ * @param {HTMLElement} element
330
+ * @return void
331
+ */
332
+ function retrieveAndSetValue(element) {
322
333
 
334
+ const self = this;
323
335
 
324
- }
325
- } else if (element instanceof HTMLTextAreaElement) {
326
- value = element.value;
336
+ const pathfinder = new Pathfinder(self[internalSymbol].subject.getSubject());
327
337
 
328
- } else if (element instanceof HTMLSelectElement) {
338
+ let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND);
329
339
 
330
- switch (element.type) {
331
- case 'select-one':
332
- value = element.value;
333
- break;
334
- case 'select-multiple':
335
- value = element.value;
340
+ if (path.indexOf('path:') !== 0) {
341
+ throw new Error('the bind argument must start as a value with a path');
342
+ }
336
343
 
337
- let options = element?.selectedOptions;
338
- if (options === undefined) options = element.querySelectorAll(":scope option:checked");
339
- value = Array.from(options).map(({value}) => value);
344
+ path = path.substr(5);
340
345
 
341
- break;
342
- }
346
+ let value;
347
+
348
+ if (element instanceof HTMLInputElement) {
349
+ switch (element.type) {
350
+
351
+ case 'checkbox':
352
+ value = element.checked ? element.value : undefined;
353
+ break;
354
+ default:
355
+ value = element.value;
356
+ break;
343
357
 
344
358
 
345
- // values from customelements
346
- } else if ((element?.constructor?.prototype && !!Object.getOwnPropertyDescriptor(element.constructor.prototype, 'value')?.['get']) || element.hasOwnProperty('value')) {
347
- value = element?.['value'];
348
- } else {
349
- throw new Error("unsupported object");
350
359
  }
360
+ } else if (element instanceof HTMLTextAreaElement) {
361
+ value = element.value;
362
+
363
+ } else if (element instanceof HTMLSelectElement) {
351
364
 
352
- const copy = clone(self.subject.getRealSubject());
353
- const pf = new Pathfinder(copy);
354
- pf.setVia(path, value);
365
+ switch (element.type) {
366
+ case 'select-one':
367
+ value = element.value;
368
+ break;
369
+ case 'select-multiple':
370
+ value = element.value;
355
371
 
356
- const diffResult = diff(copy, self.subject.getRealSubject());
372
+ let options = element?.selectedOptions;
373
+ if (options === undefined) options = element.querySelectorAll(":scope option:checked");
374
+ value = Array.from(options).map(({value}) => value);
357
375
 
358
- if (diffResult.length > 0) {
359
- pathfinder.setVia(path, value);
376
+ break;
360
377
  }
361
378
 
379
+
380
+ // values from customelements
381
+ } else if ((element?.constructor?.prototype && !!Object.getOwnPropertyDescriptor(element.constructor.prototype, 'value')?.['get']) || element.hasOwnProperty('value')) {
382
+ value = element?.['value'];
383
+ } else {
384
+ throw new Error("unsupported object");
362
385
  }
363
386
 
364
- return self[symbol];
387
+ const copy = clone(self[internalSymbol].subject.getRealSubject());
388
+ const pf = new Pathfinder(copy);
389
+ pf.setVia(path, value);
365
390
 
391
+ const diffResult = diff(copy, self[internalSymbol].subject.getRealSubject());
392
+
393
+ if (diffResult.length > 0) {
394
+ pathfinder.setVia(path, value);
395
+ }
396
+ }
397
+
398
+ /**
399
+ * @since 1.27.0
400
+ * @return void
401
+ */
402
+ function retrieveFromBindings() {
403
+ const self = this;
404
+
405
+ if (self[internalSymbol].element.matches('[' + ATTRIBUTE_UPDATER_BIND + ']')) {
406
+ retrieveAndSetValue.call(self, element)
407
+ }
408
+
409
+ for (const [, element] of self[internalSymbol].element.querySelectorAll('[' + ATTRIBUTE_UPDATER_BIND + ']').entries()) {
410
+ retrieveAndSetValue.call(self, element)
411
+ }
366
412
 
367
413
  }
368
414
 
@@ -373,7 +419,9 @@ function getControlEventHandler() {
373
419
  * @return {void}
374
420
  */
375
421
  function removeElement(change) {
376
- for (const [, element] of this.element.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_REMOVE + ']').entries()) {
422
+ const self = this;
423
+
424
+ for (const [, element] of self[internalSymbol].element.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_REMOVE + ']').entries()) {
377
425
  element.parentNode.removeChild(element);
378
426
  }
379
427
  }
@@ -391,7 +439,7 @@ function removeElement(change) {
391
439
  */
392
440
  function insertElement(change) {
393
441
  const self = this;
394
- const subject = self.subject.getRealSubject();
442
+ const subject = self[internalSymbol].subject.getRealSubject();
395
443
  const document = getDocument();
396
444
 
397
445
  let mem = new WeakSet;
@@ -407,7 +455,7 @@ function insertElement(change) {
407
455
 
408
456
  while (p.length > 0) {
409
457
  const current = p.join('.');
410
- const list = this.element.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_INSERT + '*="path:' + current + '"]').entries()
458
+ const list = this[internalSymbol].element.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_INSERT + '*="path:' + current + '"]').entries()
411
459
 
412
460
  for (const [, containerElement] of list) {
413
461
 
@@ -429,7 +477,7 @@ function insertElement(change) {
429
477
  }
430
478
 
431
479
  let pipe = new Pipe(cmd);
432
- this.callbacks.forEach((f, n) => {
480
+ this[internalSymbol].callbacks.forEach((f, n) => {
433
481
  pipe.setCallback(n, f);
434
482
  })
435
483
 
@@ -530,12 +578,12 @@ function applyRecursive(node, key, path) {
530
578
 
531
579
  if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) {
532
580
  let value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
533
- node.setAttribute(ATTRIBUTE_UPDATER_REPLACE, value.replace("path:" + key, "path:" + path));
581
+ node.setAttribute(ATTRIBUTE_UPDATER_REPLACE, value.replaceAll("path:" + key, "path:" + path));
534
582
  }
535
583
 
536
584
  if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
537
585
  let value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
538
- node.setAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES, value.replace("path:" + key, "path:" + path));
586
+ node.setAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES, value.replaceAll("path:" + key, "path:" + path));
539
587
  }
540
588
 
541
589
  for (const [, child] of Object.entries(node.childNodes)) {
@@ -553,12 +601,12 @@ function applyRecursive(node, key, path) {
553
601
  */
554
602
  function updateContent(change) {
555
603
  const self = this;
556
- const subject = self.subject.getRealSubject();
604
+ const subject = self[internalSymbol].subject.getRealSubject();
557
605
 
558
606
  let p = clone(change?.['path']);
559
- runUpdateContent.call(this, this.element, p, subject);
607
+ runUpdateContent.call(this, this[internalSymbol].element, p, subject);
560
608
 
561
- const slots = this.element.querySelectorAll('slot');
609
+ const slots = this[internalSymbol].element.querySelectorAll('slot');
562
610
  if (slots.length > 0) {
563
611
  for (const [, slot] of Object.entries(slots)) {
564
612
  for (const [, element] of Object.entries(slot.assignedNodes())) {
@@ -610,7 +658,7 @@ function runUpdateContent(container, parts, subject) {
610
658
  let cmd = trimSpaces(attributes);
611
659
 
612
660
  let pipe = new Pipe(cmd);
613
- this.callbacks.forEach((f, n) => {
661
+ this[internalSymbol].callbacks.forEach((f, n) => {
614
662
  pipe.setCallback(n, f);
615
663
  })
616
664
 
@@ -646,9 +694,9 @@ function runUpdateContent(container, parts, subject) {
646
694
  * @return {void}
647
695
  */
648
696
  function updateAttributes(change) {
649
- const subject = this.subject.getRealSubject();
697
+ const subject = this[internalSymbol].subject.getRealSubject();
650
698
  let p = clone(change?.['path']);
651
- runUpdateAttributes.call(this, this.element, p, subject);
699
+ runUpdateAttributes.call(this, this[internalSymbol].element, p, subject);
652
700
  }
653
701
 
654
702
  /**
@@ -702,7 +750,7 @@ function runUpdateAttributes(container, parts, subject) {
702
750
 
703
751
  let pipe = new Pipe(cmd);
704
752
 
705
- self.callbacks.forEach((f, n) => {
753
+ self[internalSymbol].callbacks.forEach((f, n) => {
706
754
  pipe.setCallback(n, f, element);
707
755
  })
708
756
 
@@ -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.24.0/dist/modules/dom/util.js';
16
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.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.24.0/dist/modules/dom/util.js';
25
+ * import {getDocument} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.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.24.0/dist/modules/dom/util.js';
77
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.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.24.0/dist/modules/dom/util.js';
86
+ * import {getWindow} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.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.24.0/dist/modules/dom/util.js';
143
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.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.24.0/dist/modules/dom/util.js';
152
+ * import {getDocumentFragmentFromString} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.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.27.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.27.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}