@schukai/monster 1.24.0 → 1.27.0

Sign up to get free protection for your applications and to get access to all the features.
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}