fradrive/static/js/services/utilRegistry.js
2019-04-21 21:15:13 +02:00

148 lines
3.8 KiB
JavaScript

(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();
});
})();