@schukai/monster 3.55.0 → 3.55.1

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 (99) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/package.json +1 -1
  3. package/source/components/datatable/datasource/rest.mjs +313 -326
  4. package/source/components/datatable/datatable/header.mjs +1 -1
  5. package/source/components/datatable/datatable.mjs +586 -591
  6. package/source/components/datatable/embedded-pagination.mjs +42 -49
  7. package/source/components/datatable/filter/util.mjs +115 -99
  8. package/source/components/datatable/filter.mjs +901 -842
  9. package/source/components/datatable/pagination.mjs +333 -334
  10. package/source/components/datatable/status.mjs +134 -156
  11. package/source/components/datatable/stylesheet/column-bar.mjs +14 -8
  12. package/source/components/datatable/stylesheet/dataset.mjs +14 -8
  13. package/source/components/datatable/stylesheet/datasource.mjs +14 -8
  14. package/source/components/datatable/stylesheet/datatable.mjs +14 -8
  15. package/source/components/datatable/stylesheet/embedded-pagination.mjs +14 -8
  16. package/source/components/datatable/stylesheet/filter-button.mjs +14 -8
  17. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +14 -8
  18. package/source/components/datatable/stylesheet/filter-date-range.mjs +14 -8
  19. package/source/components/datatable/stylesheet/filter-range.mjs +14 -8
  20. package/source/components/datatable/stylesheet/filter.mjs +14 -8
  21. package/source/components/datatable/stylesheet/pagination.mjs +14 -8
  22. package/source/components/datatable/stylesheet/select-filter.mjs +14 -8
  23. package/source/components/datatable/stylesheet/status.mjs +14 -8
  24. package/source/components/form/action-button.mjs +3 -1
  25. package/source/components/form/confirm-button.mjs +3 -1
  26. package/source/components/form/context-error.mjs +161 -164
  27. package/source/components/form/context-help.mjs +3 -1
  28. package/source/components/form/form.mjs +3 -1
  29. package/source/components/form/message-state-button.mjs +3 -1
  30. package/source/components/form/popper-button.mjs +6 -4
  31. package/source/components/form/popper.mjs +310 -310
  32. package/source/components/form/select.mjs +2 -2
  33. package/source/components/form/state-button.mjs +3 -1
  34. package/source/components/form/stylesheet/action-button.mjs +14 -8
  35. package/source/components/form/stylesheet/api-button.mjs +14 -8
  36. package/source/components/form/stylesheet/button-bar.mjs +14 -8
  37. package/source/components/form/stylesheet/button.mjs +14 -8
  38. package/source/components/form/stylesheet/confirm-button.mjs +14 -8
  39. package/source/components/form/stylesheet/context-error.mjs +14 -8
  40. package/source/components/form/stylesheet/context-help.mjs +14 -8
  41. package/source/components/form/stylesheet/form.mjs +14 -8
  42. package/source/components/form/stylesheet/message-state-button.mjs +14 -8
  43. package/source/components/form/stylesheet/popper-button.mjs +14 -8
  44. package/source/components/form/stylesheet/popper.mjs +14 -8
  45. package/source/components/form/stylesheet/select.mjs +14 -8
  46. package/source/components/form/stylesheet/state-button.mjs +14 -8
  47. package/source/components/form/stylesheet/tabs.mjs +14 -8
  48. package/source/components/form/stylesheet/tree-select.mjs +14 -8
  49. package/source/components/form/tabs.mjs +754 -758
  50. package/source/components/host/collapse.mjs +2 -4
  51. package/source/components/host/config-manager.mjs +11 -9
  52. package/source/components/host/stylesheet/call-button.mjs +14 -8
  53. package/source/components/host/stylesheet/collapse.mjs +14 -8
  54. package/source/components/host/stylesheet/config-manager.mjs +14 -8
  55. package/source/components/host/stylesheet/details.mjs +14 -8
  56. package/source/components/host/stylesheet/host.mjs +14 -8
  57. package/source/components/host/stylesheet/overlay.mjs +14 -8
  58. package/source/components/host/stylesheet/toggle-button.mjs +14 -8
  59. package/source/components/host/stylesheet/viewer.mjs +14 -8
  60. package/source/components/host/util.mjs +2 -2
  61. package/source/components/notify/stylesheet/message.mjs +14 -8
  62. package/source/components/notify/stylesheet/notify.mjs +14 -8
  63. package/source/components/state/stylesheet/log.mjs +14 -8
  64. package/source/components/state/stylesheet/state.mjs +14 -8
  65. package/source/components/stylesheet/badge.mjs +14 -8
  66. package/source/components/stylesheet/border.mjs +14 -8
  67. package/source/components/stylesheet/button.mjs +14 -8
  68. package/source/components/stylesheet/card.mjs +14 -8
  69. package/source/components/stylesheet/color.mjs +14 -8
  70. package/source/components/stylesheet/common.mjs +14 -8
  71. package/source/components/stylesheet/control.mjs +14 -8
  72. package/source/components/stylesheet/data-grid.mjs +14 -8
  73. package/source/components/stylesheet/display.mjs +14 -8
  74. package/source/components/stylesheet/floating-ui.mjs +14 -8
  75. package/source/components/stylesheet/form.mjs +14 -8
  76. package/source/components/stylesheet/host.mjs +14 -8
  77. package/source/components/stylesheet/icons.mjs +14 -8
  78. package/source/components/stylesheet/link.mjs +14 -8
  79. package/source/components/stylesheet/normalize.mjs +14 -8
  80. package/source/components/stylesheet/popper.mjs +14 -8
  81. package/source/components/stylesheet/property.mjs +14 -8
  82. package/source/components/stylesheet/ripple.mjs +14 -8
  83. package/source/components/stylesheet/skeleton.mjs +14 -8
  84. package/source/components/stylesheet/space.mjs +14 -8
  85. package/source/components/stylesheet/spinner.mjs +14 -8
  86. package/source/components/stylesheet/table.mjs +14 -8
  87. package/source/components/stylesheet/theme.mjs +14 -8
  88. package/source/components/stylesheet/typography.mjs +14 -8
  89. package/source/components/tree-menu/stylesheet/tree-menu.mjs +14 -8
  90. package/source/data/transformer.mjs +6 -8
  91. package/source/dom/attributes.mjs +5 -5
  92. package/source/dom/customelement.mjs +1 -1
  93. package/source/dom/updater.mjs +697 -700
  94. package/source/dom/util.mjs +2 -2
  95. package/source/monster.mjs +0 -1
  96. package/source/types/noderecursiveiterator.mjs +9 -7
  97. package/source/types/version.mjs +1 -1
  98. package/source/util/sleep.mjs +3 -4
  99. package/test/cases/monster.mjs +1 -1
@@ -5,34 +5,34 @@
5
5
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
6
  */
7
7
 
