diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..099f85b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Mocha Current File", + "program": "${workspaceRoot}/node_modules/.bin/_mocha", + "args": ["${file}"], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} diff --git a/src/compile/set.js b/src/compile/set.js index d8ce058..9dbe650 100644 --- a/src/compile/set.js +++ b/src/compile/set.js @@ -6,29 +6,28 @@ module.exports = function(Velocity, utils) { /** * get variable from context, if run in block, return local context, else return global context */ - getContext: function() { - var condition = this.condition; + getContext: function(idName) { var local = this.local; - if (condition) { - return local[condition]; - } else { - return this.context; + // context find, from the conditions stack top to end + for (var condition of this.conditions) { + if (local[condition].hasOwnProperty(idName)) { + return local[condition]; + } } + // not find local variable, return global context + return this.context; }, /** * parse #set */ setValue: function(ast) { var ref = ast.equal[0]; - var context = this.getContext(); + var context = this.getContext(ref.id); // @see #25 if (this.condition && this.condition.indexOf('macro:') === 0) { context = this.context; // fix #129 - } else if (!context.hasOwnProperty(ref.id)) { - // set var to global context, see #100 - context = this.context; } var valAst = ast.equal[1]; diff --git a/test/set.test.js b/test/set.test.js index 79d69f4..89f2ad1 100644 --- a/test/set.test.js +++ b/test/set.test.js @@ -216,4 +216,42 @@ describe('Set && Expression', function() { const html = render(tpl).replace(/\n\s.|\s{2}/g, '').trim(); html.should.eql('

test1 test3

test1 test2 test3

test1 test3

test1 test2 test3

'); }) + + it('nested foreach subprop', function() { + var tpl = ` + #set($list = [{"prop": "a"}]) + #set($list2 = ["a", "b", "c"]) + #foreach($i in $list) + #set($fc = $velocityCount - 1) + #foreach($j in $list2) + #set($i.prop = "$i.prop$j") + #end + #end + $list + ` + var ret = render(tpl).trim() + assert.strictEqual('[{prop=aabc}]', ret); + }) + + it('nested foreach set', function() { + var tpl = ` + #set($obj = [{ + "SubProp": [ + { "SubSubProp": "a" } + ] + }]) + #set($subSubPropRealValue = "b") + #foreach($sub in $obj) + #set($fc = $velocityCount - 1) + #foreach($subsub in $sub.SubProp) + #set($fcc = $velocityCount - 1) + #set($sub.SubProp[$fcc].SubSubProp = $subSubPropRealValue) + #end + #set($obj[$fc] = $sub) + #end + $obj + ` + var ret = render(tpl).trim() + assert.strictEqual('[{SubProp=[{SubSubProp=b}]}]', ret); + }); })