@schukai/monster 1.24.0 → 1.27.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. package/CHANGELOG +47 -0
  2. package/README.md +4 -4
  3. package/dist/modules/constants.js +2 -2
  4. package/dist/modules/constraints/abstract.js +1 -1
  5. package/dist/modules/constraints/abstractoperator.js +1 -1
  6. package/dist/modules/constraints/andoperator.js +1 -1
  7. package/dist/modules/constraints/invalid.js +1 -1
  8. package/dist/modules/constraints/isarray.js +1 -1
  9. package/dist/modules/constraints/isobject.js +1 -1
  10. package/dist/modules/constraints/namespace.js +1 -1
  11. package/dist/modules/constraints/oroperator.js +1 -1
  12. package/dist/modules/constraints/valid.js +1 -1
  13. package/dist/modules/data/buildmap.js +2 -2
  14. package/dist/modules/data/buildtree.js +2 -0
  15. package/dist/modules/data/datasource/namespace.js +1 -1
  16. package/dist/modules/data/datasource/restapi/writeerror.js +1 -1
  17. package/dist/modules/data/datasource/restapi.js +1 -1
  18. package/dist/modules/data/datasource/storage/localstorage.js +1 -1
  19. package/dist/modules/data/datasource/storage/namespace.js +1 -1
  20. package/dist/modules/data/datasource/storage/sessionstorage.js +1 -1
  21. package/dist/modules/data/datasource/storage.js +1 -1
  22. package/dist/modules/data/datasource.js +1 -1
  23. package/dist/modules/data/diff.js +1 -1
  24. package/dist/modules/data/extend.js +1 -1
  25. package/dist/modules/data/namespace.js +1 -1
  26. package/dist/modules/data/pathfinder.js +1 -1
  27. package/dist/modules/data/pipe.js +1 -1
  28. package/dist/modules/data/transformer.js +2 -2
  29. package/dist/modules/dom/assembler.js +1 -1
  30. package/dist/modules/dom/attributes.js +2 -2
  31. package/dist/modules/dom/constants.js +2 -2
  32. package/dist/modules/dom/customcontrol.js +1 -1
  33. package/dist/modules/dom/customelement.js +1 -1
  34. package/dist/modules/dom/events.js +1 -1
  35. package/dist/modules/dom/focusmanager.js +2 -0
  36. package/dist/modules/dom/locale.js +1 -1
  37. package/dist/modules/dom/namespace.js +1 -1
  38. package/dist/modules/dom/resource/data.js +2 -0
  39. package/dist/modules/dom/resource/link/stylesheet.js +2 -0
  40. package/dist/modules/dom/resource/link.js +2 -0
  41. package/dist/modules/dom/resource/script.js +2 -0
  42. package/dist/modules/dom/resource.js +2 -0
  43. package/dist/modules/dom/resourcemanager.js +2 -0
  44. package/dist/modules/dom/template.js +2 -2
  45. package/dist/modules/dom/theme.js +1 -1
  46. package/dist/modules/dom/updater.js +2 -2
  47. package/dist/modules/dom/util.js +1 -1
  48. package/dist/modules/dom/worker/factory.js +2 -0
  49. package/dist/modules/i18n/formatter.js +2 -0
  50. package/dist/modules/i18n/locale.js +1 -1
  51. package/dist/modules/i18n/namespace.js +1 -1
  52. package/dist/modules/i18n/provider.js +1 -1
  53. package/dist/modules/i18n/providers/fetch.js +1 -1
  54. package/dist/modules/i18n/providers/namespace.js +1 -1
  55. package/dist/modules/i18n/translations.js +1 -1
  56. package/dist/modules/logging/handler/console.js +1 -1
  57. package/dist/modules/logging/handler/namespace.js +1 -1
  58. package/dist/modules/logging/handler.js +1 -1
  59. package/dist/modules/logging/logentry.js +1 -1
  60. package/dist/modules/logging/logger.js +1 -1
  61. package/dist/modules/logging/namespace.js +1 -1
  62. package/dist/modules/math/namespace.js +1 -1
  63. package/dist/modules/math/random.js +2 -2
  64. package/dist/modules/monster.js +1 -1
  65. package/dist/modules/namespace.js +1 -1
  66. package/dist/modules/text/formatter.js +2 -2
  67. package/dist/modules/text/namespace.js +1 -1
  68. package/dist/modules/types/base.js +1 -1
  69. package/dist/modules/types/basewithoptions.js +1 -1
  70. package/dist/modules/types/binary.js +1 -1
  71. package/dist/modules/types/dataurl.js +1 -1
  72. package/dist/modules/types/global.js +1 -1
  73. package/dist/modules/types/id.js +1 -1
  74. package/dist/modules/types/is.js +2 -2
  75. package/dist/modules/types/mediatype.js +1 -1
  76. package/dist/modules/types/namespace.js +1 -1
  77. package/dist/modules/types/node.js +2 -0
  78. package/dist/modules/types/nodelist.js +2 -0
  79. package/dist/modules/types/noderecursiveiterator.js +2 -0
  80. package/dist/modules/types/observer.js +1 -1
  81. package/dist/modules/types/observerlist.js +1 -1
  82. package/dist/modules/types/proxyobserver.js +1 -1
  83. package/dist/modules/types/queue.js +1 -1
  84. package/dist/modules/types/randomid.js +1 -1
  85. package/dist/modules/types/regex.js +2 -0
  86. package/dist/modules/types/stack.js +1 -1
  87. package/dist/modules/types/tokenlist.js +1 -1
  88. package/dist/modules/types/typeof.js +1 -1
  89. package/dist/modules/types/uniquequeue.js +1 -1
  90. package/dist/modules/types/uuid.js +2 -0
  91. package/dist/modules/types/validate.js +1 -1
  92. package/dist/modules/types/version.js +2 -2
  93. package/dist/modules/util/clone.js +1 -1
  94. package/dist/modules/util/comparator.js +1 -1
  95. package/dist/modules/util/freeze.js +1 -1
  96. package/dist/modules/util/namespace.js +1 -1
  97. package/dist/modules/util/processing.js +1 -1
  98. package/dist/modules/util/trimspaces.js +1 -1
  99. package/dist/monster.dev.js +1528 -770
  100. package/dist/monster.dev.js.map +1 -1
  101. package/dist/monster.js +2 -2
  102. package/package.json +13 -2
  103. package/source/constants.js +11 -2
  104. package/source/constraints/abstract.js +5 -0
  105. package/source/constraints/abstractoperator.js +5 -0
  106. package/source/constraints/andoperator.js +10 -5
  107. package/source/constraints/invalid.js +8 -3
  108. package/source/constraints/isarray.js +9 -4
  109. package/source/constraints/isobject.js +8 -3
  110. package/source/constraints/oroperator.js +10 -5
  111. package/source/constraints/valid.js +8 -3
  112. package/source/data/buildmap.js +25 -9
  113. package/source/data/buildtree.js +95 -0
  114. package/source/data/datasource/restapi.js +3 -3
  115. package/source/data/datasource/storage/localstorage.js +2 -2
  116. package/source/data/datasource/storage/sessionstorage.js +2 -2
  117. package/source/data/datasource/storage.js +3 -3
  118. package/source/data/datasource.js +3 -3
  119. package/source/data/diff.js +3 -3
  120. package/source/data/extend.js +2 -2
  121. package/source/data/pathfinder.js +4 -4
  122. package/source/data/pipe.js +3 -3
  123. package/source/data/transformer.js +7 -5
  124. package/source/dom/assembler.js +2 -2
  125. package/source/dom/attributes.js +111 -28
  126. package/source/dom/constants.js +287 -10
  127. package/source/dom/customcontrol.js +1 -1
  128. package/source/dom/customelement.js +1 -1
  129. package/source/dom/events.js +6 -7
  130. package/source/dom/focusmanager.js +250 -0
  131. package/source/dom/locale.js +10 -5
  132. package/source/dom/resource/data.js +170 -0
  133. package/source/dom/resource/link/stylesheet.js +54 -0
  134. package/source/dom/resource/link.js +125 -0
  135. package/source/dom/resource/script.js +112 -0
  136. package/source/dom/resource.js +268 -0
  137. package/source/dom/resourcemanager.js +214 -0
  138. package/source/dom/template.js +86 -16
  139. package/source/dom/theme.js +3 -3
  140. package/source/dom/updater.js +138 -90
  141. package/source/dom/util.js +6 -6
  142. package/source/dom/worker/factory.js +134 -0
  143. package/source/i18n/formatter.js +140 -0
  144. package/source/i18n/locale.js +6 -4
  145. package/source/i18n/provider.js +2 -2
  146. package/source/i18n/providers/fetch.js +18 -3
  147. package/source/i18n/translations.js +18 -9
  148. package/source/logging/handler/console.js +2 -2
  149. package/source/logging/handler.js +2 -2
  150. package/source/logging/logentry.js +2 -2
  151. package/source/logging/logger.js +2 -2
  152. package/source/math/random.js +9 -5
  153. package/source/namespace.js +1 -1
  154. package/source/text/formatter.js +190 -48
  155. package/source/types/base.js +4 -4
  156. package/source/types/basewithoptions.js +2 -2
  157. package/source/types/binary.js +4 -4
  158. package/source/types/dataurl.js +4 -4
  159. package/source/types/global.js +4 -4
  160. package/source/types/id.js +6 -3
  161. package/source/types/is.js +103 -85
  162. package/source/types/mediatype.js +4 -4
  163. package/source/types/node.js +179 -0
  164. package/source/types/nodelist.js +125 -0
  165. package/source/types/noderecursiveiterator.js +126 -0
  166. package/source/types/observer.js +3 -3
  167. package/source/types/observerlist.js +2 -2
  168. package/source/types/proxyobserver.js +5 -5
  169. package/source/types/queue.js +4 -4
  170. package/source/types/randomid.js +2 -2
  171. package/source/types/regex.js +49 -0
  172. package/source/types/stack.js +2 -2
  173. package/source/types/tokenlist.js +2 -2
  174. package/source/types/typeof.js +3 -3
  175. package/source/types/uniquequeue.js +2 -2
  176. package/source/types/uuid.js +102 -0
  177. package/source/types/validate.js +20 -20
  178. package/source/types/version.js +6 -6
  179. package/source/util/clone.js +2 -2
  180. package/source/util/comparator.js +4 -4
  181. package/source/util/freeze.js +5 -5
  182. package/source/util/processing.js +3 -3
  183. package/source/util/trimspaces.js +3 -3
  184. package/test/cases/data/buildtree.js +149 -0
  185. package/test/cases/data/datasource/restapi.js +1 -1
  186. package/test/cases/data/transformer.js +2 -0
  187. package/test/cases/dom/attributes.js +46 -19
  188. package/test/cases/dom/customelement.js +0 -3
  189. package/test/cases/dom/focusmanager.js +111 -0
  190. package/test/cases/dom/locale.js +1 -4
  191. package/test/cases/dom/resource/data.js +129 -0
  192. package/test/cases/dom/resource/link/stylesheet.js +101 -0
  193. package/test/cases/dom/resource/link.js +101 -0
  194. package/test/cases/dom/resource/script.js +115 -0
  195. package/test/cases/dom/resourcemanager.js +118 -0
  196. package/test/cases/dom/template.js +72 -14
  197. package/test/cases/dom/updater.js +102 -75
  198. package/test/cases/dom/worker/factory.js +63 -0
  199. package/test/cases/i18n/formatter.js +66 -0
  200. package/test/cases/monster.js +1 -1
  201. package/test/cases/text/formatter.js +36 -5
  202. package/test/cases/types/node.js +196 -0
  203. package/test/cases/types/nodelist.js +64 -0
  204. package/test/cases/types/noderecursiveiterator.js +54 -0
  205. package/test/cases/types/regex.js +32 -0
  206. package/test/cases/types/uuid.js +42 -0
  207. package/test/cases/util/freeze.js +30 -4
  208. package/test/util/cleanupdom.js +48 -0
  209. package/test/util/jsdom.js +22 -9
  210. package/test/web/import.js +14 -0
  211. package/test/web/monster-dev.html +3 -3
  212. package/test/web/monster.html +2 -2
  213. package/test/web/test.html +3 -3
  214. package/test/web/tests.js +7 -7
