@schukai/monster 3.26.0 → 3.28.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.
@@ -1,5 +1,5 @@
1
1
  import {Embed} from '@schukai/monster/source/i18n/providers/embed.mjs';
2
2
 
3
- // read from scritp tag with id i18n
3
+ // read from script tag with id i18n
4
4
  const translation = new Embed('i18n');
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schukai/monster",
3
- "version": "3.26.0",
3
+ "version": "3.28.0",
4
4
  "description": "Monster is a simple library for creating fast, robust and lightweight websites.",
5
5
  "keywords": [
6
6
  "framework",
@@ -295,25 +295,45 @@ class CustomElement extends HTMLElement {
295
295
  * Before you can use this method, you must have loaded the translations.
296
296
  *
297
297
  * @returns {Monster.DOM.CustomElement}
298
+ * @throws {Error} Cannot find element with translations. Add a translations object to the document.
298
299
  */
299
300
  updateI18n() {
300
-
301
301
  const translations = getDocumentTranslations();
302
302
  if (!translations) {
303
303
  return this;
304
304
  }
305
305
 
306
- const labels = this.getOption("labels");
307
- if (!isIterable(labels)) {
306
+ let labels = this.getOption("labels");
307
+ if (!(isObject(labels) || isIterable(labels))) {
308
308
  return this;
309
309
  }
310
310
 
311
311
  for (const key in labels) {
312
- const text = translations.getText(key, labels[key]);
313
- if (text !== labels[key]) {
314
- this.setOption("labels." + key, text);
312
+ const def = labels[key];
313
+
314
+ if (isString(def)) {
315
+ const text = translations.getText(key, def);
316
+ if (text !== def) {
317
+ this.setOption("labels." + key, text);
318
+ }
319
+ continue;
320
+ } else if (isObject(def)) {
321
+ for (const k in def) {
322
+ const d = def[k];
323
+
324
+ const text = translations.getPluralRuleText(key, k, d);
325
+ if (!isString(text)) {
326
+ throw new Error("Invalid labels definition");
327
+ }
328
+ if (text !== d) {
329
+ this.setOption("labels." + key + "." + k, text);
330
+ }
331
+ }
332
+ continue;
315
333
  }
316
334
 
335
+ throw new Error("Invalid labels definition");
336
+
317
337
  }
318
338
  return this;
319
339
  }
@@ -973,10 +993,10 @@ function registerCustomElement(element) {
973
993
  if (customElements === undefined) {
974
994
  throw new Error("customElements is not supported.");
975
995
  }
976
-
996
+
977
997
  if (customElements.get(element.getTag()) !== undefined) {
978
998
  return;
979
999
  }
980
-
1000
+
981
1001
  customElements.define(element.getTag(), element);
982
1002
  }
@@ -5,14 +5,14 @@
5
5
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
6
  */
7
7
 
8
- import { internalSymbol } from "../constants.mjs";
9
- import { extend } from "../data/extend.mjs";
8
+ import {instanceSymbol, internalSymbol} from "../constants.mjs";
9
+ import {extend} from "../data/extend.mjs";
10
10
 
11
- import { Formatter as TextFormatter } from "../text/formatter.mjs";
12
- import { validateInstance, validateString } from "../types/validate.mjs";
13
- import { Translations } from "./translations.mjs";
11
+ import {Formatter as TextFormatter} from "../text/formatter.mjs";
12
+ import {validateInstance, validateString} from "../types/validate.mjs";
13
+ import {Translations} from "./translations.mjs";
14
14
 
15
- export { Formatter };
15
+ export {Formatter};
16
16
 
17
17
  /**
18
18
  * @private
@@ -41,6 +41,15 @@ class Formatter extends TextFormatter {
41
41
  this[internalTranslationSymbol] = validateInstance(translation, Translations);
42
42
  }
43
43
 
44
+ /**
45
+ * This method is called by the `instanceof` operator.
46
+ * @returns {symbol}
47
+ * @since 3.27.0
48
+ */
49
+ static get [instanceSymbol]() {
50
+ return Symbol.for("@schukai/monster/i18n/formatter@@instance");
51
+ }
52
+
44
53
  /**
45
54
  * @property {object} marker
46
55
  * @property {array} marker.open=["i18n{","${"]
@@ -5,6 +5,7 @@
5
5
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
6
  */
7
7
 
8
+ import {instanceSymbol} from "../constants.mjs";
8
9
  import { Base } from "../types/base.mjs";
9
10
  import { validateString } from "../types/validate.mjs";
10
11
  import { clone } from "../util/clone.mjs";
@@ -100,6 +101,15 @@ class Locale extends Base {
100
101
  this[localeStringSymbol] = s.join("-");
101
102
  }
102
103
 
104
+ /**
105
+ * This method is called by the `instanceof` operator.
106
+ * @returns {symbol}
107
+ * @since 3.27.0
108
+ */
109
+ static get [instanceSymbol]() {
110
+ return Symbol.for("@schukai/monster/i18n/locale@@instance");
111
+ }
112
+
103
113
  /**
104
114
  * @return {string}
105
115
  */
@@ -5,6 +5,7 @@
5
5
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
6
  */
7
7
 
8
+ import {instanceSymbol} from "../constants.mjs";
8
9
  import {hasObjectLink, getLinkedObjects,addToObjectLink} from "../dom/attributes.mjs";
9
10
  import {getLocaleOfDocument} from "../dom/locale.mjs";
10
11
  import {BaseWithOptions} from "../types/basewithoptions.mjs";
@@ -32,6 +33,16 @@ const translationsLinkSymbol = Symbol.for("@schukai/monster/i18n/translations@@l
32
33
  * @see {@link https://datatracker.ietf.org/doc/html/rfc3066}
33
34
  */
34
35
  class Provider extends BaseWithOptions {
36
+
37
+ /**
38
+ * This method is called by the `instanceof` operator.
39
+ * @returns {symbol}
40
+ * @since 3.27.0
41
+ */
42
+ static get [instanceSymbol]() {
43
+ return Symbol.for("@schukai/monster/i18n/provider@@instance");
44
+ }
45
+
35
46
  /**
36
47
  * @param {Locale|string} locale
37
48
  * @return {Promise}
@@ -5,7 +5,8 @@
5
5
  * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
6
  */
7
7
 
8
- import { getLinkedObjects,hasObjectLink} from "../dom/attributes.mjs";
8
+ import {instanceSymbol} from "../constants.mjs";
9
+ import {getLinkedObjects, hasObjectLink} from "../dom/attributes.mjs";
9
10
  import {ATTRIBUTE_OBJECTLINK} from "../dom/constants.mjs";
10
11
  import {getDocument} from "../dom/util.mjs";
11
12
  import {Base} from "../types/base.mjs";
@@ -44,6 +45,15 @@ class Translations extends Base {
44
45
  this.storage = new Map();
45
46
  }
46
47
 
48
+ /**
49
+ * This method is called by the `instanceof` operator.
50
+ * @returns {symbol}
51
+ * @since 3.27.0
52
+ */
53
+ static get [instanceSymbol]() {
54
+ return Symbol.for("@schukai/monster/i18n/translations@@instance");
55
+ }
56
+
47
57
  /**
48
58
  * Fetches a text using the specified key.
49
59
  * If no suitable key is found, `defaultText` is taken.
@@ -94,7 +104,7 @@ class Translations extends Base {
94
104
  } else {
95
105
  count = validateInteger(count);
96
106
  if (count === 0) {
97
- // special handlig for zero count
107
+ // special handling for zero count
98
108
  if (r.hasOwnProperty("zero")) {
99
109
  return validateString(r["zero"]);
100
110
  }
@@ -107,9 +117,11 @@ class Translations extends Base {
107
117
  return validateString(r[keyword]);
108
118
  }
109
119
 
110
- if (r.hasOwnProperty(DEFAULT_KEY)) {
111
- return validateString(r[DEFAULT_KEY]);
112
- }
120
+ // @deprecated since 2023-03-14
121
+ // DEFAULT_KEY is undefined
122
+ // if (r.hasOwnProperty(DEFAULT_KEY)) {
123
+ // return validateString(r[DEFAULT_KEY]);
124
+ // }
113
125
 
114
126
  return validateString(defaultText);
115
127
  }
@@ -171,7 +183,7 @@ class Translations extends Base {
171
183
  */
172
184
  assignTranslations(translations) {
173
185
  validateObject(translations);
174
-
186
+
175
187
  if (translations instanceof Translations) {
176
188
  translations.storage.forEach((v, k) => {
177
189
  this.setText(k, v);
@@ -202,7 +214,7 @@ function getDocumentTranslations(element) {
202
214
  const d = getDocument()
203
215
 
204
216
  if (!(element instanceof HTMLElement)) {
205
- element = d.querySelector('['+ATTRIBUTE_OBJECTLINK+'~="' + translationsLinkSymbol.toString() + '"]');
217
+ element = d.querySelector('[' + ATTRIBUTE_OBJECTLINK + '~="' + translationsLinkSymbol.toString() + '"]');
206
218
  if (element === null) {
207
219
  throw new Error("Cannot find element with translations. Add a translations object to the document.");
208
220
  }
@@ -215,9 +227,9 @@ function getDocumentTranslations(element) {
215
227
  if (!hasObjectLink(element, translationsLinkSymbol)) {
216
228
  throw new Error("This element has no translations.");
217
229
  }
218
-
230
+
219
231
  let obj = getLinkedObjects(element, translationsLinkSymbol);
220
-
232
+
221
233
  for (const t of obj) {
222
234
  if (t instanceof Translations) {
223
235
  return t;
@@ -142,7 +142,7 @@ function getMonsterVersion() {
142
142
  }
143
143
 
144
144
  /** don't touch, replaced by make with package.json version */
145
- monsterVersion = new Version("3.26.0");
145
+ monsterVersion = new Version("3.28.0");
146
146
 
147
147
  return monsterVersion;
148
148
  }
@@ -7,7 +7,7 @@ describe('Monster', function () {
7
7
  let monsterVersion
8
8
 
9
9
  /** don´t touch, replaced by make with package.json version */
10
- monsterVersion = new Version("3.26.0")
10
+ monsterVersion = new Version("3.28.0")
11
11
 
12
12
  let m = getMonsterVersion();
13
13