8
- import {internalSymbol} from "../constants.mjs";
9
- import {diff} from "../data/diff.mjs";
10
- import {Pathfinder} from "../data/pathfinder.mjs";
11
- import {Pipe} from "../data/pipe.mjs";
8
+ import { internalSymbol } from "../constants.mjs";
9
+ import { diff } from "../data/diff.mjs";
10
+ import { Pathfinder } from "../data/pathfinder.mjs";
11
+ import { Pipe } from "../data/pipe.mjs";
12
12
  import {
13
- ATTRIBUTE_ERRORMESSAGE,
14
- ATTRIBUTE_UPDATER_ATTRIBUTES,
15
- ATTRIBUTE_UPDATER_BIND,
16
- ATTRIBUTE_UPDATER_INSERT,
17
- ATTRIBUTE_UPDATER_INSERT_REFERENCE,
18
- ATTRIBUTE_UPDATER_REMOVE,
19
- ATTRIBUTE_UPDATER_REPLACE,
20
- ATTRIBUTE_UPDATER_SELECT_THIS,
13
+ ATTRIBUTE_ERRORMESSAGE,
14
+ ATTRIBUTE_UPDATER_ATTRIBUTES,
15
+ ATTRIBUTE_UPDATER_BIND,
16
+ ATTRIBUTE_UPDATER_INSERT,
17
+ ATTRIBUTE_UPDATER_INSERT_REFERENCE,
18
+ ATTRIBUTE_UPDATER_REMOVE,
19
+ ATTRIBUTE_UPDATER_REPLACE,
20
+ ATTRIBUTE_UPDATER_SELECT_THIS,
21
21
  } from "./constants.mjs";
22
22
 
23
- import {Base} from "../types/base.mjs";
24
- import {isArray, isInstance, isIterable} from "../types/is.mjs";
25
- import {Observer} from "../types/observer.mjs";
26
- import {ProxyObserver} from "../types/proxyobserver.mjs";
27
- import {validateArray, validateInstance} from "../types/validate.mjs";
28
- import {Sleep} from "../util/sleep.mjs";
29
- import {clone} from "../util/clone.mjs";
30
- import {trimSpaces} from "../util/trimspaces.mjs";
31
- import {addToObjectLink} from "./attributes.mjs";
32
- import {findTargetElementFromEvent} from "./events.mjs";
33
- import {findDocumentTemplate} from "./template.mjs";
23
+ import { Base } from "../types/base.mjs";
24
+ import { isArray, isInstance, isIterable } from "../types/is.mjs";
25
+ import { Observer } from "../types/observer.mjs";
26
+ import { ProxyObserver } from "../types/proxyobserver.mjs";
27
+ import { validateArray, validateInstance } from "../types/validate.mjs";
28
+ import { Sleep } from "../util/sleep.mjs";
29
+ import { clone } from "../util/clone.mjs";
30
+ import { trimSpaces } from "../util/trimspaces.mjs";
31
+ import { addToObjectLink } from "./attributes.mjs";
32
+ import { findTargetElementFromEvent } from "./events.mjs";
33
+ import { findDocumentTemplate } from "./template.mjs";
34
34
 
35
- export {Updater, addObjectWithUpdaterToElement};
35
+ export { Updater, addObjectWithUpdaterToElement };
36
36
 
37
37
  /**
38
38
  * The updater class connects an object with the dom. In this way, structures and contents in the DOM can be programmatically adapted via attributes.
@@ -57,183 +57,182 @@ export {Updater, addObjectWithUpdaterToElement};
57
57
  * @summary The updater class connects an object with the dom
58
58
  */
