@schukai/monster 4.38.10 → 4.39.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.md
CHANGED
package/package.json
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.7.4","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.
|
1
|
+
{"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.7.4","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.39.0"}
|
@@ -40,30 +40,35 @@ export { LocalePicker };
|
|
40
40
|
/**
|
41
41
|
* @private
|
42
42
|
* @type {symbol}
|
43
|
+
* Reference to the main picker element
|
43
44
|
*/
|
44
45
|
const localePickerElementSymbol = Symbol("localePickerElement");
|
45
46
|
|
46
47
|
/**
|
47
48
|
* @private
|
48
49
|
* @type {symbol}
|
50
|
+
* Reference to the other languages select element
|
49
51
|
*/
|
50
52
|
const otherLanguagesElementSymbol = Symbol("otherLanguagesElement");
|
51
53
|
|
52
54
|
/**
|
53
55
|
* @private
|
54
56
|
* @type {symbol}
|
57
|
+
* Reference to the language button element
|
55
58
|
*/
|
56
59
|
const buttonLanguageElementSymbol = Symbol("buttonLanguageElement");
|
57
60
|
|
58
61
|
/**
|
59
62
|
* @private
|
60
63
|
* @type {symbol}
|
64
|
+
* Reference to the 'no thanks' button element
|
61
65
|
*/
|
62
66
|
const buttonNoThanksElementSymbol = Symbol("buttonNoThanksElement");
|
63
67
|
|
64
68
|
/**
|
65
69
|
* @private
|
66
70
|
* @type {symbol}
|
71
|
+
* Stores detected languages
|
67
72
|
*/
|
68
73
|
const detectedLanguagesSymbol = Symbol("detectedLanguages");
|
69
74
|
|
@@ -93,7 +98,7 @@ class LocalePicker extends CustomElement {
|
|
93
98
|
}
|
94
99
|
|
95
100
|
/**
|
96
|
-
*
|
101
|
+
* Initializes the component.
|
97
102
|
* @return {LocalePicker}
|
98
103
|
*/
|
99
104
|
[assembleMethodSymbol]() {
|
@@ -168,7 +173,7 @@ class LocalePicker extends CustomElement {
|
|
168
173
|
/**
|
169
174
|
* Lifecycle method that is called when the custom element is appended into a document-connected element.
|
170
175
|
* Invokes the parent class's connectedCallback method and retrieves the user's preferred language.
|
171
|
-
*
|
176
|
+
* Hides or shows the picker depending on the user's language and stored session.
|
172
177
|
*
|
173
178
|
* @return {void}
|
174
179
|
*/
|
@@ -197,7 +202,7 @@ class LocalePicker extends CustomElement {
|
|
197
202
|
};
|
198
203
|
}
|
199
204
|
|
200
|
-
const stored =
|
205
|
+
const stored = sessionStorage.getItem(buildStorageKey.call(this));
|
201
206
|
if (stored && this.getOption("features.showAlways") !== true) {
|
202
207
|
if (this.getOption("features.removeOnSelected")) {
|
203
208
|
this.remove();
|
@@ -253,7 +258,7 @@ class LocalePicker extends CustomElement {
|
|
253
258
|
* @returns {LocalePicker}
|
254
259
|
*/
|
255
260
|
reset() {
|
256
|
-
|
261
|
+
sessionStorage.removeItem(buildStorageKey.call(this));
|
257
262
|
this.show();
|
258
263
|
return this;
|
259
264
|
}
|
@@ -304,9 +309,33 @@ class LocalePicker extends CustomElement {
|
|
304
309
|
}
|
305
310
|
}
|
306
311
|
|
312
|
+
/**
|
313
|
+
* @private
|
314
|
+
* @return {void}
|
315
|
+
* Initializes references to all relevant elements in the picker.
|
316
|
+
*/
|
317
|
+
function initControlReferences() {
|
318
|
+
this[localePickerElementSymbol] = this.shadowRoot.querySelector(
|
319
|
+
`[${ATTRIBUTE_ROLE}="control"]`,
|
320
|
+
);
|
321
|
+
|
322
|
+
this[otherLanguagesElementSymbol] = this.shadowRoot.querySelector(
|
323
|
+
`[${ATTRIBUTE_ROLE}="other-languages"]`,
|
324
|
+
);
|
325
|
+
|
326
|
+
this[buttonNoThanksElementSymbol] = this.shadowRoot.querySelector(
|
327
|
+
`[${ATTRIBUTE_ROLE}="button-no-thanks"]`,
|
328
|
+
);
|
329
|
+
|
330
|
+
this[buttonLanguageElementSymbol] = this.shadowRoot.querySelector(
|
331
|
+
`[${ATTRIBUTE_ROLE}="button-language"]`,
|
332
|
+
);
|
333
|
+
}
|
334
|
+
|
307
335
|
/**
|
308
336
|
* @private
|
309
337
|
* @return {initEventHandler}
|
338
|
+
* Initializes all event handlers for the picker.
|
310
339
|
*/
|
311
340
|
function initEventHandler() {
|
312
341
|
const self = this;
|
@@ -339,7 +368,7 @@ function initEventHandler() {
|
|
339
368
|
});
|
340
369
|
|
341
370
|
this[buttonNoThanksElementSymbol].setOption("actions.click", () => {
|
342
|
-
|
371
|
+
sessionStorage.setItem(buildStorageKey.call(this), "1");
|
343
372
|
this.hide();
|
344
373
|
if (this.getOption("features.removeOnSelected")) {
|
345
374
|
this.remove();
|
@@ -347,7 +376,7 @@ function initEventHandler() {
|
|
347
376
|
});
|
348
377
|
|
349
378
|
this[buttonLanguageElementSymbol].setOption("actions.click", () => {
|
350
|
-
|
379
|
+
sessionStorage.setItem(buildStorageKey.call(this), "1");
|
351
380
|
window.location.href = this[detectedLanguagesSymbol].offerable?.[0]?.href;
|
352
381
|
});
|
353
382
|
|
@@ -361,7 +390,7 @@ function initEventHandler() {
|
|
361
390
|
if (element) {
|
362
391
|
const selected = element?.value;
|
363
392
|
if (selected) {
|
364
|
-
|
393
|
+
sessionStorage.setItem(buildStorageKey.call(this), "1");
|
365
394
|
window.location.href = selected;
|
366
395
|
}
|
367
396
|
}
|
@@ -373,6 +402,7 @@ function initEventHandler() {
|
|
373
402
|
/**
|
374
403
|
* @private
|
375
404
|
* @returns {string}
|
405
|
+
* Builds the session storage key for the picker.
|
376
406
|
*/
|
377
407
|
function buildStorageKey() {
|
378
408
|
return "locale-picker-" + this[detectedLanguagesSymbol].current;
|
@@ -382,6 +412,7 @@ function buildStorageKey() {
|
|
382
412
|
* @private
|
383
413
|
* @param lang
|
384
414
|
* @returns {Object}
|
415
|
+
* Returns translations for the given language.
|
385
416
|
*/
|
386
417
|
function getTranslations(lang) {
|
387
418
|
const map = {
|
@@ -624,31 +655,10 @@ function getTranslations(lang) {
|
|
624
655
|
return result;
|
625
656
|
}
|
626
657
|
|
627
|
-
/**
|
628
|
-
* @private
|
629
|
-
* @return {void}
|
630
|
-
*/
|
631
|
-
function initControlReferences() {
|
632
|
-
this[localePickerElementSymbol] = this.shadowRoot.querySelector(
|
633
|
-
`[${ATTRIBUTE_ROLE}="control"]`,
|
634
|
-
);
|
635
|
-
|
636
|
-
this[otherLanguagesElementSymbol] = this.shadowRoot.querySelector(
|
637
|
-
`[${ATTRIBUTE_ROLE}="other-languages"]`,
|
638
|
-
);
|
639
|
-
|
640
|
-
this[buttonNoThanksElementSymbol] = this.shadowRoot.querySelector(
|
641
|
-
`[${ATTRIBUTE_ROLE}="button-no-thanks"]`,
|
642
|
-
);
|
643
|
-
|
644
|
-
this[buttonLanguageElementSymbol] = this.shadowRoot.querySelector(
|
645
|
-
`[${ATTRIBUTE_ROLE}="button-language"]`,
|
646
|
-
);
|
647
|
-
}
|
648
|
-
|
649
658
|
/**
|
650
659
|
* @private
|
651
660
|
* @return {string}
|
661
|
+
* Returns the template for the component.
|
652
662
|
*/
|
653
663
|
function getTemplate() {
|
654
664
|
// language=HTML
|
@@ -0,0 +1,270 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
|
3
|
+
* Node module: @schukai/monster
|
4
|
+
*
|
5
|
+
* This source code is licensed under the GNU Affero General Public License Version 3 (AGPLv3).
|
6
|
+
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.de.html
|
7
|
+
*
|
8
|
+
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
|
9
|
+
* For more information about purchasing a commercial license, please contact schukai GmbH.
|
10
|
+
*/
|
11
|
+
|
12
|
+
import { instanceSymbol } from "../../constants.mjs";
|
13
|
+
import { ATTRIBUTE_ROLE } from "../../dom/constants.mjs";
|
14
|
+
import { CustomElement } from "../../dom/customelement.mjs";
|
15
|
+
import {
|
16
|
+
assembleMethodSymbol,
|
17
|
+
registerCustomElement,
|
18
|
+
} from "../../dom/customelement.mjs";
|
19
|
+
import { isFunction, isObject } from "../../types/is.mjs";
|
20
|
+
import { LocalePickerStyleSheet } from "./stylesheet/locale-picker.mjs";
|
21
|
+
import { detectUserLanguagePreference } from "../../i18n/util.mjs";
|
22
|
+
|
23
|
+
import "../form/select.mjs";
|
24
|
+
|
25
|
+
export { LocaleSelect as LocalSelector };
|
26
|
+
|
27
|
+
/**
|
28
|
+
* @private
|
29
|
+
* @type {symbol}
|
30
|
+
* Reference to the select element
|
31
|
+
*/
|
32
|
+
const selectElementSymbol = Symbol("selectElement");
|
33
|
+
|
34
|
+
/**
|
35
|
+
* @private
|
36
|
+
* @type {symbol}
|
37
|
+
* Stores detected languages
|
38
|
+
*/
|
39
|
+
const detectedLanguagesSymbol = Symbol("detectedLanguages");
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Returns the localized label for the language selection.
|
43
|
+
* @return {string}
|
44
|
+
*/
|
45
|
+
function getLocalizedLabel() {
|
46
|
+
const lang = document.documentElement.lang || navigator.language || "en";
|
47
|
+
switch (lang.split("-")[0]) {
|
48
|
+
case "de":
|
49
|
+
return "Sprache wählen";
|
50
|
+
case "fr":
|
51
|
+
return "Sélectionnez une langue";
|
52
|
+
case "es":
|
53
|
+
return "Seleccione un idioma";
|
54
|
+
case "it":
|
55
|
+
return "Seleziona una lingua";
|
56
|
+
case "pt":
|
57
|
+
return "Selecione um idioma";
|
58
|
+
case "nl":
|
59
|
+
return "Selecteer een taal";
|
60
|
+
case "pl":
|
61
|
+
return "Wybierz język";
|
62
|
+
case "ru":
|
63
|
+
return "Выберите язык";
|
64
|
+
case "cs":
|
65
|
+
return "Vyberte jazyk";
|
66
|
+
case "sk":
|
67
|
+
return "Vyberte jazyk";
|
68
|
+
case "bg":
|
69
|
+
return "Изберете език";
|
70
|
+
case "hr":
|
71
|
+
return "Odaberite jezik";
|
72
|
+
case "fi":
|
73
|
+
return "Valitse kieli";
|
74
|
+
case "sv":
|
75
|
+
return "Välj ett språk";
|
76
|
+
case "el":
|
77
|
+
return "Επιλέξτε γλώσσα";
|
78
|
+
case "hu":
|
79
|
+
return "Válasszon egy nyelvet";
|
80
|
+
case "ro":
|
81
|
+
return "Selectați o limbă";
|
82
|
+
case "da":
|
83
|
+
return "Vælg et sprog";
|
84
|
+
case "no":
|
85
|
+
return "Velg et språk";
|
86
|
+
case "hi":
|
87
|
+
return "एक भाषा चुनें";
|
88
|
+
case "bn":
|
89
|
+
return "একটি ভাষা নির্বাচন করুন";
|
90
|
+
case "ta":
|
91
|
+
return "ஒரு மொழியைத் தேர்ந்தெடுக்கவும்";
|
92
|
+
case "te":
|
93
|
+
return "భాషను ఎంచుకోండి";
|
94
|
+
case "mr":
|
95
|
+
return "एक भाषा निवडा";
|
96
|
+
case "zh":
|
97
|
+
return "选择一种语言";
|
98
|
+
case "ja":
|
99
|
+
return "言語を選択してください";
|
100
|
+
default:
|
101
|
+
return "Select a language";
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* LocaleSelect component
|
107
|
+
*
|
108
|
+
* Displays a monster-select with all available languages except the current document language.
|
109
|
+
*
|
110
|
+
* @since 3.97.0
|
111
|
+
* @copyright schukai GmbH
|
112
|
+
* @summary A simple language switcher as a select.
|
113
|
+
*/
|
114
|
+
class LocaleSelect extends CustomElement {
|
115
|
+
/**
|
116
|
+
* Used by the instanceof operator.
|
117
|
+
* @returns {symbol}
|
118
|
+
*/
|
119
|
+
static get [instanceSymbol]() {
|
120
|
+
return Symbol.for(
|
121
|
+
"@schukai/monster/components/accessibility/local-selector@@instance",
|
122
|
+
);
|
123
|
+
}
|
124
|
+
|
125
|
+
/**
|
126
|
+
* Initializes the component.
|
127
|
+
* @return {LocaleSelect}
|
128
|
+
*/
|
129
|
+
[assembleMethodSymbol]() {
|
130
|
+
super[assembleMethodSymbol]();
|
131
|
+
initControlReferences.call(this);
|
132
|
+
initSelectOptions.call(this);
|
133
|
+
initEventHandler.call(this);
|
134
|
+
return this;
|
135
|
+
}
|
136
|
+
|
137
|
+
/**
|
138
|
+
* Default options
|
139
|
+
*/
|
140
|
+
get defaults() {
|
141
|
+
return Object.assign({}, super.defaults, {
|
142
|
+
templates: {
|
143
|
+
main: getTemplate(),
|
144
|
+
},
|
145
|
+
labels: {
|
146
|
+
"select-an-option": getLocalizedLabel(),
|
147
|
+
},
|
148
|
+
callbacks: {},
|
149
|
+
disabled: false,
|
150
|
+
});
|
151
|
+
}
|
152
|
+
|
153
|
+
/**
|
154
|
+
* connectedCallback
|
155
|
+
*/
|
156
|
+
connectedCallback() {
|
157
|
+
super.connectedCallback();
|
158
|
+
this[detectedLanguagesSymbol] = detectUserLanguagePreference();
|
159
|
+
initSelectOptions.call(this);
|
160
|
+
}
|
161
|
+
|
162
|
+
/**
|
163
|
+
* @return {string}
|
164
|
+
*/
|
165
|
+
static getTag() {
|
166
|
+
return "monster-locale-select";
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* @return {CSSStyleSheet[]}
|
171
|
+
*/
|
172
|
+
static getCSSStyleSheet() {
|
173
|
+
return [LocalePickerStyleSheet];
|
174
|
+
}
|
175
|
+
|
176
|
+
/**
|
177
|
+
* Export parts from monster-select to make them available for styling outside.
|
178
|
+
*/
|
179
|
+
static get exportparts() {
|
180
|
+
// The parts from monster-select, as defined in source/components/form/select.mjs:
|
181
|
+
return [
|
182
|
+
"control",
|
183
|
+
"container",
|
184
|
+
"popper",
|
185
|
+
"option",
|
186
|
+
"option-label",
|
187
|
+
"option-control",
|
188
|
+
"badge",
|
189
|
+
"badge-label",
|
190
|
+
"remove-badge",
|
191
|
+
"summary",
|
192
|
+
"status-or-remove-badges",
|
193
|
+
"remote-info",
|
194
|
+
"no-options",
|
195
|
+
"selection",
|
196
|
+
"inline-filter",
|
197
|
+
"popper-filter",
|
198
|
+
"content"
|
199
|
+
].join(",");
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
/**
|
204
|
+
* Initializes the reference to the select element.
|
205
|
+
* @private
|
206
|
+
*/
|
207
|
+
function initControlReferences() {
|
208
|
+
this[selectElementSymbol] = this.shadowRoot.querySelector(
|
209
|
+
`[${ATTRIBUTE_ROLE}="select"]`,
|
210
|
+
);
|
211
|
+
}
|
212
|
+
|
213
|
+
/**
|
214
|
+
* Initializes the options of the select element.
|
215
|
+
* @private
|
216
|
+
*/
|
217
|
+
function initSelectOptions() {
|
218
|
+
const detected =
|
219
|
+
this[detectedLanguagesSymbol] || detectUserLanguagePreference();
|
220
|
+
|
221
|
+
let options = [];
|
222
|
+
if (Array.isArray(detected.available)) {
|
223
|
+
const currentLang = detected.current;
|
224
|
+
options = detected.available.filter(
|
225
|
+
(lang) => lang.baseLang !== currentLang && lang.fullLang !== currentLang,
|
226
|
+
);
|
227
|
+
} else if (Array.isArray(detected.allOfferable)) {
|
228
|
+
options = detected.allOfferable;
|
229
|
+
}
|
230
|
+
|
231
|
+
options = detected.allOfferable;
|
232
|
+
if (this[selectElementSymbol]) {
|
233
|
+
this[selectElementSymbol].setOption("mapping.labelTemplate", "${label}");
|
234
|
+
this[selectElementSymbol].setOption("mapping.valueTemplate", "${href}");
|
235
|
+
this[selectElementSymbol].setOption(
|
236
|
+
"labels.select-an-option",
|
237
|
+
this.getOption("labels.select-an-option"),
|
238
|
+
);
|
239
|
+
this[selectElementSymbol].importOptions(options);
|
240
|
+
}
|
241
|
+
}
|
242
|
+
|
243
|
+
/**
|
244
|
+
* Initializes the event handler for the select element.
|
245
|
+
* @private
|
246
|
+
*/
|
247
|
+
function initEventHandler() {
|
248
|
+
if (!this[selectElementSymbol]) return;
|
249
|
+
|
250
|
+
this[selectElementSymbol].addEventListener("change", (event) => {
|
251
|
+
const selected = event.target?.value;
|
252
|
+
if (selected) {
|
253
|
+
window.location.href = selected;
|
254
|
+
}
|
255
|
+
});
|
256
|
+
}
|
257
|
+
|
258
|
+
/**
|
259
|
+
* Returns the template for the component.
|
260
|
+
* @private
|
261
|
+
* @return {string}
|
262
|
+
*/
|
263
|
+
function getTemplate() {
|
264
|
+
// language=HTML
|
265
|
+
return `
|
266
|
+
<monster-select exportparts="control,container,popper,option,option-label,option-control,badge,badge-label,remove-badge,summary,status-or-remove-badges,remote-info,no-options,selection,inline-filter,popper-filter,content" data-monster-role="select"></monster-select>
|
267
|
+
`;
|
268
|
+
}
|
269
|
+
|
270
|
+
registerCustomElement(LocaleSelect);
|