Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

docs update, bumping to 0.1.3

  • Loading branch information...
commit 72c0467d83048b23e49ed3f56e0c1b6be6f61939 1 parent 55e4336
@arturadib authored
View
15 ChangeLog
@@ -1,3 +1,18 @@
+2012.9.3, Version 0.1.3
+
+* Added event bubbling (Pindi Albert)
+
+* Added multi-event binding (Pindi Albert)
+
+* Default input type is "text" (Tristan Slominski)
+
+* .set() fires model change event when reset is true (Tristan Slominski)
+
+* Accept data-bind events in any order (Tristan Slominski)
+
+* Documentation updates
+
+
2011.12.17, Version 0.1.2
* New data-bind notation: equal sign (Tristan Slominski)
View
2  docs/README.md
@@ -17,4 +17,4 @@ On Mac OS X, you can do an `$ easy_install pip`, then:
+ `$ pip install markdown pygments` (sudo)
+ `$ brew install jsmin`
-Then do a `$ make`. This should generate all the necessary production files (`index.html`, etc).
+Then do a `$ make docs`. This should generate all the necessary production files (`index.html`, etc).
View
2  docs/VERSION
@@ -1 +1 @@
-0.1.2 (Dec 17, 2011)
+0.1.3 (Sep 3, 2012)
View
29 docs/_gallery.md
@@ -1,14 +1,27 @@
-## [The Wall](http://thewall.agilityjs.com)
+# Gallery
-_The Wall is a minimal Twitter clone, where everyone can post anonymously to a virtual "wall". It illustrates most features offered by Agility, including server-side persistence._
+The websites and apps below use Agility.js in production. If you would like to add your startup/site here, [let us know!](http://twitter.com/agilityjs)
-+ Demo: [http://thewall.agilityjs.com](http://thewall.agilityjs.com)
-+ Full source: [https://github.com/arturadib/thewall/blob/master/public/app.js](https://github.com/arturadib/thewall/blob/master/public/app.js)
-+ Screenshot:
-![Screenshot](gallery/thewall.png)
+## [cheaphotels.co.uk](http://cheaphotels.co.uk)
+
+Cheap Hotels is an online search engine and deal finder for hotels across the globe.
+
+![Screenshot](gallery/cheaphotels.png)
+
+
+
+## [OpDots.com](http://opdots.com)
+OpDots is the "see everything" dashboard for your enterprise data.
-### User submissions
+![Screenshot](gallery/opdots.png)
+
+
+
+## [The Wall](http://thewall.agilityjs.com)
+
+The Wall is a minimal Twitter clone, where everyone can post anonymously to a virtual "wall". It illustrates most features offered by Agility, including server-side persistence.
+
+![Screenshot](gallery/thewall.png)
-Have you created an awesome project that showcases Agility's capabilities? [Fork this site](https://github.com/arturadib/agility/tree/gh-pages), add a brief description of your project, and send a pull request. We'd love to see what you can do with Agility!
View
BIN  docs/agility-start.zip
Binary file not shown
View
27 docs/agility-start/agility.min.js
@@ -18,16 +18,18 @@ else if(typeof obj[attr1]==='object'){for(var attr2 in obj[attr1]){var proxied2=
obj[attr1]=proxied;}}};util.reverseEvents=function(obj,eventType){var events=$(obj).data('events');if(events!==undefined&&events[eventType]!==undefined){var reverseEvents=[];for(var e in events[eventType]){if(!events[eventType].hasOwnProperty(e))continue;reverseEvents.unshift(events[eventType][e]);}
events[eventType]=reverseEvents;}};util.size=function(obj){var size=0,key;for(key in obj){size++;}
return size;};util.extendController=function(object){for(var controllerName in object.controller){(function(){var matches,extend,eventName,previousHandler,currentHandler,newHandler;if(typeof object.controller[controllerName]==='function'){matches=controllerName.match(/^(\~)*(.+)/);extend=matches[1];eventName=matches[2];if(!extend)return;previousHandler=object.controller[eventName]?(object.controller[eventName]._preProxy||object.controller[eventName]):undefined;currentHandler=object.controller[controllerName];newHandler=function(){if(previousHandler)previousHandler.apply(this,arguments);if(currentHandler)currentHandler.apply(this,arguments);};object.controller[eventName]=newHandler;delete object.controller[controllerName];}})();}};defaultPrototype={_agility:true,_container:{_insertObject:function(obj,selector,method){var self=this;if(!util.isAgility(obj)){throw"agility.js: append argument is not an agility object";}
-this._container.children[obj._id]=obj;this.trigger(method,[obj,selector]);obj.bind('destroy',function(event,id){self._container.remove(id);});return this;},append:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'append');},prepend:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'prepend');},after:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'after');},before:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'before');},remove:function(id){delete this._container.children[id];this.trigger('remove',id);return this;},each:function(fn){$.each(this._container.children,fn);return this;},empty:function(){this.each(function(){this.destroy();});return this;},size:function(){return util.size(this._container.children);}},_events:{parseEventStr:function(eventStr){var eventObj={type:eventStr},spacePos=eventStr.search(/\s/);if(spacePos>-1){eventObj.type=eventStr.substr(0,spacePos);eventObj.selector=eventStr.substr(spacePos+1);}
+this._container.children[obj._id]=obj;this.trigger(method,[obj,selector]);obj._parent=this;obj.bind('destroy',function(event,id){self._container.remove(id);});return this;},append:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'append');},prepend:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'prepend');},after:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'after');},before:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'before');},remove:function(id){delete this._container.children[id];this.trigger('remove',id);return this;},each:function(fn){$.each(this._container.children,fn);return this;},empty:function(){this.each(function(){this.destroy();});return this;},size:function(){return util.size(this._container.children);}},_events:{parseEventStr:function(eventStr){var eventObj={type:eventStr},spacePos=eventStr.search(/\s/);if(spacePos>-1){eventObj.type=eventStr.substr(0,spacePos);eventObj.selector=eventStr.substr(spacePos+1);}
return eventObj;},bind:function(eventStr,fn){var eventObj=this._events.parseEventStr(eventStr);if(eventObj.selector){if(eventObj.selector===ROOT_SELECTOR){this.view.$().bind(eventObj.type,fn);}
else{this.view.$().delegate(eventObj.selector,eventObj.type,fn);}}
else{$(this._events.data).bind(eventObj.type,fn);}
return this;},trigger:function(eventStr,params){var eventObj=this._events.parseEventStr(eventStr);if(eventObj.selector){if(eventObj.selector===ROOT_SELECTOR){this.view.$().trigger(eventObj.type,params);}
else{this.view.$().find(eventObj.selector).trigger(eventObj.type,params);}}
-else{$(this._events.data).trigger('_'+eventObj.type,params);util.reverseEvents(this._events.data,'pre:'+eventObj.type);$(this._events.data).trigger('pre:'+eventObj.type,params);util.reverseEvents(this._events.data,'pre:'+eventObj.type);$(this._events.data).trigger(eventObj.type,params);$(this._events.data).trigger('post:'+eventObj.type,params);}
-return this;}},model:{set:function(arg,params){var self=this;var modified=[];if(typeof arg==='object'){if(params&&params.reset){this.model._data=$.extend({},arg);}
+else{$(this._events.data).trigger('_'+eventObj.type,params);util.reverseEvents(this._events.data,'pre:'+eventObj.type);$(this._events.data).trigger('pre:'+eventObj.type,params);util.reverseEvents(this._events.data,'pre:'+eventObj.type);$(this._events.data).trigger(eventObj.type,params);if(this.parent())
+this.parent().trigger((eventObj.type.match(/^child:/)?'':'child:')+eventObj.type,params);$(this._events.data).trigger('post:'+eventObj.type,params);}
+return this;}},model:{set:function(arg,params){var self=this;var modified=[];if(typeof arg==='object'){var _clone=false;if(params&&params.reset){_clone=this.model._data;this.model._data=$.extend({},arg);}
else{$.extend(this.model._data,arg);}
-for(var key in arg){modified.push(key);}}
+for(var key in arg){delete _clone[key];modified.push(key);}
+for(key in _clone){modified.push(key);}}
else{throw"agility.js: unknown argument type in model.set()";}
if(params&&params.silent===true)return this;this.trigger('change');$.each(modified,function(index,val){self.trigger('change:'+val);});return this;},get:function(arg){if(arg===undefined){return this.model._data;}
if(typeof arg==='string'){return this.model._data[arg];}
@@ -35,13 +37,14 @@ throw'agility.js: unknown argument for getter';},reset:function(){this.model.set
if(this.view.$root.size()===0){this.view.$root=$(this.view.format);}
else{this.view.$root.html($(this.view.format).html());}
if(this.view.$root.size()===0){throw'agility.js: could not generate html from format';}
-return this;},_parseBindStr:function(str){var obj={key:null,attr:[]},pairs=str.split(','),regex=/([a-zA-Z0-9_\-]+)(?:[\s=]+([a-zA-Z0-9_\-]+))?/,matched;if(pairs.length>0){matched=pairs[0].match(regex);if(matched){if(typeof(matched[2])==="undefined"||matched[2]===""){obj.key=matched[1];}else{obj.attr.push({attr:matched[1],attrVar:matched[2]});}}
-if(pairs.length>1){for(var i=1;i<pairs.length;i++){matched=pairs[i].match(regex);if(matched){if(typeof(matched[2])!=="undefined"){obj.attr.push({attr:matched[1],attrVar:matched[2]});}}}}}
-return obj;},bindings:function(){var self=this;var $rootNode=this.view.$().filter('[data-bind]');var $childNodes=this.view.$('[data-bind]');var createAttributePairClosure=function(bindData,node,i){var attrPair=bindData.attr[i];return function(){node.attr(attrPair.attr,self.model.get(attrPair.attrVar));};};$rootNode.add($childNodes).each(function(){var $node=$(this);var bindData=self.view._parseBindStr($node.data('bind'));var bindAttributesOneWay=function(){if(bindData.attr){for(var i=0;i<bindData.attr.length;i++){self.bind('_change:'+bindData.attr[i].attrVar,createAttributePairClosure(bindData,$node,i));}}};if($node.is('input[type="checkbox"]')){self.bind('_change:'+bindData.key,function(){$node.prop("checked",self.model.get(bindData.key));});$node.change(function(){var obj={};obj[bindData.key]=$(this).prop("checked");self.model.set(obj);});bindAttributesOneWay();}
+return this;},_parseBindStr:function(str){var obj={key:null,attr:[]},pairs=str.split(','),regex=/([a-zA-Z0-9_\-]+)(?:[\s=]+([a-zA-Z0-9_\-]+))?/,keyAssigned=false,matched;if(pairs.length>0){for(var i=0;i<pairs.length;i++){matched=pairs[i].match(regex);if(matched){if(typeof(matched[2])==="undefined"||matched[2]===""){if(keyAssigned){throw new Error("You may specify only one key ("+
+keyAssigned+" has already been specified in data-bind="+
+str+")");}else{keyAssigned=matched[1];obj.key=matched[1];}}else{obj.attr.push({attr:matched[1],attrVar:matched[2]});}}}}
+return obj;},bindings:function(){var self=this;var $rootNode=this.view.$().filter('[data-bind]');var $childNodes=this.view.$('[data-bind]');var createAttributePairClosure=function(bindData,node,i){var attrPair=bindData.attr[i];return function(){node.attr(attrPair.attr,self.model.get(attrPair.attrVar));};};$rootNode.add($childNodes).each(function(){var $node=$(this);var bindData=self.view._parseBindStr($node.data('bind'));var bindAttributesOneWay=function(){if(bindData.attr){for(var i=0;i<bindData.attr.length;i++){self.bind('_change:'+bindData.attr[i].attrVar,createAttributePairClosure(bindData,$node,i));}}};if($node.is('input:checkbox')){self.bind('_change:'+bindData.key,function(){$node.prop("checked",self.model.get(bindData.key));});$node.change(function(){var obj={};obj[bindData.key]=$(this).prop("checked");self.model.set(obj);});bindAttributesOneWay();}
else if($node.is('select')){self.bind('_change:'+bindData.key,function(){var nodeName=$node.attr('name');var modelValue=self.model.get(bindData.key);$node.val(modelValue);});$node.change(function(){var obj={};obj[bindData.key]=$node.val();self.model.set(obj);});bindAttributesOneWay();}
-else if($node.is('input[type="radio"]')){self.bind('_change:'+bindData.key,function(){var nodeName=$node.attr('name');var modelValue=self.model.get(bindData.key);$node.siblings('input[name="'+nodeName+'"]').filter('[value="'+modelValue+'"]').prop("checked",true);});$node.change(function(){if(!$node.prop("checked"))return;var obj={};obj[bindData.key]=$node.val();self.model.set(obj);});bindAttributesOneWay();}
+else if($node.is('input:radio')){self.bind('_change:'+bindData.key,function(){var nodeName=$node.attr('name');var modelValue=self.model.get(bindData.key);$node.siblings('input[name="'+nodeName+'"]').filter('[value="'+modelValue+'"]').prop("checked",true);});$node.change(function(){if(!$node.prop("checked"))return;var obj={};obj[bindData.key]=$node.val();self.model.set(obj);});bindAttributesOneWay();}
else if($node.is('input[type="search"]')){self.bind('_change:'+bindData.key,function(){$node.val(self.model.get(bindData.key));});$node.keypress(function(){setTimeout(function(){var obj={};obj[bindData.key]=$node.val();self.model.set(obj);},50);});bindAttributesOneWay();}
-else if($node.is('input[type="text"], textarea')){self.bind('_change:'+bindData.key,function(){$node.val(self.model.get(bindData.key));});$node.change(function(){var obj={};obj[bindData.key]=$(this).val();self.model.set(obj);});bindAttributesOneWay();}
+else if($node.is('input:text, textarea')){self.bind('_change:'+bindData.key,function(){$node.val(self.model.get(bindData.key));});$node.change(function(){var obj={};obj[bindData.key]=$(this).val();self.model.set(obj);});bindAttributesOneWay();}
else{if(bindData.key){self.bind('_change:'+bindData.key,function(){if(self.model.get(bindData.key)){$node.text(self.model.get(bindData.key).toString());}else{$node.text('');}});}
bindAttributesOneWay();}});return this;},sync:function(){var self=this;this.model.each(function(key,val){self.trigger('_change:'+key);});if(this.model.size()>0){this.trigger('_change');}
return this;},stylize:function(){var objClass,regex=new RegExp(ROOT_SELECTOR,'g');if(this.view.style.length===0||this.view.$().size()===0){return;}
@@ -49,8 +52,8 @@ if(this.view.hasOwnProperty('style')){objClass='agility_'+this._id;var styleStr=
else{var ancestorWithStyle=function(object){while(object!==null){object=Object.getPrototypeOf(object);if(object.view.hasOwnProperty('style'))
return object._id;}
return undefined;};var ancestorId=ancestorWithStyle(this);objClass='agility_'+ancestorId;this.view.$().addClass(objClass);}
-return this;}},controller:{_create:function(event){this.view.stylize();this.view.bindings();this.view.sync();},_destroy:function(event){this._container.empty();this.view.$().remove();},_append:function(event,obj,selector){this.view.$(selector).append(obj.view.$());},_prepend:function(event,obj,selector){this.view.$(selector).prepend(obj.view.$());},_before:function(event,obj,selector){if(!selector)throw'agility.js: _before needs a selector';this.view.$(selector).before(obj.view.$());},_after:function(event,obj,selector){if(!selector)throw'agility.js: _after needs a selector';this.view.$(selector).after(obj.view.$());},_remove:function(event,id){},'_change':function(event){}},destroy:function(){this.trigger('destroy',this._id);},append:function(){this._container.append.apply(this,arguments);return this;},prepend:function(){this._container.prepend.apply(this,arguments);return this;},after:function(){this._container.after.apply(this,arguments);return this;},before:function(){this._container.before.apply(this,arguments);return this;},remove:function(){this._container.remove.apply(this,arguments);return this;},size:function(){return this._container.size.apply(this,arguments);},each:function(){return this._container.each.apply(this,arguments);},empty:function(){return this._container.empty.apply(this,arguments);},bind:function(){this._events.bind.apply(this,arguments);return this;},trigger:function(){this._events.trigger.apply(this,arguments);return this;}};agility=function(){var args=Array.prototype.slice.call(arguments,0),object={},prototype=defaultPrototype;if(typeof args[0]==="object"&&util.isAgility(args[0])){prototype=args[0];args.shift();}
-object=Object.create(prototype);object.model=Object.create(prototype.model);object.view=Object.create(prototype.view);object.controller=Object.create(prototype.controller);object._container=Object.create(prototype._container);object._events=Object.create(prototype._events);object._id=idCounter++;object._events.data={};object._container.children={};object.view.$root=$();object.model._data=prototype.model._data?$.extend(true,{},prototype.model._data):{};object._data=prototype._data?$.extend(true,{},prototype._data):{};if(args.length===0){}
+return this;}},controller:{_create:function(event){this.view.stylize();this.view.bindings();this.view.sync();},_destroy:function(event){this._container.empty();this.view.$().remove();},_append:function(event,obj,selector){this.view.$(selector).append(obj.view.$());},_prepend:function(event,obj,selector){this.view.$(selector).prepend(obj.view.$());},_before:function(event,obj,selector){if(!selector)throw'agility.js: _before needs a selector';this.view.$(selector).before(obj.view.$());},_after:function(event,obj,selector){if(!selector)throw'agility.js: _after needs a selector';this.view.$(selector).after(obj.view.$());},_remove:function(event,id){},'_change':function(event){}},destroy:function(){this.trigger('destroy',this._id);},parent:function(){return this._parent;},append:function(){this._container.append.apply(this,arguments);return this;},prepend:function(){this._container.prepend.apply(this,arguments);return this;},after:function(){this._container.after.apply(this,arguments);return this;},before:function(){this._container.before.apply(this,arguments);return this;},remove:function(){this._container.remove.apply(this,arguments);return this;},size:function(){return this._container.size.apply(this,arguments);},each:function(){return this._container.each.apply(this,arguments);},empty:function(){return this._container.empty.apply(this,arguments);},bind:function(){this._events.bind.apply(this,arguments);return this;},trigger:function(){this._events.trigger.apply(this,arguments);return this;}};agility=function(){var args=Array.prototype.slice.call(arguments,0),object={},prototype=defaultPrototype;if(typeof args[0]==="object"&&util.isAgility(args[0])){prototype=args[0];args.shift();}
+object=Object.create(prototype);object.model=Object.create(prototype.model);object.view=Object.create(prototype.view);object.controller=Object.create(prototype.controller);object._container=Object.create(prototype._container);object._events=Object.create(prototype._events);object._id=idCounter++;object._parent=null;object._events.data={};object._container.children={};object.view.$root=$();object.model._data=prototype.model._data?$.extend(true,{},prototype.model._data):{};object._data=prototype._data?$.extend(true,{},prototype._data):{};if(args.length===0){}
else if(args.length===1&&typeof args[0]==='object'&&(args[0].model||args[0].view||args[0].controller)){for(var prop in args[0]){if(prop==='model'){$.extend(object.model._data,args[0].model);}
else if(prop==='view'){$.extend(object.view,args[0].view);}
else if(prop==='controller'){$.extend(object.controller,args[0].controller);util.extendController(object);}
@@ -63,7 +66,7 @@ else if(args[1]){throw"agility.js: unknown argument type (view)";}
if(typeof args[2]==='string'){object.view.style=args[2];args.splice(2,1);}
if(typeof args[2]==='object'){$.extend(object.controller,args[2]);util.extendController(object);}
else if(args[2]){throw"agility.js: unknown argument type (controller)";}}
-object.model._initData=$.extend({},object.model._data);util.proxyAll(object,object);object.view.render();for(var ev in object.controller){if(typeof object.controller[ev]==='function'){object.bind(ev,object.controller[ev]);}}
+object.model._initData=$.extend({},object.model._data);util.proxyAll(object,object);object.view.render();var bindEvent=function(ev,handler){if(typeof handler==='function'){object.bind(ev,handler);}};for(var eventStr in object.controller){var events=eventStr.split(';');var handler=object.controller[eventStr];$.each(events,function(i,ev){ev=ev.trim();bindEvent(ev,handler);});}
object.trigger('create');return object;};agility.document=agility({view:{$:function(selector){return selector?$(selector,'body'):$('body');}},controller:{_create:function(){}}});agility.fn=defaultPrototype;agility.isAgility=function(obj){if(typeof obj!=='object')return false;return util.isAgility(obj);};window.agility=window.$$=agility;agility.fn.persist=function(adapter,params){var id='id';this._data.persist=$.extend({adapter:adapter},params);this._data.persist.openRequests=0;if(params&&params.id){id=params.id;}
this.save=function(){var self=this;if(this._data.persist.openRequests===0){this.trigger('persist:start');}
this._data.persist.openRequests++;this._data.persist.adapter.call(this,{type:this.model.get(id)?'PUT':'POST',id:this.model.get(id),data:this.model.get(),complete:function(){self._data.persist.openRequests--;if(self._data.persist.openRequests===0){self.trigger('persist:stop');}},success:function(data,textStatus,jqXHR){if(data[id]){self.model.set({id:data[id]},{silent:true});}
View
27 docs/agility.min.js
@@ -18,16 +18,18 @@ else if(typeof obj[attr1]==='object'){for(var attr2 in obj[attr1]){var proxied2=
obj[attr1]=proxied;}}};util.reverseEvents=function(obj,eventType){var events=$(obj).data('events');if(events!==undefined&&events[eventType]!==undefined){var reverseEvents=[];for(var e in events[eventType]){if(!events[eventType].hasOwnProperty(e))continue;reverseEvents.unshift(events[eventType][e]);}
events[eventType]=reverseEvents;}};util.size=function(obj){var size=0,key;for(key in obj){size++;}
return size;};util.extendController=function(object){for(var controllerName in object.controller){(function(){var matches,extend,eventName,previousHandler,currentHandler,newHandler;if(typeof object.controller[controllerName]==='function'){matches=controllerName.match(/^(\~)*(.+)/);extend=matches[1];eventName=matches[2];if(!extend)return;previousHandler=object.controller[eventName]?(object.controller[eventName]._preProxy||object.controller[eventName]):undefined;currentHandler=object.controller[controllerName];newHandler=function(){if(previousHandler)previousHandler.apply(this,arguments);if(currentHandler)currentHandler.apply(this,arguments);};object.controller[eventName]=newHandler;delete object.controller[controllerName];}})();}};defaultPrototype={_agility:true,_container:{_insertObject:function(obj,selector,method){var self=this;if(!util.isAgility(obj)){throw"agility.js: append argument is not an agility object";}
-this._container.children[obj._id]=obj;this.trigger(method,[obj,selector]);obj.bind('destroy',function(event,id){self._container.remove(id);});return this;},append:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'append');},prepend:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'prepend');},after:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'after');},before:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'before');},remove:function(id){delete this._container.children[id];this.trigger('remove',id);return this;},each:function(fn){$.each(this._container.children,fn);return this;},empty:function(){this.each(function(){this.destroy();});return this;},size:function(){return util.size(this._container.children);}},_events:{parseEventStr:function(eventStr){var eventObj={type:eventStr},spacePos=eventStr.search(/\s/);if(spacePos>-1){eventObj.type=eventStr.substr(0,spacePos);eventObj.selector=eventStr.substr(spacePos+1);}
+this._container.children[obj._id]=obj;this.trigger(method,[obj,selector]);obj._parent=this;obj.bind('destroy',function(event,id){self._container.remove(id);});return this;},append:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'append');},prepend:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'prepend');},after:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'after');},before:function(obj,selector){return this._container._insertObject.call(this,obj,selector,'before');},remove:function(id){delete this._container.children[id];this.trigger('remove',id);return this;},each:function(fn){$.each(this._container.children,fn);return this;},empty:function(){this.each(function(){this.destroy();});return this;},size:function(){return util.size(this._container.children);}},_events:{parseEventStr:function(eventStr){var eventObj={type:eventStr},spacePos=eventStr.search(/\s/);if(spacePos>-1){eventObj.type=eventStr.substr(0,spacePos);eventObj.selector=eventStr.substr(spacePos+1);}
return eventObj;},bind:function(eventStr,fn){var eventObj=this._events.parseEventStr(eventStr);if(eventObj.selector){if(eventObj.selector===ROOT_SELECTOR){this.view.$().bind(eventObj.type,fn);}
else{this.view.$().delegate(eventObj.selector,eventObj.type,fn);}}
else{$(this._events.data).bind(eventObj.type,fn);}
return this;},trigger:function(eventStr,params){var eventObj=this._events.parseEventStr(eventStr);if(eventObj.selector){if(eventObj.selector===ROOT_SELECTOR){this.view.$().trigger(eventObj.type,params);}
else{this.view.$().find(eventObj.selector).trigger(eventObj.type,params);}}
-else{$(this._events.data).trigger('_'+eventObj.type,params);util.reverseEvents(this._events.data,'pre:'+eventObj.type);$(this._events.data).trigger('pre:'+eventObj.type,params);util.reverseEvents(this._events.data,'pre:'+eventObj.type);$(this._events.data).trigger(eventObj.type,params);$(this._events.data).trigger('post:'+eventObj.type,params);}
-return this;}},model:{set:function(arg,params){var self=this;var modified=[];if(typeof arg==='object'){if(params&&params.reset){this.model._data=$.extend({},arg);}
+else{$(this._events.data).trigger('_'+eventObj.type,params);util.reverseEvents(this._events.data,'pre:'+eventObj.type);$(this._events.data).trigger('pre:'+eventObj.type,params);util.reverseEvents(this._events.data,'pre:'+eventObj.type);$(this._events.data).trigger(eventObj.type,params);if(this.parent())
+this.parent().trigger((eventObj.type.match(/^child:/)?'':'child:')+eventObj.type,params);$(this._events.data).trigger('post:'+eventObj.type,params);}
+return this;}},model:{set:function(arg,params){var self=this;var modified=[];if(typeof arg==='object'){var _clone=false;if(params&&params.reset){_clone=this.model._data;this.model._data=$.extend({},arg);}
else{$.extend(this.model._data,arg);}
-for(var key in arg){modified.push(key);}}
+for(var key in arg){delete _clone[key];modified.push(key);}
+for(key in _clone){modified.push(key);}}
else{throw"agility.js: unknown argument type in model.set()";}
if(params&&params.silent===true)return this;this.trigger('change');$.each(modified,function(index,val){self.trigger('change:'+val);});return this;},get:function(arg){if(arg===undefined){return this.model._data;}
if(typeof arg==='string'){return this.model._data[arg];}
@@ -35,13 +37,14 @@ throw'agility.js: unknown argument for getter';},reset:function(){this.model.set
if(this.view.$root.size()===0){this.view.$root=$(this.view.format);}
else{this.view.$root.html($(this.view.format).html());}
if(this.view.$root.size()===0){throw'agility.js: could not generate html from format';}
-return this;},_parseBindStr:function(str){var obj={key:null,attr:[]},pairs=str.split(','),regex=/([a-zA-Z0-9_\-]+)(?:[\s=]+([a-zA-Z0-9_\-]+))?/,matched;if(pairs.length>0){matched=pairs[0].match(regex);if(matched){if(typeof(matched[2])==="undefined"||matched[2]===""){obj.key=matched[1];}else{obj.attr.push({attr:matched[1],attrVar:matched[2]});}}
-if(pairs.length>1){for(var i=1;i<pairs.length;i++){matched=pairs[i].match(regex);if(matched){if(typeof(matched[2])!=="undefined"){obj.attr.push({attr:matched[1],attrVar:matched[2]});}}}}}
-return obj;},bindings:function(){var self=this;var $rootNode=this.view.$().filter('[data-bind]');var $childNodes=this.view.$('[data-bind]');var createAttributePairClosure=function(bindData,node,i){var attrPair=bindData.attr[i];return function(){node.attr(attrPair.attr,self.model.get(attrPair.attrVar));};};$rootNode.add($childNodes).each(function(){var $node=$(this);var bindData=self.view._parseBindStr($node.data('bind'));var bindAttributesOneWay=function(){if(bindData.attr){for(var i=0;i<bindData.attr.length;i++){self.bind('_change:'+bindData.attr[i].attrVar,createAttributePairClosure(bindData,$node,i));}}};if($node.is('input[type="checkbox"]')){self.bind('_change:'+bindData.key,function(){$node.prop("checked",self.model.get(bindData.key));});$node.change(function(){var obj={};obj[bindData.key]=$(this).prop("checked");self.model.set(obj);});bindAttributesOneWay();}
+return this;},_parseBindStr:function(str){var obj={key:null,attr:[]},pairs=str.split(','),regex=/([a-zA-Z0-9_\-]+)(?:[\s=]+([a-zA-Z0-9_\-]+))?/,keyAssigned=false,matched;if(pairs.length>0){for(var i=0;i<pairs.length;i++){matched=pairs[i].match(regex);if(matched){if(typeof(matched[2])==="undefined"||matched[2]===""){if(keyAssigned){throw new Error("You may specify only one key ("+
+keyAssigned+" has already been specified in data-bind="+
+str+")");}else{keyAssigned=matched[1];obj.key=matched[1];}}else{obj.attr.push({attr:matched[1],attrVar:matched[2]});}}}}
+return obj;},bindings:function(){var self=this;var $rootNode=this.view.$().filter('[data-bind]');var $childNodes=this.view.$('[data-bind]');var createAttributePairClosure=function(bindData,node,i){var attrPair=bindData.attr[i];return function(){node.attr(attrPair.attr,self.model.get(attrPair.attrVar));};};$rootNode.add($childNodes).each(function(){var $node=$(this);var bindData=self.view._parseBindStr($node.data('bind'));var bindAttributesOneWay=function(){if(bindData.attr){for(var i=0;i<bindData.attr.length;i++){self.bind('_change:'+bindData.attr[i].attrVar,createAttributePairClosure(bindData,$node,i));}}};if($node.is('input:checkbox')){self.bind('_change:'+bindData.key,function(){$node.prop("checked",self.model.get(bindData.key));});$node.change(function(){var obj={};obj[bindData.key]=$(this).prop("checked");self.model.set(obj);});bindAttributesOneWay();}
else if($node.is('select')){self.bind('_change:'+bindData.key,function(){var nodeName=$node.attr('name');var modelValue=self.model.get(bindData.key);$node.val(modelValue);});$node.change(function(){var obj={};obj[bindData.key]=$node.val();self.model.set(obj);});bindAttributesOneWay();}
-else if($node.is('input[type="radio"]')){self.bind('_change:'+bindData.key,function(){var nodeName=$node.attr('name');var modelValue=self.model.get(bindData.key);$node.siblings('input[name="'+nodeName+'"]').filter('[value="'+modelValue+'"]').prop("checked",true);});$node.change(function(){if(!$node.prop("checked"))return;var obj={};obj[bindData.key]=$node.val();self.model.set(obj);});bindAttributesOneWay();}
+else if($node.is('input:radio')){self.bind('_change:'+bindData.key,function(){var nodeName=$node.attr('name');var modelValue=self.model.get(bindData.key);$node.siblings('input[name="'+nodeName+'"]').filter('[value="'+modelValue+'"]').prop("checked",true);});$node.change(function(){if(!$node.prop("checked"))return;var obj={};obj[bindData.key]=$node.val();self.model.set(obj);});bindAttributesOneWay();}
else if($node.is('input[type="search"]')){self.bind('_change:'+bindData.key,function(){$node.val(self.model.get(bindData.key));});$node.keypress(function(){setTimeout(function(){var obj={};obj[bindData.key]=$node.val();self.model.set(obj);},50);});bindAttributesOneWay();}
-else if($node.is('input[type="text"], textarea')){self.bind('_change:'+bindData.key,function(){$node.val(self.model.get(bindData.key));});$node.change(function(){var obj={};obj[bindData.key]=$(this).val();self.model.set(obj);});bindAttributesOneWay();}
+else if($node.is('input:text, textarea')){self.bind('_change:'+bindData.key,function(){$node.val(self.model.get(bindData.key));});$node.change(function(){var obj={};obj[bindData.key]=$(this).val();self.model.set(obj);});bindAttributesOneWay();}
else{if(bindData.key){self.bind('_change:'+bindData.key,function(){if(self.model.get(bindData.key)){$node.text(self.model.get(bindData.key).toString());}else{$node.text('');}});}
bindAttributesOneWay();}});return this;},sync:function(){var self=this;this.model.each(function(key,val){self.trigger('_change:'+key);});if(this.model.size()>0){this.trigger('_change');}
return this;},stylize:function(){var objClass,regex=new RegExp(ROOT_SELECTOR,'g');if(this.view.style.length===0||this.view.$().size()===0){return;}
@@ -49,8 +52,8 @@ if(this.view.hasOwnProperty('style')){objClass='agility_'+this._id;var styleStr=
else{var ancestorWithStyle=function(object){while(object!==null){object=Object.getPrototypeOf(object);if(object.view.hasOwnProperty('style'))
return object._id;}
return undefined;};var ancestorId=ancestorWithStyle(this);objClass='agility_'+ancestorId;this.view.$().addClass(objClass);}
-return this;}},controller:{_create:function(event){this.view.stylize();this.view.bindings();this.view.sync();},_destroy:function(event){this._container.empty();this.view.$().remove();},_append:function(event,obj,selector){this.view.$(selector).append(obj.view.$());},_prepend:function(event,obj,selector){this.view.$(selector).prepend(obj.view.$());},_before:function(event,obj,selector){if(!selector)throw'agility.js: _before needs a selector';this.view.$(selector).before(obj.view.$());},_after:function(event,obj,selector){if(!selector)throw'agility.js: _after needs a selector';this.view.$(selector).after(obj.view.$());},_remove:function(event,id){},'_change':function(event){}},destroy:function(){this.trigger('destroy',this._id);},append:function(){this._container.append.apply(this,arguments);return this;},prepend:function(){this._container.prepend.apply(this,arguments);return this;},after:function(){this._container.after.apply(this,arguments);return this;},before:function(){this._container.before.apply(this,arguments);return this;},remove:function(){this._container.remove.apply(this,arguments);return this;},size:function(){return this._container.size.apply(this,arguments);},each:function(){return this._container.each.apply(this,arguments);},empty:function(){return this._container.empty.apply(this,arguments);},bind:function(){this._events.bind.apply(this,arguments);return this;},trigger:function(){this._events.trigger.apply(this,arguments);return this;}};agility=function(){var args=Array.prototype.slice.call(arguments,0),object={},prototype=defaultPrototype;if(typeof args[0]==="object"&&util.isAgility(args[0])){prototype=args[0];args.shift();}
-object=Object.create(prototype);object.model=Object.create(prototype.model);object.view=Object.create(prototype.view);object.controller=Object.create(prototype.controller);object._container=Object.create(prototype._container);object._events=Object.create(prototype._events);object._id=idCounter++;object._events.data={};object._container.children={};object.view.$root=$();object.model._data=prototype.model._data?$.extend(true,{},prototype.model._data):{};object._data=prototype._data?$.extend(true,{},prototype._data):{};if(args.length===0){}
+return this;}},controller:{_create:function(event){this.view.stylize();this.view.bindings();this.view.sync();},_destroy:function(event){this._container.empty();this.view.$().remove();},_append:function(event,obj,selector){this.view.$(selector).append(obj.view.$());},_prepend:function(event,obj,selector){this.view.$(selector).prepend(obj.view.$());},_before:function(event,obj,selector){if(!selector)throw'agility.js: _before needs a selector';this.view.$(selector).before(obj.view.$());},_after:function(event,obj,selector){if(!selector)throw'agility.js: _after needs a selector';this.view.$(selector).after(obj.view.$());},_remove:function(event,id){},'_change':function(event){}},destroy:function(){this.trigger('destroy',this._id);},parent:function(){return this._parent;},append:function(){this._container.append.apply(this,arguments);return this;},prepend:function(){this._container.prepend.apply(this,arguments);return this;},after:function(){this._container.after.apply(this,arguments);return this;},before:function(){this._container.before.apply(this,arguments);return this;},remove:function(){this._container.remove.apply(this,arguments);return this;},size:function(){return this._container.size.apply(this,arguments);},each:function(){return this._container.each.apply(this,arguments);},empty:function(){return this._container.empty.apply(this,arguments);},bind:function(){this._events.bind.apply(this,arguments);return this;},trigger:function(){this._events.trigger.apply(this,arguments);return this;}};agility=function(){var args=Array.prototype.slice.call(arguments,0),object={},prototype=defaultPrototype;if(typeof args[0]==="object"&&util.isAgility(args[0])){prototype=args[0];args.shift();}
+object=Object.create(prototype);object.model=Object.create(prototype.model);object.view=Object.create(prototype.view);object.controller=Object.create(prototype.controller);object._container=Object.create(prototype._container);object._events=Object.create(prototype._events);object._id=idCounter++;object._parent=null;object._events.data={};object._container.children={};object.view.$root=$();object.model._data=prototype.model._data?$.extend(true,{},prototype.model._data):{};object._data=prototype._data?$.extend(true,{},prototype._data):{};if(args.length===0){}
else if(args.length===1&&typeof args[0]==='object'&&(args[0].model||args[0].view||args[0].controller)){for(var prop in args[0]){if(prop==='model'){$.extend(object.model._data,args[0].model);}
else if(prop==='view'){$.extend(object.view,args[0].view);}
else if(prop==='controller'){$.extend(object.controller,args[0].controller);util.extendController(object);}
@@ -63,7 +66,7 @@ else if(args[1]){throw"agility.js: unknown argument type (view)";}
if(typeof args[2]==='string'){object.view.style=args[2];args.splice(2,1);}
if(typeof args[2]==='object'){$.extend(object.controller,args[2]);util.extendController(object);}
else if(args[2]){throw"agility.js: unknown argument type (controller)";}}
-object.model._initData=$.extend({},object.model._data);util.proxyAll(object,object);object.view.render();for(var ev in object.controller){if(typeof object.controller[ev]==='function'){object.bind(ev,object.controller[ev]);}}
+object.model._initData=$.extend({},object.model._data);util.proxyAll(object,object);object.view.render();var bindEvent=function(ev,handler){if(typeof handler==='function'){object.bind(ev,handler);}};for(var eventStr in object.controller){var events=eventStr.split(';');var handler=object.controller[eventStr];$.each(events,function(i,ev){ev=ev.trim();bindEvent(ev,handler);});}
object.trigger('create');return object;};agility.document=agility({view:{$:function(selector){return selector?$(selector,'body'):$('body');}},controller:{_create:function(){}}});agility.fn=defaultPrototype;agility.isAgility=function(obj){if(typeof obj!=='object')return false;return util.isAgility(obj);};window.agility=window.$$=agility;agility.fn.persist=function(adapter,params){var id='id';this._data.persist=$.extend({adapter:adapter},params);this._data.persist.openRequests=0;if(params&&params.id){id=params.id;}
this.save=function(){var self=this;if(this._data.persist.openRequests===0){this.trigger('persist:start');}
this._data.persist.openRequests++;this._data.persist.adapter.call(this,{type:this.model.get(id)?'PUT':'POST',id:this.model.get(id),data:this.model.get(),complete:function(){self._data.persist.openRequests--;if(self._data.persist.openRequests===0){self.trigger('persist:stop');}},success:function(data,textStatus,jqXHR){if(data[id]){self.model.set({id:data[id]},{silent:true});}
View
3  docs/docs.html
@@ -111,7 +111,7 @@
<div id='box-wrapper'>
<!-- __INSERT_POINT__ -->
-<p class='download'><b>Version: 0.1.2 (Dec 17, 2011) </b></p>
+<p class='download'><b>Version: 0.1.3 (Sep 3, 2012) </b></p>
<h1><a href="#intro">Introduction</a></h1>
<p>Agility is a <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model-View-Controller</a> (MVC) library for client-side Javascript with some specific design principles:</p>
@@ -971,7 +971,6 @@
api/resource/123
</pre></div>
-
</div>
</div>
View
17 docs/gallery.html
@@ -89,16 +89,17 @@
<div id='box-wrapper'>
<!-- __INSERT_POINT__ -->
+<h1>Gallery</h1>
+<p>The websites and apps below use Agility.js in production. If you would like to add your startup/site here, <a href="http://twitter.com/agilityjs">let us know!</a></p>
+<h2><a href="http://cheaphotels.co.uk">cheaphotels.co.uk</a></h2>
+<p>Cheap Hotels is an online search engine and deal finder for hotels across the globe.</p>
+<p><img alt="Screenshot" src="gallery/cheaphotels.png" /></p>
+<h2><a href="http://opdots.com">OpDots.com</a></h2>
+<p>OpDots is the "see everything" dashboard for your enterprise data.</p>
+<p><img alt="Screenshot" src="gallery/opdots.png" /></p>
<h2><a href="http://thewall.agilityjs.com">The Wall</a></h2>
-<p><em>The Wall is a minimal Twitter clone, where everyone can post anonymously to a virtual "wall". It illustrates most features offered by Agility, including server-side persistence.</em></p>
-<ul>
-<li>Demo: <a href="http://thewall.agilityjs.com">http://thewall.agilityjs.com</a></li>
-<li>Full source: <a href="https://github.com/arturadib/thewall/blob/master/public/app.js">https://github.com/arturadib/thewall/blob/master/public/app.js</a></li>
-<li>Screenshot:</li>
-</ul>
+<p>The Wall is a minimal Twitter clone, where everyone can post anonymously to a virtual "wall". It illustrates most features offered by Agility, including server-side persistence.</p>
<p><img alt="Screenshot" src="gallery/thewall.png" /></p>
-<h3>User submissions</h3>
-<p>Have you created an awesome project that showcases Agility's capabilities? <a href="https://github.com/arturadib/agility/tree/gh-pages">Fork this site</a>, add a brief description of your project, and send a pull request. We'd love to see what you can do with Agility!</p>
</div>
</div>
View
BIN  docs/gallery/cheaphotels.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  docs/gallery/opdots.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
2  index.html
@@ -135,7 +135,7 @@
<!-- __INSERT_POINT__ -->
<p>Agility.js is an <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> library for Javascript that lets you write maintainable and reusable browser code without the verbose or infrastructural overhead found in <a href="http://documentcloud.github.com/backbone/">other</a> <a href="http://www.sproutcore.com/">MVC</a> <a href="http://knockoutjs.com/">libraries</a>. The goal is to enable developers to write web apps at least as quickly as with jQuery, while simplifying long-term maintainability through MVC objects.</p>
<div class='download'>
- <div><b>Latest version: 0.1.2 (Dec 17, 2011) </b> | <a href="https://raw.github.com/arturadib/agility/master/ChangeLog">ChangeLog</a></div>
+ <div><b>Latest version: 0.1.3 (Sep 3, 2012) </b> | <a href="https://raw.github.com/arturadib/agility/master/ChangeLog">ChangeLog</a></div>
<div>Download <a href="agility.min.js">minified js</a> (~4K packed + gzipped)</div>
<div>Download <a href="agility-start.zip">"getting started" package</a> (zip) or <a href="https://github.com/arturadib/agility/tree/master/docs/agility-start">browse its contents</a></div>
</div>
Please sign in to comment.
Something went wrong with that request. Please try again.