Newer
Older
(function(window,undefined){var globalOptions={ignoreUndefined:!1,escape:"general",escapeSets:{xml:{"<":"<",">":">","&":"&",'"':"""},general:{'"':'\\"',"'":"\\'"}}},deepMergeJson=function(obja,objb){var prop;for(prop in objb)objb.hasOwnProperty(prop)&&(obja[prop]="object"==typeof obja[prop]&&"object"==typeof objb[prop]?deepMergeJson(obja[prop],objb[prop]):objb[prop]);return obja},setDeepProperty=function(ident,value,obj){var list,recurse=function(propList,value,obj){propList.length>1?recurse(propList,value,obj[list.shift()]):obj[propList[0]]=value};return list=ident.push||ident.map?ident:ident.split(".").map(function(e){return e.trim()}),recurse(list,value,obj),obj},getDeepProperty=function(ident,obj){var list,ret=null,recurse=function(propList,obj){var curident;if(propList.length>1){if(!obj.hasOwnProperty(propList[0]))throw curident=propList.reduce(function(a,b,i){return a+(i>0?".":"")+b}),new Error('Invalid proprty, missing expected data "'+curident+'" (IDENT: '+ident+") from data "+JSON.stringify(obj));recurse(propList,obj[list.shift()])}else{if(!obj.hasOwnProperty(propList[0]))throw new Error('Invalid proprty, missing expected data "'+propList[0]+'" (IDENT: '+ident+") from data "+JSON.stringify(obj));ret=obj[propList[0]]}};return list=ident.push||ident.map?ident:ident.split(".").map(function(e){return e.trim()}),recurse(list,obj),ret},resolveNamespace=function(ident,blockStack){var i,l=blockStack.length,ret="";for(i=0;l>i;i+=1)ret+=blockStack[i]+".";return ret+ident},safeDeepMergeJson=function(obja,objb){if("object"!=typeof obja)throw new TypeError("Cannot deep merge with an "+typeof obja+": [Param 1]");if("object"!=typeof objb)throw new TypeError("Cannot deep merge with an "+typeof objb+": [Param 2]");return deepMergeJson(deepMergeJson({},obja),objb)},captureTags=/(\[\[)(\#|\/)?\s*(?:([a-zA-Z]+[a-zA-Z0-9]*)\s*\:\s*([a-zA-Z]+[a-zA-Z0-9]*)|([\*\&]?)\s*((?:\!(?:\(([a-zA-Z]+[a-zA-Z0-9]*)\))?)?)\s*([a-zA-Z](?:[a-zA-Z0-9]*(?:\.(?=[a-zA-Z]))?)+))\s*(\]\])/,Stack=function(){var self=this;return this.length=0,this.push=function(val){self[self.length]=val,self.length+=1},this.pop=function(){var ret=null;return self.length>0&&(ret=self[self.length-1],self[self.length-1]=null,self.length-=1),ret},this.peek=function(){return this.length>0?self[self.length-1]:null},this.contains=function(value,compare){compare=compare||function(a,b){return a===b};for(var i=this.length;i--;)if(compare(this[i],value))return!0;return!1},this},Node=function(type,val,modifiers){return this.ident=type||"N_NULL",this.val=val||null,this.content=modifiers||{},this},Token=function(ident,val,info){return this.ident=ident||"T_NULL",this.val=val||null,this.info=info||{},this},tokenise=function(src){var matcher,chunk,tok,tokens=[],i=0,match=null;for(matcher=function(){return null!==(match=captureTags.exec(chunk))};i<src.length;)chunk=src.substr(i),matcher()?(match.index>0&&tokens.push(new Token("STRING",match.input.substr(0,match.index))),tok=new Token("T_NULL",null,{close:!1,escape:!1,escapeType:null}),"#"===match[2]?(tok.ident="T_DIRECTIVE",tok.val={},tok.val[match[3]]=match[4]):("/"===match[2]&&(tok.info.close=!0),tok.ident="*"===match[5]?"T_LOOP":"&"===match[5]?"T_BLOCK":"T_DATA","undefined"!=typeof match[6]&&"!"===match[6].charAt(0)&&(tok.info.escape=!0,"undefined"!=typeof match[7]&&(tok.info.escapeType=match[7])),tok.val=match[8]),tokens.push(tok),i+=match.index+match[0].length):(tokens.push(new Token("STRING",chunk)),i+=chunk.length);return tokens.push(new Token("EOD")),tokens},collapseParse=function(tokens){for(var tokenList,j,targetToken,targetNode,i=0;i<tokens.length;)if(tokens[i].info&&tokens[i].info.close){for(tokenList=[],targetToken=tokens[i],j=i-1;tokens[j].ident!==targetToken.ident||tokens[j].val!==targetToken.val;)if(tokenList.push(tokens[j]),j-=1,0>j)throw new Error("Unmatched Closing Tag "+targetNode+" at index "+i);targetNode="T_LOOP"===targetToken.ident?new Node("N_LOOP",targetToken.val,tokenList.slice().reverse()):new Node("N_BLOCK",targetToken.val,tokenList.slice().reverse()),tokens.splice(j,i-j+1,targetNode),i=0}else i+=1;return tokens},unwindNode=function(output,node,index,arr){var innerArr,dataArr,content,i,dataVal;switch(node.ident){case"STRING":return output+node.val;case"T_DATA":return dataVal=node.val,arr.loopTag&&node.val===arr.loopTag.slice(0,-1)&&(dataVal=arr.loopTag+"."+arr.i.toString()),output+getDeepProperty(dataVal,arr.data);case"N_LOOP":for(content="",innerArr=node.content,innerArr.data=arr.data,innerArr.loopTag=node.val,dataArr=getDeepProperty(node.val,arr.data),i=0;i<dataArr.length;i+=1)innerArr.i=i,content+=innerArr.reduce(unwindNode,"");return output+content;case"N_BLOCK":return innerArr=node.content,innerArr.data=getDeepProperty(node.val,arr.data),innerArr.loopTag=null,output+innerArr.reduce(unwindNode,"");default:return output}},render=function(src,data){var nodes=collapseParse(tokenise(src));return nodes.data=data,nodes.loopTag=null,nodes.i=null,nodes.reduce(unwindNode,"")};if(render.partial=function(src){return function(tokens,data){return tokens.data=data,tokens.loopTag=null,tokens.i=null,tokens.reduce(unwindNode,"")}.bind(null,collapseParse(tokenise(src)))},!window.mu)throw new Error("tinyDOM-Sideburns requires tinyDOM to be in use on the page");mu.templates={},mu.render=function(path,data,options){return mu.templates.hasOwnProperty(path)?mu.templates[path](data,options):render(path,data,options)},mu.fn.render=function(path,data,options){var rendered=mu.render(path,data,options),opts=options||{useHtml:!0};"undefined"==typeof opts.useHtml&&(opts.useHtml=!0),this.each(function(i,e){opts.useHtml?e.innerHTML=rendered:e.textContent=rendered})},mu.ready(function(){mu("[type='x-template/sideburns']").each(function(i,e){var name=e.getAttribute("data-name");mu.templates[name]=render.partial(e.textContent)})});})(window);