UNPKG

@exadel/esl

Version:

Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components

139 lines (138 loc) 5.3 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { decorate, memoize } from '../../esl-utils/decorators'; import { microtask } from '../../esl-utils/async/microtask'; import { isObject, deepMerge } from '../../esl-utils/misc/object'; import { uniq } from '../../esl-utils/misc/array'; import { SyntheticEventTarget } from '../../esl-utils/dom/events/target'; const isNamedObject = (obj) => isObject(obj) && typeof obj.name === 'string'; const isGroupCfg = (cfg) => isNamedObject(cfg) && typeof cfg.list === 'string'; const isButtonCfg = (cfg) => isNamedObject(cfg) && typeof cfg.action === 'string'; /** Class for managing share buttons configurations */ export class ESLShareConfig extends SyntheticEventTarget { /** @returns ESLShareConfig shared instance */ static get instance() { return new ESLShareConfig(); } static set(provider) { if (typeof provider === 'function') return this.set(provider()); if (!isObject(provider)) return ESLShareConfig.instance; if (provider instanceof Promise) return provider.then((cfg) => this.set(cfg)); if (Array.isArray(provider.groups)) ESLShareConfig.instance.append(provider.groups); if (Array.isArray(provider.buttons)) ESLShareConfig.instance.append(provider.buttons); return ESLShareConfig.instance; } /** Updates items configuration from the list with the specified partial config */ static update(query, changes) { return ESLShareConfig.instance.update(query, changes); } /** Appends single button or group to current configuration */ static append(cfg) { return ESLShareConfig.instance.append(cfg); } constructor() { super(); this._groups = new Map(); this._buttons = new Map(); } /** @returns list of all available groups */ get groups() { return Array.from(this._groups.entries()).map(([name, list]) => ({ name, list })); } /** @returns list of all available buttons */ get buttons() { return Array.from(this._buttons.values()); } /** Normalize list string by removing groups and extra whitespaces */ resolve(query) { if (/\sall\s/.test(query)) return Array.from(this._buttons.keys()); const groups = new Set(); // Deduplicate groups while (query.includes('group:')) { query = query.replace(/group:(\S+)/gi, (term, name) => { if (groups.has(name)) return ''; groups.add(name); return this._groups.get(name) || ''; }); } return query.split(' ').filter(Boolean); } /** * Selects the buttons for the given list and returns their configuration. * @returns config of buttons */ get(query) { const terms = this.resolve(query); const list = []; terms.forEach((name) => { name === 'all' ? list.push(...this.buttons) : list.push(this.getButton(name)); }); return uniq(list.filter(Boolean)); } /** Clears the configuration */ clear() { this._buttons.clear(); this._groups.clear(); this._onUpdate(); return this; } /** * Gets the group of buttons configuration. * @returns config of group */ getGroup(name) { const list = this._groups.get(name); return list ? { name, list } : undefined; } /** * Gets the button configuration. * @returns config of button */ getButton(name) { return this._buttons.get(name); } /** Updates the configuration with a {@link ESLShareButtonConfig} or {@link ESLShareGroupConfig} */ add(config) { if (isGroupCfg(config)) this._groups.set(config.name, config.list); if (isButtonCfg(config)) this._buttons.set(config.name, config); } /** Updates the configuration with a {@link ESLShareButtonConfig}(s) or {@link ESLShareGroupConfig}(s) */ append(config) { if (Array.isArray(config)) { config.forEach(this.add, this); } else { this.add(config); } this._onUpdate(); return this; } /** Updates items configuration from the list with the specified partial config */ update(query, changes) { for (const btn of this.get(query)) { this.append(deepMerge({}, btn, changes)); } return this; } _onUpdate() { this.dispatchEvent(new CustomEvent('change')); } } __decorate([ decorate(microtask) ], ESLShareConfig.prototype, "_onUpdate", null); __decorate([ memoize() ], ESLShareConfig, "instance", null);