UNPKG

soma.js

Version:

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

1 lines 19.4 kB
/* soma.js - v2.1.4 - 2015-12-11 - http://somajs.github.io/somajs - http://www.soundstep.com */!function(infuse){"use strict";function contains(arr,value){for(var i=arr.length;i--;)if(arr[i]===value)return!0;return!1}infuse.version="1.0.0";var FN_ARGS=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,FN_ARG_SPLIT=/,/,FN_ARG=/^\s*(_?)(\S+?)\1\s*$/,STRIP_COMMENTS=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;infuse.errors={MAPPING_BAD_PROP:"[Error infuse.Injector.mapClass/mapValue] the first parameter is invalid, a string is expected",MAPPING_BAD_VALUE:"[Error infuse.Injector.mapClass/mapValue] the second parameter is invalid, it can't null or undefined, with property: ",MAPPING_BAD_CLASS:"[Error infuse.Injector.mapClass/mapValue] the second parameter is invalid, a function is expected, with property: ",MAPPING_BAD_SINGLETON:"[Error infuse.Injector.mapClass] the third parameter is invalid, a boolean is expected, with property: ",MAPPING_ALREADY_EXISTS:"[Error infuse.Injector.mapClass/mapValue] this mapping already exists, with property: ",CREATE_INSTANCE_INVALID_PARAM:"[Error infuse.Injector.createInstance] invalid parameter, a function is expected",NO_MAPPING_FOUND:"[Error infuse.Injector.getInstance] no mapping found",INJECT_INSTANCE_IN_ITSELF_PROPERTY:"[Error infuse.Injector.getInjectedValue] A matching property has been found in the target, you can't inject an instance in itself",INJECT_INSTANCE_IN_ITSELF_CONSTRUCTOR:"[Error infuse.Injector.getInjectedValue] A matching constructor parameter has been found in the target, you can't inject an instance in itself",DEPENDENCIES_MISSING_IN_STRICT_MODE:'[Error infuse.Injector.getDependencies] An "inject" property (array) that describes the dependencies is missing in strict mode.'};var MappingVO=function(prop,value,cl,singleton){this.prop=prop,this.value=value,this.cl=cl,this.singleton=singleton||!1},validateProp=function(prop){if("string"!=typeof prop)throw new Error(infuse.errors.MAPPING_BAD_PROP)},validateValue=function(prop,val){if(void 0===val||null===val)throw new Error(infuse.errors.MAPPING_BAD_VALUE+prop)},validateClass=function(prop,val){if("function"!=typeof val)throw new Error(infuse.errors.MAPPING_BAD_CLASS+prop)},validateBooleanSingleton=function(prop,singleton){if("boolean"!=typeof singleton)throw new Error(infuse.errors.MAPPING_BAD_SINGLETON+prop)},validateConstructorInjectionLoop=function(name,cl){var params=infuse.getDependencies(cl);if(contains(params,name))throw new Error(infuse.errors.INJECT_INSTANCE_IN_ITSELF_CONSTRUCTOR)},validatePropertyInjectionLoop=function(name,target){if(target.hasOwnProperty(name))throw new Error(infuse.errors.INJECT_INSTANCE_IN_ITSELF_PROPERTY)};infuse.Injector=function(){this.mappings={},this.parent=null,this.strictMode=!1},infuse.getDependencies=function(cl){function extractName(all,underscore,name){args.push(name)}var deps,args=[];cl.hasOwnProperty("inject")&&"[object Array]"===Object.prototype.toString.call(cl.inject)&&cl.inject.length>0&&(deps=cl.inject);for(var clStr=cl.toString().replace(STRIP_COMMENTS,""),argsFlat=clStr.match(FN_ARGS),spl=argsFlat[1].split(FN_ARG_SPLIT),i=0,l=spl.length;l>i;i++){var arg=deps&&deps[i]?deps[i]:spl[i];arg.replace(FN_ARG,extractName)}return args},infuse.Injector.prototype={createChild:function(){var injector=new infuse.Injector;return injector.parent=this,injector.strictMode=this.strictMode,injector},getMappingVo:function(prop){return this.mappings?this.mappings[prop]?this.mappings[prop]:this.parent?this.parent.getMappingVo(prop):null:null},mapValue:function(prop,val){if(this.mappings[prop])throw new Error(infuse.errors.MAPPING_ALREADY_EXISTS+prop);return validateProp(prop),validateValue(prop,val),this.mappings[prop]=new MappingVO(prop,val,void 0,void 0),this},mapClass:function(prop,cl,singleton){if(this.mappings[prop])throw new Error(infuse.errors.MAPPING_ALREADY_EXISTS+prop);return validateProp(prop),validateClass(prop,cl),singleton&&validateBooleanSingleton(prop,singleton),this.mappings[prop]=new MappingVO(prop,null,cl,singleton),this},removeMapping:function(prop){return this.mappings[prop]=null,delete this.mappings[prop],this},hasMapping:function(prop){return!!this.mappings[prop]},hasInheritedMapping:function(prop){return!!this.getMappingVo(prop)},getMapping:function(value){for(var name in this.mappings)if(this.mappings.hasOwnProperty(name)){var vo=this.mappings[name];if(vo.value===value||vo.cl===value)return vo.prop}return void 0},getValue:function(prop){var vo=this.mappings[prop];if(!vo){if(!this.parent)throw new Error(infuse.errors.NO_MAPPING_FOUND);vo=this.parent.getMappingVo.apply(this.parent,arguments)}if(vo.cl){var args=Array.prototype.slice.call(arguments);return args[0]=vo.cl,vo.singleton?(vo.value||(vo.value=this.createInstance.apply(this,args)),vo.value):this.createInstance.apply(this,args)}return vo.value},getClass:function(prop){var vo=this.mappings[prop];if(!vo){if(!this.parent)return void 0;vo=this.parent.getMappingVo.apply(this.parent,arguments)}return vo.cl?vo.cl:void 0},instantiate:function(TargetClass){if("function"!=typeof TargetClass)throw new Error(infuse.errors.CREATE_INSTANCE_INVALID_PARAM);if(this.strictMode&&!TargetClass.hasOwnProperty("inject"))throw new Error(infuse.errors.DEPENDENCIES_MISSING_IN_STRICT_MODE);for(var args=[null],params=infuse.getDependencies(TargetClass),i=0,l=params.length;l>i;i++)if(arguments.length>i+1&&void 0!==arguments[i+1]&&null!==arguments[i+1])args.push(arguments[i+1]);else{var name=params[i],vo=this.getMappingVo(name);if(vo){var val=this.getInjectedValue(vo,name);args.push(val)}else args.push(void 0)}return new(Function.prototype.bind.apply(TargetClass,args))},inject:function(target,isParent){this.parent&&this.parent.inject(target,!0);for(var name in this.mappings)if(this.mappings.hasOwnProperty(name)){var vo=this.getMappingVo(name);(target.hasOwnProperty(vo.prop)||target.constructor&&target.constructor.prototype&&target.constructor.prototype.hasOwnProperty(vo.prop))&&(target[name]=this.getInjectedValue(vo,name))}return"function"!=typeof target.postConstruct||isParent||target.postConstruct(),this},getInjectedValue:function(vo,name){var injectee,val=vo.value;return vo.cl&&(vo.singleton?(vo.value||(validateConstructorInjectionLoop(name,vo.cl),vo.value=this.instantiate(vo.cl),injectee=vo.value),val=vo.value):(validateConstructorInjectionLoop(name,vo.cl),val=this.instantiate(vo.cl),injectee=val)),injectee&&(validatePropertyInjectionLoop(name,injectee),this.inject(injectee)),val},createInstance:function(){var instance=this.instantiate.apply(this,arguments);return this.inject(instance),instance},getValueFromClass:function(cl){for(var name in this.mappings)if(this.mappings.hasOwnProperty(name)){var vo=this.mappings[name];if(vo.cl===cl)return vo.singleton?(vo.value||(vo.value=this.createInstance.apply(this,arguments)),vo.value):this.createInstance.apply(this,arguments)}if(this.parent)return this.parent.getValueFromClass.apply(this.parent,arguments);throw new Error(infuse.errors.NO_MAPPING_FOUND)},dispose:function(){this.mappings={}}},Function.prototype.bind||(Function.prototype.bind=function(that){var target=this;if("function"!=typeof target)throw new Error("Error, you must bind a function.");var args=Array.prototype.slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F,result=target.apply(self,args.concat(Array.prototype.slice.call(arguments)));return Object(result)===result?result:self}return target.apply(that,args.concat(Array.prototype.slice.call(arguments)))};return bound}),"function"==typeof define&&"undefined"!=typeof define.amd&&define("infuse",infuse),"undefined"!=typeof module&&"undefined"!=typeof module.exports&&(module.exports=infuse),"undefined"!=typeof exports&&(exports=infuse)}(this.infuse=this.infuse||{}),function(soma){"use strict";soma.events={},soma.events.version="0.5.6",Function.prototype.bind||(Function.prototype.bind=function(that){var target=this;if("function"!=typeof target)throw new Error("Error, you must bind a function.");var args=Array.prototype.slice.call(arguments,1),bound=function(){if(this instanceof bound){var F=function(){};F.prototype=target.prototype;var self=new F,result=target.apply(self,args.concat(Array.prototype.slice.call(arguments)));return Object(result)===result?result:self}return target.apply(that,args.concat(Array.prototype.slice.call(arguments)))};return bound}),soma.Event=function(type,params,bubbles,cancelable){var e=soma.Event.createGenericEvent(type,bubbles,cancelable);return null!==params&&void 0!==params&&(e.params=params),e.isCloned=!1,e.clone=this.clone.bind(e),e.isIE9orIE10=this.isIE9orIE10,e.isDefaultPrevented=this.isDefaultPrevented,(this.isIE9orIE10()||!e.preventDefault||void 0===e.getDefaultPrevented&&void 0===e.defaultPrevented)&&(e.preventDefault=this.preventDefault.bind(e)),this.isIE9orIE10()&&(e.IE9or10PreventDefault=!1),e},soma.Event.prototype.clone=function(){var e=soma.Event.createGenericEvent(this.type,this.bubbles,this.cancelable);return e.params=this.params,e.isCloned=!0,e.clone=this.clone,e.isDefaultPrevented=this.isDefaultPrevented,e.isIE9orIE10=this.isIE9orIE10,this.isIE9orIE10()&&(e.IE9or10PreventDefault=this.IE9or10PreventDefault),e},soma.Event.prototype.preventDefault=function(){return this.cancelable?(this.isIE9orIE10()?this.IE9or10PreventDefault=!0:this.defaultPrevented=!0,this):!1},soma.Event.prototype.isDefaultPrevented=function(){return this.cancelable?this.isIE9orIE10()?this.IE9or10PreventDefault:void 0!==this.defaultPrevented?this.defaultPrevented:void 0!==this.getDefaultPrevented?this.getDefaultPrevented():!1:!1},soma.Event.createGenericEvent=function(type,bubbles,cancelable){var event;return bubbles=void 0!==bubbles?bubbles:!0,"object"==typeof document&&document.createEvent?(event=document.createEvent("Event"),event.initEvent(type,!!bubbles,!!cancelable)):"object"==typeof document&&document.createEventObject?(event=document.createEventObject(),event.type=type,event.bubbles=!!bubbles,event.cancelable=!!cancelable):event=new EventObject(type,!!bubbles,!!cancelable),event},soma.Event.prototype.isIE9orIE10=function(){return"object"!=typeof document?!1:void 0!==document.body.style.scrollbar3dLightColor&&void 0!==document.body.style.opacity||void 0!==document.body.style.msTouchAction},soma.Event.prototype.toString=function(){return"[soma.Event]"};var EventObject=function(type,bubbles,cancelable){this.type=type,this.bubbles=!!bubbles,this.cancelable=!!cancelable,this.defaultPrevented=!1,this.currentTarget=null,this.target=null};soma.EventDispatcher=function(){this.listeners=[]},soma.EventDispatcher.prototype.addEventListener=function(type,listener,priority){if(this.listeners&&type&&listener){isNaN(priority)&&(priority=0);for(var i=0;i<this.listeners.length;i++){var eventObj=this.listeners[i];if(eventObj.type===type&&eventObj.listener===listener)return}this.listeners.push({type:type,listener:listener,priority:priority,scope:this})}},soma.EventDispatcher.prototype.removeEventListener=function(type,listener){if(this.listeners&&type&&listener)for(var i=this.listeners.length;i-->0;){var eventObj=this.listeners[i];eventObj.type===type&&eventObj.listener===listener&&this.listeners.splice(i,1)}},soma.EventDispatcher.prototype.hasEventListener=function(type){if(!this.listeners||!type)return!1;for(var i=0,l=this.listeners.length;l>i;++i){var eventObj=this.listeners[i];if(eventObj.type===type)return!0}return!1},soma.EventDispatcher.prototype.dispatchEvent=function(event){if(!this.listeners||!event)throw new Error("Error in EventDispatcher (dispatchEvent), one of the parameters is null or undefined.");var i,events=[];for(i=0;i<this.listeners.length;i++){var eventObj=this.listeners[i];eventObj.type===event.type&&events.push(eventObj)}for(events.sort(function(a,b){return b.priority-a.priority}),i=0;i<events.length;i++)events[i].listener.apply(event.srcElement?event.srcElement:event.currentTarget,[event]);return!event.isDefaultPrevented()},soma.EventDispatcher.prototype.dispatch=function(type,params,bubbles,cancelable){if(!this.listeners||!type||""===type)throw new Error("Error in EventDispatcher (dispatch), one of the parameters is null or undefined.");var event=new soma.Event(type,params,bubbles,cancelable);return this.dispatchEvent(event),event},soma.EventDispatcher.prototype.dispose=function(){this.listeners=null},soma.EventDispatcher.prototype.toString=function(){return"[soma.EventDispatcher]"},"function"==typeof define&&"undefined"!=typeof define.amd&&define("soma-events",soma),"undefined"!=typeof module&&"undefined"!=typeof module.exports&&(module.exports=soma),"undefined"!=typeof exports&&(exports=soma)}(this.soma=this.soma||{}),function(soma,infuse){"use strict";soma.version="2.1.4",soma.applyProperties=function(target,extension,bindToExtension,list){if("[object Array]"===Object.prototype.toString.apply(list))for(var i=0,l=list.length;l>i;i++)(void 0===target[list[i]]||null===target[list[i]])&&(target[list[i]]=bindToExtension&&"function"==typeof extension[list[i]]?extension[list[i]].bind(extension):extension[list[i]]);else for(var prop in extension)target[prop]=bindToExtension&&"function"==typeof extension[prop]?extension[prop].bind(extension):extension[prop]},soma.augment=function(target,extension,list){if(extension.prototype&&target.prototype)if("[object Array]"===Object.prototype.toString.apply(list))for(var i=0,l=list.length;l>i;i++)target.prototype[list[i]]||(target.prototype[list[i]]=extension.prototype[list[i]]);else for(var prop in extension.prototype)target.prototype[prop]||(target.prototype[prop]=extension.prototype[prop])},soma.inherit=function(parent,obj){var Subclass;Subclass=obj&&obj.hasOwnProperty("constructor")?obj.constructor:function(){return parent.apply(this,arguments)};var Chain=function(){};return Chain.prototype=parent.prototype,Subclass.prototype=new Chain,obj&&soma.applyProperties(Subclass.prototype,obj),Subclass.prototype.constructor=Subclass,Subclass.parent=parent.prototype,Subclass.extend=function(obj){return soma.inherit(Subclass,obj)},Subclass},soma.extend=function(obj){return soma.inherit(function(){},obj)};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--)plugin===plugins[i]&&plugins.splice(i,1)},soma.Application=soma.extend({constructor:function(){function setup(){self.injector=new infuse.Injector(self.dispatcher),self.dispatcher=new soma.EventDispatcher,self.injector.mapValue("injector",self.injector),self.injector.mapValue("instance",self),self.injector.mapValue("dispatcher",self.dispatcher),self.injector.mapClass("mediators",Mediators,!0),self.mediators=self.injector.getValue("mediators"),self.injector.mapClass("commands",Commands,!0),self.commands=self.injector.getValue("commands");for(var i=0,l=plugins.length;l>i;i++)self.createPlugin(plugins[i])}var self=this;setup.bind(this)(),this.init(),this.start()},createPlugin:function(){if(0===arguments.length||!arguments[0])throw new Error("Error creating a plugin, plugin class is missing.");for(var params=infuse.getDependencies(arguments[0]),args=[arguments[0]],i=0,l=params.length;l>i;i++)args.push(this.injector.hasMapping(params[i])||this.injector.hasInheritedMapping(params[i])?this.injector.getValue(params[i]):void 0);var a=args.length-1;for(args.length;a>=0&&"undefined"==typeof args[a];a--)args.splice(a,1);for(var j=1,k=arguments.length;k>j;j++)args.push(arguments[j]);return this.injector.createInstance.apply(this.injector,args)},init:function(){},start:function(){},dispose:function(){this.injector&&(this.injector.removeMapping("injector"),this.injector.removeMapping("dispatcher"),this.injector.removeMapping("mediators"),this.injector.removeMapping("commands"),this.injector.removeMapping("instance")),this.injector&&this.injector.dispose(),this.dispatcher&&this.dispatcher.dispose(),this.mediators&&this.mediators.dispose(),this.commands&&this.commands.dispose(),this.injector=void 0,this.dispatcher=void 0,this.mediators=void 0,this.commands=void 0,this.instance=void 0}});var Mediators=soma.extend({constructor:function(){this.injector=null,this.dispatcher=null},create:function(cl,target){if(!cl||"function"!=typeof cl)throw new Error("Error creating a mediator, the first parameter must be a function.");if(void 0===target||null===target)throw new Error("Error creating a mediator, the second parameter cannot be undefined or null.");var targets=[],meds=[],targetToString=Object.prototype.toString.call(target);("[object Array]"===targetToString||"[object NodeList]"===targetToString)&&target.length>0?targets=[].concat(target):targets.push(target);for(var i=0,l=targets.length;l>i;i++){var injector=this.injector.createChild();injector.mapValue("target",targets[i]);var mediator=injector.createInstance(cl);if(1===targets.length)return mediator;meds.push(mediator)}return meds},dispose:function(){this.injector=void 0,this.dispatcher=void 0}}),Commands=soma.extend({constructor:function(){this.boundHandler=this.handler.bind(this),this.dispatcher=null,this.injector=null,this.list={}},has:function(commandName){return null!==this.list[commandName]&&void 0!==this.list[commandName]},get:function(commandName){return this.has(commandName)?this.list[commandName]:void 0},getAll:function(){var copy={};for(var cmd in this.list)this.list.hasOwnProperty(cmd)&&(copy[cmd]=this.list[cmd]);return copy},add:function(commandName,command){if("string"!=typeof commandName)throw new Error("Error adding a command, the first parameter must be a string.");if("function"!=typeof command)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){this.has(commandName)&&(this.list[commandName]=void 0,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){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")&&"function"===command.execute)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)this.list.hasOwnProperty(cmd)&&this.remove(cmd);this.boundHandler=void 0,this.dispatcher=void 0,this.injector=void 0,this.list=void 0}});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)},"function"==typeof define&&"undefined"!=typeof define.amd&&define("soma",soma),"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=soma:window.soma=soma}(this.soma=this.soma||{},this.infuse);