diff options
author | kpdecker <kpdecker@gmail.com> | 2014-08-23 17:44:20 -0500 |
---|---|---|
committer | kpdecker <kpdecker@gmail.com> | 2014-08-23 17:44:20 -0500 |
commit | 84d646bb5d5a8bb01bfb9465ee1078161f069742 (patch) | |
tree | 07233774619be9d4e00e8edaaf0fc528262f40a2 /lib/handlebars/compiler/helpers.js | |
parent | ccd803ff15e98186a82988a67d9aeff411612af4 (diff) | |
download | handlebars.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.js | 84 |
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; + } } } |