| @@ -4,7 +4,7 @@ | |||||
| See http://mustache.github.com/ for more info. | See http://mustache.github.com/ for more info. | ||||
| */ | */ | ||||
| var Mustache = function() { | |||||
| var Mustache = function () { | |||||
| var _toString = Object.prototype.toString; | var _toString = Object.prototype.toString; | ||||
| Array.isArray = Array.isArray || function (obj) { | Array.isArray = Array.isArray || function (obj) { | ||||
| @@ -48,16 +48,16 @@ var Mustache = function() { | |||||
| }, | }, | ||||
| context: {}, | context: {}, | ||||
| render: function(template, context, partials, in_recursion) { | |||||
| render: function (template, context, partials, in_recursion) { | |||||
| // reset buffer & set context | // reset buffer & set context | ||||
| if(!in_recursion) { | |||||
| if (!in_recursion) { | |||||
| this.context = context; | this.context = context; | ||||
| this.buffer = []; // TODO: make this non-lazy | this.buffer = []; // TODO: make this non-lazy | ||||
| } | } | ||||
| // fail fast | // fail fast | ||||
| if(!this.includes("", template)) { | |||||
| if(in_recursion) { | |||||
| if (!this.includes("", template)) { | |||||
| if (in_recursion) { | |||||
| return template; | return template; | ||||
| } else { | } else { | ||||
| this.send(template); | this.send(template); | ||||
| @@ -86,13 +86,13 @@ var Mustache = function() { | |||||
| /* | /* | ||||
| Sends parsed lines | Sends parsed lines | ||||
| */ | */ | ||||
| send: function(line) { | |||||
| if(line !== "") { | |||||
| send: function (line) { | |||||
| if (line !== "") { | |||||
| this.buffer.push(line); | this.buffer.push(line); | ||||
| } | } | ||||
| }, | }, | ||||
| sendLines: function(text) { | |||||
| sendLines: function (text) { | |||||
| if (text) { | if (text) { | ||||
| var lines = text.split("\n"); | var lines = text.split("\n"); | ||||
| for (var i = 0; i < lines.length; i++) { | for (var i = 0; i < lines.length; i++) { | ||||
| @@ -104,25 +104,25 @@ var Mustache = function() { | |||||
| /* | /* | ||||
| Looks for %PRAGMAS | Looks for %PRAGMAS | ||||
| */ | */ | ||||
| render_pragmas: function(template) { | |||||
| render_pragmas: function (template) { | |||||
| // no pragmas | // no pragmas | ||||
| if(!this.includes("%", template)) { | |||||
| if (!this.includes("%", template)) { | |||||
| return template; | return template; | ||||
| } | } | ||||
| var that = this; | var that = this; | ||||
| var regex = this.getCachedRegex("render_pragmas", function(otag, ctag) { | |||||
| var regex = this.getCachedRegex("render_pragmas", function (otag, ctag) { | |||||
| return new RegExp(otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + ctag, "g"); | return new RegExp(otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + ctag, "g"); | ||||
| }); | }); | ||||
| return template.replace(regex, function(match, pragma, options) { | |||||
| if(!that.pragmas_implemented[pragma]) { | |||||
| return template.replace(regex, function (match, pragma, options) { | |||||
| if (!that.pragmas_implemented[pragma]) { | |||||
| throw({message: | throw({message: | ||||
| "This implementation of mustache doesn't understand the '" + | "This implementation of mustache doesn't understand the '" + | ||||
| pragma + "' pragma"}); | pragma + "' pragma"}); | ||||
| } | } | ||||
| that.pragmas[pragma] = {}; | that.pragmas[pragma] = {}; | ||||
| if(options) { | |||||
| if (options) { | |||||
| var opts = options.split("="); | var opts = options.split("="); | ||||
| that.pragmas[pragma][opts[0]] = opts[1]; | that.pragmas[pragma][opts[0]] = opts[1]; | ||||
| } | } | ||||
| @@ -134,12 +134,12 @@ var Mustache = function() { | |||||
| /* | /* | ||||
| Tries to find a partial in the curent scope and render it | Tries to find a partial in the curent scope and render it | ||||
| */ | */ | ||||
| render_partial: function(name, context, partials) { | |||||
| render_partial: function (name, context, partials) { | |||||
| name = trim(name); | name = trim(name); | ||||
| if(!partials || partials[name] === undefined) { | |||||
| if (!partials || partials[name] === undefined) { | |||||
| throw({message: "unknown_partial '" + name + "'"}); | throw({message: "unknown_partial '" + name + "'"}); | ||||
| } | } | ||||
| if(typeof(context[name]) != "object") { | |||||
| if (typeof(context[name]) != "object") { | |||||
| return this.render(partials[name], context, partials, true); | return this.render(partials[name], context, partials, true); | ||||
| } | } | ||||
| return this.render(partials[name], context[name], partials, true); | return this.render(partials[name], context[name], partials, true); | ||||
| @@ -148,15 +148,15 @@ var Mustache = function() { | |||||
| /* | /* | ||||
| Renders inverted (^) and normal (#) sections | Renders inverted (^) and normal (#) sections | ||||
| */ | */ | ||||
| render_section: function(template, context, partials) { | |||||
| if(!this.includes("#", template) && !this.includes("^", template)) { | |||||
| render_section: function (template, context, partials) { | |||||
| if (!this.includes("#", template) && !this.includes("^", template)) { | |||||
| // did not render anything, there were no sections | // did not render anything, there were no sections | ||||
| return false; | return false; | ||||
| } | } | ||||
| var that = this; | var that = this; | ||||
| var regex = this.getCachedRegex("render_section", function(otag, ctag) { | |||||
| var regex = this.getCachedRegex("render_section", function (otag, ctag) { | |||||
| // This regex matches _the first_ section ({{#foo}}{{/foo}}), and captures the remainder | // This regex matches _the first_ section ({{#foo}}{{/foo}}), and captures the remainder | ||||
| return new RegExp( | return new RegExp( | ||||
| "^([\\s\\S]*?)" + // all the crap at the beginning that is not {{*}} ($1) | "^([\\s\\S]*?)" + // all the crap at the beginning that is not {{*}} ($1) | ||||
| @@ -178,7 +178,7 @@ var Mustache = function() { | |||||
| // for each {{#foo}}{{/foo}} section do... | // for each {{#foo}}{{/foo}} section do... | ||||
| return template.replace(regex, function(match, before, type, name, content, after) { | |||||
| return template.replace(regex, function (match, before, type, name, content, after) { | |||||
| // before contains only tags, no sections | // before contains only tags, no sections | ||||
| var renderedBefore = before ? that.render_tags(before, context, partials, true) : "", | var renderedBefore = before ? that.render_tags(before, context, partials, true) : "", | ||||
| @@ -199,7 +199,7 @@ var Mustache = function() { | |||||
| } | } | ||||
| } else if (type === "#") { // normal section | } else if (type === "#") { // normal section | ||||
| if (Array.isArray(value)) { // Enumerable, Let's loop! | if (Array.isArray(value)) { // Enumerable, Let's loop! | ||||
| renderedContent = that.map(value, function(row) { | |||||
| renderedContent = that.map(value, function (row) { | |||||
| return that.render(content, that.create_context(row), partials, true); | return that.render(content, that.create_context(row), partials, true); | ||||
| }).join(""); | }).join(""); | ||||
| } else if (that.is_object(value)) { // Object, Use it as subcontext! | } else if (that.is_object(value)) { // Object, Use it as subcontext! | ||||
| @@ -207,7 +207,7 @@ var Mustache = function() { | |||||
| partials, true); | partials, true); | ||||
| } else if (typeof value === "function") { | } else if (typeof value === "function") { | ||||
| // higher order section | // higher order section | ||||
| renderedContent = value.call(context, content, function(text) { | |||||
| renderedContent = value.call(context, content, function (text) { | |||||
| return that.render(text, context, partials, true); | return that.render(text, context, partials, true); | ||||
| }); | }); | ||||
| } else if (value) { // boolean section | } else if (value) { // boolean section | ||||
| @@ -224,20 +224,20 @@ var Mustache = function() { | |||||
| /* | /* | ||||
| Replace {{foo}} and friends with values from our view | Replace {{foo}} and friends with values from our view | ||||
| */ | */ | ||||
| render_tags: function(template, context, partials, in_recursion) { | |||||
| render_tags: function (template, context, partials, in_recursion) { | |||||
| // tit for tat | // tit for tat | ||||
| var that = this; | var that = this; | ||||
| var new_regex = function() { | |||||
| return that.getCachedRegex("render_tags", function(otag, ctag) { | |||||
| var new_regex = function () { | |||||
| return that.getCachedRegex("render_tags", function (otag, ctag) { | |||||
| return new RegExp(otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" + ctag + "+", "g"); | return new RegExp(otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" + ctag + "+", "g"); | ||||
| }); | }); | ||||
| }; | }; | ||||
| var regex = new_regex(); | var regex = new_regex(); | ||||
| var tag_replace_callback = function(match, operator, name) { | |||||
| var tag_replace_callback = function (match, operator, name) { | |||||
| switch(operator) { | switch(operator) { | ||||
| case "!": // ignore comments | case "!": // ignore comments | ||||
| return ""; | return ""; | ||||
| @@ -256,25 +256,25 @@ var Mustache = function() { | |||||
| var lines = template.split("\n"); | var lines = template.split("\n"); | ||||
| for(var i = 0; i < lines.length; i++) { | for(var i = 0; i < lines.length; i++) { | ||||
| lines[i] = lines[i].replace(regex, tag_replace_callback, this); | lines[i] = lines[i].replace(regex, tag_replace_callback, this); | ||||
| if(!in_recursion) { | |||||
| if (!in_recursion) { | |||||
| this.send(lines[i]); | this.send(lines[i]); | ||||
| } | } | ||||
| } | } | ||||
| if(in_recursion) { | |||||
| if (in_recursion) { | |||||
| return lines.join("\n"); | return lines.join("\n"); | ||||
| } | } | ||||
| }, | }, | ||||
| set_delimiters: function(delimiters) { | |||||
| set_delimiters: function (delimiters) { | |||||
| var dels = delimiters.split(" "); | var dels = delimiters.split(" "); | ||||
| this.otag = this.escape_regex(dels[0]); | this.otag = this.escape_regex(dels[0]); | ||||
| this.ctag = this.escape_regex(dels[1]); | this.ctag = this.escape_regex(dels[1]); | ||||
| }, | }, | ||||
| escape_regex: function(text) { | |||||
| escape_regex: function (text) { | |||||
| // thank you Simon Willison | // thank you Simon Willison | ||||
| if(!arguments.callee.sRE) { | |||||
| if (!arguments.callee.sRE) { | |||||
| var specials = [ | var specials = [ | ||||
| '/', '.', '*', '+', '?', '|', | '/', '.', '*', '+', '?', '|', | ||||
| '(', ')', '[', ']', '{', '}', '\\' | '(', ')', '[', ']', '{', '}', '\\' | ||||
| @@ -290,7 +290,7 @@ var Mustache = function() { | |||||
| find `name` in current `context`. That is find me a value | find `name` in current `context`. That is find me a value | ||||
| from the view object | from the view object | ||||
| */ | */ | ||||
| find: function(name, context) { | |||||
| find: function (name, context) { | |||||
| name = trim(name); | name = trim(name); | ||||
| // Checks whether a value is thruthy or false or 0 | // Checks whether a value is thruthy or false or 0 | ||||
| @@ -301,41 +301,40 @@ var Mustache = function() { | |||||
| var value; | var value; | ||||
| // check for dot notation eg. foo.bar | // check for dot notation eg. foo.bar | ||||
| if(name.match(/([a-z_]+)\./ig)){ | |||||
| if (name.match(/([a-z_]+)\./ig)) { | |||||
| var childValue = this.walk_context(name, context); | var childValue = this.walk_context(name, context); | ||||
| if(is_kinda_truthy(childValue)) { | |||||
| if (is_kinda_truthy(childValue)) { | |||||
| value = childValue; | value = childValue; | ||||
| } | } | ||||
| } | |||||
| else{ | |||||
| if(is_kinda_truthy(context[name])) { | |||||
| } else { | |||||
| if (is_kinda_truthy(context[name])) { | |||||
| value = context[name]; | value = context[name]; | ||||
| } else if(is_kinda_truthy(this.context[name])) { | |||||
| } else if (is_kinda_truthy(this.context[name])) { | |||||
| value = this.context[name]; | value = this.context[name]; | ||||
| } | } | ||||
| } | } | ||||
| if(typeof value === "function") { | |||||
| if (typeof value === "function") { | |||||
| return value.apply(context); | return value.apply(context); | ||||
| } | } | ||||
| if(value !== undefined) { | |||||
| if (value !== undefined) { | |||||
| return value; | return value; | ||||
| } | } | ||||
| // silently ignore unkown variables | // silently ignore unkown variables | ||||
| return ""; | return ""; | ||||
| }, | }, | ||||
| walk_context: function(name, context){ | |||||
| walk_context: function (name, context) { | |||||
| var path = name.split('.'); | var path = name.split('.'); | ||||
| // if the var doesn't exist in current context, check the top level context | // if the var doesn't exist in current context, check the top level context | ||||
| var value_context = (context[path[0]] != undefined) ? context : this.context; | var value_context = (context[path[0]] != undefined) ? context : this.context; | ||||
| var value = value_context[path.shift()]; | var value = value_context[path.shift()]; | ||||
| while(value != undefined && path.length > 0){ | |||||
| while (value != undefined && path.length > 0) { | |||||
| value_context = value; | value_context = value; | ||||
| value = value[path.shift()]; | value = value[path.shift()]; | ||||
| } | } | ||||
| // if the value is a function, call it, binding the correct context | // if the value is a function, call it, binding the correct context | ||||
| if(typeof value === "function") { | |||||
| if (typeof value === "function") { | |||||
| return value.apply(value_context); | return value.apply(value_context); | ||||
| } | } | ||||
| return value; | return value; | ||||
| @@ -344,16 +343,16 @@ var Mustache = function() { | |||||
| // Utility methods | // Utility methods | ||||
| /* includes tag */ | /* includes tag */ | ||||
| includes: function(needle, haystack) { | |||||
| includes: function (needle, haystack) { | |||||
| return haystack.indexOf(this.otag + needle) != -1; | return haystack.indexOf(this.otag + needle) != -1; | ||||
| }, | }, | ||||
| /* | /* | ||||
| Does away with nasty characters | Does away with nasty characters | ||||
| */ | */ | ||||
| escape: function(s) { | |||||
| escape: function (s) { | |||||
| s = String(s === null ? "" : s); | s = String(s === null ? "" : s); | ||||
| return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) { | |||||
| return s.replace(/&(?!\w+;)|["'<>\\]/g, function (s) { | |||||
| switch(s) { | switch(s) { | ||||
| case "&": return "&"; | case "&": return "&"; | ||||
| case '"': return '"'; | case '"': return '"'; | ||||
| @@ -366,12 +365,12 @@ var Mustache = function() { | |||||
| }, | }, | ||||
| // by @langalex, support for arrays of strings | // by @langalex, support for arrays of strings | ||||
| create_context: function(_context) { | |||||
| if(this.is_object(_context)) { | |||||
| create_context: function (_context) { | |||||
| if (this.is_object(_context)) { | |||||
| return _context; | return _context; | ||||
| } else { | } else { | ||||
| var iterator = "."; | var iterator = "."; | ||||
| if(this.pragmas["IMPLICIT-ITERATOR"]) { | |||||
| if (this.pragmas["IMPLICIT-ITERATOR"]) { | |||||
| iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator; | iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator; | ||||
| } | } | ||||
| var ctx = {}; | var ctx = {}; | ||||
| @@ -380,14 +379,14 @@ var Mustache = function() { | |||||
| } | } | ||||
| }, | }, | ||||
| is_object: function(a) { | |||||
| is_object: function (a) { | |||||
| return a && typeof a == "object"; | return a && typeof a == "object"; | ||||
| }, | }, | ||||
| /* | /* | ||||
| Why, why, why? Because IE. Cry, cry cry. | Why, why, why? Because IE. Cry, cry cry. | ||||
| */ | */ | ||||
| map: function(array, fn) { | |||||
| map: function (array, fn) { | |||||
| if (typeof array.map == "function") { | if (typeof array.map == "function") { | ||||
| return array.map(fn); | return array.map(fn); | ||||
| } else { | } else { | ||||
| @@ -400,7 +399,7 @@ var Mustache = function() { | |||||
| } | } | ||||
| }, | }, | ||||
| getCachedRegex: function(name, generator) { | |||||
| getCachedRegex: function (name, generator) { | |||||
| var byOtag = regexCache[this.otag]; | var byOtag = regexCache[this.otag]; | ||||
| if (!byOtag) { | if (!byOtag) { | ||||
| byOtag = regexCache[this.otag] = {}; | byOtag = regexCache[this.otag] = {}; | ||||
| @@ -427,13 +426,13 @@ var Mustache = function() { | |||||
| /* | /* | ||||
| Turns a template and view into HTML | Turns a template and view into HTML | ||||
| */ | */ | ||||
| to_html: function(template, view, partials, send_fun) { | |||||
| to_html: function (template, view, partials, send_fun) { | |||||
| var renderer = new Renderer(); | var renderer = new Renderer(); | ||||
| if(send_fun) { | |||||
| if (send_fun) { | |||||
| renderer.send = send_fun; | renderer.send = send_fun; | ||||
| } | } | ||||
| renderer.render(template, view || {}, partials); | renderer.render(template, view || {}, partials); | ||||
| if(!send_fun) { | |||||
| if (!send_fun) { | |||||
| return renderer.buffer.join("\n"); | return renderer.buffer.join("\n"); | ||||
| } | } | ||||
| } | } | ||||