react / wstein / node_modules / jest-cli / node_modules / istanbul / node_modules / handlebars / dist / amd / handlebars / compiler / whitespace-control.js
80738 viewsdefine(1["./visitor","exports"],2function(__dependency1__, __exports__) {3"use strict";4var Visitor = __dependency1__["default"];56function WhitespaceControl() {7}8WhitespaceControl.prototype = new Visitor();910WhitespaceControl.prototype.Program = function(program) {11var isRoot = !this.isRootSeen;12this.isRootSeen = true;1314var body = program.body;15for (var i = 0, l = body.length; i < l; i++) {16var current = body[i],17strip = this.accept(current);1819if (!strip) {20continue;21}2223var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),24_isNextWhitespace = isNextWhitespace(body, i, isRoot),2526openStandalone = strip.openStandalone && _isPrevWhitespace,27closeStandalone = strip.closeStandalone && _isNextWhitespace,28inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;2930if (strip.close) {31omitRight(body, i, true);32}33if (strip.open) {34omitLeft(body, i, true);35}3637if (inlineStandalone) {38omitRight(body, i);3940if (omitLeft(body, i)) {41// If we are on a standalone node, save the indent info for partials42if (current.type === 'PartialStatement') {43// Pull out the whitespace from the final line44current.indent = (/([ \t]+$)/).exec(body[i-1].original)[1];45}46}47}48if (openStandalone) {49omitRight((current.program || current.inverse).body);5051// Strip out the previous content node if it's whitespace only52omitLeft(body, i);53}54if (closeStandalone) {55// Always strip the next node56omitRight(body, i);5758omitLeft((current.inverse || current.program).body);59}60}6162return program;63};64WhitespaceControl.prototype.BlockStatement = function(block) {65this.accept(block.program);66this.accept(block.inverse);6768// Find the inverse program that is involed with whitespace stripping.69var program = block.program || block.inverse,70inverse = block.program && block.inverse,71firstInverse = inverse,72lastInverse = inverse;7374if (inverse && inverse.chained) {75firstInverse = inverse.body[0].program;7677// Walk the inverse chain to find the last inverse that is actually in the chain.78while (lastInverse.chained) {79lastInverse = lastInverse.body[lastInverse.body.length-1].program;80}81}8283var strip = {84open: block.openStrip.open,85close: block.closeStrip.close,8687// Determine the standalone candiacy. Basically flag our content as being possibly standalone88// so our parent can determine if we actually are standalone89openStandalone: isNextWhitespace(program.body),90closeStandalone: isPrevWhitespace((firstInverse || program).body)91};9293if (block.openStrip.close) {94omitRight(program.body, null, true);95}9697if (inverse) {98var inverseStrip = block.inverseStrip;99100if (inverseStrip.open) {101omitLeft(program.body, null, true);102}103104if (inverseStrip.close) {105omitRight(firstInverse.body, null, true);106}107if (block.closeStrip.open) {108omitLeft(lastInverse.body, null, true);109}110111// Find standalone else statments112if (isPrevWhitespace(program.body)113&& isNextWhitespace(firstInverse.body)) {114115omitLeft(program.body);116omitRight(firstInverse.body);117}118} else {119if (block.closeStrip.open) {120omitLeft(program.body, null, true);121}122}123124return strip;125};126127WhitespaceControl.prototype.MustacheStatement = function(mustache) {128return mustache.strip;129};130131WhitespaceControl.prototype.PartialStatement =132WhitespaceControl.prototype.CommentStatement = function(node) {133/* istanbul ignore next */134var strip = node.strip || {};135return {136inlineStandalone: true,137open: strip.open,138close: strip.close139};140};141142143function isPrevWhitespace(body, i, isRoot) {144if (i === undefined) {145i = body.length;146}147148// Nodes that end with newlines are considered whitespace (but are special149// cased for strip operations)150var prev = body[i-1],151sibling = body[i-2];152if (!prev) {153return isRoot;154}155156if (prev.type === 'ContentStatement') {157return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original);158}159}160function isNextWhitespace(body, i, isRoot) {161if (i === undefined) {162i = -1;163}164165var next = body[i+1],166sibling = body[i+2];167if (!next) {168return isRoot;169}170171if (next.type === 'ContentStatement') {172return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);173}174}175176// Marks the node to the right of the position as omitted.177// I.e. {{foo}}' ' will mark the ' ' node as omitted.178//179// If i is undefined, then the first child will be marked as such.180//181// If mulitple is truthy then all whitespace will be stripped out until non-whitespace182// content is met.183function omitRight(body, i, multiple) {184var current = body[i == null ? 0 : i + 1];185if (!current || current.type !== 'ContentStatement' || (!multiple && current.rightStripped)) {186return;187}188189var original = current.value;190current.value = current.value.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');191current.rightStripped = current.value !== original;192}193194// Marks the node to the left of the position as omitted.195// I.e. ' '{{foo}} will mark the ' ' node as omitted.196//197// If i is undefined then the last child will be marked as such.198//199// If mulitple is truthy then all whitespace will be stripped out until non-whitespace200// content is met.201function omitLeft(body, i, multiple) {202var current = body[i == null ? body.length - 1 : i - 1];203if (!current || current.type !== 'ContentStatement' || (!multiple && current.leftStripped)) {204return;205}206207// We omit the last node if it's whitespace only and not preceeded by a non-content node.208var original = current.value;209current.value = current.value.replace(multiple ? (/\s+$/) : (/[ \t]+$/), '');210current.leftStripped = current.value !== original;211return current.leftStripped;212}213214__exports__["default"] = WhitespaceControl;215});216217