UNPKG

soma.js

Version:

soma.js is a javascript framework created to build scalable and maintainable applications.

246 lines (231 loc) 6.77 kB
// plugins var plugins = []; soma.plugins = soma.plugins || {}; soma.plugins.add = function(plugin) { plugins.push(plugin); }; soma.plugins.remove = function(plugin) { for (var i = plugins.length-1, l = 0; i >= l; i--) { if (plugin === plugins[i]) { plugins.splice(i, 1); } } }; // framework soma.Application = soma.extend({ constructor: function() { var self = this; function setup() { // injector self.injector = new infuse.Injector(self.dispatcher); // dispatcher self.dispatcher = new soma.EventDispatcher(); // mapping self.injector.mapValue('injector', self.injector); self.injector.mapValue('instance', self); self.injector.mapValue('dispatcher', self.dispatcher); // mediator self.injector.mapClass('mediators', Mediators, true); self.mediators = self.injector.getValue('mediators'); // commands self.injector.mapClass('commands', Commands, true); self.commands = self.injector.getValue('commands'); // plugins for (var i = 0, l = plugins.length; i < l; i++) { self.createPlugin(plugins[i]); } } setup.bind(this)(); this.init(); this.start(); }, createPlugin: function() { if (arguments.length === 0 || !arguments[0]) { throw new Error('Error creating a plugin, plugin class is missing.'); } var params = infuse.getDependencies(arguments[0]); // add plugin function var args = [arguments[0]]; // add injection mappings for (var i=0, l=params.length; i < l; i++) { if (this.injector.hasMapping(params[i]) || this.injector.hasInheritedMapping(params[i])) { args.push(this.injector.getValue(params[i])); } else { args.push(undefined); } } // trim array for (var a = args.length-1, b = args.length; a >= 0; a--) { if (typeof args[a] === 'undefined') { args.splice(a, 1); } else { break; } } // add arguments for (var j=1, k=arguments.length; j < k; j++) { args.push(arguments[j]); } return this.injector.createInstance.apply(this.injector, args); }, init: function() { }, start: function() { }, dispose: function() { // mapping if (this.injector) { this.injector.removeMapping('injector'); this.injector.removeMapping('dispatcher'); this.injector.removeMapping('mediators'); this.injector.removeMapping('commands'); this.injector.removeMapping('instance'); } // variables if (this.injector) { this.injector.dispose(); } if (this.dispatcher) { this.dispatcher.dispose(); } if (this.mediators) { this.mediators.dispose(); } if (this.commands) { this.commands.dispose(); } this.injector = undefined; this.dispatcher = undefined; this.mediators = undefined; this.commands = undefined; this.instance = undefined; } }); var Mediators = soma.extend({ constructor: function() { this.injector = null; this.dispatcher = null; }, create: function(cl, target) { if (!cl || typeof cl !== 'function') { throw new Error('Error creating a mediator, the first parameter must be a function.'); } if (target === undefined || target === null) { throw new Error('Error creating a mediator, the second parameter cannot be undefined or null.'); } var targets = []; var meds = []; var targetToString = Object.prototype.toString.call(target); if ((targetToString === '[object Array]' || targetToString === '[object NodeList]') && target.length > 0) { targets = [].concat(target); } else { targets.push(target); } for (var i= 0, l=targets.length; i<l; i++) { var injector = this.injector.createChild(); injector.mapValue('target', targets[i]); var mediator = injector.createInstance(cl); if (targets.length === 1) { return mediator; } meds.push(mediator); } return meds; }, dispose: function() { this.injector = undefined; this.dispatcher = undefined; } }); var Commands = soma.extend({ constructor: function() { this.boundHandler = this.handler.bind(this); this.dispatcher = null; this.injector = null; this.list = {}; }, has: function(commandName) { return this.list[commandName] !== null && this.list[commandName] !== undefined; }, get: function(commandName) { if (this.has(commandName)) { return this.list[commandName]; } return undefined; }, getAll: function() { var copy = {}; for (var cmd in this.list) { if (this.list.hasOwnProperty(cmd)) { copy[cmd] = this.list[cmd]; } } return copy; }, add: function(commandName, command) { if (typeof commandName !== 'string') { throw new Error('Error adding a command, the first parameter must be a string.'); } if (typeof command !== 'function') { throw new Error('Error adding a command with the name "' + command + '", the second parameter must be a function, and must contain an "execute" public method.'); } if (this.has(commandName)) { throw new Error('Error adding a command with the name: "' + commandName + '", already registered.'); } this.list[ commandName ] = command; this.addInterceptor(commandName); }, remove: function(commandName) { if (!this.has(commandName)) { return; } this.list[commandName] = undefined; delete this.list[commandName]; this.removeInterceptor(commandName); }, addInterceptor: function(commandName) { this.dispatcher.addEventListener(commandName, this.boundHandler, -Number.MAX_VALUE); }, removeInterceptor: function(commandName) { this.dispatcher.removeEventListener(commandName, this.boundHandler); }, handler: function(event) { if (event.isDefaultPrevented && !event.isDefaultPrevented()) { this.executeCommand(event); } }, executeCommand: function(event) { var commandName = event.type; if (this.has(commandName)) { var command = this.injector.createInstance(this.list[commandName]); if (!command.hasOwnProperty('execute') && command['execute'] === 'function') { throw new Error('Error in ' + this + ' Command ' + command + ' must contain an execute public method.'); } command.execute(event); } }, dispose: function() { for (var cmd in this.list) { if (this.list.hasOwnProperty(cmd)) { this.remove(cmd); } } this.boundHandler = undefined; this.dispatcher = undefined; this.injector = undefined; this.list = undefined; } }); // event extend utils soma.EventDispatcher.extend = function (obj) { return soma.inherit(soma.EventDispatcher, obj); }; soma.Event.extend = function (obj) { return soma.inherit(soma.Event, obj); }; infuse.Injector.extend = function(obj) { return soma.inherit(infuse.Injector, obj); };