@schukai/monster 1.25.0 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +43 -0
- package/README.md +4 -4
- package/dist/modules/constants.js +1 -1
- package/dist/modules/constraints/abstract.js +1 -1
- package/dist/modules/constraints/abstractoperator.js +1 -1
- package/dist/modules/constraints/andoperator.js +1 -1
- package/dist/modules/constraints/invalid.js +1 -1
- package/dist/modules/constraints/isarray.js +1 -1
- package/dist/modules/constraints/isobject.js +1 -1
- package/dist/modules/constraints/namespace.js +1 -1
- package/dist/modules/constraints/oroperator.js +1 -1
- package/dist/modules/constraints/valid.js +1 -1
- package/dist/modules/data/buildmap.js +2 -2
- package/dist/modules/data/buildtree.js +2 -0
- package/dist/modules/data/datasource/namespace.js +1 -1
- package/dist/modules/data/datasource/restapi/writeerror.js +1 -1
- package/dist/modules/data/datasource/restapi.js +1 -1
- package/dist/modules/data/datasource/storage/localstorage.js +1 -1
- package/dist/modules/data/datasource/storage/namespace.js +1 -1
- package/dist/modules/data/datasource/storage/sessionstorage.js +1 -1
- package/dist/modules/data/datasource/storage.js +1 -1
- package/dist/modules/data/datasource.js +1 -1
- package/dist/modules/data/diff.js +1 -1
- package/dist/modules/data/extend.js +1 -1
- package/dist/modules/data/namespace.js +1 -1
- package/dist/modules/data/pathfinder.js +1 -1
- package/dist/modules/data/pipe.js +1 -1
- package/dist/modules/data/transformer.js +1 -1
- package/dist/modules/dom/assembler.js +1 -1
- package/dist/modules/dom/attributes.js +2 -2
- package/dist/modules/dom/constants.js +2 -2
- package/dist/modules/dom/customcontrol.js +1 -1
- package/dist/modules/dom/customelement.js +1 -1
- package/dist/modules/dom/events.js +1 -1
- package/dist/modules/dom/focusmanager.js +1 -1
- package/dist/modules/dom/locale.js +1 -1
- package/dist/modules/dom/namespace.js +1 -1
- package/dist/modules/dom/resource/data.js +1 -1
- package/dist/modules/dom/resource/link/stylesheet.js +1 -1
- package/dist/modules/dom/resource/link.js +1 -1
- package/dist/modules/dom/resource/script.js +1 -1
- package/dist/modules/dom/resource.js +1 -1
- package/dist/modules/dom/resourcemanager.js +1 -1
- package/dist/modules/dom/template.js +2 -2
- package/dist/modules/dom/theme.js +1 -1
- package/dist/modules/dom/updater.js +2 -2
- package/dist/modules/dom/util.js +1 -1
- package/dist/modules/dom/worker/factory.js +1 -1
- package/dist/modules/i18n/formatter.js +2 -0
- package/dist/modules/i18n/locale.js +1 -1
- package/dist/modules/i18n/namespace.js +1 -1
- package/dist/modules/i18n/provider.js +1 -1
- package/dist/modules/i18n/providers/fetch.js +1 -1
- package/dist/modules/i18n/providers/namespace.js +1 -1
- package/dist/modules/i18n/translations.js +1 -1
- package/dist/modules/logging/handler/console.js +1 -1
- package/dist/modules/logging/handler/namespace.js +1 -1
- package/dist/modules/logging/handler.js +1 -1
- package/dist/modules/logging/logentry.js +1 -1
- package/dist/modules/logging/logger.js +1 -1
- package/dist/modules/logging/namespace.js +1 -1
- package/dist/modules/math/namespace.js +1 -1
- package/dist/modules/math/random.js +1 -1
- package/dist/modules/monster.js +1 -1
- package/dist/modules/namespace.js +1 -1
- package/dist/modules/text/formatter.js +2 -2
- package/dist/modules/text/namespace.js +1 -1
- package/dist/modules/types/base.js +1 -1
- package/dist/modules/types/basewithoptions.js +1 -1
- package/dist/modules/types/binary.js +1 -1
- package/dist/modules/types/dataurl.js +1 -1
- package/dist/modules/types/global.js +1 -1
- package/dist/modules/types/id.js +1 -1
- package/dist/modules/types/is.js +2 -2
- package/dist/modules/types/mediatype.js +1 -1
- package/dist/modules/types/namespace.js +1 -1
- package/dist/modules/types/node.js +2 -0
- package/dist/modules/types/nodelist.js +2 -0
- package/dist/modules/types/noderecursiveiterator.js +2 -0
- package/dist/modules/types/observer.js +1 -1
- package/dist/modules/types/observerlist.js +1 -1
- package/dist/modules/types/proxyobserver.js +1 -1
- package/dist/modules/types/queue.js +1 -1
- package/dist/modules/types/randomid.js +1 -1
- package/dist/modules/types/regex.js +2 -0
- package/dist/modules/types/stack.js +1 -1
- package/dist/modules/types/tokenlist.js +1 -1
- package/dist/modules/types/typeof.js +1 -1
- package/dist/modules/types/uniquequeue.js +1 -1
- package/dist/modules/types/uuid.js +1 -1
- package/dist/modules/types/validate.js +1 -1
- package/dist/modules/types/version.js +2 -2
- package/dist/modules/util/clone.js +1 -1
- package/dist/modules/util/comparator.js +1 -1
- package/dist/modules/util/freeze.js +1 -1
- package/dist/modules/util/namespace.js +1 -1
- package/dist/modules/util/processing.js +1 -1
- package/dist/modules/util/trimspaces.js +1 -1
- package/dist/monster.dev.js +1181 -708
- package/dist/monster.dev.js.map +1 -1
- package/dist/monster.js +2 -2
- package/package.json +13 -2
- package/source/constraints/abstract.js +5 -0
- package/source/constraints/abstractoperator.js +5 -0
- package/source/constraints/andoperator.js +10 -5
- package/source/constraints/invalid.js +8 -3
- package/source/constraints/isarray.js +9 -4
- package/source/constraints/isobject.js +8 -3
- package/source/constraints/oroperator.js +10 -5
- package/source/constraints/valid.js +8 -3
- package/source/data/buildmap.js +27 -13
- package/source/data/buildtree.js +129 -0
- package/source/data/datasource/restapi.js +3 -3
- package/source/data/datasource/storage/localstorage.js +2 -2
- package/source/data/datasource/storage/sessionstorage.js +2 -2
- package/source/data/datasource/storage.js +3 -3
- package/source/data/datasource.js +3 -3
- package/source/data/diff.js +3 -3
- package/source/data/extend.js +2 -2
- package/source/data/pathfinder.js +4 -4
- package/source/data/pipe.js +3 -3
- package/source/data/transformer.js +3 -3
- package/source/dom/assembler.js +2 -2
- package/source/dom/attributes.js +111 -28
- package/source/dom/constants.js +17 -1
- package/source/dom/customcontrol.js +1 -1
- package/source/dom/customelement.js +1 -1
- package/source/dom/events.js +6 -7
- package/source/dom/focusmanager.js +6 -7
- package/source/dom/locale.js +8 -4
- package/source/dom/resource/data.js +2 -2
- package/source/dom/resource/link/stylesheet.js +2 -2
- package/source/dom/resource/link.js +2 -2
- package/source/dom/resource/script.js +2 -2
- package/source/dom/resource.js +2 -2
- package/source/dom/resourcemanager.js +2 -2
- package/source/dom/template.js +55 -15
- package/source/dom/theme.js +3 -3
- package/source/dom/updater.js +158 -98
- package/source/dom/util.js +6 -6
- package/source/dom/worker/factory.js +2 -2
- package/source/i18n/formatter.js +140 -0
- package/source/i18n/locale.js +6 -4
- package/source/i18n/provider.js +2 -2
- package/source/i18n/providers/fetch.js +18 -3
- package/source/i18n/translations.js +18 -9
- package/source/logging/handler/console.js +2 -2
- package/source/logging/handler.js +2 -2
- package/source/logging/logentry.js +2 -2
- package/source/logging/logger.js +2 -2
- package/source/math/random.js +2 -2
- package/source/namespace.js +1 -1
- package/source/text/formatter.js +190 -48
- package/source/types/base.js +2 -2
- package/source/types/basewithoptions.js +2 -2
- package/source/types/binary.js +4 -4
- package/source/types/dataurl.js +4 -4
- package/source/types/global.js +4 -4
- package/source/types/id.js +6 -3
- package/source/types/is.js +100 -82
- package/source/types/mediatype.js +4 -4
- package/source/types/node.js +210 -0
- package/source/types/nodelist.js +129 -0
- package/source/types/noderecursiveiterator.js +148 -0
- package/source/types/observer.js +3 -3
- package/source/types/observerlist.js +2 -2
- package/source/types/proxyobserver.js +5 -5
- package/source/types/queue.js +4 -4
- package/source/types/randomid.js +2 -2
- package/source/types/regex.js +49 -0
- package/source/types/stack.js +2 -2
- package/source/types/tokenlist.js +2 -2
- package/source/types/typeof.js +3 -3
- package/source/types/uniquequeue.js +2 -2
- package/source/types/uuid.js +2 -2
- package/source/types/validate.js +20 -20
- package/source/types/version.js +6 -6
- package/source/util/clone.js +2 -2
- package/source/util/comparator.js +3 -3
- package/source/util/freeze.js +2 -2
- package/source/util/processing.js +3 -3
- package/source/util/trimspaces.js +2 -2
- package/test/cases/data/buildtree.js +212 -0
- package/test/cases/dom/attributes.js +46 -19
- package/test/cases/dom/resource/link/stylesheet.js +1 -1
- package/test/cases/dom/template.js +72 -14
- package/test/cases/dom/updater.js +102 -75
- package/test/cases/i18n/formatter.js +66 -0
- package/test/cases/monster.js +1 -1
- package/test/cases/text/formatter.js +36 -5
- package/test/cases/types/node.js +252 -0
- package/test/cases/types/nodelist.js +71 -0
- package/test/cases/types/noderecursiveiterator.js +75 -0
- package/test/cases/types/regex.js +32 -0
- package/test/util/jsdom.js +0 -1
- package/test/web/import.js +6 -0
- package/test/web/monster-dev.html +3 -3
- package/test/web/monster.html +2 -2
- package/test/web/test.html +3 -3
- package/test/web/tests.js +3 -3
package/source/dom/updater.js
CHANGED
|
@@ -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.
|
|
47
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.0/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.
|
|
56
|
+
* import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.0/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.
|
|
63
|
+
* import {Updater} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.0/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
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
316
|
+
const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND);
|
|
298
317
|
|
|
299
|
-
if (
|
|
318
|
+
if (element === undefined) {
|
|
300
319
|
return;
|
|
301
320
|
}
|
|
302
321
|
|
|
303
|
-
|
|
322
|
+
retrieveAndSetValue.call(self, element);
|
|
304
323
|
|
|
305
|
-
|
|
306
|
-
throw new Error('the bind argument must start as a value with a path.');
|
|
307
|
-
}
|
|
324
|
+
}
|
|
308
325
|
|
|
309
|
-
|
|
326
|
+
return self[symbol];
|
|
310
327
|
|
|
311
|
-
let value;
|
|
312
328
|
|
|
313
|
-
|
|
314
|
-
switch (element.type) {
|
|
329
|
+
}
|
|
315
330
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
-
|
|
342
|
+
let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND);
|
|
329
343
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
|
@@ -530,12 +582,12 @@ function applyRecursive(node, key, path) {
|
|
|
530
582
|
|
|
531
583
|
if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) {
|
|
532
584
|
let value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE);
|
|
533
|
-
node.setAttribute(ATTRIBUTE_UPDATER_REPLACE, value.
|
|
585
|
+
node.setAttribute(ATTRIBUTE_UPDATER_REPLACE, value.replaceAll("path:" + key, "path:" + path));
|
|
534
586
|
}
|
|
535
587
|
|
|
536
588
|
if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) {
|
|
537
589
|
let value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES);
|
|
538
|
-
node.setAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES, value.
|
|
590
|
+
node.setAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES, value.replaceAll("path:" + key, "path:" + path));
|
|
539
591
|
}
|
|
540
592
|
|
|
541
593
|
for (const [, child] of Object.entries(node.childNodes)) {
|
|
@@ -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'
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
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
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
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;
|
package/source/dom/util.js
CHANGED
|
@@ -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.
|
|
16
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.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.
|
|
25
|
+
* import {getDocument} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.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.
|
|
77
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.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.
|
|
86
|
+
* import {getWindow} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.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.
|
|
143
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.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.
|
|
152
|
+
* import {getDocumentFragmentFromString} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.0/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.
|
|
23
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.0/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.
|
|
32
|
+
* import {Factory} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.28.0/dist/modules/dom/worker/factory.js';
|
|
33
33
|
* console.log(new Factory())
|
|
34
34
|
* </script>
|
|
35
35
|
* ```
|