summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler/helpers.js
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-08-25 13:27:28 -0500
committerkpdecker <kpdecker@gmail.com>2014-08-25 13:27:28 -0500
commitdc9a2ed7eb97ecda0dab800c8e776cbf6a4d4555 (patch)
tree598c76a0c40d01424b9ba83a3ccb5bf900d1135d /lib/handlebars/compiler/helpers.js
parent980c38cebf9a12f80acbbc1fd97120c63f495e6d (diff)
downloadhandlebars.js-dc9a2ed7eb97ecda0dab800c8e776cbf6a4d4555.zip
handlebars.js-dc9a2ed7eb97ecda0dab800c8e776cbf6a4d4555.tar.gz
handlebars.js-dc9a2ed7eb97ecda0dab800c8e776cbf6a4d4555.tar.bz2
Refactor content blocks to ignore lines
We can simplify our previous standalone determination logic by merging content blocks again. Fixes #854
Diffstat (limited to 'lib/handlebars/compiler/helpers.js')
-rw-r--r--lib/handlebars/compiler/helpers.js88
1 files changed, 31 insertions, 57 deletions
diff --git a/lib/handlebars/compiler/helpers.js b/lib/handlebars/compiler/helpers.js
index dd32299..758c740 100644
--- a/lib/handlebars/compiler/helpers.js
+++ b/lib/handlebars/compiler/helpers.js
@@ -93,7 +93,7 @@ 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 = statements[i-1].original;
+ current.indent = (/([ \t]+$)/).exec(statements[i-1].original) ? RegExp.$1 : '';
}
}
}
@@ -114,39 +114,36 @@ export function prepareProgram(statements, isRoot) {
return statements;
}
-function isPrevWhitespace(statements, i, isRoot, disallowIndent) {
+function isPrevWhitespace(statements, i, isRoot) {
if (i === undefined) {
i = statements.length;
}
// Nodes that end with newlines are considered whitespace (but are special
// cased for strip operations)
- var prev = statements[i-1];
- if (prev && /\n$/.test(prev.string)) {
- return true;
+ var prev = statements[i-1],
+ sibling = statements[i-2];
+ if (!prev) {
+ return isRoot;
}
- return checkWhitespace(isRoot, prev, statements[i-2]);
+ if (prev.type === 'content') {
+ return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original);
+ }
}
function isNextWhitespace(statements, i, isRoot) {
if (i === undefined) {
i = -1;
}
- return checkWhitespace(isRoot, statements[i+1], statements[i+2]);
-}
-function checkWhitespace(isRoot, next1, next2) {
- if (!next1) {
+ var next = statements[i+1],
+ sibling = statements[i+2];
+ if (!next) {
return isRoot;
- } else if (next1.type === 'content') {
- // Check if the previous node is empty or whitespace only
- if (/^[\s]*$/.test(next1.string)) {
- if (next2) {
- return next2.type === 'content' || /\n$/.test(next1.string);
- } else {
- return isRoot || (next1.string.indexOf('\n') >= 0);
- }
- }
+ }
+
+ if (next.type === 'content') {
+ return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);
}
}
@@ -158,22 +155,14 @@ function checkWhitespace(isRoot, next1, next2) {
// 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;
- }
+ var current = statements[i == null ? 0 : i + 1];
+ if (!current || current.type !== 'content' || (!multiple && current.rightStripped)) {
+ return;
}
+
+ var original = current.string;
+ current.string = current.string.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');
+ current.rightStripped = current.string !== original;
}
// Marks the node to the left of the position as omitted.
@@ -184,29 +173,14 @@ function omitRight(statements, i, multiple) {
// 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 current = statements[i == null ? statements.length - 1 : i - 1];
+ if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) {
+ return;
}
- var current = statements[--i],
- prev = statements[i-1];
-
- 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;
- }
- }
+ // We omit the last node if it's whitespace only and not preceeded by a non-content node.
+ var original = current.string;
+ current.string = current.string.replace(multiple ? (/\s+$/) : (/[ \t]+$/), '');
+ current.leftStripped = current.string !== original;
+ return current.leftStripped;
}