Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,18 @@ export function prepareBlock(
);
}

if (inverseAndProgram.chain) {
inverseAndProgram.program.body[0].closeStrip = close.strip;
// Only at the outermost block (where close is the real closing tag, not another
// chain link) propagate its strip flags through all chained else-if blocks.
if (inverseAndProgram.chain && !close.chain) {
const closeStrip = close.strip;
let innerBlock = inverseAndProgram.program.body[0];
// Walk the full chain so every block gets the real closing tag's strip flags.
while (innerBlock) {
innerBlock.closeStrip = closeStrip;
innerBlock = (innerBlock.inverse && innerBlock.inverse.chained)
? innerBlock.inverse.body[0]
: null;
}
}

inverseStrip = inverseAndProgram.strip;
Expand Down
16 changes: 15 additions & 1 deletion lib/whitespace-control.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,21 @@ WhitespaceControl.prototype.Program = function (program) {
// Always strip the next node
omitRight(body, i);

omitLeft((current.inverse || current.program).body);
// For chained else-if blocks, walk the chain and strip trailing indent
// from every terminal body so all execution paths lose the close-tag indent.
let chainNode = current.inverse;
if (chainNode && chainNode.chained) {
while (chainNode && chainNode.chained) {
let lastBlock = chainNode.body[chainNode.body.length - 1];
omitLeft(lastBlock.program.body);
chainNode = lastBlock.inverse;
}
if (chainNode) {
omitLeft(chainNode.body);
}
} else {
omitLeft((current.inverse || current.program).body);
}
}
}

Expand Down
25 changes: 25 additions & 0 deletions spec/ast.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ describe('ast', function () {
equals(ast.body[0].value, '');
equals(ast.body[1].program.body[0].value, 'foo');
});

it('tilde on one else-if does not strip trailing whitespace in later branches', function () {
let ast = parse('{{#if a}}A{{else if b}}B {{~else if c}}C {{/if}}'),
block = ast.body[0],
bBlock = block.inverse.body[0],
cBlock = bBlock.inverse.body[0];

equals(block.program.body[0].value, 'A');
equals(bBlock.program.body[0].value, 'B'); // tilde strips trailing space from b
equals(cBlock.program.body[0].value, 'C '); // no tilde on {{/if}}, space preserved
});
});

describe('parseWithoutProcessing', function () {
Expand Down Expand Up @@ -236,6 +247,20 @@ describe('ast', function () {

equals(ast.body[2].value, '');
});

it('strips close-tag indent from all chained else-if branches', function () {
let ast = parse(
' {{#if a}}\n foo\n {{else if b}}\n bar\n {{else if c}}\n baz\n {{/if}}'
),
block = ast.body[1],
bBlock = block.inverse.body[0],
cBlock = bBlock.inverse.body[0];

equals(ast.body[0].value, '');
equals(block.program.body[0].value, ' foo\n');
equals(bBlock.program.body[0].value, ' bar\n');
equals(cBlock.program.body[0].value, ' baz\n'); // indent before {{/if}} stripped
});
});
describe('partials - parseWithoutProcessing', function () {
it('simple partial', function () {
Expand Down
Loading