summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler/helpers.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/handlebars/compiler/helpers.js')
-rw-r--r--lib/handlebars/compiler/helpers.js36
1 files changed, 28 insertions, 8 deletions
diff --git a/lib/handlebars/compiler/helpers.js b/lib/handlebars/compiler/helpers.js
index 02b307b..d9b7b14 100644
--- a/lib/handlebars/compiler/helpers.js
+++ b/lib/handlebars/compiler/helpers.js
@@ -30,7 +30,8 @@ export function prepareRawBlock(openRawBlock, content, close, locInfo) {
export function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
/*jshint -W040 */
- if (openBlock.sexpr.id.original !== close.path.original) {
+ // When we are chaining inverse calls, we will not have a close path
+ if (close && close.path && openBlock.sexpr.id.original !== close.path.original) {
var errorNode = {
firstLine: openBlock.sexpr.firstLine,
firstColumn: openBlock.sexpr.firstColumn
@@ -39,7 +40,24 @@ export function prepareBlock(openBlock, program, inverseAndProgram, close, inver
throw new Exception(openBlock.sexpr.id.original + ' doesn\'t match ' + close.path.original, errorNode);
}
- var inverse = inverseAndProgram && inverseAndProgram.program;
+ // Safely handle a chained inverse that does not have a non-conditional inverse
+ // (i.e. both inverseAndProgram AND close are undefined)
+ if (!close) {
+ close = {strip: {}};
+ }
+
+ // Find the inverse program that is involed with whitespace stripping.
+ var inverse = inverseAndProgram && inverseAndProgram.program,
+ firstInverse = inverse,
+ lastInverse = inverse;
+ if (inverse && inverse.inverse) {
+ firstInverse = inverse.statements[0].program;
+
+ // Walk the inverse chain to find the last inverse that is actually in the chain.
+ while (lastInverse.inverse) {
+ lastInverse = lastInverse.statements[lastInverse.statements.length-1].program;
+ }
+ }
var strip = {
left: openBlock.strip.left,
@@ -48,7 +66,7 @@ export function prepareBlock(openBlock, program, inverseAndProgram, close, inver
// Determine the standalone candiacy. Basically flag our content as being possibly standalone
// so our parent can determine if we actually are standalone
openStandalone: isNextWhitespace(program.statements),
- closeStandalone: isPrevWhitespace((inverse || program).statements)
+ closeStandalone: isPrevWhitespace((firstInverse || program).statements)
};
if (openBlock.strip.right) {
@@ -61,19 +79,20 @@ export function prepareBlock(openBlock, program, inverseAndProgram, close, inver
if (inverseStrip.left) {
omitLeft(program.statements, null, true);
}
+
if (inverseStrip.right) {
- omitRight(inverse.statements, null, true);
+ omitRight(firstInverse.statements, null, true);
}
if (close.strip.left) {
- omitLeft(inverse.statements, null, true);
+ omitLeft(lastInverse.statements, null, true);
}
// Find standalone else statments
if (isPrevWhitespace(program.statements)
- && isNextWhitespace(inverse.statements)) {
+ && isNextWhitespace(firstInverse.statements)) {
omitLeft(program.statements);
- omitRight(inverse.statements);
+ omitRight(firstInverse.statements);
}
} else {
if (close.strip.left) {
@@ -118,7 +137,8 @@ export function prepareProgram(statements, isRoot) {
if (omitLeft(statements, i)) {
// If we are on a standalone node, save the indent info for partials
if (current.type === 'partial') {
- current.indent = (/([ \t]+$)/).exec(statements[i-1].original) ? RegExp.$1 : '';
+ // Pull out the whitespace from the final line
+ current.indent = (/([ \t]+$)/).exec(statements[i-1].original)[1];
}
}
}