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.js73
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];
}
}
}