59
59
  class Updater extends Base {
60
- /**
61
- * @since 1.8.0
62
- * @param {HTMLElement} element
63
- * @param {object|ProxyObserver|undefined} subject
64
- * @throws {TypeError} value is not a object
65
- * @throws {TypeError} value is not an instance of HTMLElement
66
- * @see {@link Monster.DOM.findDocumentTemplate}
67
- */
68
- constructor(element, subject) {
69
- super();
70
-
71
- /**
72
- * @type {HTMLElement}
73
- */
74
- if (subject === undefined) subject = {};
75
- if (!isInstance(subject, ProxyObserver)) {
76
- subject = new ProxyObserver(subject);
77
- }
78
-
79
- this[internalSymbol] = {
80
- element: validateInstance(element, HTMLElement),
81
- last: {},
82
- callbacks: new Map(),
83
- eventTypes: ["keyup", "click", "change", "drop", "touchend", "input"],
84
- subject: subject,
85
- };
86
-
87
- this[internalSymbol].callbacks.set(
88
- "checkstate",
89
- getCheckStateCallback.call(this),
90
- );
91
-
92
- this[internalSymbol].subject.attachObserver(
93
- new Observer(() => {
94
- const s = this[internalSymbol].subject.getRealSubject();
95
-
96
- const diffResult = diff(this[internalSymbol].last, s);
97
- this[internalSymbol].last = clone(s);
98
-
99
- let promises = [];
100
-
101
- for (const [, change] of Object.entries(diffResult)) {
102
- promises.push(
103
- Sleep(1).then(() => {
104
- removeElement.call(this, change);
105
- insertElement.call(this, change);
106
- updateContent.call(this, change);
107
- updateAttributes.call(this, change);
108
- })
109
- )
110
- }
111
-
112
- return Promise.all(promises)
113
-
114
- }),
115
- );
116
- }
117
-
118
- /**
119
- * Defaults: 'keyup', 'click', 'change', 'drop', 'touchend'
120
- *
121
- * @see {@link https://developer.mozilla.org/de/docs/Web/Events}
122
- * @since 1.9.0
123
- * @param {Array} types
124
- * @return {Updater}
125
- */
126
- setEventTypes(types) {
127
- this[internalSymbol].eventTypes = validateArray(types);
128
- return this;
129
- }
130
-
131
- /**
132
- * With this method, the eventlisteners are hooked in and the magic begins.
133
- *
134
- * ```
135
- * updater.run().then(() => {
136
- * updater.enableEventProcessing();
137
- * });
138
- * ```
139
- *
140
- * @since 1.9.0
141
- * @return {Updater}
142
- * @throws {Error} the bind argument must start as a value with a path
143
- */
144
- enableEventProcessing() {
145
- this.disableEventProcessing();
146
-
147
- for (const type of this[internalSymbol].eventTypes) {
148
- // @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
149
- this[internalSymbol].element.addEventListener(
150
- type,
151
- getControlEventHandler.call(this),
152
- {
153
- capture: true,
154
- passive: true,
155
- },
156
- );
157
- }
158
-
159
- return this;
160
- }
161
-
162
- /**
163
- * This method turns off the magic or who loves it more profane it removes the eventListener.
164
- *
165
- * @since 1.9.0
166
- * @return {Updater}
167
- */
168
- disableEventProcessing() {
169
- for (const type of this[internalSymbol].eventTypes) {
170
- this[internalSymbol].element.removeEventListener(
171
- type,
172
- getControlEventHandler.call(this),
173
- );
174
- }
175
-
176
- return this;
177
- }
178
-
179
- /**
180
- * The run method must be called for the update to start working.
181
- * The method ensures that changes are detected.
182
- *
183
- * ```
184
- * updater.run().then(() => {
185
- * updater.enableEventProcessing();
186
- * });
187
- * ```
188
- *
189
- * @summary Let the magic begin
190
- * @return {Promise}
191
- */
192
- run() {
193
- // the key __init__has no further meaning and is only
194
- // used to create the diff for empty objects.
195
- this[internalSymbol].last = {__init__: true};
196
- return this[internalSymbol].subject.notifyObservers();
197
- }
198
-
199
- /**
200
- * Gets the values of bound elements and changes them in subject
201
- *
202
- * @since 1.27.0
203
- * @return {Monster.DOM.Updater}
204
- */
205
- retrieve() {
206
- retrieveFromBindings.call(this);
207
- return this;
208
- }
209
-
210
- /**
211
- * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here.
212
- * However, if you passed a simple object, here you will get a proxy for that object.
213
- *
214
- * For changes the ProxyObserver must be used.
215
- *
216
- * @since 1.8.0
217
- * @return {Proxy}
218
- */
219
- getSubject() {
220
- return this[internalSymbol].subject.getSubject();
221
- }
222
-
223
- /**
224
- * This method can be used to register commands that can be called via call: instruction.
225
- * This can be used to provide a pipe with its own functionality.
226
- *
227
- * @param {string} name
228
- * @param {function} callback
229
- * @returns {Transformer}
230
- * @throws {TypeError} value is not a string
231
- * @throws {TypeError} value is not a function
232
- */
233
- setCallback(name, callback) {
234
- this[internalSymbol].callbacks.set(name, callback);
235
- return this;
236
- }
60
+ /**
61
+ * @since 1.8.0
62
+ * @param {HTMLElement} element
63
+ * @param {object|ProxyObserver|undefined} subject
64
+ * @throws {TypeError} value is not a object
65
+ * @throws {TypeError} value is not an instance of HTMLElement
66
+ * @see {@link Monster.DOM.findDocumentTemplate}
67
+ */
68
+ constructor(element, subject) {
69
+ super();
70
+
71
+ /**
72
+ * @type {HTMLElement}
73
+ */
74
+ if (subject === undefined) subject = {};
75
+ if (!isInstance(subject, ProxyObserver)) {
76
+ subject = new ProxyObserver(subject);
77
+ }
78
+
79
+ this[internalSymbol] = {
80
+ element: validateInstance(element, HTMLElement),
81
+ last: {},
82
+ callbacks: new Map(),
83
+ eventTypes: ["keyup", "click", "change", "drop", "touchend", "input"],
84
+ subject: subject,
85
+ };
86
+
87
+ this[internalSymbol].callbacks.set(
88
+ "checkstate",
89
+ getCheckStateCallback.call(this),
90
+ );
91
+
92
+ this[internalSymbol].subject.attachObserver(
93
+ new Observer(() => {
94
+ const s = this[internalSymbol].subject.getRealSubject();
95
+
96
+ const diffResult = diff(this[internalSymbol].last, s);
97
+ this[internalSymbol].last = clone(s);
98
+
99
+ const promises = [];
100
+
101
+ for (const [, change] of Object.entries(diffResult)) {
102
+ promises.push(
103
+ Sleep(1).then(() => {
104
+ removeElement.call(this, change);
105
+ insertElement.call(this, change);
106
+ updateContent.call(this, change);
107
+ updateAttributes.call(this, change);
108
+ }),
109
+ );
110
+ }
111
+
112
+ return Promise.all(promises);
113
+ }),
114
+ );
115
+ }
116
+
117
+ /**
118
+ * Defaults: 'keyup', 'click', 'change', 'drop', 'touchend'
119
+ *
120
+ * @see {@link https://developer.mozilla.org/de/docs/Web/Events}
121
+ * @since 1.9.0
122
+ * @param {Array} types
123
+ * @return {Updater}
124
+ */
125
+ setEventTypes(types) {
126
+ this[internalSymbol].eventTypes = validateArray(types);
127
+ return this;
128
+ }
129
+
130
+ /**
131
+ * With this method, the eventlisteners are hooked in and the magic begins.
132
+ *
133
+ * ```
134
+ * updater.run().then(() => {
135
+ * updater.enableEventProcessing();
136
+ * });
137
+ * ```
138
+ *
139
+ * @since 1.9.0
140
+ * @return {Updater}
141
+ * @throws {Error} the bind argument must start as a value with a path
142
+ */
143
+ enableEventProcessing() {
144
+ this.disableEventProcessing();
145
+
146
+ for (const type of this[internalSymbol].eventTypes) {
147
+ // @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
148
+ this[internalSymbol].element.addEventListener(
149
+ type,
150
+ getControlEventHandler.call(this),
151
+ {
152
+ capture: true,
153
+ passive: true,
154
+ },
155
+ );
156
+ }
157
+
158
+ return this;
159
+ }
160
+
161
+ /**
162
+ * This method turns off the magic or who loves it more profane it removes the eventListener.
163
+ *
164
+ * @since 1.9.0
165
+ * @return {Updater}
166
+ */
167
+ disableEventProcessing() {
168
+ for (const type of this[internalSymbol].eventTypes) {
169
+ this[internalSymbol].element.removeEventListener(
170
+ type,
171
+ getControlEventHandler.call(this),
172
+ );
173
+ }
174
+
175
+ return this;
176
+ }
177
+
178
+ /**
179
+ * The run method must be called for the update to start working.
180
+ * The method ensures that changes are detected.
181
+ *
182
+ * ```
183
+ * updater.run().then(() => {
184
+ * updater.enableEventProcessing();
185
+ * });
186
+ * ```
187
+ *
188
+ * @summary Let the magic begin
189
+ * @return {Promise}
190
+ */
191
+ run() {
192
+ // the key __init__has no further meaning and is only
193
+ // used to create the diff for empty objects.
194
+ this[internalSymbol].last = { __init__: true };
195
+ return this[internalSymbol].subject.notifyObservers();
196
+ }
197
+
198
+ /**
199
+ * Gets the values of bound elements and changes them in subject
200
+ *
201
+ * @since 1.27.0
202
+ * @return {Monster.DOM.Updater}
203
+ */
204
+ retrieve() {
205
+ retrieveFromBindings.call(this);
206
+ return this;
207
+ }
208
+
209
+ /**
210
+ * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here.
211
+ * However, if you passed a simple object, here you will get a proxy for that object.
212
+ *
213
+ * For changes the ProxyObserver must be used.
214
+ *
215
+ * @since 1.8.0
216
+ * @return {Proxy}
217
+ */
218
+ getSubject() {
219
+ return this[internalSymbol].subject.getSubject();
220
+ }
221
+
222
+ /**
223
+ * This method can be used to register commands that can be called via call: instruction.
224
+ * This can be used to provide a pipe with its own functionality.
225
+ *
226
+ * @param {string} name
227
+ * @param {function} callback
228
+ * @returns {Transformer}
229
+ * @throws {TypeError} value is not a string
230
+ * @throws {TypeError} value is not a function
231
+ */
232
+ setCallback(name, callback) {
233
+ this[internalSymbol].callbacks.set(name, callback);
234
+ return this;
235
+ }
237
236
  }
238
237
 
239
238
  /**
@@ -244,20 +243,20 @@ class Updater extends Base {
244
243
  * @this Updater
245
244
  */
