@schukai/monster 1.22.0 → 1.26.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.
Files changed (221) hide show
  1. package/CHANGELOG +56 -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 +2 -0
  17. package/dist/modules/data/datasource/restapi.js +2 -2
  18. package/dist/modules/data/datasource/storage/localstorage.js +2 -2
  19. package/dist/modules/data/datasource/storage/namespace.js +1 -1
  20. package/dist/modules/data/datasource/storage/sessionstorage.js +2 -2
  21. package/dist/modules/data/datasource/storage.js +2 -2
  22. package/dist/modules/data/datasource.js +2 -2
  23. package/dist/modules/data/diff.js +2 -2
  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 +2 -2
  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 +1 -1
  31. package/dist/modules/dom/constants.js +2 -2
  32. package/dist/modules/dom/customcontrol.js +2 -2
  33. package/dist/modules/dom/customelement.js +2 -2
  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 +1 -1
  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 +2 -2
  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 +2 -2
  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 +2 -2
  82. package/dist/modules/types/proxyobserver.js +2 -2
  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 +2 -2
  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 +2 -2
  94. package/dist/modules/util/comparator.js +2 -2
  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 +2 -2
  98. package/dist/modules/util/trimspaces.js +2 -0
  99. package/dist/monster.dev.js +1838 -792
  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 +16 -7
  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 +27 -11
  113. package/source/data/buildtree.js +95 -0
  114. package/source/data/datasource/restapi/writeerror.js +49 -0
  115. package/source/data/datasource/restapi.js +95 -11
  116. package/source/data/datasource/storage/localstorage.js +15 -8
  117. package/source/data/datasource/storage/sessionstorage.js +16 -12
  118. package/source/data/datasource/storage.js +16 -7
  119. package/source/data/datasource.js +60 -16
  120. package/source/data/diff.js +8 -8
  121. package/source/data/extend.js +5 -5
  122. package/source/data/pathfinder.js +12 -6
  123. package/source/data/pipe.js +6 -5
  124. package/source/data/transformer.js +131 -24
  125. package/source/dom/assembler.js +2 -2
  126. package/source/dom/attributes.js +24 -24
  127. package/source/dom/constants.js +305 -12
  128. package/source/dom/customcontrol.js +40 -19
  129. package/source/dom/customelement.js +182 -102
  130. package/source/dom/events.js +6 -6
  131. package/source/dom/focusmanager.js +250 -0
  132. package/source/dom/locale.js +10 -5
  133. package/source/dom/resource/data.js +170 -0
  134. package/source/dom/resource/link/stylesheet.js +54 -0
  135. package/source/dom/resource/link.js +125 -0
  136. package/source/dom/resource/script.js +112 -0
  137. package/source/dom/resource.js +268 -0
  138. package/source/dom/resourcemanager.js +214 -0
  139. package/source/dom/template.js +40 -10
  140. package/source/dom/theme.js +3 -3
  141. package/source/dom/updater.js +115 -39
  142. package/source/dom/util.js +6 -6
  143. package/source/dom/worker/factory.js +134 -0
  144. package/source/i18n/formatter.js +140 -0
  145. package/source/i18n/locale.js +10 -8
  146. package/source/i18n/provider.js +4 -4
  147. package/source/i18n/providers/fetch.js +24 -14
  148. package/source/i18n/translations.js +20 -10
  149. package/source/logging/handler/console.js +2 -2
  150. package/source/logging/handler.js +2 -2
  151. package/source/logging/logentry.js +2 -2
  152. package/source/logging/logger.js +4 -4
  153. package/source/math/random.js +11 -5
  154. package/source/namespace.js +1 -1
  155. package/source/text/formatter.js +244 -27
  156. package/source/types/base.js +4 -4
  157. package/source/types/basewithoptions.js +10 -15
  158. package/source/types/binary.js +8 -8
  159. package/source/types/dataurl.js +6 -6
  160. package/source/types/global.js +9 -7
  161. package/source/types/id.js +6 -3
  162. package/source/types/is.js +103 -85
  163. package/source/types/mediatype.js +4 -4
  164. package/source/types/node.js +179 -0
  165. package/source/types/nodelist.js +125 -0
  166. package/source/types/noderecursiveiterator.js +126 -0
  167. package/source/types/observer.js +3 -3
  168. package/source/types/observerlist.js +3 -3
  169. package/source/types/proxyobserver.js +24 -7
  170. package/source/types/queue.js +6 -6
  171. package/source/types/randomid.js +2 -2
  172. package/source/types/regex.js +49 -0
  173. package/source/types/stack.js +2 -2
  174. package/source/types/tokenlist.js +8 -9
  175. package/source/types/typeof.js +3 -3
  176. package/source/types/uniquequeue.js +4 -4
  177. package/source/types/uuid.js +102 -0
  178. package/source/types/validate.js +20 -20
  179. package/source/types/version.js +6 -6
  180. package/source/util/clone.js +5 -6
  181. package/source/util/comparator.js +5 -5
  182. package/source/util/freeze.js +5 -5
  183. package/source/util/processing.js +33 -36
  184. package/source/util/trimspaces.js +85 -0
  185. package/test/cases/data/buildtree.js +149 -0
  186. package/test/cases/data/datasource/restapi.js +1 -1
  187. package/test/cases/data/datasource.js +4 -4
  188. package/test/cases/data/diff.js +4 -4
  189. package/test/cases/data/pathfinder.js +18 -9
  190. package/test/cases/data/pipe.js +26 -2
  191. package/test/cases/data/transformer.js +41 -10
  192. package/test/cases/dom/attributes.js +18 -14
  193. package/test/cases/dom/customcontrol.js +6 -5
  194. package/test/cases/dom/customelement.js +25 -26
  195. package/test/cases/dom/focusmanager.js +111 -0
  196. package/test/cases/dom/locale.js +1 -4
  197. package/test/cases/dom/resource/data.js +129 -0
  198. package/test/cases/dom/resource/link/stylesheet.js +101 -0
  199. package/test/cases/dom/resource/link.js +101 -0
  200. package/test/cases/dom/resource/script.js +115 -0
  201. package/test/cases/dom/resourcemanager.js +118 -0
  202. package/test/cases/dom/updater.js +42 -19
  203. package/test/cases/dom/worker/factory.js +63 -0
  204. package/test/cases/i18n/formatter.js +66 -0
  205. package/test/cases/monster.js +1 -1
  206. package/test/cases/text/formatter.js +71 -8
  207. package/test/cases/types/node.js +196 -0
  208. package/test/cases/types/nodelist.js +64 -0
  209. package/test/cases/types/noderecursiveiterator.js +54 -0
  210. package/test/cases/types/proxyobserver.js +55 -11
  211. package/test/cases/types/regex.js +32 -0
  212. package/test/cases/types/uuid.js +42 -0
  213. package/test/cases/util/freeze.js +30 -4
  214. package/test/cases/util/trimspaces.js +24 -0
  215. package/test/util/cleanupdom.js +48 -0
  216. package/test/util/jsdom.js +22 -9
  217. package/test/web/import.js +15 -0
  218. package/test/web/monster-dev.html +3 -3
  219. package/test/web/monster.html +2 -2
  220. package/test/web/test.html +3 -3
  221. 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,12 +49,12 @@ 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.22.0/dist/modules/text/formatter.js';
