diff options
Diffstat (limited to 'lib/handlebars/compiler/helpers.js')
-rw-r--r-- | lib/handlebars/compiler/helpers.js | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/lib/handlebars/compiler/helpers.js b/lib/handlebars/compiler/helpers.js index 758c740..d9b7b14 100644 --- a/lib/handlebars/compiler/helpers.js +++ b/lib/handlebars/compiler/helpers.js @@ -7,26 +7,69 @@ export function stripFlags(open, close) { }; } +export function stripComment(comment) { + return comment.replace(/^\{\{~?\!-?-?/, '') + .replace(/-?-?~?\}\}$/, ''); +} + +export function prepareRawBlock(openRawBlock, content, close, locInfo) { + /*jshint -W040 */ + if (openRawBlock.sexpr.id.original !== close) { + var errorNode = { + firstLine: openRawBlock.sexpr.firstLine, + firstColumn: openRawBlock.sexpr.firstColumn + }; + + throw new Exception(openRawBlock.sexpr.id.original + " doesn't match " + close, errorNode); + } + + var program = new this.ProgramNode([content], {}, locInfo); + + return new this.BlockNode(openRawBlock.sexpr, program, undefined, undefined, locInfo); +} -export function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) { +export function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) { /*jshint -W040 */ - if (mustache.sexpr.id.original !== close.path.original) { - throw new Exception(mustache.sexpr.id.original + ' doesn\'t match ' + close.path.original, mustache); + // 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 + }; + + throw new Exception(openBlock.sexpr.id.original + ' doesn\'t match ' + close.path.original, errorNode); + } + + // 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: {}}; } - var inverse = inverseAndProgram && inverseAndProgram.program; + // 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: mustache.strip.left, + left: openBlock.strip.left, right: close.strip.right, // 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 (mustache.strip.right) { + if (openBlock.strip.right) { omitRight(program.statements, null, true); } @@ -36,19 +79,20 @@ export function prepareBlock(mustache, program, inverseAndProgram, close, invert 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) { @@ -57,9 +101,9 @@ export function prepareBlock(mustache, program, inverseAndProgram, close, invert } if (inverted) { - return new this.BlockNode(mustache, inverse, program, strip, locInfo); + return new this.BlockNode(openBlock.sexpr, inverse, program, strip, locInfo); } else { - return new this.BlockNode(mustache, program, inverse, strip, locInfo); + return new this.BlockNode(openBlock.sexpr, program, inverse, strip, locInfo); } } @@ -93,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]; } } } |