@schukai/monster 1.26.0 → 1.28.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. package/CHANGELOG +36 -1
  2. package/README.md +4 -4
  3. package/dist/modules/constants.js +1 -1
  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 -2
  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 +1 -1
  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 +2 -2
  35. package/dist/modules/dom/focusmanager.js +1 -1
  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 +1 -1
  39. package/dist/modules/dom/resource/link/stylesheet.js +1 -1
  40. package/dist/modules/dom/resource/link.js +1 -1
  41. package/dist/modules/dom/resource/script.js +1 -1
  42. package/dist/modules/dom/resource.js +1 -1
  43. package/dist/modules/dom/resourcemanager.js +1 -1
  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 +1 -1
  49. package/dist/modules/i18n/formatter.js +1 -1
  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 +1 -1
  64. package/dist/modules/monster.js +1 -1
  65. package/dist/modules/namespace.js +1 -1
  66. package/dist/modules/text/formatter.js +1 -1
  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 +1 -1
  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 -2
  78. package/dist/modules/types/nodelist.js +2 -2
  79. package/dist/modules/types/noderecursiveiterator.js +2 -2
  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 +1 -1
  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 +1 -1
  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 +883 -604
  100. package/dist/monster.dev.js.map +1 -1
  101. package/dist/monster.js +2 -2
  102. package/package.json +1 -1
  103. package/source/constraints/andoperator.js +5 -5
  104. package/source/constraints/invalid.js +3 -3
  105. package/source/constraints/isarray.js +3 -3
  106. package/source/constraints/isobject.js +3 -3
  107. package/source/constraints/oroperator.js +5 -5
  108. package/source/constraints/valid.js +3 -3
  109. package/source/data/buildmap.js +8 -10
  110. package/source/data/buildtree.js +51 -17
  111. package/source/data/datasource/restapi.js +3 -3
  112. package/source/data/datasource/storage/localstorage.js +2 -2
  113. package/source/data/datasource/storage/sessionstorage.js +2 -2
  114. package/source/data/datasource/storage.js +3 -3
  115. package/source/data/datasource.js +3 -3
  116. package/source/data/diff.js +3 -3
  117. package/source/data/extend.js +2 -2
  118. package/source/data/pathfinder.js +4 -4
  119. package/source/data/pipe.js +3 -3
  120. package/source/data/transformer.js +3 -3
  121. package/source/dom/assembler.js +2 -2
  122. package/source/dom/attributes.js +111 -28
  123. package/source/dom/constants.js +17 -1
  124. package/source/dom/customcontrol.js +1 -1
  125. package/source/dom/customelement.js +1 -1
  126. package/source/dom/events.js +68 -12
  127. package/source/dom/focusmanager.js +2 -2
  128. package/source/dom/locale.js +2 -2
  129. package/source/dom/resource/data.js +2 -2
  130. package/source/dom/resource/link/stylesheet.js +2 -2
  131. package/source/dom/resource/link.js +2 -2
  132. package/source/dom/resource/script.js +2 -2
  133. package/source/dom/resource.js +2 -2
  134. package/source/dom/resourcemanager.js +2 -2
  135. package/source/dom/template.js +55 -15
  136. package/source/dom/theme.js +3 -3
  137. package/source/dom/updater.js +156 -96
  138. package/source/dom/util.js +6 -6
  139. package/source/dom/worker/factory.js +2 -2
  140. package/source/i18n/formatter.js +4 -4
  141. package/source/i18n/locale.js +4 -4
  142. package/source/i18n/provider.js +2 -2
  143. package/source/i18n/providers/fetch.js +3 -3
  144. package/source/i18n/translations.js +4 -4
  145. package/source/logging/handler/console.js +2 -2
  146. package/source/logging/handler.js +2 -2
  147. package/source/logging/logentry.js +2 -2
  148. package/source/logging/logger.js +2 -2
  149. package/source/math/random.js +2 -2
  150. package/source/namespace.js +1 -1
  151. package/source/text/formatter.js +3 -3
  152. package/source/types/base.js +2 -2
  153. package/source/types/basewithoptions.js +2 -2
  154. package/source/types/binary.js +4 -4
  155. package/source/types/dataurl.js +4 -4
  156. package/source/types/global.js +4 -4
  157. package/source/types/id.js +2 -2
  158. package/source/types/is.js +20 -20
  159. package/source/types/mediatype.js +4 -4
  160. package/source/types/node.js +33 -2
  161. package/source/types/nodelist.js +9 -5
  162. package/source/types/noderecursiveiterator.js +29 -7
  163. package/source/types/observer.js +3 -3
  164. package/source/types/observerlist.js +2 -2
  165. package/source/types/proxyobserver.js +5 -5
  166. package/source/types/queue.js +3 -3
  167. package/source/types/randomid.js +2 -2
  168. package/source/types/regex.js +2 -2
  169. package/source/types/stack.js +2 -2
  170. package/source/types/tokenlist.js +2 -2
  171. package/source/types/typeof.js +3 -3
  172. package/source/types/uniquequeue.js +2 -2
  173. package/source/types/uuid.js +2 -2
  174. package/source/types/validate.js +20 -20
  175. package/source/types/version.js +6 -6
  176. package/source/util/clone.js +2 -2
  177. package/source/util/comparator.js +3 -3
  178. package/source/util/freeze.js +2 -2
  179. package/source/util/processing.js +3 -3
  180. package/source/util/trimspaces.js +2 -2
  181. package/test/cases/data/buildtree.js +84 -21
  182. package/test/cases/dom/attributes.js +29 -6
  183. package/test/cases/dom/events.js +66 -1
  184. package/test/cases/dom/template.js +72 -14
  185. package/test/cases/dom/updater.js +102 -75
  186. package/test/cases/monster.js +1 -1
  187. package/test/cases/types/node.js +57 -1
  188. package/test/cases/types/nodelist.js +7 -0
  189. package/test/cases/types/noderecursiveiterator.js +21 -0
  190. package/test/web/monster-dev.html +3 -3
  191. package/test/web/monster.html +2 -2
  192. package/test/web/test.html +3 -3
  193. package/test/web/tests.js +2 -2
