Skip to content
Snippets Groups Projects
Select Git revision
  • 8af0b578f462dac2c99c6fdf6ca75d8e179698d1
  • main default protected
  • drip-server-timing
  • compress-middleware
  • v2.11.0
  • v2.10.0
  • v2.9.2
  • v2.9.1
  • v2.9.0
  • v2.8.0
  • v2.7.0
  • v2.6.0
  • v2.5.6
  • v2.5.5
  • v2.5.4
  • v2.5.3
  • v2.5.2
  • v2.5.1
  • v2.5.0
  • v2.4.2
  • v2.4.1
  • v2.4.0
  • v2.3.0
  • v2.2.2
24 results

handlers.go

Blame
  • locale-picker.mjs 23.78 KiB
    /**
     * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
     * Node module: @schukai/monster
     *
     * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
     * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
     *
     * For those who do not wish to adhere to the AGPLv3, a commercial license is available.
     * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
     * For more information about purchasing a commercial license, please contact schukai GmbH.
     */
    
    import { instanceSymbol } from "../../constants.mjs";
    import { addAttributeToken } from "../../dom/attributes.mjs";
    import {
    	ATTRIBUTE_ERRORMESSAGE,
    	ATTRIBUTE_ROLE,
    } from "../../dom/constants.mjs";
    import { CustomControl } from "../../dom/customcontrol.mjs";
    import {
    	CustomElement,
    	updaterTransformerMethodsSymbol,
    } from "../../dom/customelement.mjs";
    import {
    	assembleMethodSymbol,
    	registerCustomElement,
    } from "../../dom/customelement.mjs";
    import { findTargetElementFromEvent } from "../../dom/events.mjs";
    import { isFunction, isObject } from "../../types/is.mjs";
    import { LocalePickerStyleSheet } from "./stylesheet/locale-picker.mjs";
    import { fireCustomEvent } from "../../dom/events.mjs";
    import { detectUserLanguagePreference } from "../../i18n/util.mjs";
    import { Formatter } from "../../text/formatter.mjs";
    
    import "../form/button.mjs";
    import "../form/select.mjs";
    
    export { LocalePicker };
    
    /**
     * @private
     * @type {symbol}
     */
    const localePickerElementSymbol = Symbol("localePickerElement");
    
    /**
     * @private
     * @type {symbol}
     */
    const otherLanguagesElementSymbol = Symbol("otherLanguagesElement");
    
    /**
     * @private
     * @type {symbol}
     */
    const buttonLanguageElementSymbol = Symbol("buttonLanguageElement");
    
    /**
     * @private
     * @type {symbol}
     */
    const buttonNoThanksElementSymbol = Symbol("buttonNoThanksElement");
    
    /**
     * @private
     * @type {symbol}
     */
    const detectedLanguagesSymbol = Symbol("detectedLanguages");
    
    /**
     * A LocalePicker
     *
     * @fragments /fragments/components/accessibility/locale-picker/
     *
     * @example /examples/components/accessibility/locale-picker-simple Simple example
     * @example /examples/components/accessibility/locale-picker-reset Reset Selection
     *
     * @issue https://localhost.alvine.dev:8443/development/issues/closed/276.html
     *
     * @since 3.97.0
     * @copyright schukai GmbH
     * @summary A beautiful LocalePicker that can make your life easier and also looks good.
     */
    class LocalePicker extends CustomElement {
    	/**
    	 * This method is called by the `instanceof` operator.
    	 * @returns {symbol}
    	 */
    	static get [instanceSymbol]() {
    		return Symbol.for(
    			"@schukai/monster/components/accessibility/locale-picker@@instance",
    		);
    	}
    
    	/**
    	 *
    	 * @return {LocalePicker}
    	 */
    	[assembleMethodSymbol]() {
    		super[assembleMethodSymbol]();
    		initControlReferences.call(this);
    		initEventHandler.call(this);
    
    		return this;
    	}
    
    	/**
    	 * To set the options via the HTML Tag, the attribute `data-monster-options` must be used.
    	 * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
    	 *
    	 * The individual configuration values can be found in the table.
    	 *
    	 * @property {Object} templates Template definitions
    	 * @property {string} templates.main Main template
    	 * @property {Object} labels Label definitions
    	 * @property {string} labels.headline Headline
    	 * @property {string} labels.text Text
    	 * @property {string} labels.button-label Button label
    	 * @property {string} labels.button-no-thanks Button no thanks
    	 * @property {string} labels.headline-other Headline other languages
    	 * @property {Function} callbacks.getTranslation Callback to get the translation for the labels
    	 * @property {Object} features Features
    	 * @property {boolean} features.removeOnSelected Remove the element when a language is selected
    	 * @property {boolean} features.showAlways Show the element always
    	 * @property {boolean} disabled Disabled state
    	 */
    	get defaults() {
    		return Object.assign({}, super.defaults, {
    			templates: {
    				main: getTemplate(),
    			},
    			labels: {
    				headline: "Welcome to our Website",
    				text: "This page is currently displayed in ${currentLabel}. However, we also offer this page in your preferred language. Would you like to switch?",
    				"button-label": "Switch to ${preferred.label}",
    				"button-no-thanks": "No, thanks",
    				"headline-other": "Other languages",
    			},
    
    			callbacks: {
    				getTranslation: getTranslations,
    			},
    
    			disabled: false,
    			features: {
    				removeOnSelected: false,
    				showAlways: false,
    			},
    		});
    	}
    
    	/**
    	 * Private method that provides a mapping of transformer methods keyed by their names.
    	 * These transformer methods define custom transformations for given input values.
    	 *
    	 * @private
    	 * @return {Object} An object containing transformer methods for internal use.
    	 */
    	[updaterTransformerMethodsSymbol]() {
    		return {
    			"replace-placeholder": (value) => {
    				const formatter = new Formatter(this[detectedLanguagesSymbol]);
    				return formatter.format(value);
    			},
    		};
    	}
    
    	/**
    	 * Lifecycle method that is called when the custom element is appended into a document-connected element.
    	 * Invokes the parent class's connectedCallback method and retrieves the user's preferred language.
    	 * Logs the preferred language to the console.
    	 *
    	 * @return {void}
    	 */
    	connectedCallback() {
    		super.connectedCallback();
    
    		this[detectedLanguagesSymbol] = detectUserLanguagePreference();
    
    		if (
    			!isObject(this[detectedLanguagesSymbol]?.preferred) &&
    			this.getOption("features.showAlways") !== true
    		) {
    			this.hide();
    
    			if (this.getOption("features.removeOnSelected")) {
    				this.remove();
    			}
    			return;
    		}
    
    		if (!isObject(this[detectedLanguagesSymbol]?.preferred)) {
    			this[detectedLanguagesSymbol].preferred = {
    				fullLang: "en",
    				baseLang: "en",
    				label: "English",
    			};
    		}
    
    		const stored = localStorage.getItem(buildStorageKey.call(this));
    		if (stored && this.getOption("features.showAlways") !== true) {
    			if (this.getOption("features.removeOnSelected")) {
    				this.remove();
    			}
    			return;
    		}
    
    		this.show();
    
    		if (
    			this[otherLanguagesElementSymbol] instanceof HTMLElement &&
    			this[detectedLanguagesSymbol].offerable &&
    			this[detectedLanguagesSymbol].offerable.length > 1
    		) {
    			this[otherLanguagesElementSymbol].classList.remove("hidden");
    			this[otherLanguagesElementSymbol].setOption(
    				"mapping.labelTemplate",
    				"${label}",
    			);
    			this[otherLanguagesElementSymbol].setOption(
    				"mapping.valueTemplate",
    				"${href}",
    			);
    			this[otherLanguagesElementSymbol].importOptions(
    				this[detectedLanguagesSymbol]?.offerable || [],
    			);
    		}
    
    		if (
    			this[detectedLanguagesSymbol].offerable &&
    			this[detectedLanguagesSymbol].offerable.length > 0
    		) {
    			const getTranslationCallback = this.getOption("callbacks.getTranslation");
    			if (isFunction(getTranslationCallback)) {
    				const translations = getTranslationCallback(
    					this[detectedLanguagesSymbol].offerable[0].baseLang,
    				);
    
    				this.setOption("labels", translations.labels);
    				if (this[otherLanguagesElementSymbol]) {
    					this[otherLanguagesElementSymbol].setOption(
    						"labels.select-an-option",
    						translations.selectAnOption,
    					);
    				}
    			}
    		}
    	}
    
    	/**
    	 * Resets the locale picker by removing the stored value from the local storage.
    	 *
    	 * @returns {LocalePicker}
    	 */
    	reset() {
    		localStorage.removeItem(buildStorageKey.call(this));
    		this.show();
    		return this;
    	}
    
    	/**
    	 * Hides the locale picker.
    	 *
    	 * @returns {LocalePicker}
    	 */
    	hide() {
    		this.style.display = "none";
    
    		if (!this[localePickerElementSymbol]) {
    			return this;
    		}
    
    		this[localePickerElementSymbol].style.display = "none";
    		return this;
    	}
    
    	/**
    	 * Shows the locale picker.
    	 * @returns {LocalePicker}
    	 */
    	show() {
    		this.style.display = "block";
    
    		if (!this[localePickerElementSymbol]) {
    			return this;
    		}
    
    		this[localePickerElementSymbol].style.display = "block";
    		return this;
    	}
    
    	/**
    	 * @return {string}
    	 */
    	static getTag() {
    		return "monster-locale-picker";
    	}
    
    	/**
    	 * @return {CSSStyleSheet[]}
    	 */
    	static getCSSStyleSheet() {
    		return [LocalePickerStyleSheet];
    	}
    }
    
    /**
     * @private
     * @return {initEventHandler}
     */
    function initEventHandler() {
    	const self = this;
    	const element = this[localePickerElementSymbol];
    
    	const type = "click";
    
    	element.addEventListener(type, function (event) {
    		const callback = self.getOption("actions.click");
    
    		fireCustomEvent(self, "monster-locale-picker-clicked", {
    			element: self,
    		});
    
    		if (!isFunction(callback)) {
    			return;
    		}
    
    		const element = findTargetElementFromEvent(
    			event,
    			ATTRIBUTE_ROLE,
    			"control",
    		);
    
    		if (!(element instanceof Node && self.hasNode(element))) {
    			return;
    		}
    
    		callback.call(self, event);
    	});
    
    	this[buttonNoThanksElementSymbol].setOption("actions.click", () => {
    		localStorage.setItem(buildStorageKey.call(this), "1");
    		this.hide();
    		if (this.getOption("features.removeOnSelected")) {
    			this.remove();
    		}
    	});
    
    	this[buttonLanguageElementSymbol].setOption("actions.click", () => {
    		localStorage.setItem(buildStorageKey.call(this), "1");
    		window.location.href = this[detectedLanguagesSymbol].offerable?.[0]?.href;
    	});
    
    	this[otherLanguagesElementSymbol].addEventListener("change", (event) => {
    		const element = findTargetElementFromEvent(
    			event,
    			ATTRIBUTE_ROLE,
    			"other-languages",
    		);
    
    		if (element) {
    			const selected = element?.value;
    			if (selected) {
    				localStorage.setItem(buildStorageKey.call(this), "1");
    				window.location.href = selected;
    			}
    		}
    	});
    
    	return this;
    }
    
    /**
     * @private
     * @returns {string}
     */
    function buildStorageKey() {
    	return "locale-picker-" + this[detectedLanguagesSymbol].current;
    }
    
    /**
     * @private
     * @param lang
     * @returns {Object}
     */
    function getTranslations(lang) {
    	const map = {
    		en: {
    			headline: "Welcome to our Website",
    			text: "This page is currently displayed in ${currentLabel}. However, we also offer this page in your preferred language. Would you like to switch?",
    			"button-label": "Switch to ${preferred.label}",
    			"button-no-thanks": "No, thanks",
    			"headline-other": "Other languages",
    		},
    		de: {
    			headline: "Willkommen auf unserer Webseite",
    			text: "Diese Seite wird aktuell auf ${currentLabel} angezeigt. Wir bieten jedoch auch diese Seite in Ihrer bevorzugten Sprache an. Möchten Sie wechseln?",
    			"button-label": "Wechseln zu ${preferred.label}",
    			"button-no-thanks": "Nein, danke",
    			"headline-other": "Andere Sprachen",
    		},
    		fr: {
    			headline: "Bienvenue sur notre site web",
    			text: "Cette page est actuellement affichée en ${currentLabel}. Cependant, nous proposons également cette page dans votre langue préférée. Souhaitez-vous changer?",
    			"button-label": "Changer pour ${preferred.label}",
    			"button-no-thanks": "Non, merci",
    			"headline-other": "Autres langues",
    		},
    		es: {
    			headline: "Bienvenido a nuestro sitio web",
    			text: "Esta página se muestra actualmente en ${currentLabel}. Sin embargo, también ofrecemos esta página en su idioma preferido. ¿Le gustaría cambiar?",
    			"button-label": "Cambiar a ${preferred.label}",
    			"button-no-thanks": "No, gracias",
    			"headline-other": "Otros idiomas",
    		},
    		it: {
    			headline: "Benvenuti sul nostro sito web",
    			text: "Questa pagina è attualmente visualizzata in ${currentLabel}. Tuttavia, offriamo anche questa pagina nella tua lingua preferita. Vuoi cambiare?",
    			"button-label": "Cambia nella ${preferred.label}",
    			"button-no-thanks": "No, grazie",
    			"headline-other": "Altre lingue",
    		},
    		pt: {
    			headline: "Bem-vindo ao nosso site",
    			text: "Esta página está atualmente exibida em ${currentLabel}. No entanto, também oferecemos esta página no seu idioma preferido. Gostaria de mudar?",
    			"button-label": "Mudar para ${preferred.label}",
    			"button-no-thanks": "Não, obrigado",
    			"headline-other": "Outros idiomas",
    		},
    		nl: {
    			headline: "Welkom op onze website",
    			text: "Deze pagina wordt momenteel weergegeven in ${currentLabel}. We bieden deze pagina echter ook aan in uw voorkeurstaal. Wilt u overschakelen?",
    			"button-label": "Overschakelen naar ${preferred.label}",
    			"button-no-thanks": "Nee, bedankt",
    			"headline-other": "Andere talen",
    		},
    		pl: {
    			headline: "Witamy na naszej stronie",
    			text: "Ta strona jest obecnie wyświetlana po ${currentLabel}. Oferujemy jednak również tę stronę w Twoim preferowanym języku. Czy chcesz przełączyć?",
    			"button-label": "Przełącz na ${preferred.label}",
    			"button-no-thanks": "Nie, dziękuję",
    			"headline-other": "Inne języki",
    		},
    		ru: {
    			headline: "Добро пожаловать на наш сайт",
    			text: "Эта страница в настоящее время отображается на ${currentLabel}. Однако мы также предлагаем эту страницу на вашем предпочтительном языке. Хотите переключиться?",
    			"button-label": "Переключиться на ${preferred.label}",
    			"button-no-thanks": "Нет, спасибо",
    			"headline-other": "Другие языки",
    		},
    		cs: {
    			headline: "Vítejte na našem webu",
    			text: "Tato stránka je aktuálně zobrazena v ${currentLabel}. Nabízíme však tuto stránku také ve vašem preferovaném jazyce. Chcete přejít?",
    			"button-label": "Přejít na ${preferred.label}",
    			"button-no-thanks": "Ne, děkuji",
    			"headline-other": "Další jazyky",
    		},
    		sk: {
    			headline: "Vitajte na našej webovej stránke",
    			text: "Táto stránka je v súčasnosti zobrazená v ${currentLabel}. Ponúkame však túto stránku aj vo vašom preferovanom jazyku. Chcete prejsť?",
    			"button-label": "Prepnúť na ${preferred.label}",
    			"button-no-thanks": "Nie, ďakujem",
    			"headline-other": "Iné jazyky",
    		},
    
    		bg: {
    			headline: "Добре дошли на нашия уебсайт",
    			text: "Тази страница в момента се показва на ${currentLabel}. Въпреки това, предлагаме също тази страница на Вашия предпочитан език. Желаете ли да превключите?",
    			"button-label": "Превключете на ${preferred.label}",
    			"button-no-thanks": "Не, благодаря",
    			"headline-other": "Други езици",
    		},
    		hr: {
    			headline: "Dobrodošli na našu web stranicu",
    			text: "Ova stranica trenutno je prikazana na ${currentLabel}. Međutim, nudimo i ovu stranicu na vašem preferiranom jeziku. Želite li prebaciti?",
    			"button-label": "Prebaci na ${preferred.label}",
    			"button-no-thanks": "Ne, hvala",
    			"headline-other": "Drugi jezici",
    		},
    		fi: {
    			headline: "Tervetuloa verkkosivustollemme",
    			text: "Tämä sivu on tällä hetkellä näkyvissä ${currentLabel}. Tarjoamme kuitenkin tätä sivua myös suosimallasi kielellä. Haluaisitko vaihtaa?",
    			"button-label": "Vaihda ${preferred.label}",
    			"button-no-thanks": "Ei kiitos",
    			"headline-other": "Muut kielet",
    		},
    		sv: {
    			headline: "Välkommen till vår webbplats",
    			text: "Denna sida visas för närvarande på ${currentLabel}. Vi erbjuder dock även denna sida på ditt föredragna språk. Skulle du vilja byta?",
    			"button-label": "Byt till ${preferred.label}",
    			"button-no-thanks": "Nej tack",
    			"headline-other": "Andra språk",
    		},
    		el: {
    			headline: "Καλώς ήρθατε στην ιστοσελίδα μας",
    			text: "Αυτή η σελίδα εμφανίζεται προς το παρόν στα ${currentLabel}. Ωστόσο, προσφέρουμε επίσης αυτή τη σελίδα στην προτιμώμενη γλώσσα σας. Θα θέλατε να αλλάξετε;",
    			"button-label": "Αλλαγή σε ${preferred.label}",
    			"button-no-thanks": "Όχι, ευχαριστώ",
    			"headline-other": "Άλλες γλώσσες",
    		},
    		hu: {
    			headline: "Üdvözöljük weboldalunkon",
    			text: "Ez az oldal jelenleg ${currentLabel} nyelven jelenik meg. Azonban kínáljuk ezt az oldalt a preferált nyelvén is. Szeretne váltani?",
    			"button-label": "Váltás ${preferred.label} nyelvre",
    			"button-no-thanks": "Nem, köszönöm",
    			"headline-other": "További nyelvek",
    		},
    		ro: {
    			headline: "Bine ați venit pe site-ul nostru",
    			text: "Această pagină este afișată în prezent în ${currentLabel}. Totuși, oferim de asemenea această pagină în limba dumneavoastră preferată. Doriți să schimbați?",
    			"button-label": "Schimbați în ${preferred.label}",
    			"button-no-thanks": "Nu, mulțumesc",
    			"headline-other": "Alte limbi",
    		},
    		da: {
    			headline: "Velkommen til vores hjemmeside",
    			text: "Denne side vises i øjeblikket på ${currentLabel}. Vi tilbyder dog også denne side på dit foretrukne sprog. Vil du skifte?",
    			"button-label": "Skift til ${preferred.label}",
    			"button-no-thanks": "Nej tak",
    			"headline-other": "Andre sprog",
    		},
    		no: {
    			headline: "Velkommen til vår nettside",
    			text: "Denne siden vises for øyeblikket på ${currentLabel}. Vi tilbyr imidlertid også denne siden på ditt foretrukne språk. Ønsker du å bytte?",
    			"button-label": "Bytt til ${preferred.label}",
    			"button-no-thanks": "Nei, takk",
    			"headline-other": "Andre språk",
    		},
    		hi: {
    			headline: "हमारी वेबसाइट पर आपका स्वागत है",
    			text: "यह पृष्ठ वर्तमान में ${currentLabel} में प्रदर्शित हो रहा है। हालांकि, हम इस पृष्ठ को आपकी पसंदीदा भाषा में भी प्रदान करते हैं। क्या आप स्विच करना चाहेंगे?",
    			"button-label": "${preferred.label} में स्विच करें",
    			"button-no-thanks": "नहीं, धन्यवाद",
    			"headline-other": "अन्य भाषाएँ",
    		},
    		bn: {
    			headline: "আমাদের ওয়েবসাইটে আপনাকে স্বাগতম",
    			text: "এই পৃষ্ঠাটি বর্তমানে ${currentLabel} প্রদর্শিত হচ্ছে। তবে, আমরা এই পৃষ্ঠাটি আপনার পছন্দের ভাষায়ও অফার করি। আপনি কি সুইচ করতে চান?",
    			"button-label": "${preferred.label}-এ সুইচ করুন",
    			"button-no-thanks": "না, ধন্যবাদ",
    			"headline-other": "অন্যান্য ভাষাসমূহ",
    		},
    		ta: {
    			headline: "எங்கள் இணையதளத்திற்கு வருக",
    			text: "இந்த பக்கம் தற்போது ${currentLabel} என்ற மொழியில் காட்சியளிக்கப்படுகிறது. எனினும், நாங்கள் இந்த பக்கத்தை உங்கள் விருப்ப மொழியிலும் வழங்குகிறோம். நீங்கள் மாற்ற விரும்புகிறீர்களா?",
    			"button-label": "${preferred.label}-க்கு மாற்றவும்",
    			"button-no-thanks": "இல்லை, நன்றி",
    			"headline-other": "மற்ற மொழிகள்",
    		},
    		te: {
    			headline: "మా వెబ్‌సైట్‌కు స్వాగతం",
    			text: "ఈ పేజీ ప్రస్తుతం ${currentLabel}లో ప్రదర్శితం అవుతున్నది. అయితే, మేము ఈ పేజీని మీ ఇష్టపడే భాషలో కూడా అందిస్తున్నాము. మీరు మార్చాలనుకుంటున్నారా?",
    			"button-label": "${preferred.label}కి మార్చండి",
    			"button-no-thanks": "కాదు, ధన్యవాదాలు",
    			"headline-other": "ఇతర భాషలు",
    		},
    		mr: {
    			headline: "आपले आमच्या वेबसाइटवर स्वागत आहे",
    			text: "हे पान सध्या ${currentLabel}मध्ये दाखविले जात आहे. परंतु, आम्ही हे पान आपल्या पसंतीच्या भाषेतही देत आहोत. आपण स्विच करू इच्छिता का?",
    			"button-label": "${preferred.label}मध्ये स्विच करा",
    			"button-no-thanks": "नाही, धन्यवाद",
    			"headline-other": "इतर भाषा",
    		},
    		zh: {
    			headline: "欢迎访问我们的网站",
    			text: "本页面当前显示为${currentLabel}。然而,我们还提供您偏好的语言版本。您想切换吗?",
    			"button-label": "切换到${preferred.label}",
    			"button-no-thanks": "不,谢谢",
    			"headline-other": "其他语言",
    		},
    		ja: {
    			headline: "私たちのウェブサイトへようこそ",
    			text: "このページは現在${currentLabel}で表示されています。しかし、私たちはあなたの好みの言語でこのページを提供しています。切り替えますか?",
    			"button-label": "${preferred.label}に切り替える",
    			"button-no-thanks": "いいえ、結構です",
    			"headline-other": "他の言語",
    		},
    	};
    
    	const selectAnOption = {
    		en: "Select a language",
    		de: "Wählen Sie eine Sprache",
    		fr: "Sélectionnez une langue",
    		es: "Seleccione un idioma",
    		it: "Seleziona una lingua",
    		pt: "Selecione um idioma",
    		nl: "Selecteer een taal",
    		pl: "Wybierz język",
    		ru: "Выберите язык",
    		cs: "Vyberte jazyk",
    		sk: "Vyberte jazyk",
    		bg: "Изберете език",
    		hr: "Odaberite jezik",
    		fi: "Valitse kieli",
    		sv: "Välj ett språk",
    		el: "Επιλέξτε γλώσσα",
    		hu: "Válasszon egy nyelvet",
    		ro: "Selectați o limbă",
    		da: "Vælg et sprog",
    		no: "Velg et språk",
    		hi: "एक भाषा चुनें",
    		bn: "একটি ভাষা নির্বাচন করুন",
    		ta: "ஒரு மொழியைத் தேர்ந்தெடுக்கவும்",
    		te: "భాషను ఎంచుకోండి",
    		mr: "एक भाषा निवडा",
    		zh: "选择一种语言",
    		ja: "言語を選択してください",
    	};
    
    	const result = {};
    
    	if (map[lang]) {
    		result["labels"] = map[lang];
    	} else {
    		result["labels"] = map["en"];
    	}
    
    	if (selectAnOption[lang]) {
    		result["selectAnOption"] = selectAnOption[lang];
    	} else {
    		result["selectAnOption"] = selectAnOption["en"];
    	}
    
    	return result;
    }
    
    /**
     * @private
     * @return {void}
     */
    function initControlReferences() {
    	this[localePickerElementSymbol] = this.shadowRoot.querySelector(
    		`[${ATTRIBUTE_ROLE}="control"]`,
    	);
    
    	this[otherLanguagesElementSymbol] = this.shadowRoot.querySelector(
    		`[${ATTRIBUTE_ROLE}="other-languages"]`,
    	);
    
    	this[buttonNoThanksElementSymbol] = this.shadowRoot.querySelector(
    		`[${ATTRIBUTE_ROLE}="button-no-thanks"]`,
    	);
    
    	this[buttonLanguageElementSymbol] = this.shadowRoot.querySelector(
    		`[${ATTRIBUTE_ROLE}="button-language"]`,
    	);
    }
    
    /**
     * @private
     * @return {string}
     */
    function getTemplate() {
    	// language=HTML
    	return `
            <div data-monster-role="control" part="control">
                <h2 data-monster-role="headline" part="headline" data-monster-replace="path:labels.headline"></h2>
                <p data-monster-replace="path:labels.text | call:replace-placeholder"></p>
                <div data-monster-role="container" part="container">
                    <monster-button data-monster-role="button-language"
                                    data-monster-replace="path:labels.button-label | call:replace-placeholder"></monster-button>
                    <monster-button data-monster-role="button-no-thanks"
                                    data-monster-replace="path:labels.button-no-thanks | call:replace-placeholder"></monster-button>
                    <monster-select class="hidden" data-monster-role="other-languages"></monster-select>
                </div>
            </div>`;
    }
    
    registerCustomElement(LocalePicker);