246
245
  function getCheckStateCallback() {
247
- return function (current) {
248
- // this is a reference to the current object (therefore no array function here)
249
- if (this instanceof HTMLInputElement) {
250
- if (["radio", "checkbox"].indexOf(this.type) !== -1) {
251
- return `${this.value}` === `${current}` ? "true" : undefined;
252
- }
253
- } else if (this instanceof HTMLOptionElement) {
254
- if (isArray(current) && current.indexOf(this.value) !== -1) {
255
- return "true";
256
- }
257
-
258
- return undefined;
259
- }
260
- };
246
+ return function (current) {
247
+ // this is a reference to the current object (therefore no array function here)
248
+ if (this instanceof HTMLInputElement) {
249
+ if (["radio", "checkbox"].indexOf(this.type) !== -1) {
250
+ return `${this.value}` === `${current}` ? "true" : undefined;
251
+ }
252
+ } else if (this instanceof HTMLOptionElement) {
253
+ if (isArray(current) && current.indexOf(this.value) !== -1) {
254
+ return "true";
255
+ }
256
+
257
+ return undefined;
258
+ }
259
+ };
261
260
  }
262
261
 
263
262
  /**
@@ -272,26 +271,26 @@ const symbol = Symbol("@schukai/monster/updater@@EventHandler");
272
271
  * @throws {Error} the bind argument must start as a value with a path
273
272
  */
274
273
  function getControlEventHandler() {
275
- if (this[symbol]) {
276
- return this[symbol];
277
- }
278
-
279
- /**
280
- * @throws {Error} the bind argument must start as a value with a path.
281
- * @throws {Error} unsupported object
282
- * @param {Event} event
283
- */
284
- this[symbol] = (event) => {
285
- const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND);
286
-
287
- if (element === undefined) {
288
- return;
289
- }
290
-
291
- retrieveAndSetValue.call(this, element);
292
- };
293
-
294
- return this[symbol];
274
+ if (this[symbol]) {
275
+ return this[symbol];
276
+ }
277
+
278
+ /**
279
+ * @throws {Error} the bind argument must start as a value with a path.
280
+ * @throws {Error} unsupported object
281
+ * @param {Event} event
282
+ */
283
+ this[symbol] = (event) => {
284
+ const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND);
285
+
286
+ if (element === undefined) {
287
+ return;
288
+ }
289
+
290
+ retrieveAndSetValue.call(this, element);
291
+ };
292
+
293
+ return this[symbol];
295
294
  }
296
295
 
297
296
  /**
@@ -302,70 +301,70 @@ function getControlEventHandler() {
302
301
  * @private
303
302
  */
304
303
  function retrieveAndSetValue(element) {
305
- const pathfinder = new Pathfinder(this[internalSymbol].subject.getSubject());
306
-
307
- let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND);
308
- if (path === null)
309
- throw new Error("the bind argument must start as a value with a path");
310
-
311
- if (path.indexOf("path:") !== 0) {
312
- throw new Error("the bind argument must start as a value with a path");
313
- }
314
-
315
- path = path.substring(5);
316
-
317
- let value;
318
-
319
- if (element instanceof HTMLInputElement) {
320
- switch (element.type) {
321
- case "checkbox":
322
- value = element.checked ? element.value : undefined;
323
- break;
324
- default:
325
- value = element.value;
326
- break;
327
- }
328
- } else if (element instanceof HTMLTextAreaElement) {
329
- value = element.value;
330
- } else if (element instanceof HTMLSelectElement) {
331
- switch (element.type) {
332
- case "select-one":
333
- value = element.value;
334
- break;
335
- case "select-multiple":
336
- value = element.value;
337
-
338
- let options = element?.selectedOptions;
339
- if (options === undefined)
340
- options = element.querySelectorAll(":scope option:checked");
341
- value = Array.from(options).map(({value}) => value);
342
-
343
- break;
344
- }
345
-
346
- // values from customelements
347
- } else if (
348
- (element?.constructor?.prototype &&
349
- !!Object.getOwnPropertyDescriptor(
350
- element.constructor.prototype,
351
- "value",
352
- )?.["get"]) ||
353
- element.hasOwnProperty("value")
354
- ) {
355
- value = element?.["value"];
356
- } else {
357
- throw new Error("unsupported object");
358
- }
359
-
360
- const copy = clone(this[internalSymbol].subject.getRealSubject());
361
- const pf = new Pathfinder(copy);
362
- pf.setVia(path, value);
363
-
364
- const diffResult = diff(copy, this[internalSymbol].subject.getRealSubject());
365
-
366
- if (diffResult.length > 0) {
367
- pathfinder.setVia(path, value);
368
- }
304
+ const pathfinder = new Pathfinder(this[internalSymbol].subject.getSubject());
305
+
306
+ let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND);
307
+ if (path === null)
308
+ throw new Error("the bind argument must start as a value with a path");
309
+
310
+ if (path.indexOf("path:") !== 0) {
311
+ throw new Error("the bind argument must start as a value with a path");
312
+ }
313
+
314
+ path = path.substring(5);
315
+
316
+ let value;
317
+
318
+ if (element instanceof HTMLInputElement) {
319
+ switch (element.type) {
320
+ case "checkbox":
321
+ value = element.checked ? element.value : undefined;
322
+ break;
323
+ default:
324
+ value = element.value;
325
+ break;
326
+ }
327
+ } else if (element instanceof HTMLTextAreaElement) {
328
+ value = element.value;
329
+ } else if (element instanceof HTMLSelectElement) {
330
+ switch (element.type) {
331
+ case "select-one":
332
+ value = element.value;
333
+ break;
334
+ case "select-multiple":
335
+ value = element.value;
336
+
337
+ let options = element?.selectedOptions;
338
+ if (options === undefined)
339
+ options = element.querySelectorAll(":scope option:checked");
340
+ value = Array.from(options).map(({ value }) => value);
341
+
342
+ break;
343
+ }
344
+
345
+ // values from customelements
346
+ } else if (
347
+ (element?.constructor?.prototype &&
348
+ !!Object.getOwnPropertyDescriptor(
349
+ element.constructor.prototype,
350
+ "value",
351
+ )?.["get"]) ||
352
+ element.hasOwnProperty("value")
353
+ ) {
354
+ value = element?.["value"];
355
+ } else {
356
+ throw new Error("unsupported object");
357
+ }
358
+
359
+ const copy = clone(this[internalSymbol].subject.getRealSubject());
360
+ const pf = new Pathfinder(copy);
361
+ pf.setVia(path, value);
362
+
363
+ const diffResult = diff(copy, this[internalSymbol].subject.getRealSubject());
364
+
365
+ if (diffResult.length > 0) {
366
+ pathfinder.setVia(path, value);
367
+ }
369
368
  }
370
369
 
371
370
  /**
@@ -375,15 +374,15 @@ function retrieveAndSetValue(element) {
375
374
  * @private
376
375
  */
377
376
  function retrieveFromBindings() {
378
- if (this[internalSymbol].element.matches(`[${ATTRIBUTE_UPDATER_BIND}]`)) {
379
- retrieveAndSetValue.call(this, this[internalSymbol].element);
380
- }
381
-
382
- for (const [, element] of this[internalSymbol].element
383
- .querySelectorAll(`[${ATTRIBUTE_UPDATER_BIND}]`)
384
- .entries()) {
385
- retrieveAndSetValue.call(this, element);
386
- }
377
+ if (this[internalSymbol].element.matches(`[${ATTRIBUTE_UPDATER_BIND}]`)) {
378
+ retrieveAndSetValue.call(this, this[internalSymbol].element);
379
+ }
380
+
381
+ for (const [, element] of this[internalSymbol].element
382
+ .querySelectorAll(`[${ATTRIBUTE_UPDATER_BIND}]`)
383
+ .entries()) {
384
+ retrieveAndSetValue.call(this, element);
385
+ }
387
386
  }
