From 5589bd05ada8cf1f6f65cb001e559f65c4531d55 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar Date: Tue, 11 Dec 2007 18:12:23 +0530 Subject: [PATCH] trimpath junction like model server only does reading/writing of json objects. 99% of application logic goes to javascript. --- app/ext/jquery-1.2.1.min.js | 31 +++ app/ext/trimpath-template-1.0.38.js | 397 ++++++++++++++++++++++++++++++++++++ app/hyena.js | 10 + app/index.html | 45 ++++ screen.css => app/screen.css | 0 helpers.py | 39 ---- index.mako | 32 --- server.py | 58 +++--- 8 files changed, 517 insertions(+), 95 deletions(-) create mode 100644 app/ext/jquery-1.2.1.min.js create mode 100644 app/ext/trimpath-template-1.0.38.js create mode 100644 app/hyena.js create mode 100644 app/index.html rename screen.css => app/screen.css (100%) delete mode 100644 helpers.py delete mode 100644 index.mako diff --git a/app/ext/jquery-1.2.1.min.js b/app/ext/jquery-1.2.1.min.js new file mode 100644 index 0000000..0367037 --- /dev/null +++ b/app/ext/jquery-1.2.1.min.js @@ -0,0 +1,31 @@ +/* + * jQuery 1.2.1 - New Wave Javascript + * + * Copyright (c) 2007 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $ + * $Rev: 3353 $ + */ +(function(){if(typeof jQuery!="undefined")var _jQuery=jQuery;var jQuery=window.jQuery=function(selector,context){return this instanceof jQuery?this.init(selector,context):new jQuery(selector,context);};if(typeof $!="undefined")var _$=$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(typeof selector=="string"){var m=quickExpr.exec(selector);if(m&&(m[1]||!context)){if(m[1])selector=jQuery.clean([m[1]],context);else{var tmp=document.getElementById(m[3]);if(tmp)if(tmp.id!=m[3])return jQuery().find(selector);else{this[0]=tmp;this.length=1;return this;}else +selector=[];}}else +return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.1",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(a){var ret=jQuery(a);ret.prevObject=this;return ret;},setArray:function(a){this.length=0;Array.prototype.push.apply(this,a);return this;},each:function(fn,args){return jQuery.each(this,fn,args);},index:function(obj){var pos=-1;this.each(function(i){if(this==obj)pos=i;});return pos;},attr:function(key,value,type){var obj=key;if(key.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],key)||undefined;else{obj={};obj[key]=value;}return this.each(function(index){for(var prop in obj)jQuery.attr(type?this.style:this,prop,jQuery.prop(this,obj[prop],type,index,prop));});},css:function(key,value){return this.attr(key,value,"curCSS");},text:function(e){if(typeof e!="object"&&e!=null)return this.empty().append(document.createTextNode(e));var t="";jQuery.each(e||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)t+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return t;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,1,function(a){this.appendChild(a);});},prepend:function(){return this.domManip(arguments,true,-1,function(a){this.insertBefore(a,this.firstChild);});},before:function(){return this.domManip(arguments,false,1,function(a){this.parentNode.insertBefore(a,this);});},after:function(){return this.domManip(arguments,false,-1,function(a){this.parentNode.insertBefore(a,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(t){var data=jQuery.map(this,function(a){return jQuery.find(t,a);});return this.pushStack(/[^+>] [^+>]/.test(t)||t.indexOf("..")>-1?jQuery.unique(data):data);},clone:function(events){var ret=this.map(function(){return this.outerHTML?jQuery(this.outerHTML)[0]:this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(t){return this.pushStack(jQuery.isFunction(t)&&jQuery.grep(this,function(el,index){return t.apply(el,[index]);})||jQuery.multiFilter(t,this));},not:function(t){return this.pushStack(t.constructor==String&&jQuery.multiFilter(t,this,true)||jQuery.grep(this,function(a){return(t.constructor==Array||t.jquery)?jQuery.inArray(a,t)<0:a!=t;}));},add:function(t){return this.pushStack(jQuery.merge(this.get(),t.constructor==String?jQuery(t).get():t.length!=undefined&&(!t.nodeName||jQuery.nodeName(t,"form"))?t:[t]));},is:function(expr){return expr?jQuery.multiFilter(expr,this).length>0:false;},hasClass:function(expr){return this.is("."+expr);},val:function(val){if(val==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,a=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,val)>=0);else if(jQuery.nodeName(this,"select")){var tmp=val.constructor==Array?val:[val];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,tmp)>=0||jQuery.inArray(this.text,tmp)>=0);});if(!tmp.length)this.selectedIndex=-1;}else +this.value=val;});},html:function(val){return val==undefined?(this.length?this[0].innerHTML:null):this.empty().append(val);},replaceWith:function(val){return this.after(val).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(fn){return this.pushStack(jQuery.map(this,function(elem,i){return fn.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},domManip:function(args,table,dir,fn){var clone=this.length>1,a;return this.each(function(){if(!a){a=jQuery.clean(args,this.ownerDocument);if(dir<0)a.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(a[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(document.createElement("tbody"));jQuery.each(a,function(){var elem=clone?this.cloneNode(true):this;if(!evalScript(0,elem))fn.call(obj,elem);});});}};function evalScript(i,elem){var script=jQuery.nodeName(elem,"script");if(script){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}else if(elem.nodeType==1)jQuery("script",elem).each(evalScript);return script;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},a=1,al=arguments.length,deep=false;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};}if(al==1){target=this;a=0;}var prop;for(;a-1;}},swap:function(e,o,f){for(var i in o){e.style["old"+i]=e.style[i];e.style[i]=o[i];}f.apply(e,[]);for(var i in o)e.style[i]=e.style["old"+i];},css:function(e,p){if(p=="height"||p=="width"){var old={},oHeight,oWidth,d=["Top","Bottom","Right","Left"];jQuery.each(d,function(){old["padding"+this]=0;old["border"+this+"Width"]=0;});jQuery.swap(e,old,function(){if(jQuery(e).is(':visible')){oHeight=e.offsetHeight;oWidth=e.offsetWidth;}else{e=jQuery(e.cloneNode(true)).find(":radio").removeAttr("checked").end().css({visibility:"hidden",position:"absolute",display:"block",right:"0",left:"0"}).appendTo(e.parentNode)[0];var parPos=jQuery.css(e.parentNode,"position")||"static";if(parPos=="static")e.parentNode.style.position="relative";oHeight=e.clientHeight;oWidth=e.clientWidth;if(parPos=="static")e.parentNode.style.position="static";e.parentNode.removeChild(e);}});return p=="height"?oHeight:oWidth;}return jQuery.curCSS(e,p);},curCSS:function(elem,prop,force){var ret,stack=[],swap=[];function color(a){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(a,null);return!ret||ret.getPropertyValue("color")=="";}if(prop=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(prop.match(/float/i))prop=styleFloat;if(!force&&elem.style[prop])ret=elem.style[prop];else if(document.defaultView&&document.defaultView.getComputedStyle){if(prop.match(/float/i))prop="float";prop=prop.replace(/([A-Z])/g,"-$1").toLowerCase();var cur=document.defaultView.getComputedStyle(elem,null);if(cur&&!color(elem))ret=cur.getPropertyValue(prop);else{for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(a=0;a]*?)\/>/g,function(m,all,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)?m:all+">";});var s=jQuery.trim(arg).toLowerCase(),div=doc.createElement("div"),tb=[];var wrap=!s.indexOf("",""]||!s.indexOf("",""]||s.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!s.indexOf("",""]||(!s.indexOf("",""]||!s.indexOf("",""]||jQuery.browser.msie&&[1,"div
","
"]||[0,"",""];div.innerHTML=wrap[1]+arg+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){if(!s.indexOf(""&&s.indexOf("=0;--n)if(jQuery.nodeName(tb[n],"tbody")&&!tb[n].childNodes.length)tb[n].parentNode.removeChild(tb[n]);if(/^\s/.test(arg))div.insertBefore(doc.createTextNode(arg.match(/^\s*/)[0]),div.firstChild);}arg=jQuery.makeArray(div.childNodes);}if(0===arg.length&&(!jQuery.nodeName(arg,"form")&&!jQuery.nodeName(arg,"select")))return;if(arg[0]==undefined||jQuery.nodeName(arg,"form")||arg.options)r.push(arg);else +r=jQuery.merge(r,arg);});return r;},attr:function(elem,name,value){var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(t){return(t||"").replace(/^\s+|\s+$/g,"");},makeArray:function(a){var r=[];if(typeof a!="array")for(var i=0,al=a.length;i\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":"m[2]=='*'||jQuery.nodeName(a,m[2])","#":"a.getAttribute('id')==m[2]",":":{lt:"im[3]-0",nth:"m[3]-0==i",eq:"m[3]-0==i",first:"i==0",last:"i==r.length-1",even:"i%2==0",odd:"i%2","first-child":"a.parentNode.getElementsByTagName('*')[0]==a","last-child":"jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a","only-child":"!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",parent:"a.firstChild",empty:"!a.firstChild",contains:"(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",visible:'"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',hidden:'"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',enabled:"!a.disabled",disabled:"a.disabled",checked:"a.checked",selected:"a.selected||jQuery.attr(a,'selected')",text:"'text'==a.type",radio:"'radio'==a.type",checkbox:"'checkbox'==a.type",file:"'file'==a.type",password:"'password'==a.type",submit:"'submit'==a.type",image:"'image'==a.type",reset:"'reset'==a.type",button:'"button"==a.type||jQuery.nodeName(a,"button")',input:"/input|select|textarea|button/i.test(a.nodeName)",has:"jQuery.find(m[3],a).length",header:"/h\\d/i.test(a.nodeName)",animated:"jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&!context.nodeType)context=null;context=context||document;var ret=[context],done=[],last;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){var nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName.toUpperCase()))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var nodeName=m[2],merge={};m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=jQuery.filter(m[3],r,true).r;else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(\d*)n\+?(\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"n+"+m[3]||m[3]),first=(test[1]||1)-0,last=test[2]-0;for(var i=0,rl=r.length;i<\/script>");var script=document.getElementById("__ie_init");if(script)script.onreadystatechange=function(){if(this.readyState!="complete")return;jQuery.ready();};script=null;}else if(jQuery.browser.safari)jQuery.safariTimer=setInterval(function(){if(document.readyState=="loaded"||document.readyState=="complete"){clearInterval(jQuery.safariTimer);jQuery.safariTimer=null;jQuery.ready();}},10);jQuery.event.add(window,"load",jQuery.ready);}jQuery.fn.extend({load:function(url,params,callback){if(jQuery.isFunction(url))return this.bind("load",url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
").append(res.responseText.replace(//g,"")).find(selector):res.responseText);setTimeout(function(){self.each(callback,[res.responseText,status,res]);},13);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null},lastModified:{},ajax:function(s){var jsonp,jsre=/=(\?|%3F)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=s.data.replace(jsre,"="+jsonp);s.url=s.url.replace(jsre,"="+jsonp);s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get")s.url+=(s.url.match(/\?/)?"&":"?")+"_="+(new Date()).getTime();if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if(!s.url.indexOf("http")&&s.dataType=="script"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(!jsonp&&(s.success||s.complete)){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async);if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else +jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();return xml;function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else +s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock?this.oldblock:"";if(jQuery.css(this,"display")=="none")this.style.display="block";}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");if(this.oldblock=="none")this.oldblock="block";this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var opt=jQuery.speed(speed,easing,callback);return this[opt.queue===false?"each":"queue"](function(){opt=jQuery.extend({},opt);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(){var timers=jQuery.timers;return this.each(function(){for(var i=0;i-10000?r:parseFloat(jQuery.css(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(){return self.step();}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timers.length==1){var timer=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var absolute=jQuery.css(elem,"position")=="absolute",parent=elem.parentNode,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522;if(elem.getBoundingClientRect){box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));if(msie){var border=jQuery("html").css("borderWidth");border=(border=="medium"||jQuery.boxModel&&parseInt(version)>=7)&&2||border;add(-border,-border);}}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&/^t[d|h]$/i.test(parent.tagName)||!safari2)border(offsetParent);if(safari2&&!absolute&&jQuery.css(offsetParent,"position")=="absolute")absolute=true;offsetParent=offsetParent.offsetParent;}while(parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table-row.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if(safari2&&absolute)add(-doc.body.offsetLeft,-doc.body.offsetTop);}results={top:top,left:left};}return results;function border(elem){add(jQuery.css(elem,"borderLeftWidth"),jQuery.css(elem,"borderTopWidth"));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}};})(); \ No newline at end of file diff --git a/app/ext/trimpath-template-1.0.38.js b/app/ext/trimpath-template-1.0.38.js new file mode 100644 index 0000000..ffc40e9 --- /dev/null +++ b/app/ext/trimpath-template-1.0.38.js @@ -0,0 +1,397 @@ +/** + * TrimPath Template. Release 1.0.38. + * Copyright (C) 2004, 2005 Metaha. + * + * TrimPath Template is licensed under the GNU General Public License + * and the Apache License, Version 2.0, as follows: + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var TrimPath; + +// TODO: Debugging mode vs stop-on-error mode - runtime flag. +// TODO: Handle || (or) characters and backslashes. +// TODO: Add more modifiers. + +(function() { // Using a closure to keep global namespace clean. + if (TrimPath == null) + TrimPath = new Object(); + if (TrimPath.evalEx == null) + TrimPath.evalEx = function(src) { return eval(src); }; + + var UNDEFINED; + if (Array.prototype.pop == null) // IE 5.x fix from Igor Poteryaev. + Array.prototype.pop = function() { + if (this.length === 0) {return UNDEFINED;} + return this[--this.length]; + }; + if (Array.prototype.push == null) // IE 5.x fix from Igor Poteryaev. + Array.prototype.push = function() { + for (var i = 0; i < arguments.length; ++i) {this[this.length] = arguments[i];} + return this.length; + }; + + TrimPath.parseTemplate = function(tmplContent, optTmplName, optEtc) { + if (optEtc == null) + optEtc = TrimPath.parseTemplate_etc; + var funcSrc = parse(tmplContent, optTmplName, optEtc); + var func = TrimPath.evalEx(funcSrc, optTmplName, 1); + if (func != null) + return new optEtc.Template(optTmplName, tmplContent, funcSrc, func, optEtc); + return null; + } + + try { + String.prototype.process = function(context, optFlags) { + var template = TrimPath.parseTemplate(this, null); + if (template != null) + return template.process(context, optFlags); + return this; + } + } catch (e) { // Swallow exception, such as when String.prototype is sealed. + } + + TrimPath.parseTemplate_etc = {}; // Exposed for extensibility. + TrimPath.parseTemplate_etc.statementTag = "forelse|for|if|elseif|else|var|macro"; + TrimPath.parseTemplate_etc.statementDef = { // Lookup table for statement tags. + "if" : { delta: 1, prefix: "if (", suffix: ") {", paramMin: 1 }, + "else" : { delta: 0, prefix: "} else {" }, + "elseif" : { delta: 0, prefix: "} else if (", suffix: ") {", paramDefault: "true" }, + "/if" : { delta: -1, prefix: "}" }, + "for" : { delta: 1, paramMin: 3, + prefixFunc : function(stmtParts, state, tmplName, etc) { + if (stmtParts[2] != "in") + throw new etc.ParseError(tmplName, state.line, "bad for loop statement: " + stmtParts.join(' ')); + var iterVar = stmtParts[1]; + var listVar = "__LIST__" + iterVar; + return [ "var ", listVar, " = ", stmtParts[3], ";", + // Fix from Ross Shaull for hash looping, make sure that we have an array of loop lengths to treat like a stack. + "var __LENGTH_STACK__;", + "if (typeof(__LENGTH_STACK__) == 'undefined' || !__LENGTH_STACK__.length) __LENGTH_STACK__ = new Array();", + "__LENGTH_STACK__[__LENGTH_STACK__.length] = 0;", // Push a new for-loop onto the stack of loop lengths. + "if ((", listVar, ") != null) { ", + "var ", iterVar, "_ct = 0;", // iterVar_ct variable, added by B. Bittman + "for (var ", iterVar, "_index in ", listVar, ") { ", + iterVar, "_ct++;", + "if (typeof(", listVar, "[", iterVar, "_index]) == 'function') {continue;}", // IE 5.x fix from Igor Poteryaev. + "__LENGTH_STACK__[__LENGTH_STACK__.length - 1]++;", + "var ", iterVar, " = ", listVar, "[", iterVar, "_index];" ].join(""); + } }, + "forelse" : { delta: 0, prefix: "} } if (__LENGTH_STACK__[__LENGTH_STACK__.length - 1] == 0) { if (", suffix: ") {", paramDefault: "true" }, + "/for" : { delta: -1, prefix: "} }; delete __LENGTH_STACK__[__LENGTH_STACK__.length - 1];" }, // Remove the just-finished for-loop from the stack of loop lengths. + "var" : { delta: 0, prefix: "var ", suffix: ";" }, + "macro" : { delta: 1, + prefixFunc : function(stmtParts, state, tmplName, etc) { + var macroName = stmtParts[1].split('(')[0]; + return [ "var ", macroName, " = function", + stmtParts.slice(1).join(' ').substring(macroName.length), + "{ var _OUT_arr = []; var _OUT = { write: function(m) { if (m) _OUT_arr.push(m); } }; " ].join(''); + } }, + "/macro" : { delta: -1, prefix: " return _OUT_arr.join(''); };" } + } + TrimPath.parseTemplate_etc.modifierDef = { + "eat" : function(v) { return ""; }, + "escape" : function(s) { return String(s).replace(/&/g, "&").replace(//g, ">"); }, + "capitalize" : function(s) { return String(s).toUpperCase(); }, + "default" : function(s, d) { return s != null ? s : d; } + } + TrimPath.parseTemplate_etc.modifierDef.h = TrimPath.parseTemplate_etc.modifierDef.escape; + + TrimPath.parseTemplate_etc.Template = function(tmplName, tmplContent, funcSrc, func, etc) { + this.process = function(context, flags) { + if (context == null) + context = {}; + if (context._MODIFIERS == null) + context._MODIFIERS = {}; + if (context.defined == null) + context.defined = function(str) { return (context[str] != undefined); }; + for (var k in etc.modifierDef) { + if (context._MODIFIERS[k] == null) + context._MODIFIERS[k] = etc.modifierDef[k]; + } + if (flags == null) + flags = {}; + var resultArr = []; + var resultOut = { write: function(m) { resultArr.push(m); } }; + try { + func(resultOut, context, flags); + } catch (e) { + if (flags.throwExceptions == true) + throw e; + var result = new String(resultArr.join("") + "[ERROR: " + e.toString() + (e.message ? '; ' + e.message : '') + "]"); + result["exception"] = e; + return result; + } + return resultArr.join(""); + } + this.name = tmplName; + this.source = tmplContent; + this.sourceFunc = funcSrc; + this.toString = function() { return "TrimPath.Template [" + tmplName + "]"; } + } + TrimPath.parseTemplate_etc.ParseError = function(name, line, message) { + this.name = name; + this.line = line; + this.message = message; + } + TrimPath.parseTemplate_etc.ParseError.prototype.toString = function() { + return ("TrimPath template ParseError in " + this.name + ": line " + this.line + ", " + this.message); + } + + var parse = function(body, tmplName, etc) { + body = cleanWhiteSpace(body); + var funcText = [ "var TrimPath_Template_TEMP = function(_OUT, _CONTEXT, _FLAGS) { with (_CONTEXT) {" ]; + var state = { stack: [], line: 1 }; // TODO: Fix line number counting. + var endStmtPrev = -1; + while (endStmtPrev + 1 < body.length) { + var begStmt = endStmtPrev; + // Scan until we find some statement markup. + begStmt = body.indexOf("{", begStmt + 1); + while (begStmt >= 0) { + var endStmt = body.indexOf('}', begStmt + 1); + var stmt = body.substring(begStmt, endStmt); + var blockrx = stmt.match(/^\{(cdata|minify|eval)/); // From B. Bittman, minify/eval/cdata implementation. + if (blockrx) { + var blockType = blockrx[1]; + var blockMarkerBeg = begStmt + blockType.length + 1; + var blockMarkerEnd = body.indexOf('}', blockMarkerBeg); + if (blockMarkerEnd >= 0) { + var blockMarker; + if( blockMarkerEnd - blockMarkerBeg <= 0 ) { + blockMarker = "{/" + blockType + "}"; + } else { + blockMarker = body.substring(blockMarkerBeg + 1, blockMarkerEnd); + } + + var blockEnd = body.indexOf(blockMarker, blockMarkerEnd + 1); + if (blockEnd >= 0) { + emitSectionText(body.substring(endStmtPrev + 1, begStmt), funcText); + + var blockText = body.substring(blockMarkerEnd + 1, blockEnd); + if (blockType == 'cdata') { + emitText(blockText, funcText); + } else if (blockType == 'minify') { + emitText(scrubWhiteSpace(blockText), funcText); + } else if (blockType == 'eval') { + if (blockText != null && blockText.length > 0) // From B. Bittman, eval should not execute until process(). + funcText.push('_OUT.write( (function() { ' + blockText + ' })() );'); + } + begStmt = endStmtPrev = blockEnd + blockMarker.length - 1; + } + } + } else if (body.charAt(begStmt - 1) != '$' && // Not an expression or backslashed, + body.charAt(begStmt - 1) != '\\') { // so check if it is a statement tag. + var offset = (body.charAt(begStmt + 1) == '/' ? 2 : 1); // Close tags offset of 2 skips '/'. + // 10 is larger than maximum statement tag length. + if (body.substring(begStmt + offset, begStmt + 10 + offset).search(TrimPath.parseTemplate_etc.statementTag) == 0) + break; // Found a match. + } + begStmt = body.indexOf("{", begStmt + 1); + } + if (begStmt < 0) // In "a{for}c", begStmt will be 1. + break; + var endStmt = body.indexOf("}", begStmt + 1); // In "a{for}c", endStmt will be 5. + if (endStmt < 0) + break; + emitSectionText(body.substring(endStmtPrev + 1, begStmt), funcText); + emitStatement(body.substring(begStmt, endStmt + 1), state, funcText, tmplName, etc); + endStmtPrev = endStmt; + } + emitSectionText(body.substring(endStmtPrev + 1), funcText); + if (state.stack.length != 0) + throw new etc.ParseError(tmplName, state.line, "unclosed, unmatched statement(s): " + state.stack.join(",")); + funcText.push("}}; TrimPath_Template_TEMP"); + return funcText.join(""); + } + + var emitStatement = function(stmtStr, state, funcText, tmplName, etc) { + var parts = stmtStr.slice(1, -1).split(' '); + var stmt = etc.statementDef[parts[0]]; // Here, parts[0] == for/if/else/... + if (stmt == null) { // Not a real statement. + emitSectionText(stmtStr, funcText); + return; + } + if (stmt.delta < 0) { + if (state.stack.length <= 0) + throw new etc.ParseError(tmplName, state.line, "close tag does not match any previous statement: " + stmtStr); + state.stack.pop(); + } + if (stmt.delta > 0) + state.stack.push(stmtStr); + + if (stmt.paramMin != null && + stmt.paramMin >= parts.length) + throw new etc.ParseError(tmplName, state.line, "statement needs more parameters: " + stmtStr); + if (stmt.prefixFunc != null) + funcText.push(stmt.prefixFunc(parts, state, tmplName, etc)); + else + funcText.push(stmt.prefix); + if (stmt.suffix != null) { + if (parts.length <= 1) { + if (stmt.paramDefault != null) + funcText.push(stmt.paramDefault); + } else { + for (var i = 1; i < parts.length; i++) { + if (i > 1) + funcText.push(' '); + funcText.push(parts[i]); + } + } + funcText.push(stmt.suffix); + } + } + + var emitSectionText = function(text, funcText) { + if (text.length <= 0) + return; + var nlPrefix = 0; // Index to first non-newline in prefix. + var nlSuffix = text.length - 1; // Index to first non-space/tab in suffix. + while (nlPrefix < text.length && (text.charAt(nlPrefix) == '\n')) + nlPrefix++; + while (nlSuffix >= 0 && (text.charAt(nlSuffix) == ' ' || text.charAt(nlSuffix) == '\t')) + nlSuffix--; + if (nlSuffix < nlPrefix) + nlSuffix = nlPrefix; + if (nlPrefix > 0) { + funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write("'); + var s = text.substring(0, nlPrefix).replace('\n', '\\n'); // A macro IE fix from BJessen. + if (s.charAt(s.length - 1) == '\n') + s = s.substring(0, s.length - 1); + funcText.push(s); + funcText.push('");'); + } + var lines = text.substring(nlPrefix, nlSuffix + 1).split('\n'); + for (var i = 0; i < lines.length; i++) { + emitSectionTextLine(lines[i], funcText); + if (i < lines.length - 1) + funcText.push('_OUT.write("\\n");\n'); + } + if (nlSuffix + 1 < text.length) { + funcText.push('if (_FLAGS.keepWhitespace == true) _OUT.write("'); + var s = text.substring(nlSuffix + 1).replace('\n', '\\n'); + if (s.charAt(s.length - 1) == '\n') + s = s.substring(0, s.length - 1); + funcText.push(s); + funcText.push('");'); + } + } + + var emitSectionTextLine = function(line, funcText) { + var endMarkPrev = '}'; + var endExprPrev = -1; + while (endExprPrev + endMarkPrev.length < line.length) { + var begMark = "${", endMark = "}"; + var begExpr = line.indexOf(begMark, endExprPrev + endMarkPrev.length); // In "a${b}c", begExpr == 1 + if (begExpr < 0) + break; + if (line.charAt(begExpr + 2) == '%') { + begMark = "${%"; + endMark = "%}"; + } + var endExpr = line.indexOf(endMark, begExpr + begMark.length); // In "a${b}c", endExpr == 4; + if (endExpr < 0) + break; + emitText(line.substring(endExprPrev + endMarkPrev.length, begExpr), funcText); + // Example: exprs == 'firstName|default:"John Doe"|capitalize'.split('|') + var exprArr = line.substring(begExpr + begMark.length, endExpr).replace(/\|\|/g, "#@@#").split('|'); + for (var k in exprArr) { + if (exprArr[k].replace) // IE 5.x fix from Igor Poteryaev. + exprArr[k] = exprArr[k].replace(/#@@#/g, '||'); + } + funcText.push('_OUT.write('); + emitExpression(exprArr, exprArr.length - 1, funcText); + funcText.push(');'); + endExprPrev = endExpr; + endMarkPrev = endMark; + } + emitText(line.substring(endExprPrev + endMarkPrev.length), funcText); + } + + var emitText = function(text, funcText) { + if (text == null || + text.length <= 0) + return; + text = text.replace(/\\/g, '\\\\'); + text = text.replace(/\n/g, '\\n'); + text = text.replace(/"/g, '\\"'); + funcText.push('_OUT.write("'); + funcText.push(text); + funcText.push('");'); + } + + var emitExpression = function(exprArr, index, funcText) { + // Ex: foo|a:x|b:y1,y2|c:z1,z2 is emitted as c(b(a(foo,x),y1,y2),z1,z2) + var expr = exprArr[index]; // Ex: exprArr == [firstName,capitalize,default:"John Doe"] + if (index <= 0) { // Ex: expr == 'default:"John Doe"' + funcText.push(expr); + return; + } + var parts = expr.split(':'); + funcText.push('_MODIFIERS["'); + funcText.push(parts[0]); // The parts[0] is a modifier function name, like capitalize. + funcText.push('"]('); + emitExpression(exprArr, index - 1, funcText); + if (parts.length > 1) { + funcText.push(','); + funcText.push(parts[1]); + } + funcText.push(')'); + } + + var cleanWhiteSpace = function(result) { + result = result.replace(/\t/g, " "); + result = result.replace(/\r\n/g, "\n"); + result = result.replace(/\r/g, "\n"); + result = result.replace(/^(\s*\S*(\s+\S+)*)\s*$/, '$1'); // Right trim by Igor Poteryaev. + return result; + } + + var scrubWhiteSpace = function(result) { + result = result.replace(/^\s+/g, ""); + result = result.replace(/\s+$/g, ""); + result = result.replace(/\s+/g, " "); + result = result.replace(/^(\s*\S*(\s+\S+)*)\s*$/, '$1'); // Right trim by Igor Poteryaev. + return result; + } + + // The DOM helper functions depend on DOM/DHTML, so they only work in a browser. + // However, these are not considered core to the engine. + // + TrimPath.parseDOMTemplate = function(elementId, optDocument, optEtc) { + if (optDocument == null) + optDocument = document; + var element = optDocument.getElementById(elementId); + var content = element.value; // Like textarea.value. + if (content == null) + content = element.innerHTML; // Like textarea.innerHTML. + content = content.replace(/</g, "<").replace(/>/g, ">"); + return TrimPath.parseTemplate(content, elementId, optEtc); + } + + TrimPath.processDOMTemplate = function(elementId, context, optFlags, optDocument, optEtc) { + return TrimPath.parseDOMTemplate(elementId, optDocument, optEtc).process(context, optFlags); + } +}) (); diff --git a/app/hyena.js b/app/hyena.js new file mode 100644 index 0000000..78fb6c3 --- /dev/null +++ b/app/hyena.js @@ -0,0 +1,10 @@ +/* + * Hyena - personal portal system + */ + +$(document).ready(function(){ + $.getJSON('/', function(data){ + var html = TrimPath.processDOMTemplate('t-home', data); + $('#site').html(html); + }); +}); \ No newline at end of file diff --git a/app/index.html b/app/index.html new file mode 100644 index 0000000..1d48046 --- /dev/null +++ b/app/index.html @@ -0,0 +1,45 @@ + + + + Hyena + + + + + + + +
+ Loading... +
+ + + + + + + diff --git a/screen.css b/app/screen.css similarity index 100% rename from screen.css rename to app/screen.css diff --git a/helpers.py b/helpers.py deleted file mode 100644 index be6aaf2..0000000 --- a/helpers.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import yaml - -from mako.template import Template -from colubrid import HttpResponse -from colubrid.server import StaticExports - - -def T(name, **namespace): - "Render the template `name` with `namespace` as namespace" - return HttpResponse(Template(filename=name).render(**namespace)) - -def yamldata(new_data=None): - "Read/write YAML data" - filename = 'data.yaml' - if new_data: - yaml.dump(new_data, open(filename, 'w')) - return new_data - else: - try: - return yaml.load(open(filename)) - except IOError: - return None - - -class CorrectStaticExports(StaticExports): - # This is a fix for Colubrid's StaticExports middleware - - def __call__(self, environ, start_response): - path_info = environ.get('PATH_INFO', '') - for search_path, file_path in self.exports.iteritems(): - if path_info.startswith(search_path): - real_path = file_path - rest = path_info[len(search_path):] - if rest: - real_path = os.path.join(real_path, rest) - if os.path.exists(real_path) and os.path.isfile(real_path): - return self.serve_file(real_path, start_response) - return self.application(environ, start_response) diff --git a/index.mako b/index.mako deleted file mode 100644 index 6b256a8..0000000 --- a/index.mako +++ /dev/null @@ -1,32 +0,0 @@ - - - - Hyena 0.01 - - - - - This is the uber-portal of my Life! - ${data['name']} - -
- Next Actions -
- % for a in data['actions']: -
${a['text']}
- % endfor - -
- -
-
-
- -
- Fortune -

${fortune} -

-
- - - - diff --git a/server.py b/server.py index d43f660..2b01296 100644 --- a/server.py +++ b/server.py @@ -2,26 +2,41 @@ import os -from colubrid import RegexApplication, execute +import simplejson +from colubrid import BaseApplication, HttpResponse, execute +from colubrid.server import StaticExports from paste import reloader reloader.install() -from helpers import T, CorrectStaticExports, yamldata - -class HyenaApplication(RegexApplication): - urls = [ - (r'^$', 'show_index'), - ] - - def show_index(self): - return T("index.mako", - data=yamldata() or self.initdata(), - fortune=self.fortune_html()) - - def initdata(self): - # sample data - return { +class HyenaApplication(BaseApplication): + + def process_request(self): + if self.request.environ['REQUEST_METHOD'] == 'POST': + # write the JSON + self.write_json(self.request.form['json']) + return HttpResponse('OK') + else: + # read the JSON + response = HttpResponse(self.read_json()) + response['Content-Type'] = 'text/plain' # 'text/x-json' + return response + + def write_json(self, json): + open('data.json', 'w').write(json) + + def read_json(self): + json = self.read_json_from_disk() + data = simplejson.loads(json) + data['fortune'] = os.popen('fortune').read().replace('\n', '
') + return simplejson.dumps(data) + + def read_json_from_disk(self): + if os.path.isfile('data.json'): + return open('data.json').read() + + # defaul json + return simplejson.dumps({ 'name': 'srid', 'actions': [ {'text': 'get my sansonite zip repaired under warranty', @@ -31,16 +46,11 @@ class HyenaApplication(RegexApplication): {'text': 'm$ reimbursement', 'type': 'errand'} ] - } - - def fortune_html(self): - fortune = os.popen("fortune").read() - return fortune.replace( - '\n', '
') + }) app = HyenaApplication -app = CorrectStaticExports(app, { - '/screen.css': './screen.css', +app = StaticExports(app, { + '/app': './app', }) if __name__ == '__main__': -- 2.11.4.GIT