@@ -1,12 +1,47 @@
1
1
  'use strict';
2
2
 
3
- import {Pipe} from "../data/pipe.js";
4
3
  /**
5
4
  * @author schukai GmbH
6
5
  */
6
+
7
+ import {internalSymbol} from "../constants.js";
8
+ import {extend} from "../data/extend.js";
9
+ import {Pipe} from "../data/pipe.js";
7
10
  import {assignToNamespace, Monster} from '../namespace.js';
8
- import {Base} from "../types/base.js";
9
- import {validateObject, validateString} from "../types/validate.js";
11
+ import {BaseWithOptions} from "../types/basewithoptions.js";
12
+ import {isObject, isString} from "../types/is.js";
13
+ import {validateArray, validateString} from "../types/validate.js";
14
+
15
+
16
+ /**
17
+ * @private
18
+ * @type {symbol}
19
+ */
20
+ const internalObjectSymbol = Symbol('internalObject');
21
+
22
+ /**
23
+ * @private
24
+ * @type {symbol}
25
+ */
26
+ const watchdogSymbol = Symbol('watchdog');
27
+
28
+ /**
29
+ * @private
30
+ * @type {symbol}
31
+ */
32
+ const markerOpenIndexSymbol = Symbol('markerOpenIndex');
33
+
34
+ /**
35
+ * @private
36
+ * @type {symbol}
37
+ */
38
+ const markerCloseIndexSymbol = Symbol('markercloseIndex');
39
+
40
+ /**
41
+ * @private
42
+ * @type {symbol}
43
+ */
44
+ const workingDataSymbol = Symbol('workingData');
10
45
 
