const DEBUG_MODE = /localhost/.test(window.location.href) && 0; class UtilRegistry { _registeredUtils = []; _activeUtilInstances = []; constructor() { document.addEventListener('DOMContentLoaded', () => this.setupAll()); } /** * function registerUtil * * utils need to have at least these properties: * name: string | utils name, e.g. 'example' * selector: string | utils selector, e.g. '[uw-example]' * setup: Function | utils setup function, see below * * setup function must return instance object with at least these properties: * name: string | utils name * element: HTMLElement | element the util is applied to * destroy: Function | function to destroy the util and remove any listeners * * @param util Object Utility that should be added to the registry */ register(util) { if (DEBUG_MODE > 2) { console.log('registering util "' + util.name + '"'); console.log({ util }); } console.log('register...', { this: this }); this._registeredUtils.push(util); } deregister(name, destroy) { const utilIndex = this._findUtilIndex(name); if (utilIndex >= 0) { if (destroy === true) { this._destroyUtilInstances(name); } this._registeredUtils.splice(utilIndex, 1); } } setupAll = (scope) => { console.log('setupAll', { scope }); if (DEBUG_MODE > 1) { console.info('registered js utilities:'); console.table(this._registeredUtils); } this._registeredUtils.forEach((util) => this.setup(util, scope)); } setup(util, scope = document.body) { if (DEBUG_MODE > 2) { console.log('setting up util', { util }); } if (util && typeof util.setup === 'function') { const elements = this._findUtilElements(util, scope); elements.forEach((element) => { let utilInstance = null; try { utilInstance = util.setup(element); } catch(err) { if (DEBUG_MODE > 0) { console.warn('Error while trying to initialize a utility!', { util , element, err }); } } if (utilInstance) { if (DEBUG_MODE > 2) { console.info('Got utility instance for utility "' + util.name + '"', { utilInstance }); } this._activeUtilInstances.push(utilInstance); } }); } } find(name) { return this._registeredUtils.find((util) => util.name === name); } _findUtilElements(util, scope) { if (scope && scope.matches(util.selector)) { return [scope]; } return Array.from(scope.querySelectorAll(util.selector)); } _findUtilIndex(name) { return this._registeredUtils.findIndex((util) => util.name === name); } _destroyUtilInstances(name) { this._activeUtilInstances .map((util, index) => ({ util: util, index: index, })) .filter((activeUtil) => activeUtil.util.name === name) .forEach((activeUtil) => { // destroy util instance activeUtil.util.destroy(); delete this._activeUtilInstances[activeUtil.index]; }); // get rid of now empty array slots this._activeUtilInstances = this._activeUtilInstances.filter((util) => !!util); } } window.UtilRegistry = new UtilRegistry();