summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler/helpers.js
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-08-23 17:44:20 -0500
committerkpdecker <kpdecker@gmail.com>2014-08-23 17:44:20 -0500
commit84d646bb5d5a8bb01bfb9465ee1078161f069742 (patch)
tree07233774619be9d4e00e8edaaf0fc528262f40a2 /lib/handlebars/compiler/helpers.js
parentccd803ff15e98186a82988a67d9aeff411612af4 (diff)
downloadhandlebars.js-84d646bb5d5a8bb01bfb9465ee1078161f069742.zip
handlebars.js-84d646bb5d5a8bb01bfb9465ee1078161f069742.tar.gz
handlebars.js-84d646bb5d5a8bb01bfb9465ee1078161f069742.tar.bz2
Move strip processing into AST helper logic
We already have to track these behaviors for the standalone parsing and rather than having two whitespace pruning implementations this moves all of the behavior into one place. Fixes #852
Diffstat (limited to 'lib/handlebars/compiler/helpers.js')
-rw-r--r--lib/handlebars/compiler/helpers.js84
1 files changed, 66 insertions, 18 deletions
diff --git a/lib/handlebars/compiler/helpers.js b/lib/handlebars/compiler/helpers.js
index 8ba7b40..c93b811 100644
--- a/lib/handlebars/compiler/helpers.js
+++ b/lib/handlebars/compiler/helpers.js
@@ -26,13 +26,22 @@ export function prepareBlock(mustache, program, inverseAndProgram, close, invert
closeStandalone: isPrevWhitespace((inverse || program).statements)
};
+ if (mustache.strip.right) {
+ omitRight(program.statements, null, true);
+ }
+
if (inverse) {
var inverseStrip = inverseAndProgram.strip;
- program.strip.left = mustache.strip.right;
- program.strip.right = inverseStrip.left;
- inverse.strip.left = inverseStrip.right;
- inverse.strip.right = close.strip.left;
+ if (inverseStrip.left) {
+ omitLeft(program.statements, null, true);
+ }
+ if (inverseStrip.right) {
+ omitRight(inverse.statements, null, true);
+ }
+ if (close.strip.left) {
+ omitLeft(inverse.statements, null, true);
+ }
// Find standalone else statments
if (isPrevWhitespace(program.statements)
@@ -42,8 +51,9 @@ export function prepareBlock(mustache, program, inverseAndProgram, close, invert
omitRight(inverse.statements);
}
} else {
- program.strip.left = mustache.strip.right;
- program.strip.right = close.strip.left;
+ if (close.strip.left) {
+ omitLeft(program.statements, null, true);
+ }
}
if (inverted) {
@@ -70,6 +80,13 @@ export function prepareProgram(statements, isRoot) {
closeStandalone = strip.closeStandalone && _isNextWhitespace,
inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
+ if (strip.right) {
+ omitRight(statements, i, true);
+ }
+ if (strip.left) {
+ omitLeft(statements, i, true);
+ }
+
if (inlineStandalone) {
omitRight(statements, i);
@@ -137,10 +154,25 @@ function checkWhitespace(isRoot, next1, next2, disallowIndent) {
// I.e. {{foo}}' ' will mark the ' ' node as omitted.
//
// If i is undefined, then the first child will be marked as such.
-function omitRight(statements, i) {
- var first = statements[i == null ? 0 : i + 1];
- if (first) {
- first.string = '';
+//
+// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
+// content is met.
+function omitRight(statements, i, multiple) {
+ i = i == null ? 0 : i + 1;
+
+ var current = statements[i];
+ while (current) {
+ if (current.type !== 'content') {
+ return;
+ }
+
+ current.string = current.string.replace(/^[\s]+/, '');
+
+ if (multiple && !current.string) {
+ current = statements[++i];
+ } else {
+ return;
+ }
}
}
@@ -148,17 +180,33 @@ function omitRight(statements, i) {
// I.e. ' '{{foo}} will mark the ' ' node as omitted.
//
// If i is undefined then the last child will be marked as such.
-function omitLeft(statements, i) {
- if (i === undefined) {
+//
+// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
+// content is met.
+function omitLeft(statements, i, multiple) {
+ if (i == null) {
i = statements.length;
}
- var last = statements[i-1],
- prev = statements[i-2];
+ var current = statements[--i],
+ prev = statements[i-1];
- // We omit the last node if it's whitespace only and not preceeded by a non-content node.
- if (last && /^[\s]*$/.test(last.string) && (!prev || prev.type === 'content')) {
- last.string = '';
- return true;
+ while (current) {
+ if (current.type !== 'content') {
+ return;
+ }
+
+ // We omit the last node if it's whitespace only and not preceeded by a non-content node.
+ if (multiple || (/^[\s]*$/.test(current.string) && (!prev || prev.type === 'content'))) {
+ current.string = current.string.replace(/[\s]+$/, '');
+
+ if (multiple && !current.string) {
+ current = statements[--i];
+ } else {
+ return true;
+ }
+ } else {
+ return;
+ }
}
}