UNPKG

minsky-kit

Version:
223 lines (182 loc) 5.9 kB
// imports import _pullAll from 'lodash/pull'; import _clone from 'lodash/clone'; import EventDispatcher from './EventDispatcher'; // private statics // class definition export default class InstanceManager extends EventDispatcher { // constructor constructor (args = {}, objectName = 'InstanceManager') { args.debug = args.debug || false; // super super(args, objectName); // set properties this._instances = {}; } // methods add (key, ...instances) { // process instances array instances = processInstancesParam(instances); // ensure key's existence if (!this._instances[key]) this._instances[key] = []; // get list by key const list = this._instances[key]; // push given instances to list list.push(...instances); } addOnce (key, ...instances) { // process instances array instances = processInstancesParam(instances); // get list const list = this._instances[key]; if (list) { instances.forEach((instance) => { if (list.indexOf(instance) > -1) list.push(instance); }); } else { this.add(key, ...instances); } } initAdd (key, Class, params = {}) { this.add(key, new Class(params)); } initAddOnce (key, Class, params = {}) { if (!this.get(key).length) { this.add(key, Class, params); } } initAddComponent (key, Class, itemList, params = {}, $parent = null) { // ensure parent if (!$parent) $parent = document; // make sure its if (typeof itemList === 'string') { itemList = $parent.querySelectorAll(itemList); } // convert into an array list if (!Array.isArray(itemList)) { if (itemList.length !== undefined) { itemList = Array.from(itemList); } else { itemList = [itemList]; } } // init all & keep itemList.forEach(($item) => { // Process params const processedParam = ((typeof params === 'function') ? params($item) : _clone(params)); // provide $el if not yet set (could be overridden externally by adding a value) if (processedParam.$el === undefined) processedParam.$el = $item; // addInit instance this.initAdd(key, Class, processedParam); }); } get (key) { return this._instances[key] || []; } run (keys, prop, ...values) { // process key parameter keys = processKeys(keys); // run over all given keys keys.forEach((key) => { // grab list const list = this._instances[key]; // loop over list if it exists & apply if (list) { switch (true) { case typeof prop === 'function': list.forEach((instance) => { prop(instance, ...values); }); break; case typeof prop === 'object': list.forEach((instance) => { Object.keys(prop).forEach((k) => { assignValueToProp(instance, k, prop[k]); }); }); break; default: list.forEach((instance) => { assignValueToProp(instance, prop, ...values); }); } } }); } runDispatchers (keys, event, data = {}, process = null) { // shortcut to keep things tidy and readable in classes this.run(keys, 'dispatch', event, data, process); } clear (key) { if (this._instances[key]) this._instances[key].length = 0; } remove (keys, ...instances) { // process instances array keys = processKeys(keys); instances = processInstancesParam(instances); keys.forEach((key) => { // get list const list = this._instances[key]; // find & remove instance from list if (list) { if (!instances.length) { list.length = 0; } else if (instances.length) { _pullAll(list, instances); } } }); } destroy (keys) { // process keys keys = processKeys(keys); // destroy instances if (keys && keys.length) { this.run(keys, 'destroy'); this.remove(keys); } // full destroy else { // clear instances Object.keys(this._instances).forEach((list) => { list.length = 0; }); this._instances = null; // super destroy super.destroy(); } } // getters & setters get instances () { // shallow copy return { ...this._instances }; } } // Utils function processInstancesParam (instances) { if (!Array.isArray(instances)) { instances = [instances]; } else if (instances.length === 1 && Array.isArray(instances[0])) { instances = instances[0]; } return instances; } function processKeys (keys) { if (!Array.isArray(keys)) keys = [keys]; return keys; } function assignValueToProp (instance, prop, ...values) { const currentValue = instance[prop]; if (typeof currentValue === 'function') { instance[prop](...values); } else { // should always be just 1 in this case instance[prop] = values[0]; } } // Event handlers