fradrive/frontend/src/services/util-registry/util-registry.js

139 lines
3.6 KiB
JavaScript

const DEBUG_MODE = /localhost/.test(window.location.href) ? 2 : 0;
export class UtilRegistry {
_registeredUtils = [];
_activeUtilInstances = [];
_appInstance;
/**
* 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
*
* optional util properties:
* start: Function | utils start 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
*
* (optional) start function for registering event 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 });
}
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);
}
}
setApp(appInstance) {
this._appInstance = appInstance;
}
initAll(scope) {
const setupInstances = this._registeredUtils.map((util) => this.setup(util, scope)).flat();
setupInstances
.filter((instance) => instance && typeof instance.start === 'function')
.forEach((instance) => this.start(instance));
if (DEBUG_MODE > 1) {
console.info('initialized js util instances:');
console.table(setupInstances);
}
return setupInstances;
}
setup(util, scope = document.body) {
if (DEBUG_MODE > 2) {
console.log('setting up util', { util });
}
let instances = [];
if (util) {
const elements = this._findUtilElements(util, scope);
elements.forEach((element) => {
let utilInstance = null;
try {
utilInstance = new util(element, this._appInstance);
} catch(err) {
if (DEBUG_MODE > 0) {
console.error('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 });
}
instances.push(utilInstance);
}
});
}
this._activeUtilInstances.push(...instances);
return instances.map(instance => ({ scope: scope, util: util, ...instance }));
}
start(instance) {
instance.start();
}
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);
}
}