@@ -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";
@@ -14,7 +15,8 @@ import {
14
15
  ATTRIBUTE_UPDATER_INSERT,
15
16
  ATTRIBUTE_UPDATER_INSERT_REFERENCE,
16
17
  ATTRIBUTE_UPDATER_REMOVE,
17
- ATTRIBUTE_UPDATER_REPLACE
18
+ ATTRIBUTE_UPDATER_REPLACE,
19
+ ATTRIBUTE_UPDATER_SELECT_THIS
18
20
  } from "../dom/constants.js";
19
21
  import {assignToNamespace, Monster} from '../namespace.js';
20
22
  import {Base} from "../types/base.js";
@@ -24,6 +26,7 @@ import {ProxyObserver} from "../types/proxyobserver.js";
24
26
  import {validateArray, validateInstance} from "../types/validate.js";
25
27
  import {clone} from "../util/clone.js";
26
28
  import {trimSpaces} from "../util/trimspaces.js";
29
+ import {findTargetElementFromEvent} from "./events.js";
27
30
  import {findDocumentTemplate} from "./template.js";
28
31
  import {getDocument} from "./util.js";
29
32
 
@@ -34,11 +37,14 @@ import {getDocument} from "./util.js";
34
37
  * For example, to include a string from an object, the attribute `data-monster-replace` can be used.
35
38
  * a further explanation can be found under {@tutorial dom-based-templating-implementation}.
36
39
  *
40
+ * Changes to attributes are made only when the direct values are changed. If you want to assign changes to other values
41
+ * as well, you have to insert the attribute `data-monster-select-this`. This should be done with care, as it can reduce performance.
42
+ *
37
43
  * You can create an object of this class using the monster namespace `new Monster.DOM.Updater()`.
38
44
  *
39
45
  * ```
40
46
  * <script type="module">
41
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
47
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/monster.js';
42
48
  * new Monster.DOM.Updater()
43
49
  * </script>
44
50
  * ```
@@ -47,14 +53,14 @@ import {getDocument} from "./util.js";
47
53
  *
48
54
  * ```
49
55
  * <script type="module">
50
- * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/updater.js';
56
+ * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/dom/updater.js';
51
57
  * new Updater()
52
58
  * </script>
53
59
  * ```
54
60
  *
55
61
  * @example
56
62
  *
57
- * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/updater.js';
63
+ * import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/dom/updater.js';
58
64
  *
