1 line
8.5 KiB
JavaScript
1 line
8.5 KiB
JavaScript
(function(root,factory){if(typeof exports==="object"&&exports){module.exports=factory}else if(typeof define==="function"&&define.amd){define(factory)}else{root.Mustache=factory}})(this,function(){var exports={};exports.name="mustache.js";exports.version="0.7.2";exports.tags=["{{","}}"];exports.Scanner=Scanner;exports.Context=Context;exports.Writer=Writer;var whiteRe=/\s*/;var spaceRe=/\s+/;var nonSpaceRe=/\S/;var eqRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function testRe(re,string){return RegExp.prototype.test.call(re,string)}function isWhitespace(string){return!testRe(nonSpaceRe,string)}var isArray=Array.isArray||function(obj){return Object.prototype.toString.call(obj)==="[object Array]"};function escapeRe(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};function escapeHtml(string){return String(string).replace(/[&<>"'\/]/g,function(s){return entityMap[s]})}exports.escape=escapeHtml;function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function(){return this.tail===""};Scanner.prototype.scan=function(re){var match=this.tail.match(re);if(match&&match.index===0){this.tail=this.tail.substring(match[0].length);this.pos+=match[0].length;return match[0]}return""};Scanner.prototype.scanUntil=function(re){var match,pos=this.tail.search(re);switch(pos){case-1:match=this.tail;this.pos+=this.tail.length;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,pos);this.tail=this.tail.substring(pos);this.pos+=pos}return match};function Context(view,parent){this.view=view;this.parent=parent;this.clearCache()}Context.make=function(view){return view instanceof Context?view:new Context(view)};Context.prototype.clearCache=function(){this._cache={}};Context.prototype.push=function(view){return new Context(view,this)};Context.prototype.lookup=function(name){var value=this._cache[name];if(!value){if(name==="."){value=this.view}else{var context=this;while(context){if(name.indexOf(".")>0){var names=name.split("."),i=0;value=context.view;while(value&&i<names.length){value=value[names[i++]]}}else{value=context.view[name]}if(value!=null){break}context=context.parent}}this._cache[name]=value}if(typeof value==="function"){value=value.call(this.view)}return value};function Writer(){this.clearCache()}Writer.prototype.clearCache=function(){this._cache={};this._partialCache={}};Writer.prototype.compile=function(template,tags){var fn=this._cache[template];if(!fn){var tokens=exports.parse(template,tags);fn=this._cache[template]=this.compileTokens(tokens,template)}return fn};Writer.prototype.compilePartial=function(name,template,tags){var fn=this.compile(template,tags);this._partialCache[name]=fn;return fn};Writer.prototype.compileTokens=function(tokens,template){var fn=compileTokens(tokens);var self=this;return function(view,partials){if(partials){if(typeof partials==="function"){self._loadPartial=partials}else{for(var name in partials){self.compilePartial(name,partials[name])}}}return fn(self,Context.make(view),template)}};Writer.prototype.render=function(template,view,partials){return this.compile(template)(view,partials)};Writer.prototype._section=function(name,context,text,callback){var value=context.lookup(name);switch(typeof value){case"object":if(isArray(value)){var buffer="";for(var i=0,len=value.length;i<len;++i){buffer+=callback(this,context.push(value[i]))}return buffer}return value?callback(this,context.push(value)):"";case"function":var self=this;var scopedRender=function(template){return self.render(template,context)};var result=value.call(context.view,text,scopedRender);return result!=null?result:"";default:if(value){return callback(this,context)}}return""};Writer.prototype._inverted=function(name,context,callback){var value=context.lookup(name);if(!value||isArray(value)&&value.length===0){return callback(this,context)}return""};Writer.prototype._partial=function(name,context){if(!(name in this._partialCache)&&this._loadPartial){this.compilePartial(name,this._loadPartial(name))}var fn=this._partialCache[name];return fn?fn(context):""};Writer.prototype._name=function(name,context){var value=context.lookup(name);if(typeof value==="function"){value=value.call(context.view)}return value==null?"":String(value)};Writer.prototype._escaped=function(name,context){return exports.escape(this._name(name,context))};function compileTokens(tokens){var subRenders={};function subRender(i,tokens,template){if(!subRenders[i]){var fn=compileTokens(tokens);subRenders[i]=function(writer,context){return fn(writer,context,template)}}return subRenders[i]}return function(writer,context,template){var buffer="";var token,sectionText;for(var i=0,len=tokens.length;i<len;++i){token=tokens[i];switch(token[0]){case"#":sectionText=template.slice(token[3],token[5]);buffer+=writer._section(token[1],context,sectionText,subRender(i,token[4],template));break;case"^":buffer+=writer._inverted(token[1],context,subRender(i,token[4],template));break;case">":buffer+=writer._partial(token[1],context);break;case"&":buffer+=writer._name(token[1],context);break;case"name":buffer+=writer._escaped(token[1],context);break;case"text":buffer+=token[1];break}}return buffer}}function nestTokens(tokens){var tree=[];var collector=tree;var sections=[];var token;for(var i=0,len=tokens.length;i<len;++i){token=tokens[i];switch(token[0]){case"#":case"^":sections.push(token);collector.push(token);collector=token[4]=[];break;case"/":var section=sections.pop();section[5]=token[2];collector=sections.length>0?sections[sections.length-1][4]:tree;break;default:collector.push(token)}}return tree}function squashTokens(tokens){var squashedTokens=[];var token,lastToken;for(var i=0,len=tokens.length;i<len;++i){token=tokens[i];if(token[0]==="text"&&lastToken&&lastToken[0]==="text"){lastToken[1]+=token[1];lastToken[3]=token[3]}else{lastToken=token;squashedTokens.push(token)}}return squashedTokens}function escapeTags(tags){return[new RegExp(escapeRe(tags[0])+"\\s*"),new RegExp("\\s*"+escapeRe(tags[1]))]}exports.parse=function(template,tags){template=template||"";tags=tags||exports.tags;if(typeof tags==="string")tags=tags.split(spaceRe);if(tags.length!==2){throw new Error("Invalid tags: "+tags.join(", "))}var tagRes=escapeTags(tags);var scanner=new Scanner(template);var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length){tokens.splice(spaces.pop(),1)}}else{spaces=[]}hasTag=false;nonSpace=false}var start,type,value,chr;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(tagRes[0]);if(value){for(var i=0,len=value.length;i<len;++i){chr=value.charAt(i);if(isWhitespace(chr)){spaces.push(tokens.length)}else{nonSpace=true}tokens.push(["text",chr,start,start+1]);start+=1;if(chr==="\n"){stripSpace()}}}start=scanner.pos;if(!scanner.scan(tagRes[0])){break}hasTag=true;type=scanner.scan(tagRe)||"name";scanner.scan(whiteRe);if(type==="="){value=scanner.scanUntil(eqRe);scanner.scan(eqRe);scanner.scanUntil(tagRes[1])}else if(type==="{"){var closeRe=new RegExp("\\s*"+escapeRe("}"+tags[1]));value=scanner.scanUntil(closeRe);scanner.scan(curlyRe);scanner.scanUntil(tagRes[1]);type="&"}else{value=scanner.scanUntil(tagRes[1])}if(!scanner.scan(tagRes[1])){throw new Error("Unclosed tag at "+scanner.pos)}if(type==="/"){if(sections.length===0){throw new Error('Unopened section "'+value+'" at '+start)}var section=sections.pop();if(section[1]!==value){throw new Error('Unclosed section "'+section[1]+'" at '+start)}}var token=[type,value,start,scanner.pos];tokens.push(token);if(type==="#"||type==="^"){sections.push(token)}else if(type==="name"||type==="{"||type==="&"){nonSpace=true}else if(type==="="){tags=value.split(spaceRe);if(tags.length!==2){throw new Error("Invalid tags at "+start+": "+tags.join(", "))}tagRes=escapeTags(tags)}}var section=sections.pop();if(section){throw new Error('Unclosed section "'+section[1]+'" at '+scanner.pos)}return nestTokens(squashTokens(tokens))};var _writer=new Writer;exports.clearCache=function(){return _writer.clearCache()};exports.compile=function(template,tags){return _writer.compile(template,tags)};exports.compilePartial=function(name,template,tags){return _writer.compilePartial(name,template,tags)};exports.compileTokens=function(tokens,template){return _writer.compileTokens(tokens,template)};exports.render=function(template,view,partials){return _writer.render(template,view,partials)};exports.to_html=function(template,view,partials,send){var result=exports.render(template,view,partials);if(typeof send==="function"){send(result)}else{return result}};return exports}()); |