/** * @file felexdev-theme-manager.js * @description Миниицированная версия * @version 0.0.1 * @author felex67 (admin@felexdev.ru) * @license Apache2.0 * @warning Системная версия('auto') должна регистрироваться первой!!! */ class ThemeManager { /** Cunfigurations */ static #config = { btnId: 'btn-toggle', // Идентификатор кнопки переключения: `gpfx + btnid == 'flxd-tm-btn-toggle'` btnTabIndex: 0, // Индекс табуляции кнопки переключения тем globalPrefix: 'flxd-tm', // Глобальный префикс: `gpfx + '-' == 'flxd-tm-'` themePrefix: 'color-scheme', // Селектор CSS: `gpfx + stdid == 'flxd-tm-color-scheme'` svg: '', }; static #classList = document.documentElement.classList; static #button = document.createElement('div'); static #index = 0; static #themes = []; static toggle = () => { this.#s((this.#index + 1) % this.#themes.length); }; static { const config = this.#config; config.globalPrefix += '-'; config.themePrefix = config.globalPrefix + config.themePrefix; this.#button.id = config.btnId = config.globalPrefix + config.btnId; this.#button.tabIndex = config.btnTabIndex; this.#button.setAttribute('aria-label', 'toggle color scheme'); this.#button.addEventListener('click', this.toggle); }; /** * Add new theme * @param {string} themeName - Название темы используемое в селекторе CSS. 'auto' -> 'flxd-tm-color-scheme-auto' * @param {string?} themeIcon - Текстовое векторное изображение PlainSVG, если равно нулю используется иконка по умолчанию: 2-я фаза луны. */ static #addTheme = (name, icon = null) => { this.#themes.push({ name: name, icon: icon || this.#config.svg, selector:`${this.themePrefix}-${n}`, }); }; static #set(index) { if (index == this.#index) return; if (index && this.#index) this.#configl.replace(this.#themes[this.#index].selector, this.#themes[index].selector); else if (this.#index) this.#configl.remove(this.#themes[this.#index].selector); else this.#configl.add(this.#themes[index].selector); this.#save(this.#index = index); this.#button.innerHTML = this.#themes[index].icon; }; static #save = (() => { let save = (index) => { console.error(this.#config.globalPrefix + '#sv: Can`t save theme id, storages are unreachable.'); }; try { this.#index = parseInt(localStorage.getItem(this.#config.themePrefix)) || 0; save = (index) => { try { localStorage.setItem(this.#config.themePrefix, index); } catch(e) { console.error(e); } }; } catch(e) { console.error(this.#config.globalPrefix + '#sv-IIFE: localStorage is unreachable, trying cookie.'); try { let cookie = document.cookie.match(`${this.#config.themePrefix}\\s*=\\s*(\\d+)`); this.#index = cookie ? parseInt(c[1]) || 0 : 0; save = (i) => { try { document.cookie = `${this.#config.themePrefix}=${i};max-age=${31536000};path=/`; } catch(e) { console.error(e); } }; } catch(e) { console.error(this.#config.globalPrefix + `#s-IIFE: All storages are unreachable('localStorage' & 'document.cookie')`); } } return s; })(); static { let addTheme = this.#addTheme; /** @warning Системная версия('auto') должна регистрироваться первой!!! */ addTheme('auto',''); addTheme('light',''); addTheme('dark',''); /* Темы добавлять здесь */ addTheme('old-terminal',''); /* */ if (this.#index >= this.#themes.length || this.#index<0) { console.error(`${this.#config.globalPrefix}bottom-static: Invalid theme index loaded '${this.#index}'`); this.#index = 0; } this.#set(this.#index); }; static set = (theme) => { let i = -1; for(let j=0; j < this.#themes.length; j++) { if(this.#themes[j].n === name) { i = j; break; } } if(i == -1) { throw new Error('Invalid color sсheme.'); } this.#set(i); }; static #_ = () => { window.removeEventListener('DOMContentLoaded',this.#_); document.body.appendChild(this.#b); }; static { let m = this; this.#set(this.#index); if (!document.body)window.addEventListener('DOMContentLoaded', this.#_); } };