(function() { 'use strict'; var registeredUtils = []; var activeUtilInstances = []; var DEBUG_MODE = /localhost/.test(window.location.href) && 0; // Registry // (revealing module pattern) window.UtilRegistry = (function() { /** * 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 */ function registerUtil(util) { if (DEBUG_MODE > 2) { console.log('registering util "' + util.name + '"'); console.log({ util }); } registeredUtils.push(util); } function deregisterUtil(name, destroy) { var utilIndex = _findUtilIndex(name); if (utilIndex >= 0) { if (destroy === true) { _destroyUtilInstances(name); } registeredUtils.splice(utilIndex, 1); } } function setupAllUtils(scope) { if (DEBUG_MODE > 1) { console.info('registered js utilities:'); console.table(registeredUtils); } registeredUtils.forEach(function(util) { setupUtil(util, scope); }); } function setupUtil(util, scope) { if (DEBUG_MODE > 2) { console.log('setting up util', { util }); } scope = scope || document.body; if (util && typeof util.setup === 'function') { const elements = _findUtilElements(util, scope); elements.forEach(function(element) { var 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 }); } activeUtilInstances.push(utilInstance); } }); } } function findUtil(name) { return registeredUtils.find(function(util) { return util.name === name; }); } function _findUtilElements(util, scope) { if (scope && scope.matches(util.selector)) { return [scope]; } return Array.from(scope.querySelectorAll(util.selector)); } function _findUtilIndex(name) { return registeredUtils.findIndex(function(util) { return util.name === name; }); } function _destroyUtilInstances(name) { activeUtilInstances .map(function(util, index) { return { util: util, index: index, }; }).filter(function(activeUtil) { // find utils instances to destroy return activeUtil.util.name === name; }).forEach(function(activeUtil) { // destroy util instance activeUtil.util.destroy(); delete activeUtilInstances[activeUtil.index]; }); // get rid of now empty array slots activeUtilInstances = activeUtilInstances.filter(function(util) { return !!util; }) } // public API return { register: registerUtil, deregister: deregisterUtil, setupAll: setupAllUtils, setup: setupUtil, find: findUtil, } })(); document.addEventListener('DOMContentLoaded', function() { window.UtilRegistry.setupAll(); }); })();