const languages = require("./languages.js").languages; /** * This could be used to setup language selector. This require languages * container, and could create functional languages selector from it. This * add options to select all avaoidable languages in the container. */ class selector { /** * @var {languages} * This store languages container. */ #languages; /** * @var {?HTMLElement} * This store selector HTML container, or null when not created. */ #container; /** * @var {HTMLElement} * This store languages HTML selector object. */ #selector; /** * @var {Array} * This is array of callbacks which must being called after change. */ #callbacks; /** * This create new selector object, from languages container. * * @param {languages} languages - Languages container to work on. */ constructor(languages) { NODE: throw new Error("This module could not beind used in NodeJS."); this.#container = null; this.#languages = languages; this.#callbacks = new Array(); this.#selector = this.#create_selector(); } /** * This check that selector is currently inserted anywhere. * * @returns {bool} - True when selector is inserted anywhere. */ get is_inserted() { return this.#container !== null; } /** * This inserts selector into given HTML element, or directly into * document body, when any element is not specified. It returns * itselt, to call more functions inline. * * @param {?HTMLElement} where - Place to insert selector, or null. * @returns {selector} - This object to chain loading. */ insert(where = null) { if (this.is_inserted) { return this; } if (where === null) { where = document.querySelector("body"); } this.#container = this.#create_container(); where.appendChild(this.#container); return this; } /** * This run all functions which was registered as onChange callback. */ #on_change() { this.#callbacks.forEach(count => { count(this.current); }); } /** * This function remove selector from HTML element, if it is already * inserted anywhere. * * @returns {selector} - This object to chain loading. */ remove() { if (!this.is_inserted) { return this; } this.#container.remove(); this.#container = null; return this; } /** * This create new container with selector inside. * * @returns {HTMLElement} - New container with selector. */ #create_container() { const container = document.createElement("div"); container.classList.add(this.class_name); container.appendChild(this.#selector); return container; } /** * This add new callback to selector. All callbacks would be called * after language change. Callback would get one parameter, which is * name of the location. * * @param {CallableFunction} callback - Function to call on change. * @returns {selector} - Self for chain loading */ add_listener(callback) { this.#callbacks.push(callback); return this; } /** * This return HTML class name of selector container. * * @returns {string} - HTML class name of selector container. */ get class_name() { return 'cx-libtranslate-language-selector'; } /** * This create HTML option element from language name. * * @param {string} location - Name of single language. * @returns {HTMLElement} - New option element. */ #create_option(location) { const name = location.split("_").pop(); const option = document.createElement("option"); option.innerText = name; option.value = location; return option; } /** * This return current selected language name. * * @returns {string} - Current selected language. */ get current() { return this.#selector.value; } /** * This set current selected language for the selector. * * @param {string} name - Name of the language to set. * @returns {selector} - This to chain loading. */ set_selection(name) { if (!this.#languages.has(name)) { DEBUG: throw new Error( "Selector has not \"" + name + "\" " + "language in the container." ); } this.#selector.value = name; return this; } /** * This reload languages list in the selector. It could be used * after change in the languages container. * * @returns {selector} - Itself to chain loading. */ reload() { while (this.#selector.lastChild) { this.#selector.lastChild.remove(); } this.#languages.avairable.forEach(count => { this.#selector.appendChild(this.#create_option(count)); }); return this; } /** * This create new HTML selector object, witch all languages * from container inserted as options. * * @returns {HTMLElement} - New selector object. */ #create_selector() { const selector = document.createElement("select"); selector.addEventListener("change", () => { this.#on_change(); }); this.#languages.avairable.forEach(count => { selector.appendChild(this.#create_option(count)); }); return selector; } } exports.selector = selector;