388
387
 
389
388
  /**
@@ -394,11 +393,11 @@ function retrieveFromBindings() {
394
393
  * @return {void}
395
394
  */
396
395
  function removeElement(change) {
397
- for (const [, element] of this[internalSymbol].element
398
- .querySelectorAll(`:scope [${ATTRIBUTE_UPDATER_REMOVE}]`)
399
- .entries()) {
400
- element.parentNode.removeChild(element);
401
- }
396
+ for (const [, element] of this[internalSymbol].element
397
+ .querySelectorAll(`:scope [${ATTRIBUTE_UPDATER_REMOVE}]`)
398
+ .entries()) {
399
+ element.parentNode.removeChild(element);
400
+ }
402
401
  }
403
402
 
404
403
  /**
@@ -414,135 +413,133 @@ function removeElement(change) {
414
413
  * @this Updater
415
414
  */
416
415
  function insertElement(change) {
417
- const subject = this[internalSymbol].subject.getRealSubject();
416
+ const subject = this[internalSymbol].subject.getRealSubject();
418
417
 
419
- const mem = new WeakSet();
420
- let wd = 0;
418
+ const mem = new WeakSet();
419
+ let wd = 0;
421
420
 
422
- const container = this[internalSymbol].element;
421
+ const container = this[internalSymbol].element;
423
422
 
424
- while (true) {
425
- let found = false;
426
- wd++;
427
-
428
- const p = clone(change?.["path"]);
429
- if (!isArray(p)) return;
430
-
431
- while (p.length > 0) {
432
- const current = p.join(".");
433
-
434
- let iterator = new Set();
435
- const query = `[${ATTRIBUTE_UPDATER_INSERT}*="path:${current}"]`;
436
-
437
- const e = container.querySelectorAll(query);
438
-
439
- if (e.length > 0) {
440
- iterator = new Set([...e]);
441
- }
442
-
443
- if (container.matches(query)) {
444
- iterator.add(container);
445
- }
446
-
447
- for (const [, containerElement] of iterator.entries()) {
448
- if (mem.has(containerElement)) continue;
449
- mem.add(containerElement);
450
-
451
- found = true;
452
-
453
- const attributes = containerElement.getAttribute(
454
- ATTRIBUTE_UPDATER_INSERT,
455
- );
456
- if (attributes === null) continue;
457
-
458
- const def = trimSpaces(attributes);
459
- const i = def.indexOf(" ");
460
- const key = trimSpaces(def.substr(0, i));
461
- const refPrefix = `${key}-`;
462
- const cmd = trimSpaces(def.substr(i));
463
-
464
- // this case is actually excluded by the query but is nevertheless checked again here
465
- if (cmd.indexOf("|") > 0) {
466
- throw new Error("pipes are not allowed when cloning a node.");
467
- }
468
-
469
- const pipe = new Pipe(cmd);
470
- this[internalSymbol].callbacks.forEach((f, n) => {
471
- pipe.setCallback(n, f);
472
- });
473
-
474
- let value;
475
- try {
476
- containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
477
- value = pipe.run(subject);
478
- } catch (e) {
479
- containerElement.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
480
- }
481
-
482
- const dataPath = cmd.split(":").pop();
483
-
484
- let insertPoint;
485
- if (containerElement.hasChildNodes()) {
486
- insertPoint = containerElement.lastChild;
487
- }
488
-
489
- if (!isIterable(value)) {
490
- throw new Error("the value is not iterable");
491
- }
492
-
493
- const available = new Set();
494
-
495
- for (const [i, obj] of Object.entries(value)) {
496
- const ref = refPrefix + i;
497
- const currentPath = `${dataPath}.${i}`;
498
-
499
- available.add(ref);
500
- const refElement = containerElement.querySelector(
501
- `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}="${ref}"]`,
502
- );
503
-
504
- if (refElement instanceof HTMLElement) {
505
- insertPoint = refElement;
506
- continue;
507
- }
508
-
509
- appendNewDocumentFragment(containerElement, key, ref, currentPath);
510
- }
511
-
512
- const nodes = containerElement.querySelectorAll(
513
- `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}*="${refPrefix}"]`,
514
- );
515
-
516
- for (const [, node] of Object.entries(nodes)) {
517
- if (
518
- !available.has(
519
- node.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE),
520
- )
521
- ) {
522
- try {
523
- containerElement.removeChild(node);
524
- } catch (e) {
525
- containerElement.setAttribute(
526
- ATTRIBUTE_ERRORMESSAGE,
527
- `${containerElement.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${
528
- e.message
529
- }`.trim(),
530
- );
531
- }
532
- }
533
-
534
- }
535
-
536
- }
537
-
538
- p.pop();
539
- }
540
-
541
- if (found === false) break;
542
- if (wd++ > 200) {
543
- throw new Error("the maximum depth for the recursion is reached.");
544
- }
545
- }
423
+ while (true) {
424
+ let found = false;
425
+ wd++;
426
+
427
+ const p = clone(change?.["path"]);
428
+ if (!isArray(p)) return;
429
+
430
+ while (p.length > 0) {
431
+ const current = p.join(".");
432
+
433
+ let iterator = new Set();
434
+ const query = `[${ATTRIBUTE_UPDATER_INSERT}*="path:${current}"]`;
435
+
436
+ const e = container.querySelectorAll(query);
437
+
438
+ if (e.length > 0) {
439
+ iterator = new Set([...e]);
440
+ }
441
+
442
+ if (container.matches(query)) {
443
+ iterator.add(container);
444
+ }
445
+
446
+ for (const [, containerElement] of iterator.entries()) {
447
+ if (mem.has(containerElement)) continue;
448
+ mem.add(containerElement);
449
+
450
+ found = true;
451
+
452
+ const attributes = containerElement.getAttribute(
453
+ ATTRIBUTE_UPDATER_INSERT,
454
+ );
455
+ if (attributes === null) continue;
456
+
457
+ const def = trimSpaces(attributes);
458
+ const i = def.indexOf(" ");
459
+ const key = trimSpaces(def.substr(0, i));
460
+ const refPrefix = `${key}-`;
461
+ const cmd = trimSpaces(def.substr(i));
462
+
463
+ // this case is actually excluded by the query but is nevertheless checked again here
464
+ if (cmd.indexOf("|") > 0) {
465
+ throw new Error("pipes are not allowed when cloning a node.");
466
+ }
467
+
468
+ const pipe = new Pipe(cmd);
469
+ this[internalSymbol].callbacks.forEach((f, n) => {
470
+ pipe.setCallback(n, f);
471
+ });
472
+
473
+ let value;
474
+ try {
475
+ containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
476
+ value = pipe.run(subject);
477
+ } catch (e) {
478
+ containerElement.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
479
+ }
480
+
481
+ const dataPath = cmd.split(":").pop();
482
+
483
+ let insertPoint;
484
+ if (containerElement.hasChildNodes()) {
485
+ insertPoint = containerElement.lastChild;
486
+ }
487
+
488
+ if (!isIterable(value)) {
489
+ throw new Error("the value is not iterable");
490
+ }
491
+
492
+ const available = new Set();
493
+
494
+ for (const [i, obj] of Object.entries(value)) {
495
+ const ref = refPrefix + i;
496
+ const currentPath = `${dataPath}.${i}`;
497
+
498
+ available.add(ref);
499
+ const refElement = containerElement.querySelector(
500
+ `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}="${ref}"]`,
501
+ );
502
+
503
+ if (refElement instanceof HTMLElement) {
504
+ insertPoint = refElement;
505
+ continue;
506
+ }
507
+
508
+ appendNewDocumentFragment(containerElement, key, ref, currentPath);
509
+ }
510
+
511
+ const nodes = containerElement.querySelectorAll(
512
+ `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}*="${refPrefix}"]`,
513
+ );
514
+
515
+ for (const [, node] of Object.entries(nodes)) {
516
+ if (
517
+ !available.has(
518
+ node.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE),
519
+ )
520
+ ) {
521
+ try {
522
+ containerElement.removeChild(node);
523
+ } catch (e) {
524
+ containerElement.setAttribute(
525
+ ATTRIBUTE_ERRORMESSAGE,
526
+ `${containerElement.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${
527
+ e.message
528
+ }`.trim(),
529
+ );
530
+ }
531
+ }
532
+ }
533
+ }
534
+
535
+ p.pop();
536
+ }
537
+
538
+ if (found === false) break;
539
+ if (wd++ > 200) {
540
+ throw new Error("the maximum depth for the recursion is reached.");
541
+ }
542
+ }
546
543
  }