59
65
  * // First we prepare the html document.
60
66
  * // This is done here via script, but can also be inserted into the document as pure html.
@@ -68,7 +74,7 @@ import {getDocument} from "./util.js";
68
74
  * let obj = {
69
75
  * headline: "Hello World",
70
76
  * };
71
- *
77
+ *
72
78
  * // Now comes the real magic. we pass the updater the parent HTMLElement
73
79
  * // and the desired data structure.
74
80
  * const updater = new Updater(body, obj);
@@ -105,27 +111,27 @@ class Updater extends Base {
105
111
  /**
106
112
  * @type {HTMLElement}
107
113
  */
108
- this.element = validateInstance(element, HTMLElement);
109
-
110
114
  if (subject === undefined) subject = {}
111
- let a = subject;
112
115
  if (!isInstance(subject, ProxyObserver)) {
113
116
  subject = new ProxyObserver(subject);
114
117
  }
115
118
 
116
- this.last = {};
117
- this.callbacks = new Map();
118
- this.callbacks.set('checkstate', getCheckStateCallback.call(this));
119
+ this[internalSymbol] = {
120
+ element: validateInstance(element, HTMLElement),
121
+ last: {},
122
+ callbacks: new Map(),
123
+ eventTypes: ['keyup', 'click', 'change', 'drop', 'touchend', 'input'],
124
+ subject: subject
125
+ }
119
126
 
120
- /**
121
- * @type {object}
122
- */
123
- this.subject = subject.attachObserver(new Observer(() => {
127
+ this[internalSymbol].callbacks.set('checkstate', getCheckStateCallback.call(this));
128
+
129
+ this[internalSymbol].subject.attachObserver(new Observer(() => {
124
130
 
125
- const s = this.subject.getRealSubject();
131
+ const s = this[internalSymbol].subject.getRealSubject();
126
132
 
127
- const diffResult = diff(this.last, s)
128
- this.last = clone(s);
133
+ const diffResult = diff(this[internalSymbol].last, s)
134
+ this[internalSymbol].last = clone(s);
129
135
 
130
136
  for (const [, change] of Object.entries(diffResult)) {
131
137
  removeElement.call(this, change);
@@ -135,8 +141,6 @@ class Updater extends Base {
135
141
  }
136
142
  }));
137
143
 
138
- this.eventTypes = ['keyup', 'click', 'change', 'drop', 'touchend', 'input'];
139
-
140
144
  }
141
145
 
142
146
  /**
@@ -148,7 +152,7 @@ class Updater extends Base {
148
152
  * @return {Updater}
149
153
  */
150
154
  setEventTypes(types) {
151
- this.eventTypes = validateArray(types);
155
+ this[internalSymbol].eventTypes = validateArray(types);
152
156
  return this;
153
157
  }
154
158
 
@@ -163,12 +167,17 @@ class Updater extends Base {
163
167
  *
164
168
  * @since 1.9.0
165
169
  * @return {Updater}
170
+ * @throws {Error} the bind argument must start as a value with a path
166
171
  */
167
172
  enableEventProcessing() {
168
173
  this.disableEventProcessing();
169
174
 
170
- for (const type of this.eventTypes) {
171
- this.element.addEventListener(type, getControlEventHandler.call(this));
175
+ for (const type of this[internalSymbol].eventTypes) {
176
+ // @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
177
+ this[internalSymbol].element.addEventListener(type, getControlEventHandler.call(this), {
178
+ capture: true,
179
+ passive: true
180
+ });
172
181
  }
173
182
 
174
183
  return this;
@@ -183,8 +192,8 @@ class Updater extends Base {
183
192
  */
184
193
  disableEventProcessing() {
185
194
 
186
- for (const type of this.eventTypes) {
187
- this.element.removeEventListener(type, getControlEventHandler.call(this));
195
+ for (const type of this[internalSymbol].eventTypes) {
196
+ this[internalSymbol].element.removeEventListener(type, getControlEventHandler.call(this));
188
197
  }
189
198
 
190
199
  return this;
@@ -207,8 +216,19 @@ class Updater extends Base {
207
216
  run() {
208
217
  // the key __init__has no further meaning and is only
209
218
  // used to create the diff for empty objects.
210
- this.last = {'__init__': true};
211
- return this.subject.notifyObservers();
219
+ this[internalSymbol].last = {'__init__': true};
220
+ return this[internalSymbol].subject.notifyObservers();
221
+ }
222
+
223
+ /**
224
+ * Gets the values of bound elements and changes them in subject
225
+ *
226
+ * @since 1.27.0
227
+ * @return {Monster.DOM.Updater}
228
+ */
229
+ retrieve() {
230
+ retrieveFromBindings.call(this);
231
+ return this;
212
232
  }
213
233
 
214
234
  /**
@@ -221,7 +241,7 @@ class Updater extends Base {
221
241
  * @return {Proxy}
222
242
  */
223
243
  getSubject() {
224
- return this.subject.getSubject();
244
+ return this[internalSymbol].subject.getSubject();
225
245
  }
226
246
 
227
247
  /**
@@ -235,7 +255,7 @@ class Updater extends Base {
235
255
  * @throws {TypeError} value is not a function
236
256
  */
237
257
  setCallback(name, callback) {
238
- this.callbacks.set(name, callback);
258
+ this[internalSymbol].callbacks.set(name, callback);
239
259
  return this;
240
260
  }
241
261
 
@@ -252,6 +272,7 @@ function getCheckStateCallback() {
252
272
 
253
273
  return function (current) {
254
274
 
275
+ // this is a reference to the current object (therefore no array function here)
255
276
  if (this instanceof HTMLInputElement) {
256
277
  if (['radio', 'checkbox'].indexOf(this.type) !== -1) {
257
278
  return (this.value + "" === current + "") ? 'true' : undefined
@@ -261,9 +282,8 @@ function getCheckStateCallback() {
261
282
  if (isArray(current) && current.indexOf(this.value) !== -1) {
262
283
  return 'true'
263
284
  }
264
- return undefined;
265
-
266
285
 
286
+ return undefined;
267
287
  }
268
288
  }
269
289
  }
@@ -277,6 +297,7 @@ const symbol = Symbol('EventHandler');
277
297
  * @private
278
298
  * @return {function}
279
299
  * @this Updater
300
+ * @throws {Error} the bind argument must start as a value with a path
280
301
  */
281
302
  function getControlEventHandler() {
282
303
 
@@ -286,83 +307,112 @@ function getControlEventHandler() {
286
307
  return self[symbol];
287
308
  }
288
309
 
289
- const pathfinder = new Pathfinder(this.subject.getSubject());
290
-
291
310
  /**
292
311
  * @throws {Error} the bind argument must start as a value with a path.
293
312
  * @throws {Error} unsupported object
294
313
  * @param {Event} event
295
314
  */
296
315
  self[symbol] = (event) => {
297
- const element = event.target;
316
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND);
298
317
 
299
- if (!element.hasAttribute(ATTRIBUTE_UPDATER_BIND)) {
318
+ if (element === undefined) {
300
319
  return;
301
320
  }
302
321
 
303
- let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND);
322
+ retrieveAndSetValue.call(self, element);
304
323
 
305
- if (path.indexOf('path:') !== 0) {
306
- throw new Error('the bind argument must start as a value with a path.');
307
- }
324
+ }
308
325
 
309
- path = path.substr(5);
326
+ return self[symbol];
310
327
 
311
- let value;
312
328
 
313
- if (element instanceof HTMLInputElement) {
314
- switch (element.type) {
329
+ }
315
330
 
316
- case 'checkbox':
317
- value = element.checked ? element.value : undefined;
318
- break;
319
- default:
320
- value = element.value;
321
- break;
331
+ /**
332
+ * @throws {Error} the bind argument must start as a value with a path
333
+ * @param {HTMLElement} element
334
+ * @return void
335
+ */
336
+ function retrieveAndSetValue(element) {
322
337
 
338
+ const self = this;
323
339
 
324
- }
325
- } else if (element instanceof HTMLTextAreaElement) {
326
- value = element.value;
340
+ const pathfinder = new Pathfinder(self[internalSymbol].subject.getSubject());
327
341
 
328
- } else if (element instanceof HTMLSelectElement) {
342
+ let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND);
329
343
 
330
- switch (element.type) {
331
- case 'select-one':
332
- value = element.value;
333
- break;
334
- case 'select-multiple':
335
- value = element.value;
344
+ if (path.indexOf('path:') !== 0) {
345
+ throw new Error('the bind argument must start as a value with a path');
346
+ }
336
347
 
337
- let options = element?.selectedOptions;
338
- if (options === undefined) options = element.querySelectorAll(":scope option:checked");
339
- value = Array.from(options).map(({value}) => value);
348
+ path = path.substr(5);
340
349
 
341
- break;
342
- }
350
+ let value;
351
+
352
+ if (element instanceof HTMLInputElement) {
353
+ switch (element.type) {
354
+
355
+ case 'checkbox':
356
+ value = element.checked ? element.value : undefined;
357
+ break;
358
+ default:
359
+ value = element.value;
360
+ break;
343
361
 
344
362
 
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
363
  }
364
+ } else if (element instanceof HTMLTextAreaElement) {
365
+ value = element.value;
366
+
367
+ } else if (element instanceof HTMLSelectElement) {
351
368
 
352
- const copy = clone(self.subject.getRealSubject());
353
- const pf = new Pathfinder(copy);
354
- pf.setVia(path, value);
369
+ switch (element.type) {
370
+ case 'select-one':
371
+ value = element.value;
372
+ break;
373
+ case 'select-multiple':
374
+ value = element.value;
355
375
 
356
- const diffResult = diff(copy, self.subject.getRealSubject());
376
+ let options = element?.selectedOptions;
377
+ if (options === undefined) options = element.querySelectorAll(":scope option:checked");
378
+ value = Array.from(options).map(({value}) => value);
357
379
 
358
- if (diffResult.length > 0) {
359
- pathfinder.setVia(path, value);
380
+ break;
360
381
  }
361
382
 
383
+
384
+ // values from customelements
385
+ } else if ((element?.constructor?.prototype && !!Object.getOwnPropertyDescriptor(element.constructor.prototype, 'value')?.['get']) || element.hasOwnProperty('value')) {
386
+ value = element?.['value'];
387
+ } else {
388
+ throw new Error("unsupported object");
362
389
  }
363
390
 
364
- return self[symbol];
391
+ const copy = clone(self[internalSymbol].subject.getRealSubject());
392
+ const pf = new Pathfinder(copy);
393
+ pf.setVia(path, value);
394
+
395
+ const diffResult = diff(copy, self[internalSymbol].subject.getRealSubject());
396
+
397
+ if (diffResult.length > 0) {
398
+ pathfinder.setVia(path, value);
399
+ }
400
+ }
401
+
402
+ /**
403
+ * @since 1.27.0
404
+ * @return void
405
+ */
406
+ function retrieveFromBindings() {
407
+ const self = this;
408
+
409
+ if (self[internalSymbol].element.matches('[' + ATTRIBUTE_UPDATER_BIND + ']')) {
410
+ retrieveAndSetValue.call(self, element)
411
+ }
365
412
 
413
+ for (const [, element] of self[internalSymbol].element.querySelectorAll('[' + ATTRIBUTE_UPDATER_BIND + ']').entries()) {
414
+ retrieveAndSetValue.call(self, element)
415
+ }
366
416
 
367
417
  }
368
418
 
@@ -373,7 +423,9 @@ function getControlEventHandler() {
373
423
  * @return {void}
374
424
  */
375
425
  function removeElement(change) {
376
- for (const [, element] of this.element.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_REMOVE + ']').entries()) {
426
+ const self = this;
427
+
428
+ for (const [, element] of self[internalSymbol].element.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_REMOVE + ']').entries()) {
377
429
  element.parentNode.removeChild(element);
378
430
  }
379
431
  }
@@ -391,7 +443,7 @@ function removeElement(change) {
391
443
  */
392
444
  function insertElement(change) {
393
445
  const self = this;
394
- const subject = self.subject.getRealSubject();
446
+ const subject = self[internalSymbol].subject.getRealSubject();
395
447
  const document = getDocument();
396
448
 
397
449
  let mem = new WeakSet;
@@ -407,7 +459,7 @@ function insertElement(change) {
407
459
 
408
460
  while (p.length > 0) {
409
461
  const current = p.join('.');
410
- const list = this.element.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_INSERT + '*="path:' + current + '"]').entries()
462
+ const list = this[internalSymbol].element.querySelectorAll(':scope [' + ATTRIBUTE_UPDATER_INSERT + '*="path:' + current + '"]').entries()
411
463
 
412
464
  for (const [, containerElement] of list) {
413
465
 
@@ -429,7 +481,7 @@ function insertElement(change) {
429
481
  }
430
482
 
431
483
  let pipe = new Pipe(cmd);
432
- this.callbacks.forEach((f, n) => {
484
+ this[internalSymbol].callbacks.forEach((f, n) => {
433
485
  pipe.setCallback(n, f);
434
486
  })
435
487
 
@@ -553,12 +605,12 @@ function applyRecursive(node, key, path) {
553
605
  */
554
606
  function updateContent(change) {
555
607
  const self = this;
556
- const subject = self.subject.getRealSubject();
608
+ const subject = self[internalSymbol].subject.getRealSubject();
557
609
 
558
610
  let p = clone(change?.['path']);
559
- runUpdateContent.call(this, this.element, p, subject);
611
+ runUpdateContent.call(this, this[internalSymbol].element, p, subject);
560
612
 
561
- const slots = this.element.querySelectorAll('slot');
613
+ const slots = this[internalSymbol].element.querySelectorAll('slot');
562
614
  if (slots.length > 0) {
563
615
  for (const [, slot] of Object.entries(slots)) {
564
616
  for (const [, element] of Object.entries(slot.assignedNodes())) {
@@ -610,7 +662,7 @@ function runUpdateContent(container, parts, subject) {
610
662
  let cmd = trimSpaces(attributes);
611
663
 
612
664
  let pipe = new Pipe(cmd);
613
- this.callbacks.forEach((f, n) => {
665
+ this[internalSymbol].callbacks.forEach((f, n) => {
614
666
  pipe.setCallback(n, f);
615
667
  })
616
668
 
@@ -646,9 +698,9 @@ function runUpdateContent(container, parts, subject) {
646
698
  * @return {void}
647
699
  */
648
700
  function updateAttributes(change) {
649
- const subject = this.subject.getRealSubject();
701
+ const subject = this[internalSymbol].subject.getRealSubject();
650
702
  let p = clone(change?.['path']);
651
- runUpdateAttributes.call(this, this.element, p, subject);
703
+ runUpdateAttributes.call(this, this[internalSymbol].element, p, subject);
652
704
  }
653
705
 
654
706
  /**
@@ -674,7 +726,8 @@ function runUpdateAttributes(container, parts, subject) {
674
726
 
675
727
  let iterator = new Set;
676
728
 
677
- const query = '[' + ATTRIBUTE_UPDATER_ATTRIBUTES + '*="path:' + current + '"], [' + ATTRIBUTE_UPDATER_ATTRIBUTES + '^="static:"]';
729
+ const query = '[' + ATTRIBUTE_UPDATER_SELECT_THIS + '], [' + ATTRIBUTE_UPDATER_ATTRIBUTES + '*="path:' + current + '"], [' + ATTRIBUTE_UPDATER_ATTRIBUTES + '^="static:"]';
730
+
678
731
  const e = container.querySelectorAll(query);
679
732
 
680
733
  if (e.length > 0) {
@@ -702,7 +755,7 @@ function runUpdateAttributes(container, parts, subject) {
702
755
 
703
756
  let pipe = new Pipe(cmd);
704
757
 
705
- self.callbacks.forEach((f, n) => {
758
+ self[internalSymbol].callbacks.forEach((f, n) => {
706
759
  pipe.setCallback(n, f, element);
707
760
  })
708
761
 
@@ -776,19 +829,26 @@ function handleInputControlAttributeUpdate(element, name, value) {
776
829
  switch (element.type) {
777
830
 
778
831
  case 'radio':
779
- if (name === 'checked' && value !== undefined) {
780
- element.checked = true;
781
- } else {
782
- element.checked = false;
832
+ if (name === 'checked') {
833
+
834
+ if (value !== undefined) {
835
+ element.checked = true;
836
+ } else {
837
+ element.checked = false;
838
+ }
783
839
  }
784
840
 
785
841
  break;
786
842
 
787
843
  case 'checkbox':
788
- if (name === 'checked' && value !== undefined) {
789
- element.checked = true;
790
- } else {
791
- element.checked = false;
844
+
845
+ if (name === 'checked') {
846
+
847
+ if (value !== undefined) {
848
+ element.checked = true;
849
+ } else {
850
+ element.checked = false;
851
+ }
792
852
  }
793
853
 
794
854
  break;
@@ -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.26.0/dist/monster.js';
16
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/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.26.0/dist/modules/dom/util.js';
25
+ * import {getDocument} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/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.26.0/dist/monster.js';
77
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/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.26.0/dist/modules/dom/util.js';
86
+ * import {getWindow} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/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.26.0/dist/monster.js';
143
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/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.26.0/dist/modules/dom/util.js';
152
+ * import {getDocumentFragmentFromString} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/dom/util.js';
153
153
  * console.log(getDocumentFragmentFromString('<div></div>'))
154
154
  * </script>
155
155
  * ```
@@ -20,7 +20,7 @@ import {validateInstance, validateString} from "../../types/validate.js";
20
20
  *
21
21
  * ```
22
22
  * <script type="module">
23
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
23
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/monster.js';
24
24
  * console.log(new Monster.DOM.Worker.Factory())
25
25
  * </script>
26
26
  * ```
@@ -29,7 +29,7 @@ import {validateInstance, validateString} from "../../types/validate.js";
29
29
  *
30
30
  * ```
31
31
  * <script type="module">
32
- * import {Factory} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/dom/worker/factory.js';
32
+ * import {Factory} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/dom/worker/factory.js';
33
33
  * console.log(new Factory())
34
34
  * </script>
35
35
  * ```
@@ -25,7 +25,7 @@ const internalTranslationSymbol = Symbol('internalTranslation')
25
25
  *
26
26
  * ```
27
27
  * <script type="module">
28
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
28
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/monster.js';
29
29
  * new Monster.I18n.Formatter()
30
30
  * </script>
31
31
  * ```
@@ -34,15 +34,15 @@ const internalTranslationSymbol = Symbol('internalTranslation')
34
34
  *
35
35
  * ```
36
36
  * <script type="module">
37
- * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/i18n/formatter.js';
37
+ * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/i18n/formatter.js';
38
38
  * new Formatter()
39
39
  * </script>
40
40
  * ```
41
41
  *
42
42
  * @example
43
43
  *
44
- * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/i18n/formatter.js';
45
- * import {Translations} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/i18n/translations.js';
44
+ * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/i18n/formatter.js';
45
+ * import {Translations} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/i18n/translations.js';
46
46
  *
47
47
  * const translations = new Translations('en')
48
48
  * .assignTranslations({
@@ -25,7 +25,7 @@ const localeStringSymbol = Symbol('localeString');
25
25
  *
26
26
  * ```
27
27
  * <script type="module">
28
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
28
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/monster.js';
29
29
  * new Monster.I18n.Locale()
30
30
  * </script>
31
31
  * ```
@@ -34,7 +34,7 @@ const localeStringSymbol = Symbol('localeString');
34
34
  *
35
35
  * ```
36
36
  * <script type="module">
37
- * import {Locale} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/i18n/locale.js';
37
+ * import {Locale} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/i18n/locale.js';
38
38
  * new Locale()
39
39
  * </script>
40
40
  * ```
@@ -203,7 +203,7 @@ class Locale extends Base {
203
203
  *
204
204
  * ```
205
205
  * <script type="module">
206
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
206
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/monster.js';
207
207
  * new Monster.I18n.createLocale()
208
208
  * </script>
209
209
  * ```
@@ -212,7 +212,7 @@ class Locale extends Base {
212
212
  *
213
213
  * ```
214
214
  * <script type="module">
215
- * import {createLocale} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/i18n/locale.js';
215
+ * import {createLocale} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/i18n/locale.js';
216
216
  * createLocale()
217
217
  * </script>
218
218
  * ```
@@ -15,7 +15,7 @@ import {Translations} from "./translations.js"
15
15
  *
16
16
  * ```
17
17
  * <script type="module">
18
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
18
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/monster.js';
19
19
  * new Monster.I18n.Provider()
20
20
  * </script>
21
21
  * ```
@@ -24,7 +24,7 @@ import {Translations} from "./translations.js"
24
24
  *
25
25
  * ```
26
26
  * <script type="module">
27
- * import {Provider} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/i18n/provider.js';
27
+ * import {Provider} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.1/dist/modules/i18n/provider.js';
28
28
  * new Provider()
29
29
  * </script>
30
30
  * ```