summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/handlebars/compiler')
-rw-r--r--lib/handlebars/compiler/compiler.js14
-rw-r--r--lib/handlebars/compiler/helpers.js84
-rw-r--r--lib/handlebars/compiler/javascript-compiler.js22
3 files changed, 67 insertions, 53 deletions
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index c7fdf3d..29718d0 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -69,19 +69,7 @@ Compiler.prototype = {
},
accept: function(node) {
- var strip = node.strip || {},
- ret;
- if (strip.left) {
- this.opcode('strip');
- }
-
- ret = this[node.type](node);
-
- if (strip.right) {
- this.opcode('strip');
- }
-
- return ret;
+ return this[node.type](node);
},
program: function(program) {
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;
+ }
}
}
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index 25d45d1..fcd58fd 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -85,11 +85,6 @@ JavaScriptCompiler.prototype = {
opcode = opcodes[i];
this[opcode.opcode].apply(this, opcode.args);
-
- // Reset the stripNext flag if it was not set by this operation.
- if (opcode.opcode !== this.stripNext) {
- this.stripNext = false;
- }
}
// Flush any trailing content that might be pending.
@@ -280,27 +275,10 @@ JavaScriptCompiler.prototype = {
if (this.pendingContent) {
content = this.pendingContent + content;
}
- if (this.stripNext) {
- content = content.replace(/^\s+/, '');
- }
this.pendingContent = content;
},
- // [strip]
- //
- // On stack, before: ...
- // On stack, after: ...
- //
- // Removes any trailing whitespace from the prior content node and flags
- // the next operation for stripping if it is a content node.
- strip: function() {
- if (this.pendingContent) {
- this.pendingContent = this.pendingContent.replace(/\s+$/, '');
- }
- this.stripNext = 'strip';
- },
-
// [append]
//
// On stack, before: value, ...