547
544
 
548
545
  /**
@@ -557,17 +554,17 @@ function insertElement(change) {
557
554
  * @throws {Error} no template was found with the specified key.
558
555
  */
559
556
  function appendNewDocumentFragment(container, key, ref, path) {
560
- const template = findDocumentTemplate(key, container);
557
+ const template = findDocumentTemplate(key, container);
561
558
 
562
- const nodes = template.createDocumentFragment();
563
- for (const [, node] of Object.entries(nodes.childNodes)) {
564
- if (node instanceof HTMLElement) {
565
- applyRecursive(node, key, path);
566
- node.setAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE, ref);
567
- }
559
+ const nodes = template.createDocumentFragment();
560
+ for (const [, node] of Object.entries(nodes.childNodes)) {
561
+ if (node instanceof HTMLElement) {
562
+ applyRecursive(node, key, path);
563
+ node.setAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE, ref);
564
+ }
568
565
 
569
- container.appendChild(node);
570
- }
566
+ container.appendChild(node);
567
+ }
571
568
  }
572
569
 
573
570
  /**
@@ -580,27 +577,27 @@ function appendNewDocumentFragment(container, key, ref, path) {
580
577
  * @return {void}
581
578
  */
582
579
  function applyRecursive(node, key, path) {
583
- if (node instanceof HTMLElement) {
584
- if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) {
585
- const value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
586
- node.setAttribute(
587
- ATTRIBUTE_UPDATER_REPLACE,
588
- value.replaceAll(`path:${key}`, `path:${path}`),
589
- );
590
- }
591
-
592
- if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
593
- const value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
594
- node.setAttribute(
595
- ATTRIBUTE_UPDATER_ATTRIBUTES,
596
- value.replaceAll(`path:${key}`, `path:${path}`),
597
- );
598
- }
599
-
600
- for (const [, child] of Object.entries(node.childNodes)) {
601
- applyRecursive(child, key, path);
602
- }
603
- }
580
+ if (node instanceof HTMLElement) {
581
+ if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) {
582
+ const value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
583
+ node.setAttribute(
584
+ ATTRIBUTE_UPDATER_REPLACE,
585
+ value.replaceAll(`path:${key}`, `path:${path}`),
586
+ );
587
+ }
588
+
589
+ if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
590
+ const value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
591
+ node.setAttribute(
592
+ ATTRIBUTE_UPDATER_ATTRIBUTES,
593
+ value.replaceAll(`path:${key}`, `path:${path}`),
594
+ );
595
+ }
596
+
597
+ for (const [, child] of Object.entries(node.childNodes)) {
598
+ applyRecursive(child, key, path);
599
+ }
600
+ }
604
601
  }
605
602
 
606
603
  /**
@@ -612,19 +609,19 @@ function applyRecursive(node, key, path) {
612
609
  * @this Updater
613
610
  */
614
611
  function updateContent(change) {
615
- const subject = this[internalSymbol].subject.getRealSubject();
616
-
617
- const p = clone(change?.["path"]);
618
- runUpdateContent.call(this, this[internalSymbol].element, p, subject);
619
-
620
- const slots = this[internalSymbol].element.querySelectorAll("slot");
621
- if (slots.length > 0) {
622
- for (const [, slot] of Object.entries(slots)) {
623
- for (const [, element] of Object.entries(slot.assignedNodes())) {
624
- runUpdateContent.call(this, element, p, subject);
625
- }
626
- }
627
- }
612
+ const subject = this[internalSymbol].subject.getRealSubject();
613
+
614
+ const p = clone(change?.["path"]);
615
+ runUpdateContent.call(this, this[internalSymbol].element, p, subject);
616
+
617
+ const slots = this[internalSymbol].element.querySelectorAll("slot");
618
+ if (slots.length > 0) {
619
+ for (const [, slot] of Object.entries(slots)) {
620
+ for (const [, element] of Object.entries(slot.assignedNodes())) {
621
+ runUpdateContent.call(this, element, p, subject);
622
+ }
623
+ }
624
+ }
628
625
  }
629
626
 
630
627
  /**
@@ -637,69 +634,69 @@ function updateContent(change) {
637
634
  * @return {void}
638
635
  */
