@schukai/monster 3.7.0 → 3.9.0
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +1 -1
- package/source/data/datasource/server/restapi.mjs +0 -2
- package/source/data/pathfinder.mjs +77 -32
- package/source/data/transformer.mjs +31 -79
- package/source/dom/focusmanager.mjs +1 -1
- package/source/dom/locale.mjs +2 -1
- package/source/i18n/locale.mjs +2 -13
- package/source/i18n/provider.mjs +72 -4
- package/source/i18n/providers/embed.mjs +68 -20
- package/source/i18n/translations.mjs +61 -10
- package/source/types/version.mjs +1 -1
- package/test/cases/data/datasource/server/restapi.mjs +0 -1
- package/test/cases/data/transformer.mjs +61 -1
- package/test/cases/dom/locale.mjs +9 -6
- package/test/cases/i18n/provider.mjs +66 -3
- package/test/cases/i18n/translations.mjs +78 -1
- package/test/cases/monster.mjs +1 -1
- package/test/util/jsdom.mjs +1 -2
- package/test/web/import.js +1 -0
- package/test/web/test.html +2 -2
- package/test/web/tests.js +5736 -3152
package/package.json
CHANGED
@@ -8,8 +8,6 @@
|
|
8
8
|
import { internalSymbol, instanceSymbol } from "../../../constants.mjs";
|
9
9
|
import { isObject } from "../../../types/is.mjs";
|
10
10
|
import { Server } from "../server.mjs";
|
11
|
-
import { Pathfinder } from "../../pathfinder.mjs";
|
12
|
-
import { Pipe } from "../../pipe.mjs";
|
13
11
|
import { WriteError } from "./restapi/writeerror.mjs";
|
14
12
|
|
15
13
|
export { RestAPI };
|
@@ -6,9 +6,9 @@
|
|
6
6
|
*/
|
7
7
|
|
8
8
|
import { Base } from "../types/base.mjs";
|
9
|
-
import { isArray, isInteger, isObject, isPrimitive } from "../types/is.mjs";
|
9
|
+
import { isArray, isInteger, isObject, isPrimitive, isString } from "../types/is.mjs";
|
10
10
|
import { Stack } from "../types/stack.mjs";
|
11
|
-
import { validateInteger, validateString } from "../types/validate.mjs";
|
11
|
+
import { validateInteger, validateBoolean, validateString } from "../types/validate.mjs";
|
12
12
|
|
13
13
|
export { Pathfinder, DELIMITER, WILDCARD };
|
14
14
|
|
@@ -103,7 +103,7 @@ class Pathfinder extends Base {
|
|
103
103
|
|
104
104
|
/**
|
105
105
|
*
|
106
|
-
* @param {string} path
|
106
|
+
* @param {string|array} path
|
107
107
|
* @since 1.4.0
|
108
108
|
* @returns {*}
|
109
109
|
* @throws {TypeError} unsupported type
|
@@ -113,12 +113,12 @@ class Pathfinder extends Base {
|
|
113
113
|
* @throws {Error} unsupported action for this data type
|
114
114
|
*/
|
115
115
|
getVia(path) {
|
116
|
-
return getValueViaPath.call(this, this.object,
|
116
|
+
return getValueViaPath.call(this, this.object, path);
|
117
117
|
}
|
118
118
|
|
119
119
|
/**
|
120
120
|
*
|
121
|
-
* @param {string} path
|
121
|
+
* @param {string|array} path
|
122
122
|
* @param {*} value
|
123
123
|
* @returns {Pathfinder}
|
124
124
|
* @since 1.4.0
|
@@ -128,7 +128,6 @@ class Pathfinder extends Base {
|
|
128
128
|
* @throws {Error} unsupported action for this data type
|
129
129
|
*/
|
130
130
|
setVia(path, value) {
|
131
|
-
validateString(path);
|
132
131
|
setValueViaPath.call(this, this.object, path, value);
|
133
132
|
return this;
|
134
133
|
}
|
@@ -136,7 +135,7 @@ class Pathfinder extends Base {
|
|
136
135
|
/**
|
137
136
|
* Delete Via Path
|
138
137
|
*
|
139
|
-
* @param {string} path
|
138
|
+
* @param {string|array} path
|
140
139
|
* @returns {Pathfinder}
|
141
140
|
* @since 1.6.0
|
142
141
|
* @throws {TypeError} unsupported type
|
@@ -145,14 +144,13 @@ class Pathfinder extends Base {
|
|
145
144
|
* @throws {Error} unsupported action for this data type
|
146
145
|
*/
|
147
146
|
deleteVia(path) {
|
148
|
-
validateString(path);
|
149
147
|
deleteValueViaPath.call(this, this.object, path);
|
150
148
|
return this;
|
151
149
|
}
|
152
150
|
|
153
151
|
/**
|
154
152
|
*
|
155
|
-
* @param {string} path
|
153
|
+
* @param {string|array} path
|
156
154
|
* @return {bool}
|
157
155
|
* @throws {TypeError} unsupported type
|
158
156
|
* @throws {TypeError} value is not a string
|
@@ -160,7 +158,6 @@ class Pathfinder extends Base {
|
|
160
158
|
* @since 1.4.0
|
161
159
|
*/
|
162
160
|
exists(path) {
|
163
|
-
validateString(path);
|
164
161
|
try {
|
165
162
|
getValueViaPath.call(this, this.object, path, true);
|
166
163
|
return true;
|
@@ -173,8 +170,8 @@ class Pathfinder extends Base {
|
|
173
170
|
/**
|
174
171
|
*
|
175
172
|
* @param {*} subject
|
176
|
-
* @param {string} path
|
177
|
-
* @param {
|
173
|
+
* @param {string|array} path
|
174
|
+
* @param {boolean} check
|
178
175
|
* @return {Map}
|
179
176
|
* @throws {TypeError} unsupported type
|
180
177
|
* @throws {Error} the journey is not at its end
|
@@ -182,8 +179,17 @@ class Pathfinder extends Base {
|
|
182
179
|
* @private
|
183
180
|
*/
|
184
181
|
function iterate(subject, path, check) {
|
182
|
+
if (check === undefined) {
|
183
|
+
check = false;
|
184
|
+
}
|
185
|
+
validateBoolean(check);
|
186
|
+
|
185
187
|
const result = new Map();
|
186
188
|
|
189
|
+
if (isArray(path)) {
|
190
|
+
path = path.join(DELIMITER);
|
191
|
+
}
|
192
|
+
|
187
193
|
if (isObject(subject) || isArray(subject)) {
|
188
194
|
for (const [key, value] of Object.entries(subject)) {
|
189
195
|
result.set(key, getValueViaPath.call(this, value, path, check));
|
@@ -199,7 +205,7 @@ function iterate(subject, path, check) {
|
|
199
205
|
/**
|
200
206
|
*
|
201
207
|
* @param {*} subject
|
202
|
-
* @param [string} path
|
208
|
+
* @param [string|array} path
|
203
209
|
* @param [boolean} check
|
204
210
|
* @returns {*}
|
205
211
|
* @throws {TypeError} unsupported type
|
@@ -208,11 +214,24 @@ function iterate(subject, path, check) {
|
|
208
214
|
* @private
|
209
215
|
*/
|
210
216
|
function getValueViaPath(subject, path, check) {
|
211
|
-
if (
|
212
|
-
|
217
|
+
if (check === undefined) {
|
218
|
+
check = false;
|
219
|
+
}
|
220
|
+
validateBoolean(check);
|
221
|
+
|
222
|
+
if (!(isArray(path) || isString(path))) {
|
223
|
+
throw new Error("type error: path must be a string or an array");
|
224
|
+
}
|
225
|
+
|
226
|
+
let parts;
|
227
|
+
if (isString(path)) {
|
228
|
+
if (path === "") {
|
229
|
+
return subject;
|
230
|
+
}
|
231
|
+
|
232
|
+
parts = path.split(DELIMITER);
|
213
233
|
}
|
214
234
|
|
215
|
-
let parts = path.split(DELIMITER);
|
216
235
|
let current = parts.shift();
|
217
236
|
|
218
237
|
if (current === this.wildCard) {
|
@@ -261,9 +280,9 @@ function getValueViaPath(subject, path, check) {
|
|
261
280
|
|
262
281
|
/**
|
263
282
|
*
|
264
|
-
* @param object
|
265
|
-
* @param path
|
266
|
-
* @param value
|
283
|
+
* @param {object} subject
|
284
|
+
* @param {string|array} path
|
285
|
+
* @param {*} value
|
267
286
|
* @returns {void}
|
268
287
|
* @throws {TypeError} unsupported type
|
269
288
|
* @throws {TypeError} unsupported type
|
@@ -271,10 +290,22 @@ function getValueViaPath(subject, path, check) {
|
|
271
290
|
* @throws {Error} unsupported action for this data type
|
272
291
|
* @private
|
273
292
|
*/
|
274
|
-
function setValueViaPath(
|
275
|
-
|
293
|
+
function setValueViaPath(subject, path, value) {
|
294
|
+
if (!(isArray(path) || isString(path))) {
|
295
|
+
throw new Error("type error: path must be a string or an array");
|
296
|
+
}
|
297
|
+
|
298
|
+
let parts;
|
299
|
+
if (isArray(path)) {
|
300
|
+
if (path.length === 0) {
|
301
|
+
return subject;
|
302
|
+
}
|
303
|
+
|
304
|
+
parts = path;
|
305
|
+
} else {
|
306
|
+
parts = path.split(DELIMITER);
|
307
|
+
}
|
276
308
|
|
277
|
-
let parts = path.split(DELIMITER);
|
278
309
|
let last = parts.pop();
|
279
310
|
let subpath = parts.join(DELIMITER);
|
280
311
|
|
@@ -282,7 +313,7 @@ function setValueViaPath(object, path, value) {
|
|
282
313
|
let current = subpath;
|
283
314
|
while (true) {
|
284
315
|
try {
|
285
|
-
getValueViaPath.call(this,
|
316
|
+
getValueViaPath.call(this, subject, current, true);
|
286
317
|
break;
|
287
318
|
} catch (e) {}
|
288
319
|
|
@@ -304,13 +335,13 @@ function setValueViaPath(object, path, value) {
|
|
304
335
|
}
|
305
336
|
}
|
306
337
|
|
307
|
-
setValueViaPath.call(this,
|
338
|
+
setValueViaPath.call(this, subject, current, obj);
|
308
339
|
}
|
309
340
|
|
310
|
-
let anchor = getValueViaPath.call(this,
|
341
|
+
let anchor = getValueViaPath.call(this, subject, subpath);
|
311
342
|
|
312
|
-
if (!(isObject(
|
313
|
-
throw TypeError(`unsupported type: ${typeof
|
343
|
+
if (!(isObject(subject) || isArray(subject))) {
|
344
|
+
throw TypeError(`unsupported type: ${typeof subject}`);
|
314
345
|
}
|
315
346
|
|
316
347
|
if (anchor instanceof Map || anchor instanceof WeakMap) {
|
@@ -349,8 +380,8 @@ function assignProperty(object, key, value) {
|
|
349
380
|
|
350
381
|
/**
|
351
382
|
*
|
352
|
-
* @param object
|
353
|
-
* @param path
|
383
|
+
* @param {object} subject
|
384
|
+
* @param {string} path
|
354
385
|
* @returns {void}
|
355
386
|
* @throws {TypeError} unsupported type
|
356
387
|
* @throws {TypeError} unsupported type
|
@@ -360,12 +391,26 @@ function assignProperty(object, key, value) {
|
|
360
391
|
* @since 1.6.0
|
361
392
|
* @private
|
362
393
|
*/
|
363
|
-
function deleteValueViaPath(
|
364
|
-
|
394
|
+
function deleteValueViaPath(subject, path) {
|
395
|
+
if (!(isArray(path) || isString(path))) {
|
396
|
+
throw new Error("type error: path must be a string or an array");
|
397
|
+
}
|
398
|
+
|
399
|
+
let parts;
|
400
|
+
if (isArray(path)) {
|
401
|
+
if (path.length === 0) {
|
402
|
+
return subject;
|
403
|
+
}
|
404
|
+
|
405
|
+
parts = path;
|
406
|
+
} else {
|
407
|
+
parts = path.split(DELIMITER);
|
408
|
+
}
|
409
|
+
|
365
410
|
let last = parts.pop();
|
366
411
|
const subpath = parts.join(DELIMITER);
|
367
412
|
|
368
|
-
const anchor = getValueViaPath.call(this,
|
413
|
+
const anchor = getValueViaPath.call(this, subject, subpath);
|
369
414
|
|
370
415
|
if (anchor instanceof Map) {
|
371
416
|
anchor.delete(last);
|
@@ -5,10 +5,11 @@
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
6
6
|
*/
|
7
7
|
|
8
|
-
import {
|
9
|
-
import {
|
10
|
-
import {
|
11
|
-
import {
|
8
|
+
import {Base} from "../types/base.mjs";
|
9
|
+
import {getGlobal, getGlobalObject} from "../types/global.mjs";
|
10
|
+
import {ID} from "../types/id.mjs";
|
11
|
+
import {isArray, isObject, isString} from "../types/is.mjs";
|
12
|
+
import {getDocumentTranslations, Translations} from "../i18n/translations.mjs";
|
12
13
|
import {
|
13
14
|
validateFunction,
|
14
15
|
validateInteger,
|
@@ -16,10 +17,10 @@ import {
|
|
16
17
|
validatePrimitive,
|
17
18
|
validateString,
|
18
19
|
} from "../types/validate.mjs";
|
19
|
-
import {
|
20
|
-
import {
|
20
|
+
import {clone} from "../util/clone.mjs";
|
21
|
+
import {Pathfinder} from "./pathfinder.mjs";
|
21
22
|
|
22
|
-
export {
|
23
|
+
export {Transformer};
|
23
24
|
|
24
25
|
/**
|
25
26
|
* The transformer class is a swiss army knife for manipulating values. especially in combination with the pipe, processing chains can be built up.
|
@@ -30,78 +31,7 @@ export { Transformer };
|
|
30
31
|
* let t = new Transformer('tolower').run('ABC'); // ↦ abc
|
31
32
|
* ```
|
32
33
|
*
|
33
|
-
*
|
34
|
-
*
|
35
|
-
* in the following table all commands, parameters and existing aliases are described.
|
36
|
-
*
|
37
|
-
* | command | parameter | alias | description |
|
38
|
-
* |:-------------|:---------------------------|:------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
39
|
-
* | to-base64 | | base64, btob | Converts the value to base64 |
|
40
|
-
* | from-base64 | | atob | Converts the value from base64 |
|
41
|
-
* | call | function:param1:param2:... | | Calling a callback function. The function can be defined in three places: either globally, in the context `addCallback` or in the passed object |
|
42
|
-
* | default | value:type | ?? | If the value is undefined the first argument is returned, otherwise the value. The third optional parameter specifies the desired type. If no type is specified, string is used. Valid types are bool, string, int, float, undefined and object. An object default value must be specified as a base64 encoded json string. (since 1.12.0) |
|
43
|
-
* | debug | | | the passed value is output (console) and returned |
|
44
|
-
* | empty | | | Return empty String "" |
|
45
|
-
* | first-key | default | | Can be applied to objects and returns the value of the first key. All keys of the object are fetched and sorted. (since 1.23.0) |
|
46
|
-
* | fromjson | | | Type conversion from a JSON string (since 1.12.0) |
|
47
|
-
* | if | statement1:statement2 | ? | Is the ternary operator, the first parameter is the valid statement, the second is the false part. To use the current value in the queue, you can set the value keyword. On the other hand, if you want to have the static string "value", you have to put one backslash \\ in front of it and write value. the follow values are true: 'on', true, 'true'. If you want to have a space, you also have to write \\ in front of the space. |
|
48
|
-
* | index | key:default | property, key | Fetches a value from an object, an array, a map or a set |
|
49
|
-
* | last-key | default | | Can be applied to objects and returns the value of the last key. All keys of the object are fetched and sorted. (since 1.23.0) |
|
50
|
-
* | length | | count | Length of the string or entries of an array or object |
|
51
|
-
* | nop | | | Do nothing |
|
52
|
-
* | nth-key | index:default | | Can be applied to objects and returns the value of the nth key. All keys of the object are fetched and sorted. (since 1.23.0) |
|
53
|
-
* | nth-last-key | index:default | | Can be applied to objects and returns the value of the nth key from behind. All keys of the object are fetched and sorted. (since 1.23.0) |
|
54
|
-
* | path | path | | The access to an object is done via a Pathfinder object |
|
55
|
-
* | path-exists | path | | Check if the specified path is available in the value (since 1.24.0) |
|
56
|
-
* | plaintext | | plain | All HTML tags are removed (*) |
|
57
|
-
* | prefix | text | | Adds a prefix |
|
58
|
-
* | rawurlencode | | | URL coding |
|
59
|
-
* | static | | none | The Arguments value is used and passed to the value. Special characters \ <space> and : can be quotet by a preceding \. |
|
60
|
-
* | substring | start:length | | Returns a substring |
|
61
|
-
* | suffix | text | | Adds a suffix |
|
62
|
-
* | tointeger | | | Type conversion to an integer value |
|
63
|
-
* | tojson | | | Type conversion to a JSON string (since 1.8.0) |
|
64
|
-
* | tolower | | strtolower, tolowercase | The input value is converted to lowercase letters |
|
65
|
-
* | tostring | | | Type conversion to a string. |
|
66
|
-
* | toupper | | strtoupper, touppercase | The input value is converted to uppercase letters |
|
67
|
-
* | trim | | | Remove spaces at the beginning and end |
|
68
|
-
* | ucfirst | | | First character large |
|
69
|
-
* | ucwords | | | Any word beginning large |
|
70
|
-
* | undefined | | | Return undefined |
|
71
|
-
* | uniqid | | | Creates a string with a unique value (**)
|
72
|
-
*
|
73
|
-
* (*) for this functionality the extension [jsdom](https://www.npmjs.com/package/jsdom) must be loaded in the nodejs context.
|
74
|
-
*
|
75
|
-
* ```
|
76
|
-
* // polyfill
|
77
|
-
* if (typeof window !== "object") {
|
78
|
-
* const {window} = new JSDOM('', {
|
79
|
-
* url: 'http://example.com/',
|
80
|
-
* pretendToBeVisual: true
|
81
|
-
* });
|
82
|
-
*
|
83
|
-
* [
|
84
|
-
* 'self',
|
85
|
-
* 'document',
|
86
|
-
* 'Node',
|
87
|
-
* 'Element',
|
88
|
-
* 'HTMLElement',
|
89
|
-
* 'DocumentFragment',
|
90
|
-
* 'DOMParser',
|
91
|
-
* 'XMLSerializer',
|
92
|
-
* 'NodeFilter',
|
93
|
-
* 'InputEvent',
|
94
|
-
* 'CustomEvent'
|
95
|
-
* ].forEach(key => (global[key] = window[key]));
|
96
|
-
* }
|
97
|
-
* ```
|
98
|
-
*
|
99
|
-
* (**) for this command the crypt library is necessary in the nodejs context.
|
100
|
-
*
|
101
|
-
* ```
|
102
|
-
* import * as Crypto from "@peculiar/webcrypto";
|
103
|
-
* global['crypto'] = new Crypto.Crypto();
|
104
|
-
* ```
|
34
|
+
* @see {@link https://monsterjs.org/en/doc/#transformer|Monster Docs}
|
105
35
|
*
|
106
36
|
* @externalExample ../../example/data/transformer.mjs
|
107
37
|
* @license AGPLv3
|
@@ -236,6 +166,10 @@ function transform(value) {
|
|
236
166
|
let key;
|
237
167
|
let defaultValue;
|
238
168
|
|
169
|
+
let element;
|
170
|
+
let attribute;
|
171
|
+
let translations;
|
172
|
+
|
239
173
|
switch (this.command) {
|
240
174
|
case "static":
|
241
175
|
return this.args.join(":");
|
@@ -260,9 +194,11 @@ function transform(value) {
|
|
260
194
|
validateInteger(n);
|
261
195
|
return n;
|
262
196
|
|
197
|
+
case "to-json":
|
263
198
|
case "tojson":
|
264
199
|
return JSON.stringify(value);
|
265
200
|
|
201
|
+
case "from-json":
|
266
202
|
case "fromjson":
|
267
203
|
return JSON.parse(value);
|
268
204
|
|
@@ -527,6 +463,22 @@ function transform(value) {
|
|
527
463
|
|
528
464
|
throw new Error("type not supported");
|
529
465
|
|
466
|
+
case "i18n":
|
467
|
+
case "translation":
|
468
|
+
|
469
|
+
translations = getDocumentTranslations();
|
470
|
+
if (!(translations instanceof Translations)) {
|
471
|
+
throw new Error("missing translations");
|
472
|
+
}
|
473
|
+
|
474
|
+
key = args.shift() || undefined;
|
475
|
+
if (key === undefined) {
|
476
|
+
key = value;
|
477
|
+
}
|
478
|
+
|
479
|
+
defaultValue = args.shift() || undefined;
|
480
|
+
return translations.getText(key, defaultValue);
|
481
|
+
|
530
482
|
default:
|
531
483
|
throw new Error(`unknown command ${this.command}`);
|
532
484
|
}
|
@@ -33,7 +33,7 @@ const KEY_CONTEXT = "context";
|
|
33
33
|
const stackSymbol = Symbol("stack");
|
34
34
|
|
35
35
|
/**
|
36
|
-
* With the
|
36
|
+
* With the focus manager the focus can be stored in a document, recalled and moved.
|
37
37
|
*
|
38
38
|
* @license AGPLv3
|
39
39
|
* @since 1.25.0
|
package/source/dom/locale.mjs
CHANGED
@@ -20,12 +20,13 @@ const DEFAULT_LANGUAGE = "en";
|
|
20
20
|
/**
|
21
21
|
* With this function you can read the language version set by the document.
|
22
22
|
* For this the attribute `lang` in the html tag is read. If no attribute is set, `en` is used as default.
|
23
|
+
* Alternatively, the language version of the browser is used.
|
23
24
|
*
|
24
25
|
* ```html
|
25
26
|
* <html lang="en">
|
26
27
|
* ```
|
27
28
|
*
|
28
|
-
* You can call the function via
|
29
|
+
* You can call the function via `getLocaleOfDocument()`.
|
29
30
|
*
|
30
31
|
* @license AGPLv3
|
31
32
|
* @since 1.13.0
|
package/source/i18n/locale.mjs
CHANGED
@@ -182,22 +182,11 @@ class Locale extends Base {
|
|
182
182
|
*
|
183
183
|
* Limitations: The regex cannot handle multiple variants or private.
|
184
184
|
*
|
185
|
-
* You can call the method via
|
185
|
+
* You can call the method via this function individually:
|
186
186
|
*
|
187
|
-
* ```
|
188
|
-
* <script type="module">
|
189
|
-
* import {Monster} from '@schukai/monster/source/monster.mjs';
|
190
|
-
* new Monster.I18n.createLocale()
|
191
|
-
* </script>
|
192
|
-
* ```
|
193
|
-
*
|
194
|
-
* Alternatively, you can also integrate this function individually.
|
195
|
-
*
|
196
|
-
* ```
|
197
|
-
* <script type="module">
|
187
|
+
* ```javascript
|
198
188
|
* import {createLocale} from '@schukai/monster/source/i18n/locale.mjs';
|
199
189
|
* createLocale()
|
200
|
-
* </script>
|
201
190
|
* ```
|
202
191
|
*
|
203
192
|
* RFC
|
package/source/i18n/provider.mjs
CHANGED
@@ -5,11 +5,22 @@
|
|
5
5
|
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
|
6
6
|
*/
|
7
7
|
|
8
|
-
import {
|
9
|
-
import {
|
10
|
-
import {
|
8
|
+
import {hasObjectLink, getLinkedObjects,addToObjectLink} from "../dom/attributes.mjs";
|
9
|
+
import {getLocaleOfDocument} from "../dom/locale.mjs";
|
10
|
+
import {BaseWithOptions} from "../types/basewithoptions.mjs";
|
11
|
+
import {Locale} from "./locale.mjs";
|
12
|
+
import {Translations} from "./translations.mjs";
|
11
13
|
|
12
|
-
export {
|
14
|
+
export {Provider, translationsLinkSymbol};
|
15
|
+
|
16
|
+
/**
|
17
|
+
* @memberOf Monster.I18n
|
18
|
+
* @type {symbol}
|
19
|
+
* @license AGPLv3
|
20
|
+
* @since 3.9.0
|
21
|
+
* @private
|
22
|
+
*/
|
23
|
+
const translationsLinkSymbol = Symbol.for("@schukai/monster/i18n/translations@@link");
|
13
24
|
|
14
25
|
/**
|
15
26
|
* A provider makes a translation object available.
|
@@ -26,6 +37,11 @@ class Provider extends BaseWithOptions {
|
|
26
37
|
* @return {Promise}
|
27
38
|
*/
|
28
39
|
getTranslations(locale) {
|
40
|
+
|
41
|
+
if (locale === undefined) {
|
42
|
+
locale = getLocaleOfDocument();
|
43
|
+
}
|
44
|
+
|
29
45
|
return new Promise((resolve, reject) => {
|
30
46
|
try {
|
31
47
|
resolve(new Translations(locale));
|
@@ -34,4 +50,56 @@ class Provider extends BaseWithOptions {
|
|
34
50
|
}
|
35
51
|
});
|
36
52
|
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* @param {Locale|string} locale
|
56
|
+
* @param {HTMLElement} element
|
57
|
+
* @return {Provider}
|
58
|
+
*/
|
59
|
+
assignToElement(locale, element) {
|
60
|
+
|
61
|
+
if (locale === undefined) {
|
62
|
+
locale = getLocaleOfDocument();
|
63
|
+
}
|
64
|
+
|
65
|
+
if (!(locale instanceof Locale)) {
|
66
|
+
throw new Error("Locale is not an instance of Locale");
|
67
|
+
}
|
68
|
+
|
69
|
+
if (!(element instanceof HTMLElement)) {
|
70
|
+
element = document.querySelector("body");
|
71
|
+
}
|
72
|
+
|
73
|
+
if (!(element instanceof HTMLElement)) {
|
74
|
+
throw new Error("Element is not an HTMLElement");
|
75
|
+
}
|
76
|
+
|
77
|
+
return this.getTranslations(locale).then((obj) => {
|
78
|
+
|
79
|
+
let translations = null;
|
80
|
+
if (hasObjectLink(element, translationsLinkSymbol)) {
|
81
|
+
const objects = getLinkedObjects(element, translationsLinkSymbol);
|
82
|
+
for (const o of objects) {
|
83
|
+
if (o instanceof Translations) {
|
84
|
+
translations = o;
|
85
|
+
break;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
if (!(translations instanceof Translations)) {
|
90
|
+
throw new Error("Object is not an instance of Translations");
|
91
|
+
}
|
92
|
+
|
93
|
+
translations.assignTranslations(obj);
|
94
|
+
|
95
|
+
} else {
|
96
|
+
addToObjectLink(element, translationsLinkSymbol, obj);
|
97
|
+
}
|
98
|
+
|
99
|
+
|
100
|
+
return obj;
|
101
|
+
});
|
102
|
+
|
103
|
+
}
|
104
|
+
|
37
105
|
}
|