/** * Base class for components and views in ludoJS. This class extends * Mootools Events class. * @namepace ludo * @class ludo.Core * @param {Object} config * @param {String} config.name Name * @param {Boolean} config.stateful When set to true, properties set in statefulProperties can be saved to the browsers local storage. * @param {Array} config.statefulProperties Array of stateful properties. */ ludo.Core = new Class({ Extends:Events, id:undefined, name:undefined, module:undefined, submodule:undefined, /* Reference to a specific controller for the component. The default way is to set useController to true and create a controller in the same namespace as your component. Then that controller will be registered as controller for the component. The 'controller' property can be used to override this and assign a specific controller @memberof ludo.Core.prototype If you create your own controller by extending ludo.controller.Controller, you can control several views by adding events in the addView(component) method. attribute {Object} controller example controller : 'idOfController' example controller : { type : 'controller.MyController' } A Controller can also be a singleton. */ controller:undefined, /* * Find controller and register this component to controller * attribute {Boolean} userController * default false * @memberof ludo.Core.prototype */ useController:false, stateful:false, statefulProperties:undefined, dependency:{}, /* TODO figure out this Array of add-ons config objects Add-ons are special components which operates on a view. "parentComponent" is sent to the constructor of all add-ons and can be saved for later reference. @config plugins @type {Array} @memberof ludo.Core.prototype @example new ludo.View({<br> plugins : [ { type : 'plugins.Sound' }] }); Add event @example this.getParent().addEvent('someEvent', this.playSound.bind(this)); Which will cause the plugin to play a sound when "someEvent" is fired by parent component. */ plugins:undefined, initialize:function (config) { config = config || {}; this.lifeCycle(config); this.applyplugins(); }, lifeCycle:function(config){ this.__construct(config); this.ludoEvents(); }, applyplugins:function(){ if (this.plugins) { for (var i = 0; i < this.plugins.length; i++) { this.plugins[i].parentComponent = this; this.plugins[i] = this.createDependency('plugins' + i, this.plugins[i]); } } }, __construct:function(config){ this.setConfigParams(config, ['url','name','controller','module','submodule','stateful','id','useController','plugins']); // TODO new code 2016 - custom functions if(config != undefined){ for(var key in config){ if(config.hasOwnProperty(key) && $.type(config[key]) == "function" && this[key] == undefined){ this[key] = config[key].bind(this); } } } if (this.stateful && this.statefulProperties && this.id) { config = this.appendPropertiesFromStore(config); this.addEvent('state', this.saveStatefulProperties.bind(this)); } if (config.listeners !== undefined)this.addEvents(config.listeners); if (this.controller !== undefined)ludo.controllerManager.assignSpecificControllerFor(this.controller, this); if (this.module || this.useController)ludo.controllerManager.registerComponent(this); if(!this.id)this.id = 'ludo-' + String.uniqueID(); ludo.CmpMgr.registerComponent(this); }, setConfigParams:function(config, keys){ for(var i=0;i<keys.length;i++){ if(config[keys[i]] !== undefined)this[keys[i]] = config[keys[i]]; } }, ludoEvents:function(){}, appendPropertiesFromStore:function (config) { var c = ludo.getLocalStorage().get(this.getKeyForLocalStore()); if (c) { var keys = this.statefulProperties; for (var i = 0; i < keys.length; i++) { config[keys[i]] = c[keys[i]]; } } return config; }, saveStatefulProperties:function () { var obj = {}; var keys = this.statefulProperties; for (var i = 0; i < keys.length; i++) { obj[keys[i]] = this[keys[i]]; } ludo.getLocalStorage().save(this.getKeyForLocalStore(), obj); }, getKeyForLocalStore:function () { return 'state_' + this.id; }, /** Return id of component @function getId @return String id @memberof ludo.Core.prototype */ getId:function () { return this.id; }, /** Get name of component and form element @function getName @return String name @memberof ludo.Core.prototype */ getName:function () { return this.name; }, // TODO refactor this to use only this.url or global url. getUrl:function () { if (this.url) { return this.url; } if (this.component) { return this.component.getUrl(); } if (this.applyTo) { return this.applyTo.getUrl(); } if (this.parentComponent) { return this.parentComponent.getUrl(); } return undefined; }, getEventEl:function () { return Browser['ie'] ? $(document.documentElement) : $(window); }, isConfigObject:function (obj) { return obj.initialize === undefined; }, NS:undefined, /** * Returns component type minus class name, example: * type: calendar.View will return "calendar" * @function getNamespace * @return {String} namespace * @memberof ludo.Core.prototype */ getNamespace:function () { if (this.NS == undefined) { if (this.type) { var tokens = this.type.split(/\./g); tokens.pop(); this.NS = tokens.join('.'); } else { this.NS = ''; } } return this.NS; }, hasController:function () { return this.controller ? true : false; }, getController:function () { return this.controller; }, setController:function (controller) { this.controller = controller; this.addControllerEvents(); }, /** Add events to controller @function addControllerEvents @return void @memberof ludo.Core.prototype @example this.controller.addEvent('eventname', this.methodName.bind(this)); */ addControllerEvents:function () { }, getModule:function () { return this.getInheritedProperty('module'); }, getSubModule:function () { return this.getInheritedProperty('submodule'); }, getInheritedProperty:function (key) { return this[key] !== undefined ? this[key] : this.parentComponent ? this.parentComponent.getInheritedProperty(key) : undefined; }, /** Save state for stateful components and views. States are stored in localStorage which is supported by all major browsers(IE from version 8). @function saveState @memberof ludo.Core.prototype @return void @example myComponent.saveState(); OR @example this.fireEvent('state'); which does the same. */ saveState:function () { this.fireEvent('state'); }, createDependency:function(key, config){ this.dependency[key] = ludo.util.isLudoJSConfig(config) ? ludo._new(config) : config; return this.dependency[key]; }, hasDependency:function(key){ return this.dependency[key] ? true : false; }, getDependency:function(key, config){ if(this.dependency[key])return this.dependency[key]; return this.createDependency(key, config); }, relayEvents:function(obj, events){ for(var i=0;i<events.length;i++){ obj.on(events[i], this.getRelayFn(events[i]).bind(this)); } }, getRelayFn:function(event){ return function(){ this.fireEvent.call(this, event, Array.prototype.slice.call(arguments)); }.bind(this); } });