639
636
  function runUpdateContent(container, parts, subject) {
640
- if (!isArray(parts)) return;
641
- if (!(container instanceof HTMLElement)) return;
642
- parts = clone(parts);
643
-
644
- const mem = new WeakSet();
645
-
646
- while (parts.length > 0) {
647
- const current = parts.join(".");
648
- parts.pop();
649
-
650
- // Unfortunately, static data is always changed as well, since it is not possible to react to changes here.
651
- const query = `[${ATTRIBUTE_UPDATER_REPLACE}^="path:${current}"], [${ATTRIBUTE_UPDATER_REPLACE}^="static:"], [${ATTRIBUTE_UPDATER_REPLACE}^="i18n:"]`;
652
- const e = container.querySelectorAll(`${query}`);
653
-
654
- const iterator = new Set([...e]);
655
-
656
- if (container.matches(query)) {
657
- iterator.add(container);
658
- }
659
-
660
- /**
661
- * @type {HTMLElement}
662
- */
663
- for (const [element] of iterator.entries()) {
664
- if (mem.has(element)) return;
665
- mem.add(element);
666
-
667
- const attributes = element.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
668
- const cmd = trimSpaces(attributes);
669
-
670
- const pipe = new Pipe(cmd);
671
- this[internalSymbol].callbacks.forEach((f, n) => {
672
- pipe.setCallback(n, f);
673
- });
674
-
675
- let value;
676
- try {
677
- element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
678
- value = pipe.run(subject);
679
- } catch (e) {
680
- element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
681
- }
682
-
683
- if (value instanceof HTMLElement) {
684
- while (element.firstChild) {
685
- element.removeChild(element.firstChild);
686
- }
687
-
688
- try {
689
- element.appendChild(value);
690
- } catch (e) {
691
- element.setAttribute(
692
- ATTRIBUTE_ERRORMESSAGE,
693
- `${element.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${
694
- e.message
695
- }`.trim(),
696
- );
697
- }
698
- } else {
699
- element.innerHTML = value;
700
- }
701
- }
702
- }
637
+ if (!isArray(parts)) return;
638
+ if (!(container instanceof HTMLElement)) return;
639
+ parts = clone(parts);
640
+
641
+ const mem = new WeakSet();
642
+
643
+ while (parts.length > 0) {
644
+ const current = parts.join(".");
645
+ parts.pop();
646
+
647
+ // Unfortunately, static data is always changed as well, since it is not possible to react to changes here.
648
+ const query = `[${ATTRIBUTE_UPDATER_REPLACE}^="path:${current}"], [${ATTRIBUTE_UPDATER_REPLACE}^="static:"], [${ATTRIBUTE_UPDATER_REPLACE}^="i18n:"]`;
649
+ const e = container.querySelectorAll(`${query}`);
650
+
651
+ const iterator = new Set([...e]);
652
+
653
+ if (container.matches(query)) {
654
+ iterator.add(container);
655
+ }
656
+
657
+ /**
658
+ * @type {HTMLElement}
659
+ */
660
+ for (const [element] of iterator.entries()) {
661
+ if (mem.has(element)) return;
662
+ mem.add(element);
663
+
664
+ const attributes = element.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
665
+ const cmd = trimSpaces(attributes);
666
+
667
+ const pipe = new Pipe(cmd);
668
+ this[internalSymbol].callbacks.forEach((f, n) => {
669
+ pipe.setCallback(n, f);
670
+ });
671
+
672
+ let value;
673
+ try {
674
+ element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
675
+ value = pipe.run(subject);
676
+ } catch (e) {
677
+ element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
678
+ }
679
+
680
+ if (value instanceof HTMLElement) {
681
+ while (element.firstChild) {
682
+ element.removeChild(element.firstChild);
683
+ }
684
+
685
+ try {
686
+ element.appendChild(value);
687
+ } catch (e) {
688
+ element.setAttribute(
689
+ ATTRIBUTE_ERRORMESSAGE,
690
+ `${element.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${
691
+ e.message
692
+ }`.trim(),
693
+ );
694
+ }
695
+ } else {
696
+ element.innerHTML = value;
697
+ }
698
+ }
699
+ }
703
700
  }
704
701
 
705
702
  /**
@@ -711,9 +708,9 @@ function runUpdateContent(container, parts, subject) {
711
708
  * @return {void}
712
709
  */
713
710
  function updateAttributes(change) {
714
- const subject = this[internalSymbol].subject.getRealSubject();
715
- const p = clone(change?.["path"]);
716
- runUpdateAttributes.call(this, this[internalSymbol].element, p, subject);
711
+ const subject = this[internalSymbol].subject.getRealSubject();
712
+ const p = clone(change?.["path"]);
713
+ runUpdateAttributes.call(this, this[internalSymbol].element, p, subject);
717
714
  }
718
715
 
719
716
  /**
@@ -725,70 +722,70 @@ function updateAttributes(change) {
725
722
  * @this Updater
726
723
  */
727
724
  function runUpdateAttributes(container, parts, subject) {
728
- if (!isArray(parts)) return;
729
- parts = clone(parts);
725
+ if (!isArray(parts)) return;
726
+ parts = clone(parts);
730
727
 
731
- const mem = new WeakSet();
728
+ const mem = new WeakSet();
732
729
 
733
- while (parts.length > 0) {
734
- const current = parts.join(".");
735
- parts.pop();
730
+ while (parts.length > 0) {
731
+ const current = parts.join(".");
732
+ parts.pop();
736
733
 
737
- let iterator = new Set();
734
+ let iterator = new Set();
738
735
 
739
- const query = `[${ATTRIBUTE_UPDATER_SELECT_THIS}][${ATTRIBUTE_UPDATER_ATTRIBUTES}], [${ATTRIBUTE_UPDATER_ATTRIBUTES}*="path:${current}"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="static:"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="i18n:"]`;
736
+ const query = `[${ATTRIBUTE_UPDATER_SELECT_THIS}][${ATTRIBUTE_UPDATER_ATTRIBUTES}], [${ATTRIBUTE_UPDATER_ATTRIBUTES}*="path:${current}"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="static:"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="i18n:"]`;
740
737
 
741
- const e = container.querySelectorAll(query);
738
+ const e = container.querySelectorAll(query);
742
739
 
743
- if (e.length > 0) {
744
- iterator = new Set([...e]);
745
- }
740
+ if (e.length > 0) {
741
+ iterator = new Set([...e]);
742
+ }
746
743
 
747
- if (container.matches(query)) {
748
- iterator.add(container);
749
- }
744
+ if (container.matches(query)) {
745
+ iterator.add(container);
746
+ }
750
747
 
751
- for (const [element] of iterator.entries()) {
752
- if (mem.has(element)) return;
753
- mem.add(element);
748
+ for (const [element] of iterator.entries()) {
749
+ if (mem.has(element)) return;
750
+ mem.add(element);
754
751
 
755
- // this case occurs when the ATTRIBUTE_UPDATER_SELECT_THIS attribute is set
756
- if (!element.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
757
- continue;
758
- }
752
+ // this case occurs when the ATTRIBUTE_UPDATER_SELECT_THIS attribute is set
753
+ if (!element.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
754
+ continue;
755
+ }
759
756
 
760
- const attributes = element.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
757
+ const attributes = element.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
761
758
 
762
- for (let [, def] of Object.entries(attributes.split(","))) {
763
- def = trimSpaces(def);
764
- const i = def.indexOf(" ");
765
- const name = trimSpaces(def.substr(0, i));
766
- const cmd = trimSpaces(def.substr(i));
759
+ for (let [, def] of Object.entries(attributes.split(","))) {
760
+ def = trimSpaces(def);
761
+ const i = def.indexOf(" ");
762
+ const name = trimSpaces(def.substr(0, i));
763
+ const cmd = trimSpaces(def.substr(i));
767
764
 
768
- const pipe = new Pipe(cmd);
765
+ const pipe = new Pipe(cmd);
769
766
 
770
- this[internalSymbol].callbacks.forEach((f, n) => {
771
- pipe.setCallback(n, f, element);
772
- });
767
+ this[internalSymbol].callbacks.forEach((f, n) => {
768
+ pipe.setCallback(n, f, element);
769
+ });
773
770
 
774
- let value;
775
- try {
776
- element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
777
- value = pipe.run(subject);
778
- } catch (e) {
779
- element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
780
- }
771
+ let value;
772
+ try {
773
+ element.removeAttribute(ATTRIBUTE_ERRORMESSAGE);
774
+ value = pipe.run(subject);
775
+ } catch (e) {
776
+ element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message);
777
+ }
781
778
 
782
- if (value === undefined) {
783
- element.removeAttribute(name);
784
- } else if (element.getAttribute(name) !== value) {
785
- element.setAttribute(name, value);
786
- }
779
+ if (value === undefined) {
780
+ element.removeAttribute(name);
781
+ } else if (element.getAttribute(name) !== value) {
782
+ element.setAttribute(name, value);
783
+ }
787
784
 
788
- handleInputControlAttributeUpdate.call(this, element, name, value);
789
- }
790
- }
791
- }
785
+ handleInputControlAttributeUpdate.call(this, element, name, value);
786
+ }
787
+ }
788
+ }
792
789
  }