11
46
 
12
47
  /**
@@ -14,11 +49,11 @@ import {validateObject, validateString} from "../types/validate.js";
14
49
  *
15
50
  * Look at the example below. The placeholders use the logic of Pipe.
16
51
  *
17
- * You can call the method via the monster namespace `new Monster.Text.Formatter()`.
52
+ * You can create an instance via the monster namespace `new Monster.Text.Formatter()`.
18
53
  *
19
54
  * ```
20
55
  * <script type="module">
21
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/text/formatter.js';
56
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
22
57
  * new Monster.Text.Formatter()
23
58
  * </script>
24
59
  * ```
@@ -27,19 +62,42 @@ import {validateObject, validateString} from "../types/validate.js";
27
62
  *
28
63
  * ```
29
64
  * <script type="module">
30
- * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/text/formatter.js';
65
+ * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/text/formatter.js';
31
66
  * new Formatter()
32
67
  * </script>
33
68
  * ```
34
69
  *
35
70
  * ## Marker in marker
36
71
  *
37
- * Markers can be nested. Here, the inner marker is resolved first and then the outer marker.
72
+ * Markers can be nested. Here, the inner marker is resolved first `${subkey} ↦ 1 = ${mykey2}` and then the outer marker `${mykey2}`.
38
73
  *
39
74
  * ```
75
+ * const text = '${mykey${subkey}}';
76
+ * let obj = {
77
+ * mykey2: "1",
78
+ * subkey: "2"
79
+ * };
40
80
  *
81
+ * new Formatter(obj).format(text);
82
+ * // ↦ 1
41
83
  * ```
42
84
  *
85
+ * ## Callbacks
86
+ *
87
+ * The values in a formatter can be adjusted via the commands of the `Transformer` or the`Pipe`.
88
+ * There is also the possibility to use callbacks.
89
+ *
90
+ * const formatter = new Formatter({x: '1'}, {
91
+ * callbacks: {
92
+ * quote: (value) => {
93
+ * return '"' + value + '"'
94
+ * }
95
+ * }
96
+ * });
97
+ *
98
+ * formatter.format('${x | call:quote}'))
99
+ * // ↦ "1"
100
+ *
43
101
  * ## Marker with parameter
44
102
  *
45
103
  * A string can also bring its own values. These must then be separated from the key by a separator `::`.
@@ -49,7 +107,7 @@ import {validateObject, validateString} from "../types/validate.js";
49
107
  *
50
108
  * @example
51
109
  *
52
- * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/text/formatter.js';
110
+ * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/text/formatter.js';
53
111
  *
54
112
  * new Formatter({
55
113
  * a: {
@@ -58,7 +116,7 @@ import {validateObject, validateString} from "../types/validate.js";
58
116
  * },
59
117
  * d: "world",
60
118
  * }
61
- * }).format("${a.b.c} ${a.d | ucfirst}!");
119
+ * }).format("${a.b.c} ${a.d | ucfirst}!"); // with pipe
62
120
  *
63
121
  * // ↦ Hello World!
64
122
  *
@@ -66,7 +124,7 @@ import {validateObject, validateString} from "../types/validate.js";
66
124
  * @copyright schukai GmbH
67
125
  * @memberOf Monster.Text
68
126
  */
