diff --git a/lib/handlebars.js b/lib/handlebars.js index 3138ab90..d85336d9 100644 --- a/lib/handlebars.js +++ b/lib/handlebars.js @@ -184,31 +184,37 @@ var Handlebars = { }, handleBlock: function(lookup, context, arg, fn, notFn) { - var out = ""; + var out = "", args; + originalArgs = arg.length ? arg : [null] + if (Handlebars.isFunction(lookup)) { - out = out + lookup.call(context, arg, fn); + args = originalArgs.concat(fn); + out = out + lookup.apply(context, args); + if (notFn != null && Handlebars.isFunction(lookup.not)) { - out = out + lookup.not.call(context, arg, notFn); + args = originalArgs.concat(notFn); + out = out + lookup.not.apply(context, args); } } else { if (!Handlebars.isEmpty(lookup)) { - out = out + Handlebars.helperMissing.call(arg, lookup, fn); + // TODO: which case is this, and what does it mean for multiple args + out = out + Handlebars.helperMissing.call(arg[0], lookup, fn); } if (notFn != null) { - out = out + Handlebars.helperMissing.not.call(arg, lookup, notFn); + out = out + Handlebars.helperMissing.not.call(arg[0], lookup, notFn); } } return out; }, - handleExpression: function(lookup, context, arg, isEscaped) { + handleExpression: function(lookup, context, args, isEscaped) { var out = ""; if (Handlebars.isFunction(lookup)) { - out = out + Handlebars.filterOutput(lookup.call(context, arg), isEscaped); + out = out + Handlebars.filterOutput(lookup.apply(context, args), isEscaped); } else if(!Handlebars.isEmpty(lookup)) { out = out + Handlebars.filterOutput(lookup, isEscaped); } @@ -333,11 +339,13 @@ Handlebars.Compiler.prototype = { } }, - addExpression: function(mustache, param) { - param = param || null; + addExpression: function(mustache, params) { + if(!params[0]) params = ["null"] + params = params.join(", ") + var expr = this.lookupFor(mustache); this.fn += "var proxy = Handlebars.buildContext(context, stack);" - this.fn += "out = out + Handlebars.handleExpression(" + expr + ", proxy, " + param + ", " + this.escaped + ");"; + this.fn += "out = out + Handlebars.handleExpression(" + expr + ", proxy, [" + params + "], " + this.escaped + ");"; }, addInvertedSection: function(mustache) { @@ -385,7 +393,7 @@ Handlebars.Compiler.prototype = { return compiler; }, - addBlock: function(mustache, param, parts) { + addBlock: function(mustache, params) { var compiler = this.compileToEndOfBlock(mustache); var result = compiler.fn; @@ -395,7 +403,7 @@ Handlebars.Compiler.prototype = { this.fn += "var wrappedContext = Handlebars.buildContext(context, stack);"; this.fn += "var " + fnId + " = function(context) {" + result + "}; "; this.fn += "lookup = " + this.lookupFor(mustache) + "; "; - this.fn += "arg = " + param + ";"; + this.fn += "arg = [" + params.join(", ") + "] ;"; this.fn += "stack.push(context);"; if (compiler.continueInverted) { @@ -441,13 +449,41 @@ Handlebars.Compiler.prototype = { } this.addText(); - this.mustache = " "; + var params = [""], currentParam = 0, literals = []; while(chr = this.getChar()) { - if(this.mustache && chr === "}" && this.peek() === "}") { - var parts = Handlebars.trim(this.mustache).split(/\s+/); - mustache = parts[0]; - param = this.lookupFor(parts[1]); + if(this.stringLiteral) { + params[currentParam] += chr; + + if(chr === "\\" && this.peek() === '"') { + params[currentParam] += '"'; + this.getChar(); + } else if(chr === '"') { + params[++currentParam] = "" + this.stringLiteral = false; + } + } else if(chr === '"') { + if(params[currentParam] !== "") { + throw new Handlebars.Exception("You are already in the middle of" + + "the " + params[currentParam] + " param. " + + "You cannot start a String param") + } + + this.stringLiteral = true; + params[currentParam] = chr; + literals[currentParam] = true; + } else if(chr === " ") { + if(params[currentParam] !== "") params[++currentParam] = "" + } else if(chr === "}" && this.peek() === "}") { + mustache = params[0]; + arguments = []; + + if(!params[1]) params[1] = undefined; + + for(var i=1,l=params.length; i