793
790
 
794
791
  /**
@@ -801,66 +798,66 @@ function runUpdateAttributes(container, parts, subject) {
801
798
  */
802
799
 
803
800
  function handleInputControlAttributeUpdate(element, name, value) {
804
- if (element instanceof HTMLSelectElement) {
805
- switch (element.type) {
806
- case "select-multiple":
807
- for (const [index, opt] of Object.entries(element.options)) {
808
- if (value.indexOf(opt.value) !== -1) {
809
- opt.selected = true;
810
- } else {
811
- opt.selected = false;
812
- }
813
- }
814
-
815
- break;
816
- case "select-one":
817
- // Only one value may be selected
818
-
819
- for (const [index, opt] of Object.entries(element.options)) {
820
- if (opt.value === value) {
821
- element.selectedIndex = index;
822
- break;
823
- }
824
- }
825
-
826
- break;
827
- }
828
- } else if (element instanceof HTMLInputElement) {
829
- switch (element.type) {
830
- case "radio":
831
- if (name === "checked") {
832
- if (value !== undefined) {
833
- element.checked = true;
834
- } else {
835
- element.checked = false;
836
- }
837
- }
838
-
839
- break;
840
-
841
- case "checkbox":
842
- if (name === "checked") {
843
- if (value !== undefined) {
844
- element.checked = true;
845
- } else {
846
- element.checked = false;
847
- }
848
- }
849
-
850
- break;
851
- case "text":
852
- default:
853
- if (name === "value") {
854
- element.value = value === undefined ? "" : value;
855
- }
856
-
857
- break;
858
- }
859
- } else if (element instanceof HTMLTextAreaElement) {
860
- if (name === "value") {
861
- element.value = value === undefined ? "" : value;
862
- }
863
- }
801
+ if (element instanceof HTMLSelectElement) {
802
+ switch (element.type) {
803
+ case "select-multiple":
804
+ for (const [index, opt] of Object.entries(element.options)) {
805
+ if (value.indexOf(opt.value) !== -1) {
806
+ opt.selected = true;
807
+ } else {
808
+ opt.selected = false;
809
+ }
810
+ }
811
+
812
+ break;
813
+ case "select-one":
814
+ // Only one value may be selected
815
+
816
+ for (const [index, opt] of Object.entries(element.options)) {
817
+ if (opt.value === value) {
818
+ element.selectedIndex = index;
819
+ break;
820
+ }
821
+ }
822
+
823
+ break;
824
+ }
825
+ } else if (element instanceof HTMLInputElement) {
826
+ switch (element.type) {
827
+ case "radio":
828
+ if (name === "checked") {
829
+ if (value !== undefined) {
830
+ element.checked = true;
831
+ } else {
832
+ element.checked = false;
833
+ }
834
+ }
835
+
836
+ break;
837
+
838
+ case "checkbox":
839
+ if (name === "checked") {
840
+ if (value !== undefined) {
841
+ element.checked = true;
842
+ } else {
843
+ element.checked = false;
844
+ }
845
+ }
846
+
847
+ break;
848
+ case "text":
849
+ default:
850
+ if (name === "value") {
851
+ element.value = value === undefined ? "" : value;
852
+ }
853
+
854
+ break;
855
+ }
856
+ } else if (element instanceof HTMLTextAreaElement) {
857
+ if (name === "value") {
858
+ element.value = value === undefined ? "" : value;
859
+ }
860
+ }
864
861
  }
865
862
 
866
863
  /**
@@ -876,48 +873,48 @@ function handleInputControlAttributeUpdate(element, name, value) {
876
873
  * @throws {TypeError} symbol must be an instance of Symbol
877
874
  */
878
875
  function addObjectWithUpdaterToElement(elements, symbol, object) {
879
- if (!(this instanceof HTMLElement)) {
880
- throw new TypeError(
881
- "the context of this function must be an instance of HTMLElement",
882
- );
883
- }
884
-
885
- if (!(typeof symbol === "symbol")) {
886
- throw new TypeError("symbol must be an instance of Symbol");
887
- }
888
-
889
- const updaters = new Set();
890
-
891
- if (elements instanceof NodeList) {
892
- elements = new Set([...elements]);
893
- } else if (elements instanceof HTMLElement) {
894
- elements = new Set([elements]);
895
- } else if (elements instanceof Set) {
896
- } else {
897
- throw new TypeError(
898
- `elements is not a valid type. (actual: ${typeof elements})`,
899
- );
900
- }
901
-
902
- const result = [];
903
-
904
- elements.forEach((element) => {
905
- if (!(element instanceof HTMLElement)) return;
906
- if (element instanceof HTMLTemplateElement) return;
907
-
908
- const u = new Updater(element, object);
909
- updaters.add(u);
910
-
911
- result.push(
912
- u.run().then(() => {
913
- return u.enableEventProcessing();
914
- }),
915
- );
916
- });
917
-
918
- if (updaters.size > 0) {
919
- addToObjectLink(this, symbol, updaters);
920
- }
921
-
922
- return result;
876
+ if (!(this instanceof HTMLElement)) {
877
+ throw new TypeError(
878
+ "the context of this function must be an instance of HTMLElement",
879
+ );
880
+ }
881
+
882
+ if (!(typeof symbol === "symbol")) {
883
+ throw new TypeError("symbol must be an instance of Symbol");
884
+ }
885
+
886
+ const updaters = new Set();
887
+
888
+ if (elements instanceof NodeList) {
889
+ elements = new Set([...elements]);
890
+ } else if (elements instanceof HTMLElement) {
891
+ elements = new Set([elements]);
892
+ } else if (elements instanceof Set) {
893
+ } else {
894
+ throw new TypeError(
895
+ `elements is not a valid type. (actual: ${typeof elements})`,
896
+ );
897
+ }
898
+
899
+ const result = [];
900
+
901
+ elements.forEach((element) => {
902
+ if (!(element instanceof HTMLElement)) return;
903
+ if (element instanceof HTMLTemplateElement) return;
904
+
905
+ const u = new Updater(element, object);
906
+ updaters.add(u);
907
+
908
+ result.push(
909
+ u.run().then(() => {
910
+ return u.enableEventProcessing();
911
+ }),
912
+ );
913
+ });
914
+
915
+ if (updaters.size > 0) {
916
+ addToObjectLink(this, symbol, updaters);
917
+ }
918
+
919
+ return result;
923
920
  }