-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoffle.min.js
1 lines (1 loc) · 11.3 KB
/
toffle.min.js
1
function toffle(){}toffle.tokenType={IF:function(){this.type="if",this.condition="",this.tokens=[],this.wrapsTokens=!0},NOT:function(){this.type="not",this.condition="",this.tokens=[],this.wrapsTokens=!0},REF:function(){this.type="ref",this.value="",this.wrapsTokens=!1},TEMP:function(){this.type="template",this.template="",this.params="",this.wrapsTokens=!1},EACH:function(){this.type="each",this.pointer="",this.reference="",this.tokens=[],this.wrapsTokens=!0},MATCH:function(){this.type="match",this.pointer="",this.reference="",this.func="",this.tokens=[],this.wrapsTokens=!0},CONTENT:function(){this.type="content",this.value="",this.wrapsTokens=!1},HELPER:function(){this.type="helper",this.arguments="",this.func="",this.tokens=[],this.wrapsTokens=!0},CLS:function(){this.type="cls",this.wrapsTokens=!1}},toffle.template=function(e){var t={},r=[],n=[];if(e)if(e.nodeType&&1===e.nodeType){if("text/toffle-template"!=e.type)throw"toffle: template DOM element must be defined as type 'text/toffle-template'"}else{if(!("template"in e))throw"toffle: error! you must provide an initial template";if("helpers"in e)for(var a in e.helpers)t[a]=e.helpers[a];e=e.template}toffle.compileTemplate(e,!0,n,r);for(var i=({templates:{},hlprFunctions:t,go:function(e){var t="",r=[],n={pos:0,tokens:[],params:{},pointer:null,iterative:null,counter:1,iterations:1};for(var a in this.templates){var i=this.templates[a];if(i.isInitialTemplate){for(var o=0;o<i.ast.tokens.length;o++)n.tokens.push(i.ast.tokens[o]);n.params=e,r.push(n);break}}for(;;){var n;if(0==r.length)break;if(n=r[r.length-1],n.pos==n.tokens.length){if(!(n.counter<n.iterations)){r.pop();continue}n.counter=n.counter+1,n.pointer=n.matchIndexes?n.iterative[n.matchIndexes[n.counter-1]]:n.iterative[n.counter-1],n.pos=0}var s=(n.pos,n.tokens[n.pos]);switch(s.type){case"content":t+=s.value;break;case"ref":try{var l=this.getParamPool(r),f=this.parseReference(s.value).idents,p=this.grabValue(l,f);t+=p}catch(h){throw"toffle: error evaluating value '"+s.value+"'"}break;case"if":try{var l=this.getParamPool(r),f=this.parseReference(s.condition).idents,p=this.grabValue(l,f),c=p}catch(h){throw"toffle: error evaluating condition '"+s.condition+"'"}c&&r.push({pos:0,tokens:s.tokens,params:{},pointer:null,iterative:null,counter:1,iterations:1});break;case"not":try{var l=this.getParamPool(r),f=this.parseReference(s.condition).idents,p=this.grabValue(l,f),c=p}catch(h){throw"toffle: error evaluating condition '"+s.condition+"'"}c||r.push({pos:0,tokens:s.tokens,params:{},pointer:null,iterative:null,counter:1,iterations:1});break;case"each":var u={},g=0;if(s.wrapsAllTokens){if(!(e instanceof Array))throw"toffle: cannot iterate over input dataset, not an array.";u=e,g=u.length}else try{var l=this.getParamPool(r),f=this.parseReference(s.reference).idents,p=this.grabValue(l,f);if(!(p instanceof Array))throw"toffle: cannot iterate over '"+s.reference+"', not an array.";var u=p;g=u.length}catch(h){throw"toffle: error evaluating reference '"+s.reference+"'"}g>0&&r.push({pos:0,tokens:s.tokens,params:{},pointer:u[0],pointerIdent:s.pointer,iterative:u,counter:1,iterations:g});break;case"match":var u={},g=0,m=[];try{var l=this.getParamPool(r),f=this.parseReference(s.reference).idents,p=this.grabValue(l,f),u=p}catch(h){throw"toffle: error evaluating reference '"+s.reference+"'"}for(var d=0;d<u.length;d++){var v=u[d],k=[];if(k.push(v),!this.hlprFunctions[s.func])throw"toffle: error! Helper function not specified for match: "+s.func;var c=this.hlprFunctions[s.func].apply(this,k);c&&(g++,m.push(d))}g>0&&r.push({pos:0,tokens:s.tokens,params:{},pointer:u[m[0]],pointerIdent:s.pointer,iterative:u,counter:1,matchIndexes:m,iterations:g});break;case"template":for(var T=this.templates[s.template],w={pos:0,tokens:[],params:{},pointer:{},iterative:{},counter:1,iterations:1},o=0;o<T.ast.tokens.length;o++)w.tokens.push(T.ast.tokens[o]);w.params=toffle.parseRawArgumentList(s.params.trim());var y,b=document.getElementById(s.template).getAttribute("data-params");if(y=b?b.split("|"):[],y.length!=w.params.length)throw"toffle: error! Template reference arguments do not match parameters.";var A;for(A=0;A<y.length;A++){var E=y[A],P=w.params[A];if("boolean"==typeof P||null===P)w.params[E]=P;else if("'"==P.charAt(0)&&"'"==P.charAt(P.length-1)||'"'==P.charAt(0)&&'"'==P.charAt(P.length-1))w.params[E]=P.substring(1,P.length-1);else if(isNaN(P)){var l=this.getParamPool(r),f=this.parseReference(P).idents,p=this.grabValue(l,f);w.params[E]=p}else w.params[E]=Number(P)}r.push(w);break;case"helper":if(!this.hlprFunctions[s.func])throw"toffle: error! Helper function not specified: "+s.func;s.arguments instanceof Array||(s.arguments=toffle.parseRawArgumentList(s.arguments));for(var C=[],I=0;I<s.arguments.length;I++){var N=s.arguments[I];if("boolean"==typeof N||null===N)C[I]=N;else if("'"==N.charAt(0)&&"'"==N.charAt(N.length-1)||'"'==N.charAt(0)&&'"'==N.charAt(N.length-1))C[I]=N.substring(1,N.length-1);else if(isNaN(N)){var l=this.getParamPool(r),f=this.parseReference(N).idents,p=this.grabValue(l,f);C[I]=p}else C[I]=Number(N)}var c=this.hlprFunctions[s.func].apply(this,C);c&&r.push({pos:0,tokens:s.tokens,params:{},pointer:null,iterative:null,counter:1,iterations:1});break;default:throw"toffle: error! Unknown token type: "+s.type}n.pos=n.pos+1}return t},goAway:function(e){if(!e)throw"toffle: error! you must specify details for this function";if(!("url"in e))throw"toffle: error! no url specified";if(!("type"in e))throw"toffle: error! no type specified";try{var t;t=window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");var r=this;t.onreadystatechange=function(){if(4==t.readyState&&200==t.status){var n;try{n=JSON.parse(t.responseText)}catch(a){return void r.handleAjaxError(e,a,"toffle: error parsing returned data as JSON")}if("parse"in e)try{var i=e.parse(n);if(!i)return}catch(a){return void r.handleAjaxError(e,a,"toffle: Error parsing JSON.")}var o;try{o=r.go(n)}catch(a){return void r.handleAjaxError(e,a,"toffle: error generating output")}if("dropoff"in e)try{e.dropoff.innerHTML=o}catch(a){return void r.handleAjaxError(e,a,"toffle: error! invalid dropoff")}"finished"in e&&e.finished({responseJSON:n,output:o})}},t.open(e.type,e.url,!0),"data"in e&&"POST"==e.type.toUpperCase()?t.send(e.data):t.send()}catch(n){this.handleAjaxError(e,n,"toffle: error carrying out ajax request")}},goOver:function(e,t){var r;for(var n in this.templates)if(this.templates.hasOwnProperty(n)){var a=this.templates[n];if(a.isInitialTemplate){r=a;break}}return wrappingEachtoken=new toffle.tokenType.EACH,wrappingEachtoken.pointer=t,wrappingEachtoken.reference="WILLNOTWORK",wrappingEachtoken.wrapsAllTokens=!0,wrappingEachtoken.tokens=r.ast.tokens,r.ast.tokens=[wrappingEachtoken],this.go(e)},grabValue:function(e,t){var r=e;if(void 0==r)return void 0;for(var n=0;n<t.length;n++){var a=t[n].sub;if(a.length>0){if(r=r[t[n].name][this.grabValue(e,t[n].sub)],t[n].subTrail)for(var i=0;i<t[n].subTrail.length;i++){var o=t[n].subTrail[i];r=r[grabValue(e,o)]}}else r=r[t[n].name];if(void 0==r)return void 0}return r},parseReference:function(e){for(var t=0,r=[],n="",a=0;a<e.length;a++){var i=e.charAt(a);if("."==i)n.length>0&&r.push({name:n.trim(),sub:[]}),n="";else if("["==i)if(n.length>0&&r.push({name:n.trim(),sub:[]}),n="","["==e.charAt(a+1)){for(var o=!1,s=a+2;s<e.length-1;s++)if("]]"==e.substring(s,s+2)){o=!0,r.push({name:e.substring(a+2,s),sub:[],literal:!0});break}if(!o)throw"toffle: No closing ']]' for literal identifier";t+=s-a+1,a+=s-a+1}else{var l=this.parseReference(e.substring(a+1));0==r[r.length-1].sub.length?r[r.length-1].sub=l.idents:r[r.length-1].subTrail?r[r.length-1].subTrail.push(l.idents):(r[r.length-1].subTrail=[],r[r.length-1].subTrail.push(l.idents)),t+=l.count,a+=l.count}else{if("]"==i)return n.length>0&&r.push({name:n.trim(),sub:[]}),{idents:r,count:t+1};n+=i}t++}return n.length>0&&r.push({name:n.trim(),sub:[]}),t+=n.length,{idents:r,count:t}},getParamPool:function(e){for(var t={},r=0;r<e.length;r++){var n=e[r];for(var a in n.params)t[a]=n.params[a];n.pointerIdent&&(t[n.pointerIdent]=n.pointer)}return t},handleAjaxError:function(e,t,r){if(!("failed"in e))throw r;e.failed(t)}}),o=0;o<r.length;o++)i.templates[r[o].name]={ast:r[o].temp.AST,isInitialTemplate:r[o].temp.initialTemplate,varList:[]};return i},toffle.compileTemplate=function(e,t,r,n){if(null==e)throw"toffle: Compilation failed! Could not find Template.";var a={initialTemplate:t,tokens:[],openTokens:[],AST:{},templateString:e.innerHTML};r.push(e.id);for(var i=!1,o="",s=0;s<a.templateString.length-1;s++){if("<^"==a.templateString.slice(s,s+2)){if(o.length>0){var l=new toffle.tokenType.CONTENT;l.value=o,a.tokens.push(l),o=""}a.openTokens.push(s),i=!0}else if("^>"==a.templateString.slice(s,s+2)){s+=2,i=!1;var f=a.openTokens.pop(),p=a.templateString.slice(f,s);p=toffle.tokenify(p,e.id,r,n),p.tokenIndex=s-f,a.tokens.push(p)}i||(o+=a.templateString.charAt(s))}if(o.length>0){var l=new toffle.tokenType.CONTENT;l.value=o,a.tokens.push(l),o=""}if(a.openTokens.length>0)throw"toffle: Compilation failed! No closing '^>'";var h=toffle.generateTokenAST(a);a.AST=h,n.push({name:e.id,temp:a})},toffle.tokenify=function(e,t,r,n){var a;if("<^/^>"==e)return new toffle.tokenType.CLS;e=e.replace("<^",""),e=e.replace("^>",""),e=e.trim();var i=e.split(" ");switch(i[0]){case"plug":a=new toffle.tokenType.TEMP,a.template=i[1];for(var o=document.getElementById(a.template),s=!1,l=0;l<r.length;l++)if(r[l]==a.template){s=!0;break}a.template==t||s||toffle.compileTemplate(o,!1,r,n),i.length>2?(i.splice(0,2),a.params=i.join(" ")):a.params="";break;case"each":if(a=new toffle.tokenType.EACH,!(i.length>3))throw"toffle: Compilation failed! Incorrect 'each' declaration.";if("in"!=i[2])throw"toffle: Compilation failed! Incorrect 'each' declaration, missing 'in'.";a.pointer=i[1],i.splice(0,3),a.reference=i.join(" ");break;case"match":if(a=new toffle.tokenType.MATCH,!(i.length>4))throw"toffle: Compilation failed! Incorrect 'each' declaration.";if("in"!=i[2])throw"toffle: Compilation failed! Incorrect 'each' declaration, missing 'in'.";if(a.pointer=i[1],!(i[3].length>2&&"??"==i[3].substring(0,2)))throw"toffle: Compilation failed! Incorrect 'match' declaration, not a valid Helper identifier: "+i[3];a.func=i[3].substring(2),i.splice(0,4),a.reference=i.join(" ");break;case"if":if(a=new toffle.tokenType.IF,!(i.length>1))throw"toffle: Compilation failed! Missing 'if' condition.";i.splice(0,1),a.condition=i.join(" ");break;case"not":if(a=new toffle.tokenType.NOT,!(i.length>1))throw"toffle: Compilation failed! Missing 'not' condition.";i.splice(0,1),a.condition=i.join(" ");break;default:i[0].length>1&&"??"==i[0].substring(0,2)?(a=new toffle.tokenType.HELPER,a.func=i[0].substring(2),i.splice(0,1),a.arguments=i.join(" ")):(a=new toffle.tokenType.REF,a.value=e)}return a},toffle.parseRawArgumentList=function(e){for(var t=[],r=!1,n="",a="",i=0;i<e.length;i++){var o=e.charAt(i);'"'==o||"'"==o?(r?o!=n||toffle.isQuoteEscaped(i,e)||(r=!1):(r=!0,n=o),a+=o):" "!=o||r?a+=o:a.length>0&&(t.push(a),a="")}a.length>0&&(t.push(a),a="");for(var i=0;i<t.length;i++){var s=t[i];"true"===s?t[i]=!0:"false"===s?t[i]=!1:"null"===s&&(t[i]=null)}return t},toffle.isQuoteEscaped=function(e,t){return 0==e?!1:"\\"==t.charAt(e-1)?e-1==0?!0:"\\"==t.charAt(e-2)?!1:!0:!1},toffle.generateTokenAST=function(e){var t=[];t.push({tokens:[]});for(var r=0;r<e.tokens.length;r++){var n=e.tokens[r];if(n.wrapsTokens)t.push(n);else if("cls"==n.type){var a=t.pop();t[t.length-1].tokens.push(a)}else{var a=t[t.length-1];a.tokens.push(n)}}return t[0]};