22
- * console.log(new Monster.Text.Formatter())
56
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
57
+ * new Monster.Text.Formatter()
23
58
  * </script>
24
59
  * ```
25
60
  *
@@ -27,13 +62,53 @@ 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.22.0/dist/modules/text/formatter.js';
31
- * console.log(new Formatter())
65
+ * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/text/formatter.js';
66
+ * new Formatter()
32
67
  * </script>
33
68
  * ```
34
69
  *
70
+ * ## Marker in marker
71
+ *
72
+ * Markers can be nested. Here, the inner marker is resolved first `${subkey} ↦ 1 = ${mykey2}` and then the outer marker `${mykey2}`.
73
+ *
74
+ * ```
75
+ * const text = '${mykey${subkey}}';
76
+ * let obj = {
77
+ * mykey2: "1",
78
+ * subkey: "2"
79
+ * };
80
+ *
81
+ * new Formatter(obj).format(text);
82
+ * // ↦ 1
83
+ * ```
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
+ *
101
+ * ## Marker with parameter
102
+ *
103
+ * A string can also bring its own values. These must then be separated from the key by a separator `::`.
104
+ * The values themselves must be specified in key/value pairs. The key must be separated from the value by a separator `=`.
105
+ *
106
+ * When using a pipe, you must pay attention to the separators.
107
+ *
35
108
  * @example
36
109
  *
