From 49de778abb943bbb5dec3ba5e8f64dcc3d0a89f1 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 27 Dec 2012 19:13:59 -0800 Subject: [PATCH] Inline rendering functions --- mustache.js | 181 ++++++++++++++++++++-------------------------------- 1 file changed, 68 insertions(+), 113 deletions(-) diff --git a/mustache.js b/mustache.js index 73c693d..b78e48d 100644 --- a/mustache.js +++ b/mustache.js @@ -203,13 +203,19 @@ return fn; }; + Writer.prototype.getPartial = function (name) { + if (!(name in this._partialCache) && this._loadPartial) { + this.compilePartial(name, this._loadPartial(name)); + } + + return this._partialCache[name]; + }; + Writer.prototype.compileTokens = function (tokens, template) { - var fn = compileTokens(tokens); var self = this; - return function (view, partials) { if (partials) { - if (typeof partials === "function") { + if (typeof partials === 'function') { self._loadPartial = partials; } else { for (var name in partials) { @@ -218,7 +224,7 @@ } } - return fn(self, Context.make(view), template); + return renderTokens(tokens, self, Context.make(view), template); }; }; @@ -226,122 +232,72 @@ return this.compile(template)(view, partials); }; - Writer.prototype._section = function (token, context, template, callback) { - var name = token[1]; - 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 text = template == null ? null : template.slice(token[3], token[5]); - 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 (token, context, callback) { - var value = context.lookup(token[1]); - - // Use JavaScript's definition of falsy. Include empty arrays. - // See https://github.com/janl/mustache.js/issues/186 - if (!value || (isArray(value) && value.length === 0)) { - return callback(this, context); - } - - return ''; - }; - - Writer.prototype._partial = function (token, context) { - var name = token[1]; + /** + * Low-level function that renders the given `tokens` using the given `writer` + * and `context`. The `template` string is only needed for templates that use + * higher-order sections to extract the portion of the original template that + * was contained in that section. + */ + function renderTokens(tokens, writer, context, template) { + var buffer = ''; - if (!(name in this._partialCache) && this._loadPartial) { - this.compilePartial(name, this._loadPartial(name)); - } + var token, tokenValue, value; + for (var i = 0, len = tokens.length; i < len; ++i) { + token = tokens[i]; + tokenValue = token[1]; - var fn = this._partialCache[name]; + switch (token[0]) { + case '#': + value = context.lookup(tokenValue); - return fn ? fn(context) : ''; - }; + if (typeof value === 'object') { + if (isArray(value)) { + for (var j = 0, jlen = value.length; j < jlen; ++j) { + buffer += renderTokens(token[4], writer, context.push(value[j]), template); + } + } else if (value) { + buffer += renderTokens(token[4], writer, context.push(value), template); + } + } else if (typeof value === 'function') { + var text = template == null ? null : template.slice(token[3], token[5]); + var result = value.call(context.view, text, function (template) { + return writer.render(template, context); + }); + if (result != null) buffer += result; + } else if (value) { + buffer += renderTokens(token[4], writer, context, template); + } - Writer.prototype._name = function (token, context) { - var value = context.lookup(token[1]); - return value == null ? '' : value; - }; + break; + case '^': + value = context.lookup(tokenValue); - Writer.prototype._escaped = function (token, context) { - return exports.escape(this._name(token, context)); - }; + // Use JavaScript's definition of falsy. Include empty arrays. + // See https://github.com/janl/mustache.js/issues/186 + if (!value || (isArray(value) && value.length === 0)) { + buffer += renderTokens(token[4], writer, context, template); + } - /** - * Low-level function that compiles the given `tokens` into a function - * that accepts three arguments: a Writer, a Context, and the template. - */ - 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); - }; + break; + case '>': + value = writer.getPartial(tokenValue); + if (typeof value === 'function') buffer += value(context); + break; + case '&': + value = context.lookup(tokenValue); + if (value != null) buffer += value; + break; + case 'name': + value = context.lookup(tokenValue); + if (value != null) buffer += exports.escape(value); + break; + case 'text': + buffer += tokenValue; + break; } - - return subRenders[i]; } - return function (writer, context, template) { - var buffer = ''; - - var token; - for (var i = 0, len = tokens.length; i < len; ++i) { - token = tokens[i]; - switch (token[0]) { - case "#": - buffer += writer._section(token, context, template, subRender(i, token[4], template)); - break; - case "^": - buffer += writer._inverted(token, context, subRender(i, token[4], template)); - break; - case ">": - buffer += writer._partial(token, context); - break; - case "&": - buffer += writer._name(token, context); - break; - case "name": - buffer += writer._escaped(token, context); - break; - case "text": - buffer += token[1]; - break; - } - } - - return buffer; - }; + return buffer; } /** @@ -544,8 +500,7 @@ return nestTokens(squashTokens(tokens)); }; - // The high-level clearCache, compile, compilePartial, and render functions - // use this default writer. + // All Mustache.* functions use this writer. var _writer = new Writer(); /**