diff --git a/dist/handlebars.js b/dist/handlebars.js index 828bbee5c..963e72c27 100644 --- a/dist/handlebars.js +++ b/dist/handlebars.js @@ -1050,6 +1050,10 @@ Compiler.prototype = { val = pair[1]; if (this.options.stringParams) { + if(val.depth) { + this.addDepth(val.depth); + } + this.opcode('getContext', val.depth || 0); this.opcode('pushStringParam', val.stringModeValue, val.type); } else { this.accept(val); @@ -1634,16 +1638,18 @@ JavaScriptCompiler.prototype = { if (this.options.stringParams) { this.register('hashTypes', '{}'); + this.register('hashContexts', '{}'); } }, pushHash: function() { - this.hash = {values: [], types: []}; + this.hash = {values: [], types: [], contexts: []}; }, popHash: function() { var hash = this.hash; this.hash = undefined; if (this.options.stringParams) { + this.register('hashContexts', '{' + hash.contexts.join(',') + '}'); this.register('hashTypes', '{' + hash.types.join(',') + '}'); } this.push('{\n ' + hash.values.join(',\n ') + '\n }'); @@ -1786,14 +1792,18 @@ JavaScriptCompiler.prototype = { // and pushes the hash back onto the stack. assignToHash: function(key) { var value = this.popStack(), + context, type; if (this.options.stringParams) { type = this.popStack(); - this.popStack(); + context = this.popStack(); } var hash = this.hash; + if (context) { + hash.contexts.push("'" + key + "': " + context); + } if (type) { hash.types.push("'" + key + "': " + type); } @@ -2044,6 +2054,7 @@ JavaScriptCompiler.prototype = { if (this.options.stringParams) { options.push("contexts:[" + contexts.join(",") + "]"); options.push("types:[" + types.join(",") + "]"); + options.push("hashContexts:hashContexts"); options.push("hashTypes:hashTypes"); } diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js index 7c8b55257..98f5396e4 100644 --- a/lib/handlebars/compiler/compiler.js +++ b/lib/handlebars/compiler/compiler.js @@ -189,6 +189,10 @@ Compiler.prototype = { val = pair[1]; if (this.options.stringParams) { + if(val.depth) { + this.addDepth(val.depth); + } + this.opcode('getContext', val.depth || 0); this.opcode('pushStringParam', val.stringModeValue, val.type); } else { this.accept(val); @@ -773,16 +777,18 @@ JavaScriptCompiler.prototype = { if (this.options.stringParams) { this.register('hashTypes', '{}'); + this.register('hashContexts', '{}'); } }, pushHash: function() { - this.hash = {values: [], types: []}; + this.hash = {values: [], types: [], contexts: []}; }, popHash: function() { var hash = this.hash; this.hash = undefined; if (this.options.stringParams) { + this.register('hashContexts', '{' + hash.contexts.join(',') + '}'); this.register('hashTypes', '{' + hash.types.join(',') + '}'); } this.push('{\n ' + hash.values.join(',\n ') + '\n }'); @@ -925,14 +931,18 @@ JavaScriptCompiler.prototype = { // and pushes the hash back onto the stack. assignToHash: function(key) { var value = this.popStack(), + context, type; if (this.options.stringParams) { type = this.popStack(); - this.popStack(); + context = this.popStack(); } var hash = this.hash; + if (context) { + hash.contexts.push("'" + key + "': " + context); + } if (type) { hash.types.push("'" + key + "': " + type); } @@ -1183,6 +1193,7 @@ JavaScriptCompiler.prototype = { if (this.options.stringParams) { options.push("contexts:[" + contexts.join(",") + "]"); options.push("types:[" + types.join(",") + "]"); + options.push("hashContexts:hashContexts"); options.push("hashTypes:hashTypes"); } diff --git a/spec/qunit_spec.js b/spec/qunit_spec.js index 1fb45a5c1..e2f7d47d0 100644 --- a/spec/qunit_spec.js +++ b/spec/qunit_spec.js @@ -1329,6 +1329,32 @@ test("in string mode, hash parameters get type information", function() { equal(result, "Helper called"); }); +test("in string mode, hash parameters get context information", function() { + var template = CompilerContext.compile('{{#with dale}}{{tomdale he.says desire="need" noun=../dad/joke bool=true}}{{/with}}', { stringParams: true }); + + var context = {dale: {}}; + + var helpers = { + tomdale: function(exclamation, options) { + equal(exclamation, "he.says"); + equal(options.types[0], "ID"); + + equal(options.contexts.length, 1); + equal(options.hashContexts.noun, context); + equal(options.hash.desire, "need"); + equal(options.hash.noun, "dad.joke"); + equal(options.hash.bool, true); + return "Helper called"; + }, + "with": function(context, options) { + return options.fn(options.contexts[0][context]); + } + }; + + var result = template(context, { helpers: helpers }); + equal(result, "Helper called"); +}); + test("when inside a block in String mode, .. passes the appropriate context in the options hash to a block helper", function() { var template = CompilerContext.compile('{{#with dale}}{{#tomdale ../need dad.joke}}wot{{/tomdale}}{{/with}}', {stringParams: true});