/* * Copyright 2011 Twitter, Inc. * 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 Hogan = {}; (function (Hogan) { Hogan.Template = function constructor(renderFunc, text, compiler) { if (renderFunc) { this.r = renderFunc; } this.c = compiler; this.text = text || ''; } Hogan.Template.prototype = { // render: replaced by generated code. r: function (context, partials, indent) { return ''; }, // variable escaping v: hoganEscape, render: function render(context, partials, indent) { return this.ri([context], partials || {}, indent); }, // render internal -- a hook for overrides that catches partials too ri: function (context, partials, indent) { return this.r(context, partials, indent); }, // tries to find a partial in the curent scope and render it rp: function(name, context, partials, indent) { var partial = partials[name]; if (!partial) { return ''; } if (this.c && typeof partial == 'string') { partial = this.c.compile(partial); } return partial.ri(context, partials, indent); }, // render a section rs: function(context, partials, section) { var buf = '', tail = context[context.length - 1]; if (!isArray(tail)) { return buf = section(context, partials); } for (var i = 0; i < tail.length; i++) { context.push(tail[i]); buf += section(context, partials); context.pop(); } return buf; }, // maybe start a section s: function(val, ctx, partials, inverted, start, end, tags) { var pass; if (isArray(val) && val.length === 0) { return false; } if (typeof val == 'function') { val = this.ls(val, ctx, partials, inverted, start, end, tags); } pass = (val === '') || !!val; if (!inverted && pass && ctx) { ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]); } return pass; }, // find values with dotted names d: function(key, ctx, partials, returnFound) { var names = key.split('.'), val = this.f(names[0], ctx, partials, returnFound), cx = null; if (key === '.' && isArray(ctx[ctx.length - 2])) { return ctx[ctx.length - 1]; } for (var i = 1; i < names.length; i++) { if (val && typeof val == 'object' && names[i] in val) { cx = val; val = val[names[i]]; } else { val = ''; } } if (returnFound && !val) { return false; } if (!returnFound && typeof val == 'function') { ctx.push(cx); val = this.lv(val, ctx, partials); ctx.pop(); } return val; }, // find values with normal names f: function(key, ctx, partials, returnFound) { var val = false, v = null, found = false; for (var i = ctx.length - 1; i >= 0; i--) { v = ctx[i]; if (v && typeof v == 'object' && key in v) { val = v[key]; found = true; break; } } if (!found) { return (returnFound) ? false : ""; } if (!returnFound && typeof val == 'function') { val = this.lv(val, ctx, partials); } return val; }, // higher order templates ho: function(val, cx, partials, text, tags) { var compiler = this.c; var t = val.call(cx, text, function(t) { return compiler.compile(t, {delimiters: tags}).render(cx, partials); }); var s = compiler.compile(t.toString(), {delimiters: tags}).render(cx, partials); this.b = s; return false; }, // higher order template result buffer b: '', // lambda replace section ls: function(val, ctx, partials, inverted, start, end, tags) { var cx = ctx[ctx.length - 1], t = null; if (!inverted && this.c && val.length > 0) { return this.ho(val, cx, partials, this.text.substring(start, end), tags); } t = val.call(cx); if (typeof t == 'function') { if (inverted) { return true; } else if (this.c) { return this.ho(t, cx, partials, this.text.substring(start, end), tags); } } return t; }, // lambda replace variable lv: function(val, ctx, partials) { var cx = ctx[ctx.length - 1]; var result = val.call(cx); if (typeof result == 'function') { result = result.call(cx); } result = result.toString(); if (this.c && ~result.indexOf("{{")) { return this.c.compile(result).render(cx, partials); } return result; } }; var rAmp = /&/g, rLt = //g, rApos =/\'/g, rQuot = /\"/g, hChars =/[&<>\"\']/; function hoganEscape(str) { str = String((str === null || str === undefined) ? '' : str); return hChars.test(str) ? str .replace(rAmp,'&') .replace(rLt,'<') .replace(rGt,'>') .replace(rApos,''') .replace(rQuot, '"') : str; } var isArray = Array.isArray || function(a) { return Object.prototype.toString.call(a) === '[object Array]'; }; })(typeof exports !== 'undefined' ? exports : Hogan);