@schukai/monster 4.29.1 → 4.30.1
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.md +16 -0
- package/package.json +1 -1
- package/source/components/content/viewer/stylesheet/message.mjs +1 -1
- package/source/components/data/stylesheet/metric-graph.mjs +1 -1
- package/source/components/data/stylesheet/metric.mjs +1 -1
- package/source/components/datatable/stylesheet/datatable.mjs +1 -1
- package/source/components/form/digits.mjs +0 -1
- package/source/components/form/select.mjs +1 -1
- package/source/components/form/stylesheet/button-bar.mjs +1 -1
- package/source/components/form/stylesheet/button.mjs +1 -1
- package/source/components/form/stylesheet/confirm-button.mjs +1 -1
- package/source/components/form/stylesheet/form.mjs +1 -1
- package/source/components/form/stylesheet/input-group.mjs +1 -1
- package/source/components/form/stylesheet/login.mjs +1 -1
- package/source/components/form/stylesheet/message-state-button.mjs +1 -1
- package/source/components/form/stylesheet/password.mjs +1 -1
- package/source/components/form/stylesheet/popper-button.mjs +1 -1
- package/source/components/form/stylesheet/state-button.mjs +1 -1
- package/source/components/host/stylesheet/host.mjs +1 -1
- package/source/components/layout/stylesheet/overlay.mjs +1 -1
- package/source/components/navigation/stylesheet/wizard-navigation.mjs +13 -6
- package/source/components/navigation/wizard-navigation.mjs +10 -13
- package/source/components/style/typography.css +4 -0
- package/source/components/style/typography.pcss +5 -0
- package/source/components/stylesheet/typography.mjs +1 -1
- package/source/components/time/stylesheet/day.mjs +1 -1
- package/source/components/time/stylesheet/month-calendar.mjs +1 -1
- package/source/components/time/timeline/stylesheet/appointment.mjs +1 -1
- package/source/components/time/timeline/stylesheet/segment.mjs +1 -1
- package/source/components/tree-menu/stylesheet/tree-menu.mjs +1 -1
- package/source/dom/customelement.mjs +0 -1
- package/source/dom/updater.mjs +838 -843
- package/source/i18n/translations.mjs +188 -188
- package/source/types/version.mjs +1 -1
- package/test/cases/monster.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +45 -33
@@ -12,21 +12,21 @@
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
13
13
|
*/
|
14
14
|
|
15
|
-
import {instanceSymbol} from "../constants.mjs";
|
16
|
-
import {getLinkedObjects, hasObjectLink} from "../dom/attributes.mjs";
|
17
|
-
import {ATTRIBUTE_OBJECTLINK} from "../dom/constants.mjs";
|
18
|
-
import {getDocument} from "../dom/util.mjs";
|
19
|
-
import {Base} from "../types/base.mjs";
|
20
|
-
import {isObject, isString} from "../types/is.mjs";
|
15
|
+
import { instanceSymbol } from "../constants.mjs";
|
16
|
+
import { getLinkedObjects, hasObjectLink } from "../dom/attributes.mjs";
|
17
|
+
import { ATTRIBUTE_OBJECTLINK } from "../dom/constants.mjs";
|
18
|
+
import { getDocument } from "../dom/util.mjs";
|
19
|
+
import { Base } from "../types/base.mjs";
|
20
|
+
import { isObject, isString } from "../types/is.mjs";
|
21
21
|
import {
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
validateInteger,
|
23
|
+
validateObject,
|
24
|
+
validateString,
|
25
25
|
} from "../types/validate.mjs";
|
26
|
-
import {Locale, parseLocale} from "./locale.mjs";
|
27
|
-
import {translationsLinkSymbol} from "./provider.mjs";
|
26
|
+
import { Locale, parseLocale } from "./locale.mjs";
|
27
|
+
import { translationsLinkSymbol } from "./provider.mjs";
|
28
28
|
|
29
|
-
export {Translations, getDocumentTranslations};
|
29
|
+
export { Translations, getDocumentTranslations };
|
30
30
|
|
31
31
|
/**
|
32
32
|
* With this class you can manage translations and access the keys.
|
@@ -38,178 +38,178 @@ export {Translations, getDocumentTranslations};
|
|
38
38
|
* @see https://datatracker.ietf.org/doc/html/rfc3066
|
39
39
|
*/
|
40
40
|
class Translations extends Base {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
/**
|
42
|
+
*
|
43
|
+
* @param {Locale} locale
|
44
|
+
*/
|
45
|
+
constructor(locale) {
|
46
|
+
super();
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
if (locale instanceof Locale) {
|
49
|
+
this.locale = locale;
|
50
|
+
} else if (isString(locale)) {
|
51
|
+
this.locale = parseLocale(validateString(locale));
|
52
|
+
} else {
|
53
|
+
this.locale = getDocumentTranslations();
|
54
|
+
}
|
55
55
|
|
56
|
-
|
57
|
-
|
56
|
+
this.storage = new Map();
|
57
|
+
}
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
59
|
+
/**
|
60
|
+
* This method is called by the `instanceof` operator.
|
61
|
+
* @return {symbol}
|
62
|
+
* @since 3.27.0
|
63
|
+
*/
|
64
|
+
static get [instanceSymbol]() {
|
65
|
+
return Symbol.for("@schukai/monster/i18n/translations@@instance");
|
66
|
+
}
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
68
|
+
/**
|
69
|
+
* Fetches a text using the specified key.
|
70
|
+
* If no suitable key is found, `defaultText` is taken.
|
71
|
+
*
|
72
|
+
* @param {string} key
|
73
|
+
* @param {string|undefined} defaultText
|
74
|
+
* @return {string}
|
75
|
+
* @throws {Error} key not found
|
76
|
+
*/
|
77
|
+
getText(key, defaultText) {
|
78
|
+
if (!this.storage.has(key)) {
|
79
|
+
if (defaultText === undefined) {
|
80
|
+
throw new Error(`key ${key} not found`);
|
81
|
+
}
|
82
82
|
|
83
|
-
|
84
|
-
|
83
|
+
return validateString(defaultText);
|
84
|
+
}
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
86
|
+
const r = this.storage.get(key);
|
87
|
+
if (isObject(r)) {
|
88
|
+
return this.getPluralRuleText(key, "other", defaultText);
|
89
|
+
}
|
90
90
|
|
91
|
-
|
92
|
-
|
91
|
+
return this.storage.get(key);
|
92
|
+
}
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
94
|
+
/**
|
95
|
+
* A number `count` can be passed to this method. In addition to a number, one of the keywords can also be passed directly.
|
96
|
+
* "zero", "one", "two", "few", "many" and "other". Remember: not every language has all rules.
|
97
|
+
*
|
98
|
+
* The appropriate text for this number is then selected. If no suitable key is found, `defaultText` is taken.
|
99
|
+
*
|
100
|
+
* @param {string} key
|
101
|
+
* @param {integer|string} count
|
102
|
+
* @param {string|undefined} defaultText
|
103
|
+
* @return {string}
|
104
|
+
*/
|
105
|
+
getPluralRuleText(key, count, defaultText) {
|
106
|
+
if (!this.storage.has(key)) {
|
107
|
+
return validateString(defaultText);
|
108
|
+
}
|
109
109
|
|
110
|
-
|
110
|
+
const r = validateObject(this.storage.get(key));
|
111
111
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
112
|
+
let keyword;
|
113
|
+
if (isString(count)) {
|
114
|
+
keyword = count.toLocaleString();
|
115
|
+
} else {
|
116
|
+
count = validateInteger(count);
|
117
|
+
if (count === 0) {
|
118
|
+
// special handling for zero count
|
119
|
+
if (r.hasOwnProperty("zero")) {
|
120
|
+
return validateString(r?.zero);
|
121
|
+
}
|
122
|
+
}
|
123
123
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
124
|
+
keyword = new Intl.PluralRules(this.locale.toString()).select(
|
125
|
+
validateInteger(count),
|
126
|
+
);
|
127
|
+
}
|
128
128
|
|
129
|
-
|
130
|
-
|
131
|
-
|
129
|
+
if (r.hasOwnProperty(keyword)) {
|
130
|
+
return validateString(r[keyword]);
|
131
|
+
}
|
132
132
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
133
|
+
// @deprecated since 2023-03-14
|
134
|
+
// DEFAULT_KEY is undefined
|
135
|
+
// if (r.hasOwnProperty(DEFAULT_KEY)) {
|
136
|
+
// return validateString(r[DEFAULT_KEY]);
|
137
|
+
// }
|
138
138
|
|
139
|
-
|
140
|
-
|
139
|
+
return validateString(defaultText);
|
140
|
+
}
|
141
141
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
142
|
+
/**
|
143
|
+
* Set a text for a key
|
144
|
+
*
|
145
|
+
* ```
|
146
|
+
* translations.setText("text1", "Make my day!");
|
147
|
+
* // plural rules
|
148
|
+
* translations.setText("text6", {
|
149
|
+
* "zero": "There are no files on Disk.",
|
150
|
+
* "one": "There is one file on Disk.",
|
151
|
+
* "other": "There are files on Disk."
|
152
|
+
* "default": "There are files on Disk."
|
153
|
+
* });
|
154
|
+
* ```
|
155
|
+
*
|
156
|
+
* @param {string} key
|
157
|
+
* @param {string|object} text
|
158
|
+
* @return {Translations}
|
159
|
+
* @throws {TypeError} value is not a string or object
|
160
|
+
*/
|
161
|
+
setText(key, text) {
|
162
|
+
if (isString(text) || isObject(text)) {
|
163
|
+
this.storage.set(validateString(key), text);
|
164
|
+
return this;
|
165
|
+
}
|
166
166
|
|
167
|
-
|
168
|
-
|
167
|
+
throw new TypeError("value is not a string or object");
|
168
|
+
}
|
169
169
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
170
|
+
/**
|
171
|
+
* This method can be used to transfer overlays from an object. The keys are transferred, and the values are entered
|
172
|
+
* as text.
|
173
|
+
*
|
174
|
+
* The values can either be character strings or, in the case of texts with plural forms, objects. The plural forms
|
175
|
+
* must be stored as text via a standard key "zero", "one", "two", "few", "many" and "other".
|
176
|
+
*
|
177
|
+
* Additionally, the key default can be specified, which will be used if no other key fits.
|
178
|
+
*
|
179
|
+
* In some languages, like for example in German, there is no own more number at the value 0. In these languages,
|
180
|
+
* the function applies additionally zero.
|
181
|
+
*
|
182
|
+
* ```
|
183
|
+
* translations.assignTranslations({
|
184
|
+
* "text1": "Make my day!",
|
185
|
+
* "text2": "I'll be back!",
|
186
|
+
* "text6": {
|
187
|
+
* "zero": "There are no files on Disk.",
|
188
|
+
* "one": "There is one file on Disk.",
|
189
|
+
* "other": "There are files on Disk."
|
190
|
+
* "default": "There are files on Disk."
|
191
|
+
* });
|
192
|
+
* ```
|
193
|
+
*
|
194
|
+
* @param {object} translations
|
195
|
+
* @return {Translations}
|
196
|
+
*/
|
197
|
+
assignTranslations(translations) {
|
198
|
+
validateObject(translations);
|
199
199
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
200
|
+
if (translations instanceof Translations) {
|
201
|
+
translations.storage.forEach((v, k) => {
|
202
|
+
this.setText(k, v);
|
203
|
+
});
|
204
|
+
return this;
|
205
|
+
}
|
206
206
|
|
207
|
-
|
208
|
-
|
209
|
-
|
207
|
+
for (const [k, v] of Object.entries(translations)) {
|
208
|
+
this.setText(k, v);
|
209
|
+
}
|
210
210
|
|
211
|
-
|
212
|
-
|
211
|
+
return this;
|
212
|
+
}
|
213
213
|
}
|
214
214
|
|
215
215
|
/**
|
@@ -223,34 +223,34 @@ class Translations extends Base {
|
|
223
223
|
* @throws {Error} Missing translations.
|
224
224
|
*/
|
225
225
|
function getDocumentTranslations(element) {
|
226
|
-
|
226
|
+
const d = getDocument();
|
227
227
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
228
|
+
if (!(element instanceof HTMLElement)) {
|
229
|
+
element = d.querySelector(
|
230
|
+
`[${ATTRIBUTE_OBJECTLINK}~="${translationsLinkSymbol.toString()}"]`,
|
231
|
+
);
|
232
|
+
if (element === null) {
|
233
|
+
throw new Error(
|
234
|
+
"Cannot find the element with translations. Add the translation object to the document.",
|
235
|
+
);
|
236
|
+
}
|
237
|
+
}
|
238
238
|
|
239
|
-
|
240
|
-
|
241
|
-
|
239
|
+
if (!(element instanceof HTMLElement)) {
|
240
|
+
throw new Error("Element is not an HTMLElement.");
|
241
|
+
}
|
242
242
|
|
243
|
-
|
244
|
-
|
245
|
-
|
243
|
+
if (!hasObjectLink(element, translationsLinkSymbol)) {
|
244
|
+
throw new Error("This element has no translations.");
|
245
|
+
}
|
246
246
|
|
247
|
-
|
247
|
+
const obj = getLinkedObjects(element, translationsLinkSymbol);
|
248
248
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
249
|
+
for (const t of obj) {
|
250
|
+
if (t instanceof Translations) {
|
251
|
+
return t;
|
252
|
+
}
|
253
|
+
}
|
254
254
|
|
255
|
-
|
255
|
+
throw new Error("Missing translations.");
|
256
256
|
}
|
package/source/types/version.mjs
CHANGED
package/test/cases/monster.mjs
CHANGED
package/test/web/test.html
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
</head>
|
10
10
|
<body>
|
11
11
|
<div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
|
12
|
-
<h1 style='margin-bottom: 0.1em;'>Monster 4.
|
13
|
-
<div id="lastupdate" style='font-size:0.7em'>last update
|
12
|
+
<h1 style='margin-bottom: 0.1em;'>Monster 4.30.0</h1>
|
13
|
+
<div id="lastupdate" style='font-size:0.7em'>last update Di 8. Jul 03:38:54 CEST 2025</div>
|
14
14
|
</div>
|
15
15
|
<div id="mocha-errors"
|
16
16
|
style="color: red;font-weight: bold;display: flex;align-items: center;justify-content: center;flex-direction: column;margin:20px;"></div>
|