69
- class Formatter extends Base {
127
+ class Formatter extends BaseWithOptions {
70
128
 
71
129
  /**
72
130
  * Default values for the markers are `${` and `}`
@@ -74,18 +132,37 @@ class Formatter extends Base {
74
132
  * @param {object} object
75
133
  * @throws {TypeError} value is not a object
76
134
  */
77
- constructor(object) {
78
- super();
79
- if (object === undefined) {
80
- object = {};
81
- }
82
- this.object = validateObject(object);
83
- this.openMarker = '${';
84
- this.closeMarker = '}';
85
- this.parameterDelimiter = '::';
86
- this.parameterAssignment = '=';
135
+ constructor(object, options) {
136
+ super(options);
137
+ this[internalObjectSymbol] = object || {}
138
+ this[markerOpenIndexSymbol] = 0;
139
+ this[markerCloseIndexSymbol] = 0;
87
140
  }
88
141
 
142
+ /**
143
+ * @property {object} marker
144
+ * @property {array} marker.open=["${"]
145
+ * @property {array} marker.close=["${"]
146
+ * @property {object} parameter
147
+ * @property {string} parameter.delimiter="::"
148
+ * @property {string} parameter.assignment="="
149
+ * @property {object} callbacks={}
150
+ */
151
+ get defaults() {
152
+ return extend({}, super.defaults, {
153
+ marker: {
154
+ open: ['${'],
155
+ close: ['}']
156
+ },
157
+ parameter: {
158
+ delimiter: '::',
159
+ assignment: '='
160
+ },
161
+ callbacks: {},
162
+ })
163
+ }
164
+
165
+
89
166
  /**
90
167
  * Set new Parameter Character
91
168
  *
@@ -106,11 +183,11 @@ class Formatter extends Base {
106
183
  setParameterChars(delimiter, assignment) {
107
184
 
108
185
  if (delimiter !== undefined) {
109
- this.parameterDelimiter = validateString(delimiter);
186
+ this[internalSymbol]['parameter']['delimiter'] = validateString(delimiter);
110
187
  }
111
188
 
112
189
  if (assignment !== undefined) {
113
- this.parameterAssignment = validateString(assignment);
190
+ this[internalSymbol]['parameter']['assignment'] = validateString(assignment);
114
191
  }
115
192
 
116
193
  return this;
@@ -127,8 +204,8 @@ class Formatter extends Base {
127
204
  * formatter.setMarker('i18n{','}');
128
205
  * ```
129
206
  *
130
- * @param {string} open
131
- * @param {string} close
207
+ * @param {array|string} open
208
+ * @param {array|string|undefined} close
132
209
  * @return {Formatter}
133
210
  * @since 1.12.0
134
211
  * @throws {TypeError} value is not a string
@@ -139,8 +216,11 @@ class Formatter extends Base {
139
216
  close = open;
140
217
  }
141
218
 
142
- this.openMarker = validateString(open);
143
- this.closeMarker = validateString(close);
219
+ if (isString(open)) open = [open];
220
+ if (isString(close)) close = [close];
221
+
222
+ this[internalSymbol]['marker']['open'] = validateArray(open);
223
+ this[internalSymbol]['marker']['close'] = validateArray(close);
144
224
  return this;
145
225
  }
146
226
 
@@ -149,11 +229,51 @@ class Formatter extends Base {
149
229
  * @param {string} text
150
230
  * @return {string}
151
231
  * @throws {TypeError} value is not a string
232
+ * @throws {Error} too deep nesting
152
233
  */
153
234
  format(text) {
154
- return tokenizer.call(this, validateString(text))
235
+ this[watchdogSymbol] = 0;
236
+ this[markerOpenIndexSymbol] = 0;
237
+ this[markerCloseIndexSymbol] = 0;
238
+ this[workingDataSymbol] = {};
239
+ return format.call(this, text);
240
+ }
241
+
242
+ }
243
+
244
+ /**
245
+ * @private
246
+ * @return {string}
247
+ */
248
+ function format(text) {
249
+ const self = this;
250
+
251
+ self[watchdogSymbol]++;
252
+ if (this[watchdogSymbol] > 20) {
253
+ throw new Error('too deep nesting')
254
+ }
255
+
256
+ let openMarker = self[internalSymbol]['marker']['open']?.[this[markerOpenIndexSymbol]];
257
+ let closeMarker = self[internalSymbol]['marker']['close']?.[this[markerCloseIndexSymbol]];
258
+
259
+ // contains no placeholders
260
+ if (text.indexOf(openMarker) === -1 || text.indexOf(closeMarker) === -1) {
261
+ return text;
262
+ }
263
+
264
+ let result = tokenize.call(this, validateString(text), openMarker, closeMarker)
265
+
266
+ if (self[internalSymbol]['marker']['open']?.[this[markerOpenIndexSymbol] + 1]) {
267
+ this[markerOpenIndexSymbol]++;
268
+ }
269
+
270
+ if (self[internalSymbol]['marker']['close']?.[this[markerCloseIndexSymbol] + 1]) {
271
+ this[markerCloseIndexSymbol]++;
155
272
  }
156
273
 
274
+ result = format.call(self, result)
275
+
276
+ return result;
157
277
  }
158
278
 
159
279
  /**
@@ -162,15 +282,18 @@ class Formatter extends Base {
162
282
  * @param text
163
283
  * @return {string}
164
284
  */
165
- function tokenizer(text) {
285
+ function tokenize(text, openMarker, closeMarker) {
166
286
  const self = this;
167
287
 
168
288
  let formatted = [];
169
289
 
170
- while (true) {
290
+ const parameterAssignment = self[internalSymbol]['parameter']['assignment']
291
+ const parameterDelimiter = self[internalSymbol]['parameter']['delimiter']
292
+ const callbacks = self[internalSymbol]['callbacks'];
171
293
 
294
+ while (true) {
172
295
 
173
- let startIndex = text.indexOf(self.openMarker);
296
+ let startIndex = text.indexOf(openMarker);
174
297
  // no marker
175
298
  if (startIndex === -1) {
176
299
  formatted.push(text);
@@ -180,41 +303,60 @@ function tokenizer(text) {
180
303
  text = text.substring(startIndex)
181
304
  }
182
305
 
183
- let endIndex = text.substring(self.openMarker.length).indexOf(self.closeMarker);
184
- if (endIndex !== -1) endIndex += self.openMarker.length;
185
- let insideStartIndex = text.substring(self.openMarker.length).indexOf(self.openMarker);
306
+ let endIndex = text.substring(openMarker.length).indexOf(closeMarker);
307
+ if (endIndex !== -1) endIndex += openMarker.length;
308
+ let insideStartIndex = text.substring(openMarker.length).indexOf(openMarker);
186
309
  if (insideStartIndex !== -1) {
187
- insideStartIndex += self.openMarker.length;
310
+ insideStartIndex += openMarker.length;
188
311
  if (insideStartIndex < endIndex) {
189
- let sub = text.substring(insideStartIndex);
190
- let result = tokenizer.call(self, text.substring(insideStartIndex));
312
+ let result = tokenize.call(self, text.substring(insideStartIndex), openMarker, closeMarker);
191
313
  text = text.substring(0, insideStartIndex) + result
192
- endIndex = text.substring(self.openMarker.length).indexOf(self.closeMarker);
193
- if (endIndex !== -1) endIndex += self.openMarker.length;
314
+ endIndex = text.substring(openMarker.length).indexOf(closeMarker);
315
+ if (endIndex !== -1) endIndex += openMarker.length;
194
316
  }
195
317
  }
196
318
 
197
-
198
319
  if (endIndex === -1) {
199
320
  throw new Error("syntax error in formatter template")
200
321
  return;
201
322
  }
202
323
 
203
- let command = "path:";
204
- let key = text.substring(self.openMarker.length, endIndex);
205
- let parts = key.split(self.parameterDelimiter);
206
- command += parts.shift();
324
+ let key = text.substring(openMarker.length, endIndex);
325
+ let parts = key.split(parameterDelimiter);
326
+ let currentPipe = parts.shift();
207
327
 
208
- const temp = self.object;
328
+ self[workingDataSymbol] = extend({}, self[internalObjectSymbol], self[workingDataSymbol]);
209
329
 
210
330
  for (const kv of parts) {
211
- const [k, v] = kv.split(self.parameterAssignment);
212
- temp[k] = v;
331
+ const [k, v] = kv.split(parameterAssignment);
332
+ self[workingDataSymbol][k] = v;
333
+ }
334
+
335
+ const t1 = key.split('|').shift().trim(); // pipe symbol
336
+ const t2 = t1.split('::').shift().trim(); // key value delimiter
337
+ const t3 = t2.split('.').shift().trim(); // path delimiter
338
+ let prefix = self[workingDataSymbol]?.[t3] ? 'path:' : 'static:';
339
+
340
+ let command = "";
341
+ if (prefix && key.indexOf(prefix) !== 0
342
+ && key.indexOf('path:') !== 0
343
+ && key.indexOf('static:') !== 0) {
344
+ command = prefix;
345
+ }
346
+
347
+ command += currentPipe;
348
+
349
+ const pipe = new Pipe(command);
350
+
351
+ if (isObject(callbacks)) {
352
+ for (const [name, callback] of Object.entries(callbacks)) {
353
+ pipe.setCallback(name, callback);
354
+ }
213
355
  }
214
356
 
215
- formatted.push(validateString(new Pipe(command).run(temp)));
357
+ formatted.push(validateString(pipe.run(self[workingDataSymbol])));
216
358
 
217
- text = text.substring(endIndex + self.closeMarker.length);
359
+ text = text.substring(endIndex + closeMarker.length);
218
360
 
219
361
  }
220
362
 
@@ -13,8 +13,8 @@ import {assignToNamespace, Monster} from '../namespace.js';
13
13
  *
14
14
  * ```
15
15
  * <script type="module">
16
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/base.js';
17
- * console.log(new Monster.Types.Base())
16
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
17
+ * new Monster.Types.Base()
18
18
  * </script>
19
19
  * ```
20
20
  *
@@ -22,8 +22,8 @@ import {assignToNamespace, Monster} from '../namespace.js';
22
22
  *
23
23
  * ```
24
24
  * <script type="module">
25
- * import {Base} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/base.js';
26
- * console.log(new Base())
25
+ * import {Base} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/types/base.js';
26
+ * new Base()
27
27
  * </script>
28
28
  * ```
29
29
  *
@@ -18,7 +18,7 @@ import {validateObject} from "./validate.js";
18
18
  *
19
19
  * ```
20
20
  * <script type="module">
21
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/basewithoptions.js';
21
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
22
22
  * new Monster.Types.BaseWithOptions()
23
23
  * </script>
24
24
  * ```
@@ -27,7 +27,7 @@ import {validateObject} from "./validate.js";
27
27
  *
28
28
  * ```
29
29
  * <script type="module">
30
- * import {BaseWithOptions} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/basewithoptions.js';
30
+ * import {BaseWithOptions} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/types/basewithoptions.js';
31
31
  * new BaseWithOptions()
32
32
  * </script>
33
33
  * ```
@@ -13,7 +13,7 @@ import {Monster, validateString} from "./validate.js";
13
13
  *
14
14
  * ```
15
15
  * <script type="module">
16
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/binary.js';
16
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
17
17
  * Monster.Types.toBinary()
18
18
  * </script>
19
19
  * ```
@@ -22,7 +22,7 @@ import {Monster, validateString} from "./validate.js";
22
22
  *
23
23
  * ```
24
24
  * <script type="module">
25
- * import {toBinary} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/binary.js';
25
+ * import {toBinary} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/types/binary.js';
26
26
  * toBinary()
27
27
  * </script>
28
28
  * ```
@@ -54,7 +54,7 @@ function toBinary(string) {
54
54
  *
55
55
  * ```
56
56
  * <script type="module">
57
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/binary.js';
57
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
58
58
  * Monster.Types.fromBinary()
59
59
  * </script>
60
60
  * ```
@@ -63,7 +63,7 @@ function toBinary(string) {
63
63
  *
64
64
  * ```
65
65
  * <script type="module">
66
- * import {fromBinary} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/binary.js';
66
+ * import {fromBinary} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/types/binary.js';
67
67
  * fromBinary()
68
68
  * </script>
69
69
  * ```
@@ -20,7 +20,7 @@ const internal = Symbol('internal');
20
20
  *
21
21
  * ```
22
22
  * <script type="module">
23
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/dataurl.js';
23
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
24
24
  * new Monster.Types.DataUrl()
25
25
  * </script>
26
26
  * ```
@@ -29,7 +29,7 @@ const internal = Symbol('internal');
29
29
  *
30
30
  * ```
31
31
  * <script type="module">
32
- * import {DataUrl} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/dataurl.js';
32
+ * import {DataUrl} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/types/dataurl.js';
33
33
  * new DataUrl()
34
34
  * </script>
35
35
  * ```
@@ -98,7 +98,7 @@ class DataUrl extends Base {
98
98
  *
99
99
  * ```
100
100
  * <script type="module">
101
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/dataurl.js';
101
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
102
102
  * console.log(Monster.Types.parseDataURL())
103
103
  * </script>
104
104
  * ```
@@ -107,7 +107,7 @@ class DataUrl extends Base {
107
107
  *
108
108
  * ```
109
109
  * <script type="module">
110
- * import {parseDataURL} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/dataurl.js';
110
+ * import {parseDataURL} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/types/dataurl.js';
111
111
  * console.log(parseDataURL())
112
112
  * </script>
113
113
  * ```
@@ -78,7 +78,7 @@ function getGlobal() {
78
78
  *
79
79
  * ```
80
80
  * <script type="module">
81
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/global.js';
81
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
82
82
  * Monster.Types.getGlobalObject('document')
83
83
  * // ↦ { }
84
84
  * </script>
@@ -88,7 +88,7 @@ function getGlobal() {
88
88
  *
89
89
  * ```
90
90
  * <script type="module">
91
- * import {getGlobalObject} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/global.js';
91
+ * import {getGlobalObject} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/types/global.js';
92
92
  * getGlobalObject('document')
93
93
  * // ↦ { }
94
94
  * </script>
@@ -117,7 +117,7 @@ function getGlobalObject(name) {
117
117
  *
118
118
  * ```
119
119
  * <script type="module">
120
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/global.js';
120
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
121
121
  * console.log(Monster.Types.getGlobalFunction('parseInt')) // ↦ f parseInt() { }
122
122
  * </script>
123
123
  * ```
@@ -126,7 +126,7 @@ function getGlobalObject(name) {
126
126
  *
127
127
  * ```
128
128
  * <script type="module">
129
- * import {getGlobalFunction} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/global.js';
129
+ * import {getGlobalFunction} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/types/global.js';
130
130
  * console.log(getGlobalFunction('parseInt')) // ↦ f parseInt() { }
131
131
  * </script>
132
132
  * ```
@@ -24,7 +24,7 @@ let internalCounter = new Map;
24
24
  *
25
25
  * ```
26
26
  * <script type="module">
27
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/id.js';
27
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/monster.js';
28
28
  * console.log(new Monster.Types.ID())
29
29
  * </script>
30
30
  * ```
@@ -33,7 +33,7 @@ let internalCounter = new Map;
33
33
  *
34
34
  * ```
35
35
  * <script type="module">
36
- * import {ID} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.24.0/dist/modules/types/id.js';
36
+ * import {ID} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.27.0/dist/modules/types/id.js';
37
37
  * console.log(new ID())
38
38
  * </script>
39
39
  * ```
@@ -43,11 +43,14 @@ let internalCounter = new Map;
43
43
  * @since 1.0.0
44
44
  * @copyright schukai GmbH
45
45
  * @memberOf Monster.Types
46
+ * @summary Automatic generation of ids
46
47
  */
47
48
  class ID extends Base {
48
49
 
49
50
  /**
50
- * create new object
51
+ * create new id with prefix
52
+ *
53
+ * @param {string} prefix
51
54
  */
52
55
  constructor(prefix) {
53
56
  super();