110
+ * import {Formatter} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/text/formatter.js';
111
+ *
37
112
  * new Formatter({
38
113
  * a: {
39
114
  * b: {
@@ -41,7 +116,7 @@ import {validateObject, validateString} from "../types/validate.js";
41
116
  * },
42
117
  * d: "world",
43
118
  * }
44
- * }).format("${a.b.c} ${a.d | ucfirst}!");
119
+ * }).format("${a.b.c} ${a.d | ucfirst}!"); // with pipe
45
120
  *
46
121
  * // ↦ Hello World!
47
122
  *
@@ -49,7 +124,7 @@ import {validateObject, validateString} from "../types/validate.js";
49
124
  * @copyright schukai GmbH
50
125
  * @memberOf Monster.Text
51
126
  */
52
- class Formatter extends Base {
127
+ class Formatter extends BaseWithOptions {
53
128
 
54
129
  /**
55
130
  * Default values for the markers are `${` and `}`
@@ -57,11 +132,65 @@ class Formatter extends Base {
57
132
  * @param {object} object
58
133
  * @throws {TypeError} value is not a object
59
134
  */
60
- constructor(object) {
61
- super();
62
- this.object = validateObject(object);
63
- this.openMarker = '${';
64
- this.closeMarker = '}';
135
+ constructor(object, options) {
136
+ super(options);
137
+ this[internalObjectSymbol] = object || {}
138
+ this[markerOpenIndexSymbol] = 0;
139
+ this[markerCloseIndexSymbol] = 0;
140
+ }
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
+
166
+ /**
167
+ * Set new Parameter Character
168
+ *
169
+ * Default values for the chars are `::` and `=`
170
+ *
171
+ * ```
172
+ * formatter.setParameterChars('#');
173
+ * formatter.setParameterChars('[',']');
174
+ * formatter.setParameterChars('i18n{','}');
175
+ * ```
176
+ *
177
+ * @param {string} delimiter
178
+ * @param {string} assignment
179
+ * @return {Formatter}
180
+ * @since 1.24.0
181
+ * @throws {TypeError} value is not a string
182
+ */
183
+ setParameterChars(delimiter, assignment) {
184
+
185
+ if (delimiter !== undefined) {
186
+ this[internalSymbol]['parameter']['delimiter'] = validateString(delimiter);
187
+ }
188
+
189
+ if (assignment !== undefined) {
190
+ this[internalSymbol]['parameter']['assignment'] = validateString(assignment);
191
+ }
192
+
193
+ return this;
65
194
  }
66
195
 
67
196
  /**
@@ -75,8 +204,8 @@ class Formatter extends Base {
75
204
  * formatter.setMarker('i18n{','}');
76
205
  * ```
77
206
  *
78
- * @param {string} open
79
- * @param {string} close
207
+ * @param {array|string} open
208
+ * @param {array|string|undefined} close
80
209
  * @return {Formatter}
81
210
  * @since 1.12.0
82
211
  * @throws {TypeError} value is not a string
@@ -87,8 +216,11 @@ class Formatter extends Base {
87
216
  close = open;
88
217
  }
89
218
 
90
- this.openMarker = validateString(open);
91
- 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);
92
224
  return this;
93
225
  }
94
226
 
@@ -97,11 +229,51 @@ class Formatter extends Base {
97
229
  * @param {string} text
98
230
  * @return {string}
99
231
  * @throws {TypeError} value is not a string
232
+ * @throws {Error} too deep nesting
100
233
  */
101
234
  format(text) {
102
- 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]++;
103
272
  }
104
273
 
274
+ result = format.call(self, result)
275
+
276
+ return result;
105
277
  }
106
278
 
107
279
  /**
@@ -110,15 +282,18 @@ class Formatter extends Base {
110
282
  * @param text
111
283
  * @return {string}
112
284
  */
113
- function tokenizer(text) {
285
+ function tokenize(text, openMarker, closeMarker) {
114
286
  const self = this;
115
287
 
116
288
  let formatted = [];
117
289
 
118
- while (true) {
290
+ const parameterAssignment = self[internalSymbol]['parameter']['assignment']
291
+ const parameterDelimiter = self[internalSymbol]['parameter']['delimiter']
292
+ const callbacks = self[internalSymbol]['callbacks'];
119
293
 
294
+ while (true) {
120
295
 
121
- let startIndex = text.indexOf(self.openMarker);
296
+ let startIndex = text.indexOf(openMarker);
122
297
  // no marker
123
298
  if (startIndex === -1) {
124
299
  formatted.push(text);
@@ -128,18 +303,60 @@ function tokenizer(text) {
128
303
  text = text.substring(startIndex)
129
304
  }
130
305
 
131
- let endIndex = text.substring(self.openMarker.length).indexOf(self.closeMarker) + self.openMarker.length;
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);
309
+ if (insideStartIndex !== -1) {
310
+ insideStartIndex += openMarker.length;
311
+ if (insideStartIndex < endIndex) {
312
+ let result = tokenize.call(self, text.substring(insideStartIndex), openMarker, closeMarker);
313
+ text = text.substring(0, insideStartIndex) + result
314
+ endIndex = text.substring(openMarker.length).indexOf(closeMarker);
315
+ if (endIndex !== -1) endIndex += openMarker.length;
316
+ }
317
+ }
132
318
 
133
319
  if (endIndex === -1) {
134
320
  throw new Error("syntax error in formatter template")
135
321
  return;
136
322
  }
137
323
 
138
- let command = "path:" + text.substring(self.openMarker.length, endIndex);
324
+ let key = text.substring(openMarker.length, endIndex);
325
+ let parts = key.split(parameterDelimiter);
326
+ let currentPipe = parts.shift();
327
+
328
+ self[workingDataSymbol] = extend({}, self[internalObjectSymbol], self[workingDataSymbol]);
329
+
330
+ for (const kv of parts) {
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
+ }
355
+ }
139
356
 
140
- formatted.push(validateString(new Pipe(command).run(self.object)));
357
+ formatted.push(validateString(pipe.run(self[workingDataSymbol])));
141
358
 
142
- text = text.substring(endIndex + self.closeMarker.length);
359
+ text = text.substring(endIndex + closeMarker.length);
143
360
 
144
361
  }
145
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.22.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.26.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.22.0/dist/modules/types/base.js';
26
- * console.log(new Base())
25
+ * import {Base} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/types/base.js';
26
+ * new Base()
27
27
  * </script>
28
28
  * ```
29
29
  *
@@ -1,21 +1,16 @@
1
1
  'use strict';
2
2
 
3
- import {PROPERTY_KEY_INTERNALDATA} from "../constants.js";
4
- import {extend} from "../data/extend.js";
5
- import {Pathfinder} from "../data/pathfinder.js";
6
3
  /**
7
4
  * @author schukai GmbH
8
5
  */
6
+
7
+ import {internalSymbol} from "../constants.js";
8
+ import {extend} from "../data/extend.js";
9
+ import {Pathfinder} from "../data/pathfinder.js";
9
10
  import {assignToNamespace, Monster} from '../namespace.js';
10
11
  import {Base} from "./base.js";
11
12
  import {validateObject} from "./validate.js";
12
13
 
13
- /**
14
- * @private
15
- * @type {symbol}
16
- */
17
- const optionsSymbol = Symbol.for(PROPERTY_KEY_INTERNALDATA);
18
-
19
14
  /**
20
15
  * This is the base class with options from which some monster classes are derived.
21
16
  *
@@ -23,8 +18,8 @@ const optionsSymbol = Symbol.for(PROPERTY_KEY_INTERNALDATA);
23
18
  *
24
19
  * ```
25
20
  * <script type="module">
26
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/types/basewithoptions.js';
27
- * console.log(new Monster.Types.BaseWithOptions())
21
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
22
+ * new Monster.Types.BaseWithOptions()
28
23
  * </script>
29
24
  * ```
30
25
  *
@@ -32,8 +27,8 @@ const optionsSymbol = Symbol.for(PROPERTY_KEY_INTERNALDATA);
32
27
  *
33
28
  * ```
34
29
  * <script type="module">
35
- * import {BaseWithOptions} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/types/basewithoptions.js';
36
- * console.log(new BaseWithOptions())
30
+ * import {BaseWithOptions} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/types/basewithoptions.js';
31
+ * new BaseWithOptions()
37
32
  * </script>
38
33
  * ```
39
34
  *
@@ -56,7 +51,7 @@ class BaseWithOptions extends Base {
56
51
  options = {};
57
52
  }
58
53
 
59
- this[optionsSymbol] = extend({}, this.defaults, validateObject(options));
54
+ this[internalSymbol] = extend({}, this.defaults, validateObject(options));
60
55
 
61
56
  }
62
57
 
@@ -81,7 +76,7 @@ class BaseWithOptions extends Base {
81
76
  let value;
82
77
 
83
78
  try {
84
- value = new Pathfinder(this[optionsSymbol]).getVia(path);
79
+ value = new Pathfinder(this[internalSymbol]).getVia(path);
85
80
  } catch (e) {
86
81
 
87
82
  }
@@ -13,8 +13,8 @@ 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.22.0/dist/modules/types/binary.js';
17
- * console.log(Monster.Types.toBinary())
16
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
17
+ * Monster.Types.toBinary()
18
18
  * </script>
19
19
  * ```
20
20
  *
@@ -22,8 +22,8 @@ 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.22.0/dist/modules/types/binary.js';
26
- * console.log(toBinary())
25
+ * import {toBinary} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/types/binary.js';
26
+ * toBinary()
27
27
  * </script>
28
28
  * ```
29
29
  *
@@ -54,8 +54,8 @@ function toBinary(string) {
54
54
  *
55
55
  * ```
56
56
  * <script type="module">
57
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/types/binary.js';
58
- * console.log(Monster.Types.fromBinary())
57
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
58
+ * Monster.Types.fromBinary()
59
59
  * </script>
60
60
  * ```
61
61
  *
@@ -63,8 +63,8 @@ function toBinary(string) {
63
63
  *
64
64
  * ```
65
65
  * <script type="module">
66
- * import {fromBinary} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/types/binary.js';
67
- * console.log(fromBinary())
66
+ * import {fromBinary} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/types/binary.js';
67
+ * fromBinary()
68
68
  * </script>
69
69
  * ```
70
70
  *
@@ -20,8 +20,8 @@ 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.22.0/dist/modules/types/dataurl.js';
24
- * console.log(new Monster.Types.DataUrl())
23
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
24
+ * new Monster.Types.DataUrl()
25
25
  * </script>
26
26
  * ```
27
27
  *
@@ -29,8 +29,8 @@ 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.22.0/dist/modules/types/dataurl.js';
33
- * console.log(new DataUrl())
32
+ * import {DataUrl} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/types/dataurl.js';
33
+ * new DataUrl()
34
34
  * </script>
35
35
  * ```
36
36
  *
@@ -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.22.0/dist/modules/types/dataurl.js';
101
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.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.22.0/dist/modules/types/dataurl.js';
110
+ * import {parseDataURL} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/types/dataurl.js';
111
111
  * console.log(parseDataURL())
112
112
  * </script>
113
113
  * ```
@@ -78,8 +78,9 @@ function getGlobal() {
78
78
  *
79
79
  * ```
80
80
  * <script type="module">
81
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/types/global.js';
82
- * console.log(Monster.Types.getGlobalObject('document')) // ↦ { }
81
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
82
+ * Monster.Types.getGlobalObject('document')
83
+ * // ↦ { }
83
84
  * </script>
84
85
  * ```
85
86
  *
@@ -87,8 +88,9 @@ function getGlobal() {
87
88
  *
88
89
  * ```
89
90
  * <script type="module">
90
- * import {getGlobalObject} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/types/global.js';
91
- * console.log(getGlobalObject('document')) // ↦ { }
91
+ * import {getGlobalObject} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/types/global.js';
92
+ * getGlobalObject('document')
93
+ * // ↦ { }
92
94
  * </script>
93
95
  * ```
94
96
  *
@@ -115,7 +117,7 @@ function getGlobalObject(name) {
115
117
  *
116
118
  * ```
117
119
  * <script type="module">
118
- * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/types/global.js';
120
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/monster.js';
119
121
  * console.log(Monster.Types.getGlobalFunction('parseInt')) // ↦ f parseInt() { }
120
122
  * </script>
121
123
  * ```
@@ -124,7 +126,7 @@ function getGlobalObject(name) {
124
126
  *
125
127
  * ```
126
128
  * <script type="module">
127
- * import {getGlobalFunction} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.22.0/dist/modules/types/global.js';
129
+ * import {getGlobalFunction} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.0/dist/modules/types/global.js';
128
130
  * console.log(getGlobalFunction('parseInt')) // ↦ f parseInt() { }
129
131
  * </script>
130
132
  * ```
@@ -132,7 +134,7 @@ function getGlobalObject(name) {
132
134
  * @since 1.6.0
133
135
  * @memberOf Monster.Types
134
136
  * @param {string} name
135
- * @returns {objec}
137
+ * @return {objec}
136
138
  * @throws {TypeError} value is not a function
137
139
  * @throws {Error} the function is not defined
138
140
  * @throws {TypeError} value is not a string
@@ -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.22.0/dist/modules/types/id.js';
27
+ * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.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.22.0/dist/modules/types/id.js';
36
+ * import {ID} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.26.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();