Commit 254fa67a authored by DimitarChristoff's avatar DimitarChristoff

refactor for code style, spaces creep in, fix issue with active filter, change...

refactor for code style, spaces creep in, fix issue with active filter, change completed to boolean, editing enter fires blur, see pull/235#issuecomment-7264416
parent 9447769a
......@@ -25,19 +25,19 @@
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="https://github.com/DimitarChristoff/">Dimitar Christoff</a></p>
<p>Powered by <a href="https://github.com/DimitarChristoff/Epitome">Epitome for MooTools</a></p>
<p>Powered by <a href="https://dimitarchristoff.github.com/Epitome">Epitome for MooTools</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script type="text/template" id="item-template">
<div class="view">
<input class="toggle" type="checkbox" <%=completedCheckbox%>>
<input class="toggle" type="checkbox" <%=completedCheckbox%>>
<label><%=title%></label>
<button class="destroy"></button>
</div>
<input class="edit" value="<%=title%>">
<input class="edit" value="<%=title%>">
</script>
<script type="text/template" id="stats-template">
<span id="todo-count"><strong><%=remaining%></strong> item<% if (obj.remaining !== 1) { %>s<% } %> left</span>
<span id="todo-count"><strong><%=remaining%></strong> item<% if (obj.remaining !== 1) { %>s<% } %> left</span>
<ul id="filters">
<li>
<a class="selected" href="#!/">All</a>
......@@ -53,16 +53,17 @@
<button id="clear-completed">Clear completed (<%=completed%>)</button>
<% } %>
</script>
<script src="../../../assets/base.js"></script>
<!-- mootools -->
<script src="js/lib/mootools-yui-compressed.js"></script>
<!-- epitome pre-compiled -->
<script src="js/lib/Epitome-min.js"></script>
<!-- todo app -->
<script src="js/models/todo-model.js"></script>
<script src="js/collections/todo-collection.js"></script>
<script src="../../../assets/base.js"></script>
<!-- mootools -->
<script src="js/lib/mootools-yui-compressed.js"></script>
<!-- epitome pre-compiled -->
<script src="js/lib/Epitome-min.js"></script>
<!-- todo app -->
<script src="js/models/todo-model.js"></script>
<script src="js/collections/todo-collection.js"></script>
<script src="js/views/todo-list.js"></script>
<script src="js/views/todo-main.js"></script>
<script src="js/controllers/todo-router.js"></script>
<script src="js/app.js"></script>
</body>
</html>
\ No newline at end of file
/*global Epitome */
/*jshint mootools:true */
(function( window ) {
'use strict';
var App = window.App;
var todos = new App.TodoCollection( null, {
// a consistent collection if is needed if you want to use storage for a collection
var todos = new App.TodoCollection( null, {
// a consistent collection if is needed if you want to use storage for a collection
id: 'todos'
});
// populate from storage if available
todos.setUp( todos.retrieve() );
todos.setUp( todos.retrieve() );
// instantiate the todo list view
App.todoView = new App.TodoView({
......@@ -19,10 +20,10 @@
collection: todos,
// encapsulating element to bind to
element: document.id('todo-list'),
element: document.id( 'todo-list' ),
// template to use
template: document.id('item-template').get('text')
template: document.id( 'item-template' ).get( 'text' )
});
......@@ -36,11 +37,23 @@
element: document.id('todoapp'),
// stats template from DOM
template: document.id('stats-template').get('text')
template: document.id( 'stats-template' ).get( 'text' ),
onReady: function() {
// need to work with controller that sets the current state of filtering
var proxy = function() {
App.router.showActiveFilter();
};
this.addEvents({
'add:collection': proxy,
'change:collection': proxy
});
}
});
// the pseudo controller via Epitome.Router
App.router = new Epitome.Router({
App.router = new App.Router({
routes: {
'': 'init',
'#!/': 'applyFilter',
......@@ -49,10 +62,10 @@
onInit: function() {
// we want to always have a state
this.navigate('#!/');
this.navigate( '#!/' );
},
onApplyFilter: function( filter ) {
onApplyFilter: function( filter ) {
// the filter is being used by the todo collection and view.
// when false, the whole collection is being passed.
todos.filterType = filter || false;
......@@ -60,11 +73,7 @@
// render as per current filter
App.todoView.render();
// fix up the links quickie.
var self = this;
document.getElements('#filters li a').each(function( link ) {
link.set( 'class', link.get('href') === self.req ? 'selected' : '' );
});
this.showActiveFilter();
}
});
}( window ));
\ No newline at end of file
/*global Epitome, App, Class */
/*global Epitome, App */
/*jshint mootools:true */
(function(window) {
'use strict';
......@@ -15,9 +16,14 @@
// base model class prototype
model: App.Todo,
todoFilter: function( model ) {
map: {
active: 0,
completed: 1
},
todoFilter: function( model ) {
// references the filterType which the controller sets
return this.filterType === false ? true : model.get('completed') === this.filterType;
return this.filterType === false ? true : this.map[this.filterType] === +model.get( 'completed' );
}
});
}( window ));
\ No newline at end of file
/*global Epitome, App */
/*jshint mootools:true */
(function(window) {
'use strict';
window.App = window.App || {};
App.Router = new Class({
Extends: Epitome.Router,
showActiveFilter: function() {
// fix up the links for current filter
var self = this;
document.getElements( '#filters li a' ).each(function( link ) {
link.set( 'class', link.get( 'href' ) === self.req ? 'selected' : '' );
});
}
});
}( window ));
\ No newline at end of file
(function(exports){var Epitome={};typeof define=="function"&&define.amd?define("epitome",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome})(this),function(exports){var Epitome=typeof require=="function"?require("./epitome"):exports.Epitome,eq=Epitome.isEqual=function(a,b,stack){stack=stack||[];if(a===b)return a!==0||1/a==1/b;if(a==null||b==null)return a===b;var typeA=typeOf(a),typeB=typeOf(b);if(typeA!=typeB)return!1;switch(typeA){case"string":return a==String(b);case"number":return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case"date":case"boolean":return+a==+b;case"regexp":return a.source==b.source&&a.global==b.global&&a.multiline==b.multiline&&a.ignoreCase==b.ignoreCase}if(typeof a!="object"||typeof b!="object")return!1;var length=stack.length;while(length--)if(stack[length]==a)return!0;stack.push(a);var size=0,result=!0;if(typeA=="array"){size=a.length,result=size==b.length;if(result)while(size--)if(!(result=size in a==size in b&&eq(a[size],b[size],stack)))break}else{if("constructor"in a!="constructor"in b||a.constructor!=b.constructor)return!1;for(var key in a)if(a.hasOwnProperty(key)){size++;if(!(result=b.hasOwnProperty(key)&&eq(a[key],b[key],stack)))break}if(result){for(key in b)if(b.hasOwnProperty(key)&&!(size--))break;result=!size}}return stack.pop(),result};typeof define=="function"&&define.amd?define("epitome-isequal",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome}(this),function(exports){var Epitome=typeof require=="function"?require("./epitome"):exports.Epitome;Epitome.Model=new Class({Implements:[Options,Events],_attributes:{},properties:{id:{get:function(){var id=this._attributes.id||(this._attributes.id=String.uniqueID());return this.cid||(this.cid=id),id}}},options:{defaults:{}},collections:[],initialize:function(obj,options){return options&&options.defaults&&(this.options.defaults=Object.merge(this.options.defaults,options.defaults)),obj=obj&&typeOf(obj)==="object"?obj:{},this.set(Object.merge(this.options.defaults,obj)),this.setOptions(options),this.fireEvent("ready")},set:function(){this.propertiesChanged=[],this._set.apply(this,arguments),this.propertiesChanged.length&&this.fireEvent("change",this.get(this.propertiesChanged))},_set:function(key,value){return!key||typeof value=="undefined"?this:this.properties[key]&&this.properties[key].set?this.properties[key].set.call(this,value):this._attributes[key]&&Epitome.isEqual(this._attributes[key],value)?this:(value===null?delete this._attributes[key]:this._attributes[key]=value,this.fireEvent("change:"+key,value),this.propertiesChanged.push(key),this)}.overloadSetter(),get:function(key){return key&&this.properties[key]&&this.properties[key].get?this.properties[key].get.call(this):key&&typeof this._attributes[key]!="undefined"?this._attributes[key]:null}.overloadGetter(),unset:function(){var keys=Array.prototype.slice.apply(arguments),obj={},len=keys.length;return len?(Array.each(Array.flatten(keys),function(key){obj[key]=null}),this.set(obj),this):this},toJSON:function(){return Object.clone(this._attributes)},empty:function(){var keys=Object.keys(this.toJSON()),self=this;this.fireEvent("change",[keys]),Array.each(keys,function(key){self.fireEvent("change:"+key,null)},this),this._attributes={},this.fireEvent("empty")},destroy:function(){this._attributes={},this.fireEvent("destroy")}}),typeof define=="function"&&define.amd?define("epitome-model",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome}(this),function(exports){var Epitome=typeof require=="function"?require("./epitome-model"):exports.Epitome,Model=Epitome.Model,syncPseudo="sync:",methodMap={create:"POST",read:"GET",update:"PUT",delete_:"DELETE"};Model.Sync=new Class({Extends:Model,properties:{id:{get:function(){var id=this._attributes.id||(this._attributes.id=String.uniqueID());return this.cid||(this.cid=id),id}},urlRoot:{set:function(value){this.urlRoot=value,delete this._attributes.urlRoot},get:function(){var base=this.urlRoot||this.options.urlRoot||"no-urlRoot-set";return base.charAt(base.length-1)!="/"&&(base+="/"),base}}},options:{emulateREST:!1},initialize:function(obj,options){this.setupSync(),this.parent(obj,options)},sync:function(method,model){var options={};method=method&&methodMap[method]?methodMap[method]:methodMap.read,options.method=method;if(method==methodMap.create||method==methodMap.update)options.data=model||this.toJSON();return options.url=this.get("urlRoot")+this.get("id")+"/",this.request.setOptions(options),this.request[method](model),this},setupSync:function(){var self=this,rid=0,incrementRequestId=function(){rid++};return this.getRequestId=function(){return rid+1},this.request=new Request.JSON({link:"chain",url:this.get("urlRoot"),emulation:this.options.emulateREST,onRequest:incrementRequestId,onCancel:function(){this.removeEvents(syncPseudo+rid)},onSuccess:function(responseObj){responseObj=self.parse&&self.parse(responseObj),self.fireEvent(syncPseudo+rid,[responseObj]),self.fireEvent("sync",[responseObj,this.options.method,this.options.data])},onFailure:function(){self.fireEvent(syncPseudo+"error",[this.options.method,this.options.url,this.options.data])}}),Object.each(methodMap,function(requestMethod,protoMethod){self[protoMethod]=function(model){this.sync(protoMethod,model)}}),this},_throwAwaySyncEvent:function(eventName,callback){eventName=eventName||syncPseudo+this.getRequestId();var self=this,throwAway={};return throwAway[eventName]=function(responseObj){responseObj&&typeof responseObj=="object"&&(self.set(responseObj),callback&&callback.call(self,responseObj)),self.removeEvents(throwAway)},this.addEvents(throwAway)}.protect(),parse:function(resp){return resp},fetch:function(){return this._throwAwaySyncEvent(syncPseudo+this.getRequestId(),function(){this.fireEvent("fetch"),this.isNewModel=!1}),this.read(),this},save:function(key,value){var method=["update","create"][+this.isNew()];if(key){var ktype=typeOf(key),canSet=ktype=="object"||ktype=="string"&&typeof value!="undefined";canSet&&this._set.apply(this,arguments)}return this._throwAwaySyncEvent(syncPseudo+this.getRequestId(),function(){this.fireEvent("save"),this.fireEvent(method)}),this[method](),this.isNewModel=!1,this},destroy:function(){this._throwAwaySyncEvent(syncPseudo+this.getRequestId(),function(){this._attributes={},this.delete_(),this.fireEvent("destroy")})},isNew:function(){return typeof this.isNewModel=="undefined"&&(this.isNewModel=!0),this.isNewModel}}),typeof define=="function"&&define.amd?define("epitome-model-sync",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome}(this),function(exports){var Epitome=typeof require=="function"?require("./epitome"):exports.Epitome;Epitome.Storage=function(){var hasNativeStorage=typeof exports.localStorage=="object"&&!!exports.localStorage.getItem,localStorage="localStorage",sessionStorage="sessionStorage",setStorage=function(storageMethod){var s,privateKey="epitome-"+storageMethod,storage={},storagePrefix="model";if(hasNativeStorage)try{storage=JSON.decode(exports[storageMethod].getItem(privateKey))||storage}catch(e){hasNativeStorage=!1}if(!hasNativeStorage)try{s=JSON.decode(exports.name),s&&typeof s=="object"&&s[privateKey]&&(storage=s[privateKey])}catch(e){serializeWindowName()}var Methods={store:function(model){model=model||this.toJSON(),setItem([storagePrefix,this.get("id")].join(":"),model),this.fireEvent("store",model)},eliminate:function(){return removeItem([storagePrefix,this.get("id")].join(":")),this.fireEvent("eliminate")},retrieve:function(){var model=getItem([storagePrefix,this.get("id")].join(":"))||null;return this.fireEvent("retrieve",model),model}},getItem=function(item){return storage[item]||null},setItem=function(item,value){storage=JSON.decode(exports[storageMethod].getItem(privateKey))||storage,storage[item]=value;if(hasNativeStorage)try{exports[storageMethod].setItem(privateKey,JSON.encode(storage))}catch(e){}else serializeWindowName();return this},removeItem=function(item){delete storage[item];if(hasNativeStorage)try{exports[storageMethod].setItem(privateKey,JSON.encode(storage))}catch(e){}else serializeWindowName()},serializeWindowName=function(){var obj={},s=JSON.decode(exports.name);obj[privateKey]=storage,exports.name=JSON.encode(Object.merge(obj,s))};return function(storageName){return storageName&&(storagePrefix=storageName),new Class(Object.clone(Methods))}};return{localStorage:setStorage(localStorage),sessionStorage:setStorage(sessionStorage)}}(),typeof define=="function"&&define.amd?define("epitome-storage",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome}(this),function(exports){var Epitome=typeof require=="function"?require("./epitome"):exports.Epitome,methodMap=["forEach","each","invoke","filter","map","some","indexOf","contains","getRandom","getLast"];Function.extend({monitorModelEvents:function(listener,orig){var self=this;return orig=orig||this,!listener||!listener.fireEvent?this:function(type,args,delay){self.apply(orig,arguments),listener.getModelByCID(orig.cid)&&listener.fireEvent(type,Array.flatten([orig,args]),delay)}}});var Collection=Epitome.Collection=new Class({Implements:[Options,Events],model:Epitome.Model,_models:[],initialize:function(models,options){return this.setOptions(options),models&&this.setUp(models),this.id=this.options.id||String.uniqueID(),this.fireEvent("ready")},setUp:function(models){return models=Array.from(models),Array.each(models,this.addModel.bind(this)),this.addEvent("destroy",this.removeModel.bind(this)),this},addModel:function(model,replace){var exists;return typeOf(model)=="object"&&!instanceOf(model,this.model)&&(model=new this.model(model)),model.cid=model.cid||model.get("id")||String.uniqueID(),exists=this.getModelByCID(model.cid),exists&&replace!==!0?this.fireEvent("add:error",model):(exists&&replace===!0&&(this._models[this._models.indexOf(model)]=model),model.fireEvent=Function.monitorModelEvents.apply(model.fireEvent,[this,model]),this._models.push(model),model.collections.include(this),this.length=this._models.length,this.fireEvent("add",[model,model.cid]).fireEvent("reset",[model,model.cid]))},removeModel:function(models){var self=this;return models=Array.from(models),Array.each(models,function(model){model.collections.erase(self),model.collections.length||delete model.fireEvent,Array.erase(self._models,model),self.length=self._models.length,self.fireEvent("remove",[model,model.cid])}),this.fireEvent("reset",[models])},get:function(what){return this[what]},getModelByCID:function(cid){var last=null;return this.some(function(el){return el.cid==cid&&(last=el)}),last},getModelById:function(id){var last=null;return this.some(function(el){return el.get("id")==id&&(last=el)}),last},getModel:function(index){return this._models[index]},toJSON:function(){var getJSON=function(model){return model.toJSON()};return Array.map(this._models,getJSON)},empty:function(){return this.removeModel(this._models),this.fireEvent("empty")},sort:function(how){if(!how)return this._models.sort(),this.fireEvent("sort");if(typeof how=="function")return this.model.sort(how),this.fireEvent("sort");var type="asc",pseudos=how.split(":"),key=pseudos[0],c=function(a,b){return a<b?-1:a>b?1:0};return pseudos[1]&&(type=pseudos[1]),this._models.sort(function(a,b){var ak=a.get(key),bk=b.get(key),cm=c(ak,bk),map={asc:cm,desc:-cm};return typeof map[type]=="undefined"&&(type="asc"),map[type]}),this.fireEvent("sort")},reverse:function(){return Array.reverse(this._models),this.fireEvent("sort")}});Array.each(methodMap,function(method){Collection.implement(method,function(){return Array.prototype[method].apply(this._models,arguments)})}),typeof define=="function"&&define.amd?define("epitome-collection",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome}(this),function(exports){var Epitome=typeof require=="function"?require("./epitome-collection"):exports.Epitome,noUrl="no-urlRoot-set",eventPseudo="fetch:";Epitome.Collection.Sync=new Class({Extends:Epitome.Collection,options:{urlRoot:noUrl},initialize:function(models,options){this.setupSync(),this.parent(models,options)},setupSync:function(){var self=this,rid=0,incrementRequestId=function(){rid++};return this.getRequestId=function(){return rid+1},this.request=new Request.JSON({link:"chain",url:this.options.urlRoot,emulation:this.options.emulateREST,onRequest:incrementRequestId,onCancel:function(){this.removeEvents(eventPseudo+rid)},onSuccess:function(responseObj){responseObj=self.parse&&self.parse(responseObj),self.fireEvent(eventPseudo+rid,[[responseObj]])},onFailure:function(){self.fireEvent(eventPseudo+"error",[this.options.method,this.options.url,this.options.data])}}),this},parse:function(resp){return resp},fetch:function(refresh){return this._throwAwayEvent(function(models){refresh?(this.empty(),Array.each(models,this.addModel.bind(this))):this.processModels(models),this.fireEvent("fetch",[models])}),this.request.get(),this},processModels:function(models){var self=this;Array.each(models,function(model){var exists=model.id&&self.getModelById(model.id);exists?exists.set(model):self.addModel(model)})},_throwAwayEvent:function(callback){var eventName=eventPseudo+this.getRequestId(),self=this,throwAway={};if(!callback||typeof callback!="function")return;return throwAway[eventName]=function(responseObj){callback.apply(self,responseObj),self.removeEvents(throwAway)},this.addEvents(throwAway)}.protect()}),typeof define=="function"&&define.amd?define("epitome-collection-sync",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome}(this),function(exports){var Epitome=typeof require=="function"?require("./epitome"):exports.Epitome;Epitome.Template=new Class({options:{evaluate:/<%([\s\S]+?)%>/g,normal:/<%=([\s\S]+?)%>/g,noMatch:/.^/,escaper:/\\|'|\r|\n|\t|\u2028|\u2029/g,unescaper:/\\(\\|'|r|n|t|u2028|u2029)/g},Implements:[Options],initialize:function(options){this.setOptions(options);var unescaper=this.options.unescaper,escapes=this.escapes={"\\":"\\","'":"'",r:"\r",n:"\n",t:" ",u2028:"\u2028",u2029:"\u2029"};return Object.each(escapes,function(value,key){this[value]=key},escapes),this.unescape=function(code){return code.replace(unescaper,function(match,escape){return escapes[escape]})},this},template:function(str,data){var o=this.options,escapes=this.escapes,unescape=this.unescape,noMatch=o.noMatch,escaper=o.escaper,template,source=["var __p=[],print=function(){__p.push.apply(__p,arguments);};","with(obj||{}){__p.push('",str.replace(escaper,function(match){return"\\"+escapes[match]}).replace(o.normal||noMatch,function(match,code){return"',\nobj['"+unescape(code)+"'],\n'"}).replace(o.evaluate||noMatch,function(match,code){return"');\n"+unescape(code)+"\n;__p.push('"}),"');\n}\nreturn __p.join('');"].join(""),render=new Function("obj","_",source);return data?render(data):(template=function(data){return render.call(this,data)},template.source="function(obj){\n"+source+"\n}",template)}}),typeof define=="function"&&define.amd?define("epitome-template",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome}(this),function(exports){var Epitome=typeof require=="function"?require("./epitome-template"):exports.Epitome;Epitome.View=new Class({Implements:[Options,Events],element:null,collection:null,model:null,options:{template:"",events:{}},initialize:function(options){return options&&options.collection&&(this.setCollection(options.collection),delete options.collection),options&&options.model&&(this.setModel(options.model),delete options.model),this.setOptions(options),this.options.element&&(this.setElement(this.options.element,this.options.events),delete this.options.element),this.fireEvent("ready")},setElement:function(el,events){return this.element&&this.detachEvents()&&this.destroy(),this.element=document.id(el),events&&this.attachEvents(events),this},setCollection:function(collection){var self=this,eventProxy=function(type){return function(){self.fireEvent(type+":collection",arguments)}};return instanceOf(collection,Epitome.Collection)&&(this.collection=collection,this.collection.addEvents({change:eventProxy("change"),fetch:eventProxy("fetch"),add:eventProxy("add"),remove:eventProxy("remove"),sort:eventProxy("sort"),reset:eventProxy("reset")})),this},setModel:function(model){var self=this,eventProxy=function(type){return function(){self.fireEvent(type+":model",arguments)}};return instanceOf(model,Epitome.Model)&&(this.model=model,this.model.addEvents({change:eventProxy("change"),destroy:eventProxy("destroy"),empty:eventProxy("empty")})),this},attachEvents:function(events){var self=this;return Object.each(events,function(method,type){self.element.addEvent(type,function(e){self.fireEvent(method,arguments)})}),this.element.store("attachedEvents",events),this},detachEvents:function(){var events=this.element.retrieve("attachedEvents");return events&&this.element.removeEvents(events).eliminate("attachedEvents"),this},template:function(data,template){template=template||this.options.template;var compiler=this.Template||(this.Template=new Epitome.Template);return compiler.template(template,data)},render:function(){return this.fireEvent("render")},empty:function(soft){return soft?this.element.empty():this.element.set("html",""),this.fireEvent("empty")},dispose:function(){return this.element.dispose(),this.fireEvent("dispose")},destroy:function(){return this.element.destroy(),this.fireEvent("destroy")}}),typeof define=="function"&&define.amd?define("epitome-view",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome}(this),function(exports){var Epitome=typeof require=="function"?require("./epitome"):exports.Epitome,hc="hashchange",hcSupported="on"+hc in window,eventHosts=[window,document],timer,getQueryString=function(queryString){var result={},re=/([^&=]+)=([^&]*)/g,m;while(m=re.exec(queryString))result[decodeURIComponent(m[1])]=decodeURIComponent(m[2]);return result};Element.Events.hashchange={onAdd:function(){var hash=location.hash,check=function(){if(hash==location.hash)return;hash=location.hash,eventHosts.invoke("fireEvent",hc,hash.indexOf("#")==0?hash.substr(1):hash)};hcSupported&&(window.onhashchange=check)||(timer=check.periodical(100))},onRemove:function(){hcSupported&&(window.onhashchange=null)||clearInterval(timer)}},Epitome.Router=new Class({Implements:[Options,Events],options:{triggerOnLoad:!0},routes:{},boundEvents:{},initialize:function(options){var self=this;this.setOptions(options),this.options.routes&&(this.routes=this.options.routes),window.addEvent(hc,function(e){var hash=location.hash,path=hash.split("?")[0],query=hash.split("?")[1]||"",notfound=!0,route;for(route in self.routes){var keys=[],regex=self.normalize(route,keys,!0,!1),found=regex.exec(path),routeEvent=!1;if(found){notfound=!1,self.req=found[0];var args=found.slice(1),param={};Array.each(args,function(a,i){typeof keys[i]!="undefined"&&(param[keys[i].name]=a)}),self.route=route,self.param=param||{},self.query=query&&getQueryString(query),routeEvent=self.routes[route],self.fireEvent("before",routeEvent),routeEvent&&self.$events[routeEvent]?(self.fireEvent(routeEvent+":before"),self.fireEvent(routeEvent,Object.values(self.param))):self.fireEvent("error",["Route",routeEvent,"is undefined"].join(" ")),self.fireEvent("after",routeEvent),routeEvent&&self.fireEvent(routeEvent+":after");break}}notfound&&self.fireEvent("undefined")}),this.fireEvent("ready"),this.options.triggerOnLoad&&window.fireEvent(hc)},navigate:function(route,trigger){location.hash==route&&trigger?window.fireEvent(hc):location.hash=route},normalize:function(path,keys,sensitive,strict){return path instanceof RegExp?path:(path=path.concat(strict?"":"/?").replace(/\/\(/g,"(?:/").replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g,function(_,slash,format,key,capture,optional){return keys.push({name:key,optional:!!optional}),slash=slash||"",[optional?"":slash,"(?:",optional?slash:"",(format||"")+(capture||format&&"([^/.]+?)"||"([^/]+?)")+")",optional||""].join("")}).replace(/([\/.])/g,"\\$1").replace(/\*/g,"(.*)"),new RegExp("^"+path+"$",sensitive?"":"i"))},addRoute:function(obj){return!obj||!obj.route||!obj.id||!obj.events?this.fireEvent("error","Please include route, id and events in the argument object when adding a route"):obj.id.length?this.routes[obj.route]?this.fireEvent("error",'Route "{route}" or id "{id}" already exists, aborting'.substitute(obj)):(this.routes[obj.route]=obj.id,this.addEvents(this.boundEvents[obj.route]=obj.events),this.fireEvent("route:add",obj)):this.fireEvent("error","Route id cannot be empty, aborting")},removeRoute:function(route){return!route||!this.routes[route]||!this.boundEvents[route]?this.fireEvent("error","Could not find route or route is not removable"):(this.removeEvents(this.boundEvents[route]),delete this.routes[route],delete this.boundEvents[route],this.fireEvent("route:remove",route))}}),typeof define=="function"&&define.amd?define("epitome-router",[],function(){return Epitome}):typeof module=="object"?module.exports=Epitome:exports.Epitome=Epitome}(this)
\ No newline at end of file
(function(e){var t=function(){return{}};typeof define=="function"&&define.amd?define("epitome",[],t):e.Epitome=t(e)})(this),function(e){var t=function(e){var t=e.isEqual=function(e,n,r){r=r||[];if(e===n)return e!==0||1/e==1/n;if(e==null||n==null)return e===n;var i=typeOf(e),s=typeOf(n);if(i!=s)return!1;switch(i){case"string":return e==String(n);case"number":return e!=+e?n!=+n:e==0?1/e==1/n:e==+n;case"date":case"boolean":return+e==+n;case"regexp":return e.source==n.source&&e.global==n.global&&e.multiline==n.multiline&&e.ignoreCase==n.ignoreCase}if(typeof e!="object"||typeof n!="object")return!1;var o=r.length;while(o--)if(r[o]==e)return!0;r.push(e);var u=0,a=!0;if(i=="array"){u=e.length,a=u==n.length;if(a)while(u--)if(!(a=u in e==u in n&&t(e[u],n[u],r)))break}else{if("constructor"in e!="constructor"in n||e.constructor!=n.constructor)return!1;for(var f in e)if(e.hasOwnProperty(f)){u++;if(!(a=n.hasOwnProperty(f)&&t(e[f],n[f],r)))break}if(a){for(f in n)if(n.hasOwnProperty(f)&&!(u--))break;a=!u}}return r.pop(),a};return e};typeof define=="function"&&define.amd?define("epitome-isequal",["./epitome"],t):e.Epitome=t(e)}(this),function(e){var t=function(e){return e.Model=new Class({Implements:[Options,Events],_attributes:{},properties:{id:{get:function(){var e=this._attributes.id||(this._attributes.id=String.uniqueID());return this.cid||(this.cid=e),e}}},options:{defaults:{}},collections:[],initialize:function(e,t){return t&&t.defaults&&(this.options.defaults=Object.merge(this.options.defaults,t.defaults)),e=e&&typeOf(e)==="object"?e:{},this.set(Object.merge(this.options.defaults,e)),this.setOptions(t),this.fireEvent("ready")},set:function(){this.propertiesChanged=[],this._set.apply(this,arguments),this.propertiesChanged.length&&this.fireEvent("change",this.get(this.propertiesChanged))},_set:function(t,n){return!t||typeof n=="undefined"?this:this.properties[t]&&this.properties[t].set?this.properties[t].set.call(this,n):this._attributes[t]&&e.isEqual(this._attributes[t],n)?this:(n===null?delete this._attributes[t]:this._attributes[t]=n,this.fireEvent("change:"+t,n),this.propertiesChanged.push(t),this)}.overloadSetter(),get:function(e){return e&&this.properties[e]&&this.properties[e].get?this.properties[e].get.call(this):e&&typeof this._attributes[e]!="undefined"?this._attributes[e]:null}.overloadGetter(),unset:function(){var e=Array.prototype.slice.apply(arguments),t={},n=e.length;return n?(Array.each(Array.flatten(e),function(e){t[e]=null}),this.set(t),this):this},toJSON:function(){return Object.clone(this._attributes)},empty:function(){var e=Object.keys(this.toJSON()),t=this;this.fireEvent("change",[e]),Array.each(e,function(e){t.fireEvent("change:"+e,null)},this),this._attributes={},this.fireEvent("empty")},destroy:function(){this._attributes={},this.fireEvent("destroy")}}),e};typeof define=="function"&&define.amd?define("epitome-model",["./epitome-isequal"],t):e.Epitome=t(e)}(this),function(e){var t=function(e){var t=e.Model,n="sync:",r={create:"POST",read:"GET",update:"PUT",delete_:"DELETE"};return t.Sync=new Class({Extends:t,properties:{id:{get:function(){var e=this._attributes.id||(this._attributes.id=String.uniqueID());return this.cid||(this.cid=e),e}},urlRoot:{set:function(e){this.urlRoot=e,delete this._attributes.urlRoot},get:function(){var e=this.urlRoot||this.options.urlRoot||"no-urlRoot-set";return e.charAt(e.length-1)!="/"&&(e+="/"),e}}},options:{emulateREST:!1},initialize:function(e,t){this.setupSync(),this.parent(e,t)},sync:function(e,t){var n={};e=e&&r[e]?r[e]:r.read,n.method=e;if(e==r.create||e==r.update)n.data=t||this.toJSON();return n.url=this.get("urlRoot")+this.get("id")+"/",this.request.setOptions(n),this.request[e](t),this},setupSync:function(){var e=this,t=0,i=function(){t++};return this.getRequestId=function(){return t+1},this.request=new Request.JSON({link:"chain",url:this.get("urlRoot"),emulation:this.options.emulateREST,onRequest:i,onCancel:function(){this.removeEvents(n+t)},onSuccess:function(r){r=e.parse&&e.parse(r),e.fireEvent(n+t,[r]),e.fireEvent("sync",[r,this.options.method,this.options.data])},onFailure:function(){e.fireEvent(n+"error",[this.options.method,this.options.url,this.options.data])}}),Object.each(r,function(t,n){e[n]=function(e){this.sync(n,e)}}),this},_throwAwaySyncEvent:function(e,t){e=e||n+this.getRequestId();var r=this,i={};return i[e]=function(e){e&&typeof e=="object"&&(r.set(e),t&&t.call(r,e)),r.removeEvents(i)},this.addEvents(i)}.protect(),parse:function(e){return e},fetch:function(){return this._throwAwaySyncEvent(n+this.getRequestId(),function(){this.fireEvent("fetch"),this.isNewModel=!1}),this.read(),this},save:function(e,t){var r=["update","create"][+this.isNew()];if(e){var i=typeOf(e),s=i=="object"||i=="string"&&typeof t!="undefined";s&&this._set.apply(this,arguments)}return this._throwAwaySyncEvent(n+this.getRequestId(),function(){this.fireEvent("save"),this.fireEvent(r)}),this[r](),this.isNewModel=!1,this},destroy:function(){this._throwAwaySyncEvent(n+this.getRequestId(),function(){this._attributes={},this.delete_(),this.fireEvent("destroy")})},isNew:function(){return typeof this.isNewModel=="undefined"&&(this.isNewModel=!0),this.isNewModel}}),e};typeof define=="function"&&define.amd?define("epitome-model-sync",["./epitome-model"],t):e.Epitome=t(e)}(this),function(e){var t=function(t){return t.Storage=function(){var t=typeof e.localStorage=="object"&&!!e.localStorage.getItem,n="localStorage",r="sessionStorage",i=function(n){var r,i="epitome-"+n,s={},o="model";if(t)try{s=JSON.decode(e[n].getItem(i))||s}catch(u){t=!1}if(!t)try{r=JSON.decode(e.name),r&&typeof r=="object"&&r[i]&&(s=r[i])}catch(u){h()}var a={store:function(e){e=e||this.toJSON(),l([o,this.get("id")].join(":"),e),this.fireEvent("store",e)},eliminate:function(){return c([o,this.get("id")].join(":")),this.fireEvent("eliminate")},retrieve:function(){var e=f([o,this.get("id")].join(":"))||null;return this.fireEvent("retrieve",e),e}},f=function(e){return s[e]||null},l=function(r,o){s=JSON.decode(e[n].getItem(i))||s,s[r]=o;if(t)try{e[n].setItem(i,JSON.encode(s))}catch(u){}else h();return this},c=function(r){delete s[r];if(t)try{e[n].setItem(i,JSON.encode(s))}catch(o){}else h()},h=function(){var t={},n=JSON.decode(e.name);t[i]=s,e.name=JSON.encode(Object.merge(t,n))};return function(e){return e&&(o=e),new Class(Object.clone(a))}};return{localStorage:i(n),sessionStorage:i(r)}}(),t};typeof define=="function"&&define.amd?define("epitome-storage",["./epitome"],t):e.Epitome=t(e)}(this),function(e){var t=function(e){var t=["forEach","each","invoke","filter","map","some","indexOf","contains","getRandom","getLast"];Function.extend({monitorModelEvents:function(e,t){var n=this;return t=t||this,!e||!e.fireEvent?this:function(r,i,s){n.apply(t,arguments),e.getModelByCID(t.cid)&&e.fireEvent(r,Array.flatten([t,i]),s)}}});var n=e.Collection=new Class({Implements:[Options,Events],model:e.Model,_models:[],initialize:function(e,t){return this.setOptions(t),e&&this.setUp(e),this.id=this.options.id||String.uniqueID(),this.fireEvent("ready")},setUp:function(e){return e=Array.from(e),Array.each(e,this.addModel.bind(this)),this.addEvent("destroy",this.removeModel.bind(this)),this},addModel:function(e,t){var n;return typeOf(e)=="object"&&!instanceOf(e,this.model)&&(e=new this.model(e)),e.cid=e.cid||e.get("id")||String.uniqueID(),n=this.getModelByCID(e.cid),n&&t!==!0?this.fireEvent("add:error",e):(n&&t===!0&&(this._models[this._models.indexOf(e)]=e),e.fireEvent=Function.monitorModelEvents.apply(e.fireEvent,[this,e]),this._models.push(e),e.collections.include(this),this.length=this._models.length,this.fireEvent("add",[e,e.cid]).fireEvent("reset",[e,e.cid]))},removeModel:function(e){var t=this;return e=Array.from(e),Array.each(e,function(e){e.collections.erase(t),e.collections.length||delete e.fireEvent,Array.erase(t._models,e),t.length=t._models.length,t.fireEvent("remove",[e,e.cid])}),this.fireEvent("reset",[e])},get:function(e){return this[e]},getModelByCID:function(e){var t=null;return this.some(function(n){return n.cid==e&&(t=n)}),t},getModelById:function(e){var t=null;return this.some(function(n){return n.get("id")==e&&(t=n)}),t},getModel:function(e){return this._models[e]},toJSON:function(){var e=function(e){return e.toJSON()};return Array.map(this._models,e)},empty:function(){return this.removeModel(this._models),this.fireEvent("empty")},sort:function(e){if(!e)return this._models.sort(),this.fireEvent("sort");if(typeof e=="function")return this.model.sort(e),this.fireEvent("sort");var t="asc",n=e.split(":"),r=n[0],i=function(e,t){return e<t?-1:e>t?1:0};return n[1]&&(t=n[1]),this._models.sort(function(e,n){var s=e.get(r),o=n.get(r),u=i(s,o),a={asc:u,desc:-u};return typeof a[t]=="undefined"&&(t="asc"),a[t]}),this.fireEvent("sort")},reverse:function(){return Array.reverse(this._models),this.fireEvent("sort")}});return Array.each(t,function(e){n.implement(e,function(){return Array.prototype[e].apply(this._models,arguments)})}),e};typeof define=="function"&&define.amd?define("epitome-collection",["./epitome-model"],t):e.Epitome=t(e)}(this),function(e){var t=function(e){var t="no-urlRoot-set",n="fetch:";return e.Collection.Sync=new Class({Extends:e.Collection,options:{urlRoot:t},initialize:function(e,t){this.setupSync(),this.parent(e,t)},setupSync:function(){var e=this,t=0,r=function(){t++};return this.getRequestId=function(){return t+1},this.request=new Request.JSON({link:"chain",url:this.options.urlRoot,emulation:this.options.emulateREST,onRequest:r,onCancel:function(){this.removeEvents(n+t)},onSuccess:function(r){r=e.parse&&e.parse(r),e.fireEvent(n+t,[[r]])},onFailure:function(){e.fireEvent(n+"error",[this.options.method,this.options.url,this.options.data])}}),this},parse:function(e){return e},fetch:function(e){return this._throwAwayEvent(function(t){e?(this.empty(),Array.each(t,this.addModel.bind(this))):this.processModels(t),this.fireEvent("fetch",[t])}),this.request.get(),this},processModels:function(e){var t=this;Array.each(e,function(e){var n=e.id&&t.getModelById(e.id);n?n.set(e):t.addModel(e)})},_throwAwayEvent:function(e){var t=n+this.getRequestId(),r=this,i={};if(!e||typeof e!="function")return;return i[t]=function(t){e.apply(r,t),r.removeEvents(i)},this.addEvents(i)}.protect()}),e};typeof define=="function"&&define.amd?define("epitome-collection-sync",["./epitome-model"],t):e.Epitome=t(e)}(this),function(e){var t=function(e){return e.Template=new Class({options:{evaluate:/<%([\s\S]+?)%>/g,normal:/<%=([\s\S]+?)%>/g,noMatch:/.^/,escaper:/\\|'|\r|\n|\t|\u2028|\u2029/g,unescaper:/\\(\\|'|r|n|t|u2028|u2029)/g},Implements:[Options],initialize:function(e){this.setOptions(e);var t=this.options.unescaper,n=this.escapes={"\\":"\\","'":"'",r:"\r",n:"\n",t:" ",u2028:"\u2028",u2029:"\u2029"};return Object.each(n,function(e,t){this[e]=t},n),this.unescape=function(e){return e.replace(t,function(e,t){return n[t]})},this},template:function(e,t){var n=this.options,r=this.escapes,i=this.unescape,s=n.noMatch,o=n.escaper,u,a=["var __p=[],print=function(){__p.push.apply(__p,arguments);};","with(obj||{}){__p.push('",e.replace(o,function(e){return"\\"+r[e]}).replace(n.normal||s,function(e,t){return"',\nobj['"+i(t)+"'],\n'"}).replace(n.evaluate||s,function(e,t){return"');\n"+i(t)+"\n;__p.push('"}),"');\n}\nreturn __p.join('');"].join(""),f=new Function("obj","_",a);return t?f(t):(u=function(e){return f.call(this,e)},u.source="function(obj){\n"+a+"\n}",u)}}),e};typeof define=="function"&&define.amd?define("epitome-template",["./epitome"],t):e.Epitome=t(e)}(this),function(e){var t=function(e){return e.View=new Class({Implements:[Options,Events],element:null,collection:null,model:null,options:{template:"",events:{}},initialize:function(e){return e&&e.collection&&(this.setCollection(e.collection),delete e.collection),e&&e.model&&(this.setModel(e.model),delete e.model),this.setOptions(e),this.options.element&&(this.setElement(this.options.element,this.options.events),delete this.options.element),this.fireEvent("ready")},setElement:function(e,t){return this.element&&this.detachEvents()&&this.destroy(),this.element=document.id(e),t&&this.attachEvents(t),this},setCollection:function(t){var n=this,r=function(e){return function(){n.fireEvent(e+":collection",arguments)}};return instanceOf(t,e.Collection)&&(this.collection=t,this.collection.addEvents({change:r("change"),fetch:r("fetch"),add:r("add"),remove:r("remove"),sort:r("sort"),reset:r("reset")})),this},setModel:function(t){var n=this,r=function(e){return function(){n.fireEvent(e+":model",arguments)}};return instanceOf(t,e.Model)&&(this.model=t,this.model.addEvents({change:r("change"),destroy:r("destroy"),empty:r("empty")})),this},attachEvents:function(e){var t=this;return Object.each(e,function(e,n){t.element.addEvent(n,function(n){t.fireEvent(e,arguments)})}),this.element.store("attachedEvents",e),this},detachEvents:function(){var e=this.element.retrieve("attachedEvents");return e&&this.element.removeEvents(e).eliminate("attachedEvents"),this},template:function(t,n){n=n||this.options.template;var r=this.Template||(this.Template=new e.Template);return r.template(n,t)},render:function(){return this.fireEvent("render")},empty:function(e){return e?this.element.empty():this.element.set("html",""),this.fireEvent("empty")},dispose:function(){return this.element.dispose(),this.fireEvent("dispose")},destroy:function(){return this.element.destroy(),this.fireEvent("destroy")}}),e};typeof define=="function"&&define.amd?define("epitome-view",["./epitome-template","./epitome-model","./epitome-collection"],t):e.Epitome=t(e)}(this),function(e){var t=function(e){var t="hashchange",n="on"+t in window,r=[window,document],i,s=function(e){var t={},n=/([^&=]+)=([^&]*)/g,r;while(r=n.exec(e))t[decodeURIComponent(r[1])]=decodeURIComponent(r[2]);return t};return Element.Events.hashchange={onAdd:function(){var e=location.hash,s=function(){if(e==location.hash)return;e=location.hash,r.invoke("fireEvent",t,e.indexOf("#")==0?e.substr(1):e)};n&&(window.onhashchange=s)||(i=s.periodical(100))},onRemove:function(){n&&(window.onhashchange=null)||clearInterval(i)}},e.Router=new Class({Implements:[Options,Events],options:{triggerOnLoad:!0},routes:{},boundEvents:{},initialize:function(e){var n=this;this.setOptions(e),this.options.routes&&(this.routes=this.options.routes),window.addEvent(t,function(e){var t=location.hash,r=t.split("?")[0],i=t.split("?")[1]||"",o=!0,u;for(u in n.routes){var a=[],f=n.normalize(u,a,!0,!1),l=f.exec(r),c=!1;if(l){o=!1,n.req=l[0];var h=l.slice(1),p={};Array.each(h,function(e,t){typeof a[t]!="undefined"&&(p[a[t].name]=e)}),n.route=u,n.param=p||{},n.query=i&&s(i),c=n.routes[u],n.fireEvent("before",c),c&&n.$events[c]?(n.fireEvent(c+":before"),n.fireEvent(c,Object.values(n.param))):n.fireEvent("error",["Route",c,"is undefined"].join(" ")),n.fireEvent("after",c),c&&n.fireEvent(c+":after");break}}o&&n.fireEvent("undefined")}),this.fireEvent("ready"),this.options.triggerOnLoad&&window.fireEvent(t)},navigate:function(e,n){location.hash==e&&n?window.fireEvent(t):location.hash=e},normalize:function(e,t,n,r){return e instanceof RegExp?e:(e=e.concat(r?"":"/?").replace(/\/\(/g,"(?:/").replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g,function(e,n,r,i,s,o){return t.push({name:i,optional:!!o}),n=n||"",[o?"":n,"(?:",o?n:"",(r||"")+(s||r&&"([^/.]+?)"||"([^/]+?)")+")",o||""].join("")}).replace(/([\/.])/g,"\\$1").replace(/\*/g,"(.*)"),new RegExp("^"+e+"$",n?"":"i"))},addRoute:function(e){return!e||!e.route||!e.id||!e.events?this.fireEvent("error","Please include route, id and events in the argument object when adding a route"):e.id.length?this.routes[e.route]?this.fireEvent("error",'Route "{route}" or id "{id}" already exists, aborting'.substitute(e)):(this.routes[e.route]=e.id,this.addEvents(this.boundEvents[e.route]=e.events),this.fireEvent("route:add",e)):this.fireEvent("error","Route id cannot be empty, aborting")},removeRoute:function(e){return!e||!this.routes[e]||!this.boundEvents[e]?this.fireEvent("error","Could not find route or route is not removable"):(this.removeEvents(this.boundEvents[e]),delete this.routes[e],delete this.boundEvents[e],this.fireEvent("route:remove",e))}}),e};typeof define=="function"&&define.amd?define("epitome-router",["./epitome"],t):e.Epitome=t(e)}(this)
\ No newline at end of file
/*global Epitome, App, Class */
/*global Epitome, App */
/*jshint mootools:true */
(function(window) {
'use strict';
......@@ -11,7 +12,7 @@
options: {
defaults: {
completed: 'active',
completed: false,
title: ''
}
}
......
/*global Epitome, App, Class, Elements, Element */
/*global Epitome, App */
/*jshint mootools:true */
(function( window ) {
'use strict';
......@@ -34,94 +35,103 @@
},
// when collection changes, save the data to storage and re-render
'onChange:collection': function( model ) {
'onChange:collection': function( model ) {
this.collection.store();
this.render();
},
// when models get removed, re-render
'onRemove:collection': function( model ) {
'onRemove:collection': function( model ) {
this.collection.store();
this.render();
},
// when sort is applied, re-render
'onSort:collection': function() {
'onSort:collection': function() {
this.collection.store();
this.render();
},
// when a new model is added, re-render
'onAdd:collection': function( model ) {
'onAdd:collection': function( model ) {
this.collection.store();
this.render();
},
// handler for the edit event
onEditing: function( e, el ) {
if ( e && e.stop ) {
e.stop();
}
onEditing: function( e, el ) {
if ( e && e.stop ) {
e.stop();
}
el.addClass( this.options.editingClass );
el.getElement( this.options.input ).focus();
},
el.addClass( this.options.editingClass );
el.getElement( this.options.input ).focus();
// when enter pressed while editing
onHandleKeypress: function( e, el ) {
// on enter, blur() and let it bubble to onUpdate.
if ( e.key === 'enter' ) {
el.blur();
}
},
// fired when editing ends
onUpdate: function( e, el ) {
var p = el.getParent('li').removeClass( this.options.editingClass );
var val = el.get('value').trim();
onUpdate: function( e, el ) {
var p = el.getParent( 'li ').removeClass( this.options.editingClass );
var val = el.get( 'value' ).trim();
if ( !val.length ) {
if ( !val.length ) {
// the render method stores the model into the element, get it and remove
this.collection.removeModel( p.retrieve('model') );
this.collection.removeModel( p.retrieve( 'model' ) );
return;
}
p.retrieve('model').set( 'title', val );
p.retrieve( 'model' ).set( 'title', val );
},
// handler for clicks on the checkboxes
onStatusChange: function( e, el ) {
var p = el.getParent('li');
var done = !!el.get('checked') ? 'completed' : 'active';
onStatusChange: function( e, el ) {
var p = el.getParent( 'li' );
var done = !!el.get( 'checked' );
p.retrieve('model').set( 'completed', done );
p.retrieve( 'model' ).set( 'completed', done );
},
// when the X is pressed, drop the model
onRemoveItem: function( e, el ) {
if ( e && e.stop ) {
e.stop();
}
onRemoveItem: function( e, el ) {
if ( e && e.stop ) {
e.stop();
}
// the render method stores the model into the element, get it and remove
this.collection.removeModel( el.getParent('li').retrieve('model') );
this.collection.removeModel( el.getParent( 'li' ).retrieve( 'model' ) );
}
},
render: function() {
// main render method, will also fire onRender
var todos = new Elements();
var self = this;
var todos = new Elements();
var self = this;
// empty the container.
this.empty();
// the route controller works with the todoFilter to help determine what we render.
this.collection.filter( this.collection.todoFilter.bind( this.collection ) ).each(function( model ) {
var obj = model.toJSON();
var li = new Element( self.tagName ).toggleClass( 'completed', obj.completed === 'completed' ).store( 'model', model );
this.collection.filter( this.collection.todoFilter.bind( this.collection ) ).each(function( model ) {
var obj = model.toJSON();
var li = new Element( self.tagName ).toggleClass( 'completed', obj.completed ).store( 'model', model );
// help the template to avoid slower logic in the template layer
obj.completedCheckbox = obj.completed === 'completed' ? 'checked' : '';
obj.completedCheckbox = obj.completed ? 'checked' : '';
// compile template and store resulting element in our Elements collection
todos.push( li.set( 'html', self.template( obj ) ) );
todos.push( li.set( 'html', self.template( obj ) ) );
});
// inject the elements collection into the container element
this.element.adopt( todos );
this.element.adopt( todos );
// propagate the render event.
this.parent();
......
/*global Epitome, App, Class */
/*global Epitome, App */
/*jshint mootools:true */
(function( window ) {
'use strict';
......@@ -28,29 +29,29 @@
toggleAll: 'toggle-all',
onToggleAll: function( e, el ) {
onToggleAll: function( e, el ) {
// all todos will change their models to the new completed value
var state = el.get('checked') ? 'completed' : 'active';
this.collection.each(function( model ) {
model.set( 'completed', state );
var state = !!el.get( 'checked' );
this.collection.each( function( model ) {
model.set( 'completed', state );
});
},
onHandleKeypress: function( e, el ) {
onHandleKeypress: function( e, el ) {
// on enter, submit.
if ( e.key === 'enter' ) {
if ( e.key === 'enter' ) {
this.addTodo();
}
}
},
onClearCompleted: function() {
// because removing a model re-indexes so we don't get a sparse array, cannot apply that in a normal loop.
var toRemove = this.collection.filter(function( model ) {
return model.get('completed') === 'completed';
var toRemove = this.collection.filter(function( model ) {
return model.get( 'completed' );
});
// removeModel actually supports a single model or an array of models as arguments.
this.collection.removeModel( toRemove );
this.collection.removeModel( toRemove );
this.render();
},
......@@ -70,14 +71,14 @@
}
},
initialize: function( options ) {
initialize: function( options ) {
// call default view constructor.
this.parent( options );
this.parent( options );
// store some pointers to static elements
this.newTodo = document.id( this.options.newTodo );
this.footer = document.id( this.options.footer );
this.toggleAll = document.id( this.options.toggleAll );
this.newTodo = document.id( this.options.newTodo );
this.footer = document.id( this.options.footer );
this.toggleAll = document.id( this.options.toggleAll );
// draw it.
this.render();
......@@ -85,43 +86,43 @@
addTodo: function() {
// adding a new model when data exists
var val = this.newTodo.get('value').trim();
var val = this.newTodo.get( 'value' ).trim();
if ( val.length ) {
if ( val.length ) {
this.collection.addModel({
title: val,
completed: 'active'
completed: false
});
}
// clear the input
this.newTodo.set( 'value', '' );
this.newTodo.set( 'value', '' );
},
render: function() {
// main method to output everything. well. the footer anyway.
// work out what we have remaining and what is complete
var remaining = 0;
var remaining = 0;
var completed = this.collection.filter(function( el ) {
var status = el.get('completed') === 'completed';
var completed = this.collection.filter(function( model ) {
var status = model.get( 'completed' );
if ( !status ) {
remaining++;
}
if ( status === false ) {
remaining++;
}
return status;
}).length;
return status;
}).length;
// output footer
this.footer.set( 'html', this.template({
this.footer.set( 'html', this.template({
completed: completed,
remaining: remaining
}));
// auto-correct the toggle-all checkbox with the new stats.
this.toggleAll.set( 'checked', this.collection.length ? !remaining : false );
this.toggleAll.set( 'checked', this.collection.length ? !remaining : false );
}
});
}( window ));
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment