Comparing version 1.0.1 to 1.0.2
@@ -5,4 +5,13 @@ (function(global) { | ||
$scope.title = "App works!"; | ||
$scope.buttonClicked = function(text) { | ||
console.log(text); | ||
}; | ||
setTimeout(function() { | ||
$scope.title = "Hello World!"; | ||
_update(); | ||
}, 3000) | ||
}); | ||
})(Function('return this')()); |
@@ -134,4 +134,4 @@ (function(global) { | ||
if(!injectable.compare(this.values[i-skipped], getterValue)) { | ||
this.values[i-skipped] = getterValue; | ||
if(injectable.justModify && this.self) { | ||
this.values[i-skipped] = getterValue; | ||
injectable.modifier(this, getterValue); | ||
@@ -142,3 +142,3 @@ } else { | ||
} | ||
} else if(Array.isArray(getterValue.array)) { | ||
} else if(getterValue && Array.isArray(getterValue.array)) { | ||
break; | ||
@@ -195,3 +195,3 @@ } | ||
if(newNode.isComponent()) { | ||
newNode.comp = global.Core.Bootstrap(newNode.self); | ||
newNode.comp = global.Core.Bootstrap(newNode.self, newNode.inputs); | ||
newNode.self = newNode.comp.nodeTree.self; | ||
@@ -245,5 +245,10 @@ } | ||
CompNode.prototype.isComponent = function() { | ||
return this.self && this.self.nodeType === 1 && this.viewNode.controller; | ||
return this.self && this.self.nodeType === 1 && this.viewNode.controller && !this.iterator; | ||
}; | ||
CompNode.prototype.bootstrap = function() { | ||
this.comp = global.Core.Bootstrap(this.self, this.inputs); | ||
this.self = this.comp.nodeTree.self; | ||
}; | ||
global.Base = global.Base || {}; | ||
@@ -270,2 +275,10 @@ global.Base.CompNode = CompNode; | ||
Component.prototype.getInput = function(name) { | ||
if(this.inputs && this.inputs.hasOwnProperty(name)) | ||
return this.inputs[name]; | ||
else { | ||
throw { message: "Input " + name + " doesn't exist." }; | ||
} | ||
}; | ||
global.Base = global.Base || {}; | ||
@@ -283,3 +296,3 @@ global.Base.Component = Component; | ||
Controller.prototype.generateComponent = function(el) { | ||
Controller.prototype.generateComponent = function(el, inputs) { | ||
// Creating new scope object | ||
@@ -291,2 +304,11 @@ var $scope = {}; | ||
// If inputs assigning them to comp | ||
if(typeof inputs === 'object') | ||
comp.inputs = inputs; | ||
// Provide the $scope with a function to retrieve inputs | ||
$scope.getInput = function(name) { | ||
$scope[name] = this.getInput(name); | ||
}.bind(comp); | ||
// Running the constructor | ||
@@ -307,2 +329,4 @@ this.constructor.call(this, $scope, comp.update.bind(comp)); | ||
var TAG = "[Injectable]"; | ||
var Injectable = function(name, options) { | ||
@@ -312,3 +336,7 @@ this.name = name; | ||
// Modifier function: | ||
this.modifier = options.modifier.bind(this); | ||
try { | ||
this.modifier = options.modifier.bind(this); | ||
} catch(err) { | ||
console.error(TAG, this.name + ": No modifier set."); | ||
} | ||
@@ -327,3 +355,2 @@ // Overriding prototype functions | ||
Injectable.prototype.getter = function(statement, $scope) { | ||
var TAG = "[Injectable:Getter]"; | ||
var result; | ||
@@ -349,2 +376,56 @@ try { | ||
var Model = function(name, initFunc) { | ||
this.name = name; | ||
this.initFunc = initFunc; | ||
// Default events | ||
this.events = {}; | ||
this.getData(); | ||
}; | ||
Model.prototype.getData = function() { | ||
if(typeof this.initFunc !== 'function') { | ||
throw { message: this.name + ": Couldn't initialize the model (initFunc err)" }; | ||
} else { | ||
this.initFunc(function(data) { | ||
this.setData(data); | ||
}.bind(this)); | ||
} | ||
}; | ||
Model.prototype.setData = function(data, /*optional:*/ eventName) { | ||
this.data = data; | ||
// If eventName isn't specified default to 'setData'. | ||
this.emit(eventName || 'setData', data); | ||
}; | ||
Model.prototype.emit = function(event, data) { | ||
if(Array.isArray(this.events[event])) { | ||
for(var i = 0; i < this.events[event].length; i++) { | ||
this.events[event][i](data); | ||
} | ||
} | ||
}; | ||
Model.prototype.subscribe = function(event, listener) { | ||
if(!this.events[event]) | ||
this.events[event] = []; | ||
this.events[event].push(listener); | ||
return { | ||
unsubscribe: function(listener) { | ||
this.events.splice(this.events.indexOf(listener), 1); | ||
}.bind(this, listener) | ||
}; | ||
}; | ||
global.Base = global.Base || {}; | ||
global.Base.Model = Model; | ||
})(Function('return this')()); | ||
(function(global) { | ||
var viewOptions = global.Config.viewOptions; | ||
@@ -488,2 +569,3 @@ | ||
compNode.appendChild(childNode); | ||
if(childNode.isComponent()) childNode.bootstrap(); | ||
} | ||
@@ -506,9 +588,5 @@ | ||
generated = viewNode.children[i].generate($scope, node); | ||
generated.parent = node; | ||
node.appendChild(generated); | ||
if(generated.isComponent()) { | ||
generated.comp = global.Core.Bootstrap(generated.self); | ||
generated.self = generated.comp.nodeTree.self; | ||
} | ||
if(generated.isComponent()) generated.bootstrap(); | ||
} | ||
@@ -524,7 +602,7 @@ } | ||
var Bootstrap = function(el) { | ||
var Bootstrap = function(el, inputs) { | ||
if(el.nodeType === 1) { | ||
var controller = getControllerFromEl(el); | ||
if(controller instanceof global.Base.Controller) { | ||
return controller.generateComponent(el); | ||
return controller.generateComponent(el, inputs); | ||
} else | ||
@@ -553,2 +631,3 @@ throw { message: "Controller " + el.getAttribute('controller') + " not found." }; | ||
var Injectables = {}; | ||
var Models = {}; | ||
@@ -563,2 +642,5 @@ global.App = { | ||
}, | ||
getModel: function(name) { | ||
return Models[name]; | ||
}, | ||
@@ -568,3 +650,4 @@ // Generators | ||
Controller: generateController, | ||
Injectable: generateInjectable | ||
Injectable: generateInjectable, | ||
Model: createModel | ||
}; | ||
@@ -610,6 +693,56 @@ | ||
function createModel(name, initFunc) { | ||
var TAG = "[Model]"; | ||
try { | ||
Models[name] = new global.Base.Model(name, initFunc); | ||
} catch(err) { | ||
console.error(TAG, err.message); | ||
} | ||
} | ||
})(Function('return this')()); | ||
(function(global) { | ||
global.App.Injectable('bind-class', { | ||
// Options | ||
justModify: true, | ||
// Functions | ||
getter: function(statement, $scope) { | ||
var classes = global.Utils.String.toDictionary(statement), | ||
value; | ||
try { | ||
with($scope) { | ||
for(var className in classes) if(classes.hasOwnProperty(className)) { | ||
value = eval(classes[className]); | ||
classes[className] = !!value; | ||
} | ||
} | ||
} catch(err) { | ||
throw { message: this.name + ": " + err.message }; | ||
} | ||
return classes; | ||
}, | ||
modifier: function(compNode, value) { | ||
for(var className in value) if(value.hasOwnProperty(className)) { | ||
value[className] ? | ||
compNode.self.classList.add(className) : | ||
compNode.self.classList.remove(className); | ||
} | ||
} | ||
}); | ||
})(Function('return this')()); | ||
(function(global) { | ||
global.App.Injectable('bind-if', { | ||
getter: function(statement, $scope) { | ||
var result; | ||
try { | ||
with($scope) { result = eval(statement); } | ||
} catch(err) { | ||
throw this.name + ": Couldn't evaluate '" + statement + "'."; | ||
} | ||
return !!result; | ||
}, | ||
modifier: function(compNode, value) { | ||
@@ -625,2 +758,83 @@ if(!value) { | ||
global.App.Injectable('bind-events', { | ||
getter: function(statement, $scope) { | ||
var events = global.Utils.String.toDictionary(statement), | ||
matches, funcName, variables; | ||
for(var event in events) if(events.hasOwnProperty(event)) { | ||
var regEx = new RegExp("^(.+)\\((.*)\\)$"); | ||
matches = events[event].match(regEx); | ||
funcName = matches[1]; | ||
variables = matches[2].split(','); | ||
for(var i = 0; i < variables.length; i++) { | ||
variables[i] = $scope[variables[i]]; | ||
} | ||
events[event] = function(funcName, variables) { | ||
var func; | ||
try { | ||
with($scope) { | ||
func = eval(funcName); | ||
} | ||
func.apply(undefined, variables); | ||
} catch(err) { | ||
throw (this.name + ": " + err.message) | ||
} | ||
}.bind(this, funcName, variables); | ||
} | ||
return events; | ||
}, | ||
modifier: function(compNode, value) { | ||
for(var event in value) if(value.hasOwnProperty(event)) { | ||
compNode.self.addEventListener(event, function(callback, e) { | ||
if(e && e.preventDefault) e.preventDefault(); | ||
try { | ||
callback(); | ||
} catch(err) { | ||
console.error('[Injectable]', err); | ||
} | ||
}.bind(this, value[event])); | ||
} | ||
}, | ||
compare: function(oldVal, newVal) { | ||
return true; | ||
} | ||
}); | ||
})(Function('return this')()); | ||
(function(global) { | ||
global.App.Injectable('input', { | ||
getter: function(statement, $scope) { | ||
var inputs = global.Utils.String.toDictionary(statement); | ||
try { | ||
for(var input in inputs) if(inputs.hasOwnProperty(input)) { | ||
with($scope) { | ||
inputs[input] = eval(inputs[input]); | ||
} | ||
} | ||
} catch(err) { | ||
throw { message: this.name + ": " + err.message }; | ||
} | ||
return inputs; | ||
}, | ||
modifier: function(compNode, value) { | ||
compNode.inputs = value; | ||
}, | ||
compare: function(oldVal, newVal) { | ||
var equals = true; | ||
for(var input in newVal) if(newVal.hasOwnProperty(input)) { | ||
if(newVal[input] !== oldVal[input]) { | ||
equals = false; | ||
break; | ||
} | ||
} | ||
return equals; | ||
} | ||
}); | ||
})(Function('return this')()); | ||
(function(global) { | ||
global.App.Injectable('bind-for', { | ||
@@ -627,0 +841,0 @@ getter: function(statement, $scope) { |
@@ -1,1 +0,1 @@ | ||
Function("return this")().Config={viewOptions:{templatesFolder:"app"}},function(e){var t={get:function(e,t,r){if("object"==typeof t){var i="?";for(var n in t)t.hasOwnProperty(n)&&(i+=n+"="+t[n]+"&");e+=i}var o=new XMLHttpRequest;o.open("GET",e,!0),o.onreadystatechange=function(){200===o.status&&4===o.readyState&&r(JSON.parse(o.responseText))},o.send()}};e.Utils=e.Utils||{},e.Utils.Http=t}(Function("return this")()),function(e){var t=function(){this.listeners=[],this.lastMessage=void 0};t.prototype={subscribe:function(e){if("function"==typeof e)return this.listeners.push(e),{unsubscribe:this.unsubscribe.bind(this,e)};console.error(e,"is not a function. Cannot subscribe to Observable.")},unsubscribe:function(e){for(var t=this.listeners.length-1;t>=0;t--)this.listeners[t]===e&&this.listeners.splice(t,1)},next:function(e){this.listeners.forEach(function(t){t(e)}),this.lastMessage=e}},e.Utils=e.Utils||{},e.Utils.Observable=t}(Function("return this")()),function(e){e.Utils=e.Utils||{},e.Utils.String={toKeyValueArray:function(e,t){"string"!=typeof t&&(t=",");var r,i=[];return e.split(t).forEach(function(e){r=/([\w-]+): *(.+)/g.exec(e.trim()),i.push({key:r[1],value:r[2]})}),i},toDictionary:function(e,t){"string"!=typeof t&&(t=",");var r,i={};return e.split(t).forEach(function(e){r=/([\w-]+): *(.+)/g.exec(e.trim()),i[r[1]]=r[2]}),i}}}(Function("return this")()),function(e){var t=function(e,t){this.viewNode=e,this.self=e.self.cloneNode(!1),Array.isArray(t)&&(this.values=t),this.children=[]};t.prototype.compare=function(r){var i=!1;if(Array.isArray(this.viewNode.directives))for(var n,o,s=this.viewNode.directives,a=0,l=0;l<s.length;l++)if(s[l])if(n=s[l].injectable,o=n.getter(s[l].statement,r),n.compare(this.values[l-a],o)){if(Array.isArray(o.array))break}else{if(!n.justModify||!this.self){i=!0;break}this.values[l-a]=o,n.modifier(this,o)}else a++;if(i){var c=this.viewNode.generate(r);this.iteratorValue&&(c.iteratorValue=this.iteratorValue),this.parent.replaceChild(c,this),c.isComponent()&&(c.comp=e.Core.Bootstrap(c.self),c.self=c.comp.nodeTree.self)}else if(this.multipleNodes){var h,f=this.viewNode,u=this.iterator,p=r[u.varName],d=f.directives[l],v=l;for(f.directives[v]=void 0,l=0;l<u.array.length;l++)r[u.varName]=u.array[l],this.children[l]instanceof t?(this.children[l].compare(r),this.children[l].iteratorValue=u.array[l]):((h=f.generate(r)).iteratorValue=u.array[l],this.appendChild(h));r[u.varName]=p,f.directives[v]=d}else this.children.forEach(function(e){e.compare(r)})},t.prototype.appendChild=function(e){this.children.push(e),e.parent=this,e.self&&this.self.appendChild(e.self)},t.prototype.replaceChild=function(e,t){if(e.parent=t.parent,e.self&&t.self)this.self.replaceChild(e.self,t.self),this.children.splice(this.children.indexOf(t),1,e);else if(e.self&&!t.self){var r=this.children.indexOf(t);if(r>=0){this.children.splice(r,1,e);for(var i;!i&&r<this.children.length-1;)this.children[++r].self&&(i=this.children[r].self);i?i.parentNode.insertBefore(e.self,i):this.self.appendChild(e.self)}else console.error("CompNode: replaceChild failed, 2nd parameter is not a child of this node.")}else!e.self&&t.self&&this.removeChild(t)},t.prototype.removeChild=function(e){this.self.removeChild(e.self),e.self=void 0,e.children.splice(0,e.children.length)},t.prototype.isComponent=function(){return this.self&&1===this.self.nodeType&&this.viewNode.controller},e.Base=e.Base||{},e.Base.CompNode=t}(Function("return this")()),function(e){var t=function(e,t){this.el=e,this.$scope=t};t.prototype.setView=function(e){this.el.parentNode.replaceChild(e.self,this.el),this.nodeTree=e,this.el=e.self},t.prototype.update=function(){this.nodeTree.compare(this.$scope)},e.Base=e.Base||{},e.Base.Component=t}(Function("return this")()),function(e){var t=function(e,t,r){this.name=e,this.view=t,this.constructor=r};t.prototype.generateComponent=function(t){var r={},i=new e.Base.Component(t,r);return this.constructor.call(this,r,i.update.bind(i)),i.setView(this.view.generate(r)),i},e.Base=e.Base||{},e.Base.Controller=t}(Function("return this")()),function(global){var Injectable=function(e,t){this.name=e,this.modifier=t.modifier.bind(this),"function"==typeof t.getter&&(this.getter=t.getter.bind(this)),"function"==typeof t.compare&&(this.compare=t.compare.bind(this)),this.keepAttribute=!!t.keepAttribute,this.justModify=!!t.justModify};Injectable.prototype.getter=function(statement,$scope){var TAG="[Injectable:Getter]",result;try{with($scope)result=eval(statement)}catch(e){console.error(TAG,this.name+":","Couldn't evaluate '"+statement+"'.")}return result},Injectable.prototype.compare=function(e,t){if(e===t)return!0},global.Base=global.Base||{},global.Base.Injectable=Injectable}(Function("return this")()),function(e){var t=e.Config.viewOptions,r=function(e,t){this.name=e,this.loadTemplate(t),this.buildNodeTree()};r.prototype.loadTemplate=function(e){var r=t.templatesFolder+"/"+e+this.name+".html";r=r.replace(/\/\//g,"/"),this.templateSrc=function(e){var t=new XMLHttpRequest;return t.open("GET",e,!1),t.send(),t.responseText}(r)},r.prototype.buildNodeTree=function(){function t(r){for(var i,n=new e.Base.ViewNode(r),o=0;o<r.childNodes.length;o++)(i=t(r.childNodes[o])).parent=n,n.children.push(i);return n}var r=document.createElement("temp");r.innerHTML=this.templateSrc;for(var i=new e.Base.ViewNode(document.createElement(this.name)),n=0;n<r.childNodes.length;n++)i.children.push(t(r.childNodes[n]));this.nodeTree=i},r.prototype.generate=function(t){for(var r=new e.Base.CompNode(this.nodeTree),i=0;i<this.nodeTree.children.length;i++)r.appendChild(this.nodeTree.children[i].generate(t,r));return r},e.Base=e.Base||{},e.Base.View=r}(Function("return this")()),function(e){var t=function(e){this.self=e,this.children=[],this.parseNode()};t.prototype.parseNode=function(){var t=this.self.attributes;if(t&&t.length>0)for(var r=0;r<t.length;r++)if("controller"===t[r].name)this.controller=t[r].value;else{var i=e.App.getInjectable(t[r].name);i instanceof e.Base.Injectable&&(Array.isArray(this.directives)||(this.directives=[]),this.directives.push({injectable:i,statement:t[r].value}),i.keepAttribute||(this.self.removeAttribute(t[r].name),r--))}},t.prototype.generate=function(t){var r=new e.Base.CompNode(this);if(Array.isArray(this.directives)){var i,n;for(r.values=[],n=0;n<this.directives.length&&r.self;n++)if(this.directives[n]){var o=(i=this.directives[n]).injectable.getter(i.statement,t);if(i.injectable.modifier(r,o),r.values.push(o),r.multipleNodes)break}}if(r.self)if(r.multipleNodes){var s,a=r.iterator.array,l=t[r.iterator.varName],c=this.directives[n],h=n;this.directives[n]=void 0;for(n=0;n<a.length;n++)t[r.iterator.varName]=a[n],(s=this.generate(t)).iteratorValue=a[n],s.self&&0,r.appendChild(s);t[r.iterator.varName]=l,this.directives[h]=c}else!function(r,i){for(var n,o=0;o<r.children.length;o++)(n=r.children[o].generate(t,i)).parent=i,i.appendChild(n),n.isComponent()&&(n.comp=e.Core.Bootstrap(n.self),n.self=n.comp.nodeTree.self)}(this,r);return r},e.Base=e.Base||{},e.Base.ViewNode=t}(Function("return this")()),function(e){function t(t){var r=t.getAttribute("controller");if("string"==typeof r){var i=e.App.getController(r);if(i instanceof e.Base.Controller)return i}}e.Core=e.Core||{},e.Core.Bootstrap=function(r){if(1===r.nodeType){var i=t(r);if(i instanceof e.Base.Controller)return i.generateComponent(r);throw{message:"Controller "+r.getAttribute("controller")+" not found."}}throw{message:"Cannot bootstrap a non-element object."}}}(Function("return this")()),function(e){var t={},r={};e.App={getController:function(e){return t[e]},getInjectable:function(e){return r[e]},Bootstrap:function(t){var r="[Bootstrap]",i=document.querySelector('*[controller="'+t+'"]');if(i&&1===i.nodeType){try{var n=e.Core.Bootstrap(i)}catch(e){console.error(r,e.message)}return n}console.error(r,"Could not find placeholder for '"+t+"'.")},Controller:function(r,i,n){try{var o=new e.Base.View(r,i);t[r]=new e.Base.Controller(r,o,n)}catch(e){console.error("[Controller]",e.message)}},Injectable:function(t,i){try{r[t]=new e.Base.Injectable(t,i)}catch(e){console.error("[Injectable]",e.message)}}}}(Function("return this")()),Function("return this")().App.Injectable("bind-if",{modifier:function(e,t){t||(e.self=void 0)}}),function(global){global.App.Injectable("bind-for",{getter:function(statement,$scope){for(var words=statement.split(" "),result={},w=0;w<words.length;w++)if("in"===words[w]&&w>0&&w<words.length-1){try{with($scope)result.array=eval(words[w+1])}catch(e){throw e}result.varName=words[w-1]}return result},compare:function(e,t){return e.array===t.array},modifier:function(e,t){e.self=document.createElement("iterator"),e.multipleNodes=!0,e.iterator=t}})}(Function("return this")()),Function("return this")().App.Injectable("bind-value",{justModify:!0,modifier:function(e,t){e.self.innerHTML=t}}); | ||
Function("return this")().Config={viewOptions:{templatesFolder:"app"}},function(e){var t={get:function(e,t,n){if("object"==typeof t){var i="?";for(var r in t)t.hasOwnProperty(r)&&(i+=r+"="+t[r]+"&");e+=i}var s=new XMLHttpRequest;s.open("GET",e,!0),s.onreadystatechange=function(){200===s.status&&4===s.readyState&&n(JSON.parse(s.responseText))},s.send()}};e.Utils=e.Utils||{},e.Utils.Http=t}(Function("return this")()),function(e){var t=function(){this.listeners=[],this.lastMessage=void 0};t.prototype={subscribe:function(e){if("function"==typeof e)return this.listeners.push(e),{unsubscribe:this.unsubscribe.bind(this,e)};console.error(e,"is not a function. Cannot subscribe to Observable.")},unsubscribe:function(e){for(var t=this.listeners.length-1;t>=0;t--)this.listeners[t]===e&&this.listeners.splice(t,1)},next:function(e){this.listeners.forEach(function(t){t(e)}),this.lastMessage=e}},e.Utils=e.Utils||{},e.Utils.Observable=t}(Function("return this")()),function(e){e.Utils=e.Utils||{},e.Utils.String={toKeyValueArray:function(e,t){"string"!=typeof t&&(t=",");var n,i=[];return e.split(t).forEach(function(e){n=/([\w-]+): *(.+)/g.exec(e.trim()),i.push({key:n[1],value:n[2]})}),i},toDictionary:function(e,t){"string"!=typeof t&&(t=",");var n,i={};return e.split(t).forEach(function(e){n=/([\w-]+): *(.+)/g.exec(e.trim()),i[n[1]]=n[2]}),i}}}(Function("return this")()),function(e){var t=function(e,t){this.viewNode=e,this.self=e.self.cloneNode(!1),Array.isArray(t)&&(this.values=t),this.children=[]};t.prototype.compare=function(n){var i=!1;if(Array.isArray(this.viewNode.directives))for(var r,s,o=this.viewNode.directives,a=0,l=0;l<o.length;l++)if(o[l])if(r=o[l].injectable,s=r.getter(o[l].statement,n),r.compare(this.values[l-a],s)){if(s&&Array.isArray(s.array))break}else{if(this.values[l-a]=s,!r.justModify||!this.self){i=!0;break}r.modifier(this,s)}else a++;if(i){var c=this.viewNode.generate(n);this.iteratorValue&&(c.iteratorValue=this.iteratorValue),this.parent.replaceChild(c,this),c.isComponent()&&(c.comp=e.Core.Bootstrap(c.self,c.inputs),c.self=c.comp.nodeTree.self)}else if(this.multipleNodes){var u,h=this.viewNode,f=this.iterator,p=n[f.varName],d=h.directives[l],v=l;for(h.directives[v]=void 0,l=0;l<f.array.length;l++)n[f.varName]=f.array[l],this.children[l]instanceof t?(this.children[l].compare(n),this.children[l].iteratorValue=f.array[l]):((u=h.generate(n)).iteratorValue=f.array[l],this.appendChild(u));n[f.varName]=p,h.directives[v]=d}else this.children.forEach(function(e){e.compare(n)})},t.prototype.appendChild=function(e){this.children.push(e),e.parent=this,e.self&&this.self.appendChild(e.self)},t.prototype.replaceChild=function(e,t){if(e.parent=t.parent,e.self&&t.self)this.self.replaceChild(e.self,t.self),this.children.splice(this.children.indexOf(t),1,e);else if(e.self&&!t.self){var n=this.children.indexOf(t);if(n>=0){this.children.splice(n,1,e);for(var i;!i&&n<this.children.length-1;)this.children[++n].self&&(i=this.children[n].self);i?i.parentNode.insertBefore(e.self,i):this.self.appendChild(e.self)}else console.error("CompNode: replaceChild failed, 2nd parameter is not a child of this node.")}else!e.self&&t.self&&this.removeChild(t)},t.prototype.removeChild=function(e){this.self.removeChild(e.self),e.self=void 0,e.children.splice(0,e.children.length)},t.prototype.isComponent=function(){return this.self&&1===this.self.nodeType&&this.viewNode.controller&&!this.iterator},t.prototype.bootstrap=function(){this.comp=e.Core.Bootstrap(this.self,this.inputs),this.self=this.comp.nodeTree.self},e.Base=e.Base||{},e.Base.CompNode=t}(Function("return this")()),function(e){var t=function(e,t){this.el=e,this.$scope=t};t.prototype.setView=function(e){this.el.parentNode.replaceChild(e.self,this.el),this.nodeTree=e,this.el=e.self},t.prototype.update=function(){this.nodeTree.compare(this.$scope)},t.prototype.getInput=function(e){if(this.inputs&&this.inputs.hasOwnProperty(e))return this.inputs[e];throw{message:"Input "+e+" doesn't exist."}},e.Base=e.Base||{},e.Base.Component=t}(Function("return this")()),function(e){var t=function(e,t,n){this.name=e,this.view=t,this.constructor=n};t.prototype.generateComponent=function(t,n){var i={},r=new e.Base.Component(t,i);return"object"==typeof n&&(r.inputs=n),i.getInput=function(e){i[e]=this.getInput(e)}.bind(r),this.constructor.call(this,i,r.update.bind(r)),r.setView(this.view.generate(i)),r},e.Base=e.Base||{},e.Base.Controller=t}(Function("return this")()),function(global){var TAG="[Injectable]",Injectable=function(e,t){this.name=e;try{this.modifier=t.modifier.bind(this)}catch(e){console.error(TAG,this.name+": No modifier set.")}"function"==typeof t.getter&&(this.getter=t.getter.bind(this)),"function"==typeof t.compare&&(this.compare=t.compare.bind(this)),this.keepAttribute=!!t.keepAttribute,this.justModify=!!t.justModify};Injectable.prototype.getter=function(statement,$scope){var result;try{with($scope)result=eval(statement)}catch(e){console.error(TAG,this.name+":","Couldn't evaluate '"+statement+"'.")}return result},Injectable.prototype.compare=function(e,t){if(e===t)return!0},global.Base=global.Base||{},global.Base.Injectable=Injectable}(Function("return this")()),function(e){var t=function(e,t){this.name=e,this.initFunc=t,this.events={},this.getData()};t.prototype.getData=function(){if("function"!=typeof this.initFunc)throw{message:this.name+": Couldn't initialize the model (initFunc err)"};this.initFunc(function(e){this.setData(e)}.bind(this))},t.prototype.setData=function(e,t){this.data=e,this.emit(t||"setData",e)},t.prototype.emit=function(e,t){if(Array.isArray(this.events[e]))for(var n=0;n<this.events[e].length;n++)this.events[e][n](t)},t.prototype.subscribe=function(e,t){return this.events[e]||(this.events[e]=[]),this.events[e].push(t),{unsubscribe:function(e){this.events.splice(this.events.indexOf(e),1)}.bind(this,t)}},e.Base=e.Base||{},e.Base.Model=t}(Function("return this")()),function(e){var t=e.Config.viewOptions,n=function(e,t){this.name=e,this.loadTemplate(t),this.buildNodeTree()};n.prototype.loadTemplate=function(e){var n=t.templatesFolder+"/"+e+this.name+".html";n=n.replace(/\/\//g,"/"),this.templateSrc=function(e){var t=new XMLHttpRequest;return t.open("GET",e,!1),t.send(),t.responseText}(n)},n.prototype.buildNodeTree=function(){function t(n){for(var i,r=new e.Base.ViewNode(n),s=0;s<n.childNodes.length;s++)(i=t(n.childNodes[s])).parent=r,r.children.push(i);return r}var n=document.createElement("temp");n.innerHTML=this.templateSrc;for(var i=new e.Base.ViewNode(document.createElement(this.name)),r=0;r<n.childNodes.length;r++)i.children.push(t(n.childNodes[r]));this.nodeTree=i},n.prototype.generate=function(t){for(var n=new e.Base.CompNode(this.nodeTree),i=0;i<this.nodeTree.children.length;i++)n.appendChild(this.nodeTree.children[i].generate(t,n));return n},e.Base=e.Base||{},e.Base.View=n}(Function("return this")()),function(e){var t=function(e){this.self=e,this.children=[],this.parseNode()};t.prototype.parseNode=function(){var t=this.self.attributes;if(t&&t.length>0)for(var n=0;n<t.length;n++)if("controller"===t[n].name)this.controller=t[n].value;else{var i=e.App.getInjectable(t[n].name);i instanceof e.Base.Injectable&&(Array.isArray(this.directives)||(this.directives=[]),this.directives.push({injectable:i,statement:t[n].value}),i.keepAttribute||(this.self.removeAttribute(t[n].name),n--))}},t.prototype.generate=function(t){var n=new e.Base.CompNode(this);if(Array.isArray(this.directives)){var i,r;for(n.values=[],r=0;r<this.directives.length&&n.self;r++)if(this.directives[r]){var s=(i=this.directives[r]).injectable.getter(i.statement,t);if(i.injectable.modifier(n,s),n.values.push(s),n.multipleNodes)break}}if(n.self)if(n.multipleNodes){var o,a=n.iterator.array,l=t[n.iterator.varName],c=this.directives[r],u=r;this.directives[r]=void 0;for(r=0;r<a.length;r++)t[n.iterator.varName]=a[r],(o=this.generate(t)).iteratorValue=a[r],o.self&&0,n.appendChild(o),o.isComponent()&&o.bootstrap();t[n.iterator.varName]=l,this.directives[u]=c}else!function(e,n){for(var i,r=0;r<e.children.length;r++)i=e.children[r].generate(t,n),n.appendChild(i),i.isComponent()&&i.bootstrap()}(this,n);return n},e.Base=e.Base||{},e.Base.ViewNode=t}(Function("return this")()),function(e){function t(t){var n=t.getAttribute("controller");if("string"==typeof n){var i=e.App.getController(n);if(i instanceof e.Base.Controller)return i}}e.Core=e.Core||{},e.Core.Bootstrap=function(n,i){if(1===n.nodeType){var r=t(n);if(r instanceof e.Base.Controller)return r.generateComponent(n,i);throw{message:"Controller "+n.getAttribute("controller")+" not found."}}throw{message:"Cannot bootstrap a non-element object."}}}(Function("return this")()),function(e){var t={},n={},i={};e.App={getController:function(e){return t[e]},getInjectable:function(e){return n[e]},getModel:function(e){return i[e]},Bootstrap:function(t){var n="[Bootstrap]",i=document.querySelector('*[controller="'+t+'"]');if(i&&1===i.nodeType){try{var r=e.Core.Bootstrap(i)}catch(e){console.error(n,e.message)}return r}console.error(n,"Could not find placeholder for '"+t+"'.")},Controller:function(n,i,r){try{var s=new e.Base.View(n,i);t[n]=new e.Base.Controller(n,s,r)}catch(e){console.error("[Controller]",e.message)}},Injectable:function(t,i){try{n[t]=new e.Base.Injectable(t,i)}catch(e){console.error("[Injectable]",e.message)}},Model:function(t,n){try{i[t]=new e.Base.Model(t,n)}catch(e){console.error("[Model]",e.message)}}}}(Function("return this")()),function(global){global.App.Injectable("bind-class",{justModify:!0,getter:function(statement,$scope){var classes=global.Utils.String.toDictionary(statement),value;try{with($scope)for(var className in classes)classes.hasOwnProperty(className)&&(value=eval(classes[className]),classes[className]=!!value)}catch(e){throw{message:this.name+": "+e.message}}return classes},modifier:function(e,t){for(var n in t)t.hasOwnProperty(n)&&(t[n]?e.self.classList.add(n):e.self.classList.remove(n))}})}(Function("return this")()),function(global){global.App.Injectable("bind-if",{getter:function(statement,$scope){var result;try{with($scope)result=eval(statement)}catch(e){throw this.name+": Couldn't evaluate '"+statement+"'."}return!!result},modifier:function(e,t){t||(e.self=void 0)}})}(Function("return this")()),function(global){global.App.Injectable("bind-events",{getter:function(statement,$scope){var events=global.Utils.String.toDictionary(statement),matches,funcName,variables;for(var event in events)if(events.hasOwnProperty(event)){var regEx=new RegExp("^(.+)\\((.*)\\)$");matches=events[event].match(regEx),funcName=matches[1],variables=matches[2].split(",");for(var i=0;i<variables.length;i++)variables[i]=$scope[variables[i]];events[event]=function(funcName,variables){var func;try{with($scope)func=eval(funcName);func.apply(void 0,variables)}catch(e){throw this.name+": "+e.message}}.bind(this,funcName,variables)}return events},modifier:function(e,t){for(var n in t)t.hasOwnProperty(n)&&e.self.addEventListener(n,function(e,t){t&&t.preventDefault&&t.preventDefault();try{e()}catch(e){console.error("[Injectable]",e)}}.bind(this,t[n]))},compare:function(e,t){return!0}})}(Function("return this")()),function(global){global.App.Injectable("input",{getter:function(statement,$scope){var inputs=global.Utils.String.toDictionary(statement);try{for(var input in inputs)if(inputs.hasOwnProperty(input))with($scope)inputs[input]=eval(inputs[input])}catch(e){throw{message:this.name+": "+e.message}}return inputs},modifier:function(e,t){e.inputs=t},compare:function(e,t){var n=!0;for(var i in t)if(t.hasOwnProperty(i)&&t[i]!==e[i]){n=!1;break}return n}})}(Function("return this")()),function(global){global.App.Injectable("bind-for",{getter:function(statement,$scope){for(var words=statement.split(" "),result={},w=0;w<words.length;w++)if("in"===words[w]&&w>0&&w<words.length-1){try{with($scope)result.array=eval(words[w+1])}catch(e){throw e}result.varName=words[w-1]}return result},compare:function(e,t){return e.array===t.array},modifier:function(e,t){e.self=document.createElement("iterator"),e.multipleNodes=!0,e.iterator=t}})}(Function("return this")()),Function("return this")().App.Injectable("bind-value",{justModify:!0,modifier:function(e,t){e.self.innerHTML=t}}); |
@@ -7,23 +7,47 @@ var gulp = require('gulp'); | ||
var SOURCE = [ | ||
// Framework code | ||
'./js/config/*.js', | ||
'./js/utils/*.js', | ||
'./js/base/*.js', | ||
'./js/core/*.js', | ||
'./js/App.js', | ||
var LibraryConfig = { | ||
SOURCE: [ | ||
// Framework code | ||
'./js/config/*.js', | ||
'./js/utils/*.js', | ||
'./js/base/*.js', | ||
'./js/core/*.js', | ||
'./js/App.js', | ||
// Built-ins | ||
'./js/builtin/**/*.js' | ||
]; | ||
var DEST_NAME = "mvc-lite"; | ||
// Built-ins | ||
'./js/builtin/**/*.js' | ||
], | ||
DEST_NAME: 'mvc-lite' | ||
}; | ||
var AppConfig = { | ||
SOURCE: [ | ||
'./app/**/*.js', | ||
], | ||
DEST_NAME: 'app' | ||
}; | ||
var DEST_PATH = "./dist/"; | ||
gulp.task('compile', function() { | ||
return gulp.src(SOURCE) | ||
.pipe(concat(DEST_NAME + '.js')) | ||
gulp.task('compile-mvc', function() { | ||
return gulp.src(LibraryConfig.SOURCE) | ||
.pipe(concat(LibraryConfig.DEST_NAME + '.js')) | ||
.pipe(gulp.dest(DEST_PATH)) | ||
.pipe(rename(DEST_NAME + '.min.js')) | ||
.pipe(rename(LibraryConfig.DEST_NAME + '.min.js')) | ||
.pipe(uglify()) | ||
.pipe(gulp.dest(DEST_PATH)); | ||
}); | ||
gulp.task('compile-app', function() { | ||
return gulp.src(AppConfig.SOURCE) | ||
.pipe(concat(AppConfig.DEST_NAME + '.js')) | ||
.pipe(gulp.dest(DEST_PATH)) | ||
.pipe(rename(AppConfig.DEST_NAME + '.min.js')) | ||
.pipe(uglify()) | ||
.pipe(gulp.dest(DEST_PATH)); | ||
}); | ||
gulp.task('watch', function() { | ||
gulp.watch('js/**/*.js', ['compile-mvc']); | ||
gulp.watch('app/**/*.js', ['compile-app']); | ||
}); |
@@ -5,2 +5,3 @@ (function(global) { | ||
var Injectables = {}; | ||
var Models = {}; | ||
@@ -15,2 +16,5 @@ global.App = { | ||
}, | ||
getModel: function(name) { | ||
return Models[name]; | ||
}, | ||
@@ -20,3 +24,4 @@ // Generators | ||
Controller: generateController, | ||
Injectable: generateInjectable | ||
Injectable: generateInjectable, | ||
Model: createModel | ||
}; | ||
@@ -62,2 +67,11 @@ | ||
function createModel(name, initFunc) { | ||
var TAG = "[Model]"; | ||
try { | ||
Models[name] = new global.Base.Model(name, initFunc); | ||
} catch(err) { | ||
console.error(TAG, err.message); | ||
} | ||
} | ||
})(Function('return this')()); |
@@ -23,4 +23,4 @@ (function(global) { | ||
if(!injectable.compare(this.values[i-skipped], getterValue)) { | ||
this.values[i-skipped] = getterValue; | ||
if(injectable.justModify && this.self) { | ||
this.values[i-skipped] = getterValue; | ||
injectable.modifier(this, getterValue); | ||
@@ -31,3 +31,3 @@ } else { | ||
} | ||
} else if(Array.isArray(getterValue.array)) { | ||
} else if(getterValue && Array.isArray(getterValue.array)) { | ||
break; | ||
@@ -84,3 +84,3 @@ } | ||
if(newNode.isComponent()) { | ||
newNode.comp = global.Core.Bootstrap(newNode.self); | ||
newNode.comp = global.Core.Bootstrap(newNode.self, newNode.inputs); | ||
newNode.self = newNode.comp.nodeTree.self; | ||
@@ -134,5 +134,10 @@ } | ||
CompNode.prototype.isComponent = function() { | ||
return this.self && this.self.nodeType === 1 && this.viewNode.controller; | ||
return this.self && this.self.nodeType === 1 && this.viewNode.controller && !this.iterator; | ||
}; | ||
CompNode.prototype.bootstrap = function() { | ||
this.comp = global.Core.Bootstrap(this.self, this.inputs); | ||
this.self = this.comp.nodeTree.self; | ||
}; | ||
global.Base = global.Base || {}; | ||
@@ -139,0 +144,0 @@ global.Base.CompNode = CompNode; |
@@ -18,2 +18,10 @@ (function(global) { | ||
Component.prototype.getInput = function(name) { | ||
if(this.inputs && this.inputs.hasOwnProperty(name)) | ||
return this.inputs[name]; | ||
else { | ||
throw { message: "Input " + name + " doesn't exist." }; | ||
} | ||
}; | ||
global.Base = global.Base || {}; | ||
@@ -20,0 +28,0 @@ global.Base.Component = Component; |
@@ -9,3 +9,3 @@ (function(global) { | ||
Controller.prototype.generateComponent = function(el) { | ||
Controller.prototype.generateComponent = function(el, inputs) { | ||
// Creating new scope object | ||
@@ -17,2 +17,11 @@ var $scope = {}; | ||
// If inputs assigning them to comp | ||
if(typeof inputs === 'object') | ||
comp.inputs = inputs; | ||
// Provide the $scope with a function to retrieve inputs | ||
$scope.getInput = function(name) { | ||
$scope[name] = this.getInput(name); | ||
}.bind(comp); | ||
// Running the constructor | ||
@@ -19,0 +28,0 @@ this.constructor.call(this, $scope, comp.update.bind(comp)); |
(function(global) { | ||
var TAG = "[Injectable]"; | ||
var Injectable = function(name, options) { | ||
@@ -7,3 +9,7 @@ this.name = name; | ||
// Modifier function: | ||
this.modifier = options.modifier.bind(this); | ||
try { | ||
this.modifier = options.modifier.bind(this); | ||
} catch(err) { | ||
console.error(TAG, this.name + ": No modifier set."); | ||
} | ||
@@ -22,3 +28,2 @@ // Overriding prototype functions | ||
Injectable.prototype.getter = function(statement, $scope) { | ||
var TAG = "[Injectable:Getter]"; | ||
var result; | ||
@@ -25,0 +30,0 @@ try { |
@@ -80,2 +80,3 @@ (function(global) { | ||
compNode.appendChild(childNode); | ||
if(childNode.isComponent()) childNode.bootstrap(); | ||
} | ||
@@ -98,9 +99,5 @@ | ||
generated = viewNode.children[i].generate($scope, node); | ||
generated.parent = node; | ||
node.appendChild(generated); | ||
if(generated.isComponent()) { | ||
generated.comp = global.Core.Bootstrap(generated.self); | ||
generated.self = generated.comp.nodeTree.self; | ||
} | ||
if(generated.isComponent()) generated.bootstrap(); | ||
} | ||
@@ -107,0 +104,0 @@ } |
(function(global) { | ||
global.App.Injectable('bind-if', { | ||
getter: function(statement, $scope) { | ||
var result; | ||
try { | ||
with($scope) { result = eval(statement); } | ||
} catch(err) { | ||
throw this.name + ": Couldn't evaluate '" + statement + "'."; | ||
} | ||
return !!result; | ||
}, | ||
modifier: function(compNode, value) { | ||
@@ -5,0 +14,0 @@ if(!value) { |
(function(global) { | ||
var Bootstrap = function(el) { | ||
var Bootstrap = function(el, inputs) { | ||
if(el.nodeType === 1) { | ||
var controller = getControllerFromEl(el); | ||
if(controller instanceof global.Base.Controller) { | ||
return controller.generateComponent(el); | ||
return controller.generateComponent(el, inputs); | ||
} else | ||
@@ -9,0 +9,0 @@ throw { message: "Controller " + el.getAttribute('controller') + " not found." }; |
(function(global) { | ||
var app = global.App.Bootstrap('app'); | ||
global.App.Bootstrap('app'); | ||
})(Function('return this')()); |
{ | ||
"name": "mvc-lite", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "Lite MVC Library using pure EcmaScript5", | ||
@@ -5,0 +5,0 @@ "main": "main.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
77094
34
1546
1
67