Skip to content

Commit

Permalink
Add contexts for string mode hash values
Browse files Browse the repository at this point in the history
Allows for evaluating hash parameters such as ../city in string mode.
  • Loading branch information
leshill committed Mar 20, 2013
1 parent bcc15ea commit 53de759
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
15 changes: 13 additions & 2 deletions dist/handlebars.js
Expand Up @@ -1023,6 +1023,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);
Expand Down Expand Up @@ -1607,16 +1611,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 }');
Expand Down Expand Up @@ -1759,14 +1765,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);
}
Expand Down Expand Up @@ -2020,6 +2030,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");
}

Expand Down
15 changes: 13 additions & 2 deletions lib/handlebars/compiler/compiler.js
Expand Up @@ -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);
Expand Down Expand Up @@ -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 }');
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -1186,6 +1196,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");
}

Expand Down
26 changes: 26 additions & 0 deletions spec/qunit_spec.js
Expand Up @@ -1286,6 +1286,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});

Expand Down

0 comments on commit 53de759

Please sign in to comment.