@schukai/monster 1.12.0 → 1.15.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 +40 -1
- package/README.md +5 -5
- package/dist/modules/constants.js +2 -0
- package/dist/modules/constraints/abstract.js +2 -2
- package/dist/modules/constraints/abstractoperator.js +2 -2
- package/dist/modules/constraints/andoperator.js +2 -2
- package/dist/modules/constraints/invalid.js +2 -2
- package/dist/modules/constraints/isarray.js +2 -2
- package/dist/modules/constraints/isobject.js +2 -2
- package/dist/modules/constraints/namespace.js +1 -1
- package/dist/modules/constraints/oroperator.js +2 -2
- package/dist/modules/constraints/valid.js +2 -2
- package/dist/modules/data/buildmap.js +2 -2
- package/dist/modules/data/diff.js +2 -2
- package/dist/modules/data/extend.js +2 -2
- package/dist/modules/data/namespace.js +1 -1
- package/dist/modules/data/pathfinder.js +2 -2
- package/dist/modules/data/pipe.js +2 -2
- package/dist/modules/data/transformer.js +2 -2
- package/dist/modules/dom/assembler.js +2 -2
- package/dist/modules/dom/attributes.js +2 -2
- package/dist/modules/dom/constants.js +2 -2
- package/dist/modules/dom/customcontrol.js +2 -0
- package/dist/modules/dom/customelement.js +2 -2
- package/dist/modules/dom/events.js +2 -2
- package/dist/modules/dom/locale.js +2 -0
- package/dist/modules/dom/namespace.js +1 -1
- package/dist/modules/dom/template.js +2 -2
- package/dist/modules/dom/theme.js +2 -2
- package/dist/modules/dom/updater.js +2 -2
- package/dist/modules/dom/util.js +2 -2
- package/dist/modules/i18n/locale.js +2 -0
- package/dist/modules/i18n/namespace.js +2 -0
- package/dist/modules/i18n/provider.js +2 -0
- package/dist/modules/i18n/providers/fetch.js +2 -0
- package/dist/modules/i18n/providers/namespace.js +2 -0
- package/dist/modules/i18n/translations.js +2 -0
- package/dist/modules/logging/handler/console.js +2 -2
- package/dist/modules/logging/handler/namespace.js +1 -1
- package/dist/modules/logging/handler.js +2 -2
- package/dist/modules/logging/logentry.js +2 -2
- package/dist/modules/logging/logger.js +2 -2
- package/dist/modules/logging/namespace.js +1 -1
- package/dist/modules/math/namespace.js +1 -1
- package/dist/modules/math/random.js +2 -2
- package/dist/modules/monster.js +2 -2
- 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 +2 -2
- package/dist/modules/types/basewithoptions.js +2 -0
- package/dist/modules/types/global.js +2 -2
- package/dist/modules/types/id.js +2 -2
- package/dist/modules/types/is.js +2 -2
- package/dist/modules/types/namespace.js +1 -1
- package/dist/modules/types/observer.js +2 -2
- package/dist/modules/types/observerlist.js +2 -2
- package/dist/modules/types/proxyobserver.js +2 -2
- package/dist/modules/types/queue.js +2 -2
- package/dist/modules/types/randomid.js +2 -2
- package/dist/modules/types/stack.js +2 -2
- package/dist/modules/types/tokenlist.js +2 -2
- package/dist/modules/types/typeof.js +2 -2
- package/dist/modules/types/uniquequeue.js +2 -2
- package/dist/modules/types/validate.js +2 -2
- package/dist/modules/types/version.js +2 -2
- package/dist/modules/util/clone.js +2 -2
- package/dist/modules/util/comparator.js +2 -2
- package/dist/modules/util/freeze.js +2 -2
- package/dist/modules/util/namespace.js +1 -1
- package/dist/monster.dev.js +8692 -6669
- package/dist/monster.dev.js.map +1 -1
- package/dist/monster.js +3 -3
- package/package.json +1 -1
- package/source/constants.js +22 -0
- package/source/constraints/abstract.js +2 -2
- package/source/constraints/abstractoperator.js +3 -3
- package/source/constraints/andoperator.js +7 -7
- package/source/constraints/invalid.js +6 -6
- package/source/constraints/isarray.js +6 -6
- package/source/constraints/isobject.js +6 -6
- package/source/constraints/namespace.js +2 -0
- package/source/constraints/oroperator.js +8 -8
- package/source/constraints/valid.js +6 -6
- package/source/data/buildmap.js +15 -15
- package/source/data/diff.js +6 -6
- package/source/data/extend.js +55 -13
- package/source/data/namespace.js +2 -0
- package/source/data/pathfinder.js +6 -7
- package/source/data/pipe.js +5 -5
- package/source/data/transformer.js +6 -6
- package/source/dom/assembler.js +5 -5
- package/source/dom/attributes.js +89 -45
- package/source/dom/constants.js +8 -9
- package/source/dom/customcontrol.js +301 -0
- package/source/dom/customelement.js +149 -31
- package/source/dom/events.js +58 -8
- package/source/dom/locale.js +59 -0
- package/source/dom/namespace.js +2 -0
- package/source/dom/template.js +7 -7
- package/source/dom/theme.js +6 -6
- package/source/dom/updater.js +38 -11
- package/source/dom/util.js +10 -10
- package/source/i18n/locale.js +322 -0
- package/source/i18n/namespace.js +15 -0
- package/source/i18n/provider.js +58 -0
- package/source/i18n/providers/fetch.js +121 -0
- package/source/i18n/providers/namespace.js +15 -0
- package/source/i18n/translations.js +209 -0
- package/source/logging/handler/console.js +4 -4
- package/source/logging/handler.js +4 -4
- package/source/logging/logentry.js +4 -4
- package/source/logging/logger.js +4 -4
- package/source/logging/namespace.js +2 -0
- package/source/math/namespace.js +2 -0
- package/source/math/random.js +5 -5
- package/source/monster.js +26 -16
- package/source/namespace.js +10 -8
- package/source/text/formatter.js +4 -5
- package/source/text/namespace.js +1 -1
- package/source/types/base.js +4 -7
- package/source/types/basewithoptions.js +97 -0
- package/source/types/global.js +6 -6
- package/source/types/id.js +6 -6
- package/source/types/is.js +22 -22
- package/source/types/namespace.js +3 -1
- package/source/types/observer.js +5 -5
- package/source/types/observerlist.js +4 -4
- package/source/types/proxyobserver.js +32 -26
- package/source/types/queue.js +13 -7
- package/source/types/randomid.js +5 -5
- package/source/types/stack.js +11 -4
- package/source/types/tokenlist.js +4 -4
- package/source/types/typeof.js +5 -5
- package/source/types/uniquequeue.js +11 -4
- package/source/types/validate.js +22 -22
- package/source/types/version.js +9 -9
- package/source/util/clone.js +4 -4
- package/source/util/comparator.js +6 -6
- package/source/util/freeze.js +4 -4
- package/source/util/namespace.js +2 -0
- package/test/cases/data/extend.js +66 -13
- package/test/cases/dom/attributes.js +56 -1
- package/test/cases/dom/customcontrol.js +264 -0
- package/test/cases/dom/customelement.js +112 -51
- package/test/cases/dom/events.js +32 -14
- package/test/cases/dom/locale.js +44 -0
- package/test/cases/i18n/locale.js +80 -0
- package/test/cases/i18n/provider.js +15 -0
- package/test/cases/i18n/providers/fetch.js +65 -0
- package/test/cases/i18n/translations.js +57 -0
- package/test/cases/monster.js +3 -1
- package/test/cases/{util → text}/formatter.js +2 -0
- package/test/cases/types/basewithoptions.js +25 -0
- package/test/cases/types/proxyobserver.js +9 -0
- package/test/cases/{text → util}/clone.js +0 -0
- package/test/cases/{text → util}/comparator.js +0 -0
- package/test/util/jsdom.js +4 -0
- package/test/web/import.js +10 -3
- package/test/web/monster-dev.html +3 -3
- package/test/web/monster.html +3 -3
- package/test/web/test.html +3 -3
- package/test/web/tests.js +3 -3
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @author schukai GmbH
|
|
5
|
+
*/
|
|
6
|
+
import {Monster, assignToNamespace} from '../namespace.js';
|
|
7
|
+
import {Base} from "../types/base.js";
|
|
8
|
+
import {validateString} from "../types/validate.js";
|
|
9
|
+
import {clone} from "../util/clone.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @type {symbol}
|
|
13
|
+
*/
|
|
14
|
+
const propertiesSymbol = Symbol('properties');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @type {symbol}
|
|
18
|
+
*/
|
|
19
|
+
const localeStringSymbol = Symbol('localeString');
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* You can call the method via the monster namespace `new Monster.I18n.Locale()`.
|
|
23
|
+
*
|
|
24
|
+
* ```
|
|
25
|
+
* <script type="module">
|
|
26
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.0/dist/modules/i18n/locale.js';
|
|
27
|
+
* console.log(new Monster.I18n.Locale())
|
|
28
|
+
* </script>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Alternatively, you can also integrate this function individually.
|
|
32
|
+
*
|
|
33
|
+
* ```
|
|
34
|
+
* <script type="module">
|
|
35
|
+
* import {Locale} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.0/dist/modules/i18n/locale.js';
|
|
36
|
+
* console.log(new Locale())
|
|
37
|
+
* </script>
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* RFC
|
|
41
|
+
*
|
|
42
|
+
* ```
|
|
43
|
+
* A Language-Tag consists of:
|
|
44
|
+
* langtag ; generated tag
|
|
45
|
+
* -or- private-use ; a private use tag
|
|
46
|
+
*
|
|
47
|
+
* langtag = (language
|
|
48
|
+
* ["-" script]
|
|
49
|
+
* ["-" region]
|
|
50
|
+
* *("-" variant)
|
|
51
|
+
* *("-" extension)
|
|
52
|
+
* ["-" privateuse])
|
|
53
|
+
*
|
|
54
|
+
* language = "en", "ale", or a registered value
|
|
55
|
+
*
|
|
56
|
+
* script = "Latn", "Cyrl", "Hant" ISO 15924 codes
|
|
57
|
+
*
|
|
58
|
+
* region = "US", "CS", "FR" ISO 3166 codes
|
|
59
|
+
* "419", "019", or UN M.49 codes
|
|
60
|
+
*
|
|
61
|
+
* variant = "rozaj", "nedis", "1996", multiple subtags can be used in a tag
|
|
62
|
+
*
|
|
63
|
+
* extension = single letter followed by additional subtags; more than one extension
|
|
64
|
+
* may be used in a language tag
|
|
65
|
+
*
|
|
66
|
+
* private-use = "x-" followed by additional subtags, as many as are required
|
|
67
|
+
* Note that these can start a tag or appear at the end (but not
|
|
68
|
+
* in the middle)
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @since 1.13.0
|
|
72
|
+
* @copyright schukai GmbH
|
|
73
|
+
* @memberOf Monster/I18n
|
|
74
|
+
* @see https://datatracker.ietf.org/doc/html/rfc3066
|
|
75
|
+
*/
|
|
76
|
+
class Locale extends Base {
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @param {string|undefined} language
|
|
80
|
+
* @param {string|undefined} region
|
|
81
|
+
* @param {string|undefined} script
|
|
82
|
+
* @param {string|undefined} variants
|
|
83
|
+
* @param {string|undefined} extlang
|
|
84
|
+
* @param {string|undefined} privateUse
|
|
85
|
+
* @throws {Error} unsupported locale
|
|
86
|
+
*/
|
|
87
|
+
constructor(language, region, script, variants, extlang, privateUse) {
|
|
88
|
+
super();
|
|
89
|
+
|
|
90
|
+
this[propertiesSymbol] = {
|
|
91
|
+
language: (language === undefined) ? undefined : validateString(language),
|
|
92
|
+
script: (script === undefined) ? undefined : validateString(script),
|
|
93
|
+
region: (region === undefined) ? undefined : validateString(region),
|
|
94
|
+
variants: (variants === undefined) ? undefined : validateString(variants),
|
|
95
|
+
extlang: (extlang === undefined) ? undefined : validateString(extlang),
|
|
96
|
+
privateUse: (privateUse === undefined) ? undefined : validateString(privateUse),
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
let s = [];
|
|
100
|
+
if (language !== undefined) s.push(language);
|
|
101
|
+
if (script !== undefined) s.push(script);
|
|
102
|
+
if (region !== undefined) s.push(region);
|
|
103
|
+
if (variants !== undefined) s.push(variants);
|
|
104
|
+
if (extlang !== undefined) s.push(extlang);
|
|
105
|
+
if (privateUse !== undefined) s.push(privateUse);
|
|
106
|
+
|
|
107
|
+
if (s.length === 0) {
|
|
108
|
+
throw new Error('unsupported locale');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
this[localeStringSymbol] = s.join('-');
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @return {string}
|
|
117
|
+
*/
|
|
118
|
+
get localeString() {
|
|
119
|
+
return this[localeStringSymbol];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @return {string|undefined}
|
|
124
|
+
*/
|
|
125
|
+
get language() {
|
|
126
|
+
return this[propertiesSymbol].language;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @return {string|undefined}
|
|
131
|
+
*/
|
|
132
|
+
get region() {
|
|
133
|
+
return this[propertiesSymbol].region;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @return {string|undefined}
|
|
138
|
+
*/
|
|
139
|
+
get script() {
|
|
140
|
+
return this[propertiesSymbol].script;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @return {string|undefined}
|
|
145
|
+
*/
|
|
146
|
+
get variants() {
|
|
147
|
+
return this[propertiesSymbol].variants;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @return {string|undefined}
|
|
152
|
+
*/
|
|
153
|
+
get extlang() {
|
|
154
|
+
return this[propertiesSymbol].extlang;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @return {string|undefined}
|
|
159
|
+
*/
|
|
160
|
+
get privateUse() {
|
|
161
|
+
return this[propertiesSymbol].privateValue;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @return {string}
|
|
167
|
+
*/
|
|
168
|
+
toString() {
|
|
169
|
+
return "" + this.localeString;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @return {object}
|
|
174
|
+
*/
|
|
175
|
+
getMap() {
|
|
176
|
+
return clone(this[propertiesSymbol])
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Parse local according to rfc4646 standard
|
|
185
|
+
*
|
|
186
|
+
* Limitations: The regex cannot handle multiple variants or private.
|
|
187
|
+
*
|
|
188
|
+
* You can call the method via the monster namespace `Monster.I18n.createLocale()`.
|
|
189
|
+
*
|
|
190
|
+
* ```
|
|
191
|
+
* <script type="module">
|
|
192
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.0/dist/modules/i18n/locale.js';
|
|
193
|
+
* console.log(new Monster.I18n.createLocale())
|
|
194
|
+
* </script>
|
|
195
|
+
* ```
|
|
196
|
+
*
|
|
197
|
+
* Alternatively, you can also integrate this function individually.
|
|
198
|
+
*
|
|
199
|
+
* ```
|
|
200
|
+
* <script type="module">
|
|
201
|
+
* import {createLocale} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.0/dist/modules/i18n/locale.js';
|
|
202
|
+
* console.log(createLocale())
|
|
203
|
+
* </script>
|
|
204
|
+
* ```
|
|
205
|
+
*
|
|
206
|
+
* RFC
|
|
207
|
+
*
|
|
208
|
+
* ```
|
|
209
|
+
* The syntax of the language tag in ABNF [RFC4234] is:
|
|
210
|
+
*
|
|
211
|
+
* Language-Tag = langtag
|
|
212
|
+
* / privateuse ; private use tag
|
|
213
|
+
* / grandfathered ; grandfathered registrations
|
|
214
|
+
*
|
|
215
|
+
* langtag = (language
|
|
216
|
+
* ["-" script]
|
|
217
|
+
* ["-" region]
|
|
218
|
+
* *("-" variant)
|
|
219
|
+
* *("-" extension)
|
|
220
|
+
* ["-" privateuse])
|
|
221
|
+
*
|
|
222
|
+
* language = (2*3ALPHA [ extlang ]) ; shortest ISO 639 code
|
|
223
|
+
* / 4ALPHA ; reserved for future use
|
|
224
|
+
* / 5*8ALPHA ; registered language subtag
|
|
225
|
+
*
|
|
226
|
+
* extlang = *3("-" 3ALPHA) ; reserved for future use
|
|
227
|
+
*
|
|
228
|
+
* script = 4ALPHA ; ISO 15924 code
|
|
229
|
+
*
|
|
230
|
+
* region = 2ALPHA ; ISO 3166 code
|
|
231
|
+
* / 3DIGIT ; UN M.49 code
|
|
232
|
+
*
|
|
233
|
+
* variant = 5*8alphanum ; registered variants
|
|
234
|
+
* / (DIGIT 3alphanum)
|
|
235
|
+
*
|
|
236
|
+
* extension = singleton 1*("-" (2*8alphanum))
|
|
237
|
+
*
|
|
238
|
+
* singleton = %x41-57 / %x59-5A / %x61-77 / %x79-7A / DIGIT
|
|
239
|
+
* ; "a"-"w" / "y"-"z" / "A"-"W" / "Y"-"Z" / "0"-"9"
|
|
240
|
+
* ; Single letters: x/X is reserved for private use
|
|
241
|
+
*
|
|
242
|
+
* privateuse = ("x"/"X") 1*("-" (1*8alphanum))
|
|
243
|
+
*
|
|
244
|
+
* grandfathered = 1*3ALPHA 1*2("-" (2*8alphanum))
|
|
245
|
+
* ; grandfathered registration
|
|
246
|
+
* ; Note: i is the only singleton
|
|
247
|
+
* ; that starts a grandfathered tag
|
|
248
|
+
*
|
|
249
|
+
* alphanum = (ALPHA / DIGIT) ; letters and numbers
|
|
250
|
+
*
|
|
251
|
+
* Figure 1: Language Tag ABNF
|
|
252
|
+
* ```
|
|
253
|
+
*
|
|
254
|
+
* @param {string} locale
|
|
255
|
+
* @returns {Locale}
|
|
256
|
+
* @since 1.14.0
|
|
257
|
+
* @copyright schukai GmbH
|
|
258
|
+
* @memberOf Monster/I18n
|
|
259
|
+
* @throws {TypeError} value is not a string
|
|
260
|
+
* @throws {Error} unsupported locale
|
|
261
|
+
*/
|
|
262
|
+
function parseLocale(locale) {
|
|
263
|
+
|
|
264
|
+
locale = validateString(locale).replace(/_/g, "-");
|
|
265
|
+
|
|
266
|
+
let language, region, variants, parts, script, extlang,
|
|
267
|
+
regexRegular = "(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)",
|
|
268
|
+
regexIrregular = "(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)",
|
|
269
|
+
regexGrandfathered = "(" + regexIrregular + "|" + regexRegular + ")",
|
|
270
|
+
regexPrivateUse = "(x(-[A-Za-z0-9]{1,8})+)",
|
|
271
|
+
regexSingleton = "[0-9A-WY-Za-wy-z]",
|
|
272
|
+
regexExtension = "(" + regexSingleton + "(-[A-Za-z0-9]{2,8})+)",
|
|
273
|
+
regexVariant = "([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3})",
|
|
274
|
+
regexRegion = "([A-Za-z]{2}|[0-9]{3})",
|
|
275
|
+
regexScript = "([A-Za-z]{4})",
|
|
276
|
+
regexExtlang = "([A-Za-z]{3}(-[A-Za-z]{3}){0,2})",
|
|
277
|
+
regexLanguage = "(([A-Za-z]{2,3}(-" + regexExtlang + ")?)|[A-Za-z]{4}|[A-Za-z]{5,8})",
|
|
278
|
+
regexLangtag = "(" + regexLanguage + "(-" + regexScript + ")?" + "(-" + regexRegion + ")?" + "(-" + regexVariant + ")*" + "(-" + regexExtension + ")*" + "(-" + regexPrivateUse + ")?" + ")",
|
|
279
|
+
regexLanguageTag = "^(" + regexGrandfathered + "|" + regexLangtag + "|" + regexPrivateUse + ")$",
|
|
280
|
+
regex = new RegExp(regexLanguageTag), match;
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
if ((match = regex.exec(locale)) !== null) {
|
|
284
|
+
if (match.index === regex.lastIndex) {
|
|
285
|
+
regex.lastIndex++;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (match === undefined || match === null) {
|
|
290
|
+
throw new Error('unsupported locale');
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (match[6] !== undefined) {
|
|
294
|
+
language = match[6];
|
|
295
|
+
|
|
296
|
+
parts = language.split('-');
|
|
297
|
+
if (parts.length > 1) {
|
|
298
|
+
language = parts[0];
|
|
299
|
+
extlang = parts[1];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (match[14] !== undefined) {
|
|
305
|
+
region = match[14];
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (match[12] !== undefined) {
|
|
309
|
+
script = match[12];
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (match[16] !== undefined) {
|
|
313
|
+
variants = match[16];
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return new Locale(language, region, script, variants, extlang);
|
|
317
|
+
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
assignToNamespace('Monster.I18n', Locale, parseLocale);
|
|
322
|
+
export {Monster, Locale, parseLocale}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* In this namespace you will find classes and methods for handling locale and localized texts.
|
|
5
|
+
*
|
|
6
|
+
* @namespace Monster/I18n
|
|
7
|
+
* @author schukai GmbH
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @private
|
|
13
|
+
* @type {string}
|
|
14
|
+
*/
|
|
15
|
+
const namespace = "Monster.I18n";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @author schukai GmbH
|
|
5
|
+
*/
|
|
6
|
+
import {Monster, assignToNamespace} from '../namespace.js';
|
|
7
|
+
import {BaseWithOptions} from "../types/basewithoptions.js";
|
|
8
|
+
import {Locale} from "./locale.js"
|
|
9
|
+
import {Translations} from "./translations.js"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A provider makes a translation object available.
|
|
13
|
+
*
|
|
14
|
+
* You can call the method via the monster namespace `new Monster.I18n.Provider()`.
|
|
15
|
+
*
|
|
16
|
+
* ```
|
|
17
|
+
* <script type="module">
|
|
18
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.0/dist/modules/i18n/provider.js';
|
|
19
|
+
* console.log(new Monster.I18n.Provider())
|
|
20
|
+
* </script>
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Alternatively, you can also integrate this function individually.
|
|
24
|
+
*
|
|
25
|
+
* ```
|
|
26
|
+
* <script type="module">
|
|
27
|
+
* import {Provider} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.0/dist/modules/i18n/provider.js';
|
|
28
|
+
* console.log(new Provider())
|
|
29
|
+
* </script>
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @since 1.13.0
|
|
33
|
+
* @copyright schukai GmbH
|
|
34
|
+
* @memberOf Monster/I18n
|
|
35
|
+
* @see https://datatracker.ietf.org/doc/html/rfc3066
|
|
36
|
+
*/
|
|
37
|
+
class Provider extends BaseWithOptions {
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {Locale|string} locale
|
|
41
|
+
* @return {Promise}
|
|
42
|
+
*/
|
|
43
|
+
getTranslations(locale) {
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
try {
|
|
46
|
+
resolve(new Translations(locale));
|
|
47
|
+
} catch (e) {
|
|
48
|
+
reject(e);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
assignToNamespace('Monster.I18n', Provider);
|
|
58
|
+
export {Monster, Provider}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @author schukai GmbH
|
|
5
|
+
*/
|
|
6
|
+
import {Monster, assignToNamespace} from '../../namespace.js';
|
|
7
|
+
import {Formatter} from "../../text/formatter.js";
|
|
8
|
+
import {getGlobalFunction} from "../../types/global.js";
|
|
9
|
+
import { validateObject, validateString} from "../../types/validate.js";
|
|
10
|
+
import {isString, isInstance} from "../../types/is.js";
|
|
11
|
+
import {parseLocale} from "../locale.js";
|
|
12
|
+
import {Provider} from "../provider.js";
|
|
13
|
+
import {PROPERTY_KEY_INTERNALDATA} from "../../constants.js";
|
|
14
|
+
import {Translations} from "../translations.js";
|
|
15
|
+
import {extend} from "../../data/extend.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @private
|
|
19
|
+
* @type {symbol}
|
|
20
|
+
*/
|
|
21
|
+
const optionsSymbol = Symbol.for(PROPERTY_KEY_INTERNALDATA);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The fetch provider retrieves a JSON file from the given URL and returns a translation object.
|
|
25
|
+
*
|
|
26
|
+
* You can call the method via the monster namespace `new Monster.I18n.Provider()`.
|
|
27
|
+
*
|
|
28
|
+
* ```
|
|
29
|
+
* <script type="module">
|
|
30
|
+
* import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.0/dist/modules/i18n/providers/fetch.js';
|
|
31
|
+
* console.log(new Monster.I18n.Providers.Fetch())
|
|
32
|
+
* </script>
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* Alternatively, you can also integrate this function individually.
|
|
36
|
+
*
|
|
37
|
+
* ```
|
|
38
|
+
* <script type="module">
|
|
39
|
+
* import {Fetch} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.15.0/dist/modules/i18n/providers/fetch.js';
|
|
40
|
+
* console.log(new Fetch())
|
|
41
|
+
* </script>
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @since 1.13.0
|
|
45
|
+
* @copyright schukai GmbH
|
|
46
|
+
* @memberOf Monster/I18n/Providers
|
|
47
|
+
* @see https://datatracker.ietf.org/doc/html/rfc3066
|
|
48
|
+
*/
|
|
49
|
+
class Fetch extends Provider {
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* As options the key `fetch` can be passed. This config object is passed to the fetch method as init.
|
|
53
|
+
*
|
|
54
|
+
* @param {string|URL} url
|
|
55
|
+
* @param {object} options
|
|
56
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/fetch
|
|
57
|
+
*/
|
|
58
|
+
constructor(url, options) {
|
|
59
|
+
super(options);
|
|
60
|
+
|
|
61
|
+
if (isInstance(url, URL)) {
|
|
62
|
+
url = url.toString();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (options === undefined) {
|
|
66
|
+
options = {};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
validateString(url);
|
|
70
|
+
|
|
71
|
+
this.url = url;
|
|
72
|
+
this[optionsSymbol] = extend({}, super.defaults, this.defaults, validateObject(options));
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Defaults
|
|
78
|
+
* @return {object}
|
|
79
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
|
|
80
|
+
*/
|
|
81
|
+
get defaults() {
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
fetch: {
|
|
85
|
+
method: 'GET', // *GET, POST, PUT, DELETE, etc.
|
|
86
|
+
mode: 'cors', // no-cors, *cors, same-origin
|
|
87
|
+
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
|
|
88
|
+
credentials: 'omit', // include, *same-origin, omit
|
|
89
|
+
redirect: 'follow', // manual, *follow, error
|
|
90
|
+
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* @param {Locale|string} locale
|
|
99
|
+
* @return {Promise}
|
|
100
|
+
*/
|
|
101
|
+
getTranslations(locale) {
|
|
102
|
+
|
|
103
|
+
if (isString(locale)) {
|
|
104
|
+
locale = parseLocale(locale);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let formatter = new Formatter(locale.getMap())
|
|
108
|
+
|
|
109
|
+
return getGlobalFunction('fetch')(formatter.format(this.url), this.getOption('fetch', {}))
|
|
110
|
+
.then((response) => response.json()).then(data => {
|
|
111
|
+
return new Translations(locale).assignTranslations(data);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
assignToNamespace('Monster.I18n.Providers', Fetch);
|
|
121
|
+
export {Monster, Fetch}
|