| @@ -10,7 +10,9 @@ | |||
| factory(exports); // CommonJS | |||
| } else { | |||
| var mustache = {}; | |||
| factory(mustache); | |||
| if (typeof define === "function" && define.amd) { | |||
| define(mustache); // AMD | |||
| } else { | |||
| @@ -60,9 +62,8 @@ | |||
| } | |||
| function escapeTags(tags) { | |||
| if (!isArray(tags) || tags.length !== 2) { | |||
| if (!isArray(tags) || tags.length !== 2) | |||
| throw new Error('Invalid tags: ' + tags); | |||
| } | |||
| return [ | |||
| new RegExp(escapeRegExp(tags[0]) + "\\s*"), | |||
| @@ -102,9 +103,8 @@ | |||
| tags = tags || mustache.tags; | |||
| template = template || ''; | |||
| if (typeof tags === 'string') { | |||
| if (typeof tags === 'string') | |||
| tags = tags.split(spaceRe); | |||
| } | |||
| var tagRes = escapeTags(tags); | |||
| var scanner = new Scanner(template); | |||
| @@ -119,9 +119,8 @@ | |||
| // if there was a {{#tag}} on it and otherwise only space. | |||
| function stripSpace() { | |||
| if (hasTag && !nonSpace) { | |||
| while (spaces.length) { | |||
| while (spaces.length) | |||
| delete tokens[spaces.pop()]; | |||
| } | |||
| } else { | |||
| spaces = []; | |||
| } | |||
| @@ -137,7 +136,7 @@ | |||
| // Match any text between tags. | |||
| value = scanner.scanUntil(tagRes[0]); | |||
| if (value) { | |||
| for (var i = 0, len = value.length; i < len; ++i) { | |||
| for (var i = 0, valueLength = value.length; i < valueLength; ++i) { | |||
| chr = value.charAt(i); | |||
| if (isWhitespace(chr)) { | |||
| @@ -150,9 +149,8 @@ | |||
| start += 1; | |||
| // Check for whitespace on the current line. | |||
| if (chr === '\n') { | |||
| if (chr === '\n') | |||
| stripSpace(); | |||
| } | |||
| } | |||
| } | |||
| @@ -179,9 +177,8 @@ | |||
| } | |||
| // Match the closing tag. | |||
| if (!scanner.scan(tagRes[1])) { | |||
| if (!scanner.scan(tagRes[1])) | |||
| throw new Error('Unclosed tag at ' + scanner.pos); | |||
| } | |||
| token = [ type, value, start, scanner.pos ]; | |||
| tokens.push(token); | |||
| @@ -192,12 +189,11 @@ | |||
| // Check section nesting. | |||
| openSection = sections.pop(); | |||
| if (!openSection) { | |||
| if (!openSection) | |||
| throw new Error('Unopened section "' + value + '" at ' + start); | |||
| } | |||
| if (openSection[1] !== value) { | |||
| if (openSection[1] !== value) | |||
| throw new Error('Unclosed section "' + openSection[1] + '" at ' + start); | |||
| } | |||
| } else if (type === 'name' || type === '{' || type === '&') { | |||
| nonSpace = true; | |||
| } else if (type === '=') { | |||
| @@ -208,9 +204,9 @@ | |||
| // Make sure there are no open sections when we're done. | |||
| openSection = sections.pop(); | |||
| if (openSection) { | |||
| if (openSection) | |||
| throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos); | |||
| } | |||
| return nestTokens(squashTokens(tokens)); | |||
| } | |||
| @@ -223,7 +219,7 @@ | |||
| var squashedTokens = []; | |||
| var token, lastToken; | |||
| for (var i = 0, len = tokens.length; i < len; ++i) { | |||
| for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { | |||
| token = tokens[i]; | |||
| if (token) { | |||
| @@ -252,7 +248,7 @@ | |||
| var sections = []; | |||
| var token, section; | |||
| for (var i = 0, len = tokens.length; i < len; ++i) { | |||
| for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { | |||
| token = tokens[i]; | |||
| switch (token[0]) { | |||
| @@ -299,14 +295,15 @@ | |||
| Scanner.prototype.scan = function (re) { | |||
| var match = this.tail.match(re); | |||
| if (match && match.index === 0) { | |||
| var string = match[0]; | |||
| this.tail = this.tail.substring(string.length); | |||
| this.pos += string.length; | |||
| return string; | |||
| } | |||
| if (!match || match.index !== 0) | |||
| return ''; | |||
| var string = match[0]; | |||
| this.tail = this.tail.substring(string.length); | |||
| this.pos += string.length; | |||
| return ""; | |||
| return string; | |||
| }; | |||
| /** | |||
| @@ -361,21 +358,22 @@ | |||
| if (name in this.cache) { | |||
| value = this.cache[name]; | |||
| } else { | |||
| var context = this; | |||
| var context = this, names, index; | |||
| while (context) { | |||
| if (name.indexOf('.') > 0) { | |||
| value = context.view; | |||
| names = name.split('.'); | |||
| index = 0; | |||
| var names = name.split('.'), i = 0; | |||
| while (value != null && i < names.length) { | |||
| value = value[names[i++]]; | |||
| } | |||
| while (value != null && index < names.length) | |||
| value = value[names[index++]]; | |||
| } else { | |||
| value = context.view[name]; | |||
| } | |||
| if (value != null) break; | |||
| if (value != null) | |||
| break; | |||
| context = context.parent; | |||
| } | |||
| @@ -383,9 +381,8 @@ | |||
| this.cache[name] = value; | |||
| } | |||
| if (isFunction(value)) { | |||
| if (isFunction(value)) | |||
| value = value.call(this.view); | |||
| } | |||
| return value; | |||
| }; | |||
| @@ -414,9 +411,8 @@ | |||
| var cache = this.cache; | |||
| var tokens = cache[template]; | |||
| if (tokens == null) { | |||
| if (tokens == null) | |||
| tokens = cache[template] = parseTemplate(template, tags); | |||
| } | |||
| return tokens; | |||
| }; | |||
| @@ -456,29 +452,31 @@ | |||
| } | |||
| var token, value; | |||
| for (var i = 0, len = tokens.length; i < len; ++i) { | |||
| for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { | |||
| token = tokens[i]; | |||
| switch (token[0]) { | |||
| case '#': | |||
| value = context.lookup(token[1]); | |||
| if (!value) continue; | |||
| if (!value) | |||
| continue; | |||
| if (isArray(value)) { | |||
| for (var j = 0, jlen = value.length; j < jlen; ++j) { | |||
| for (var j = 0, valueLength = value.length; j < valueLength; ++j) { | |||
| buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate); | |||
| } | |||
| } else if (typeof value === 'object' || typeof value === 'string') { | |||
| buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate); | |||
| } else if (isFunction(value)) { | |||
| if (typeof originalTemplate !== 'string') { | |||
| if (typeof originalTemplate !== 'string') | |||
| throw new Error('Cannot use higher-order sections without the original template'); | |||
| } | |||
| // Extract the portion of the original template that the section contains. | |||
| value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender); | |||
| if (value != null) buffer += value; | |||
| if (value != null) | |||
| buffer += value; | |||
| } else { | |||
| buffer += this.renderTokens(token[4], context, partials, originalTemplate); | |||
| } | |||
| @@ -489,23 +487,33 @@ | |||
| // 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)) { | |||
| if (!value || (isArray(value) && value.length === 0)) | |||
| buffer += this.renderTokens(token[4], context, partials, originalTemplate); | |||
| } | |||
| break; | |||
| case '>': | |||
| if (!partials) continue; | |||
| if (!partials) | |||
| continue; | |||
| value = isFunction(partials) ? partials(token[1]) : partials[token[1]]; | |||
| if (value != null) buffer += this.renderTokens(this.parse(value), context, partials, value); | |||
| if (value != null) | |||
| buffer += this.renderTokens(this.parse(value), context, partials, value); | |||
| break; | |||
| case '&': | |||
| value = context.lookup(token[1]); | |||
| if (value != null) buffer += value; | |||
| if (value != null) | |||
| buffer += value; | |||
| break; | |||
| case 'name': | |||
| value = context.lookup(token[1]); | |||
| if (value != null) buffer += mustache.escape(value); | |||
| if (value != null) | |||
| buffer += mustache.escape(value); | |||
| break; | |||
| case 'text': | |||
| buffer += token[1]; | |||