(function() { 'use strict'; window.utils = window.utils || {}; var registeredSetupListeners = {}; var activeInstances = {}; /** * setup function to initiate a util (utilName) on a scope (sope) with options (options). * * Utils need to be defined as property of `window.utils` and need to accept a scope and (optionally) options. * Example: `window.utils.autoSubmit = function(scope, options) { ... };` */ window.utils.setup = function(utilName, scope, options) { if (!utilName || !scope) { return; } options = options || {}; var utilInstance; // i18n if (window.I18N) { options.i18n = window.I18N; } if (activeInstances[utilName]) { var instanceWithSameScope = activeInstances[utilName] .filter(function(instance) { return !!instance; }) .find(function(instance) { return instance.scope === scope; }); var isAlreadySetup = !!instanceWithSameScope; if (isAlreadySetup) { console.warn('Trying to setup a JS utility that\'s already been set up', { utility: utilName, scope, options }); } } function setup() { var listener = function(event) { if (event.detail.targetUtil !== utilName) { return false; } if (options.setupFunction) { utilInstance = options.setupFunction(scope, options); } else { var util = window.utils[utilName]; if (!util) { throw new Error('"' + utilName + '" is not a known js util'); } utilInstance = util(scope, options); } if (utilInstance) { if (activeInstances[utilName] && Array.isArray(activeInstances[utilName])) { activeInstances[utilName].push(utilInstance); } else { activeInstances[utilName] = [ utilInstance ]; } } }; if (registeredSetupListeners[utilName] && Array.isArray(registeredSetupListeners[utilName])) { window.utils.teardown(utilName); } if (!registeredSetupListeners[utilName] || Array.isArray(registeredSetupListeners[utilName])) { registeredSetupListeners[utilName] = []; } registeredSetupListeners[utilName].push(listener); document.addEventListener('setup', listener); document.dispatchEvent(new CustomEvent('setup', { detail: { targetUtil: utilName, module: 'none' }, bubbles: true, cancelable: true, })); } setup(); return utilInstance; }; window.utils.teardown = function(utilName, destroy) { if (registeredSetupListeners[utilName]) { registeredSetupListeners[utilName] .filter(function(listener) { return !!listener }) .forEach(function(listener) { document.removeEventListener('setup', listener); }); delete registeredSetupListeners[utilName]; } if (destroy === true && activeInstances[utilName]) { activeInstances[utilName] .filter(function(instance) { return !!instance }) .forEach(function(instance) { instance.destroy(); }); delete activeInstances[utilName]; } } })();