# Code coverage report for dist/cjs/handlebars/compiler/helpers.js

## Statements: 100% (82 / 82) Branches: 98.92% (92 / 93) Functions: 100% (7 / 7) Lines: 100% (81 / 81) Ignored: none

All files » dist/cjs/handlebars/compiler/ » helpers.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    1

    1
    2323

    1
    1

    603
    2

    601

    601

    601
    34

    601
    62

    62
    22

    62
    22

    62
    18

    62

    17
    17

    539
    14

    601
    80

    521

    1
    1
    2718
    5434

    5434
    2583

    2851

    2851
    72

    2851
    64

    2851
    63

    63

    20
    11

    2851
    109

    109

    2851

    115

    115

    2718

    1
    3514
    663

    3514

    3514
    1480

    2034
    1712

    1
    3469
    618

    3469

    3469
    1401

    2068
    1729

    1
    432
    432
    150

    282
    282
    282

    1
    422
    422
    90

    332
    332
    332
    332
     "use strict";
    var Exception = require("../exception")["default"];

    function stripFlags(open, close) {
      return {
        left: open.charAt(2) === '~',
        right: close.charAt(close.length-3) === '~'
      };
    }

    exports.stripFlags = stripFlags;
    function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) {
      /*jshint -W040 */
      if (mustache.sexpr.id.original !== close.path.original) {
        throw new Exception(mustache.sexpr.id.original + ' doesn\'t match ' + close.path.original, mustache);
      }

      var inverse = inverseAndProgram && inverseAndProgram.program;

      var strip = {
        left: mustache.strip.left,
        right: close.strip.right,

        // Determine the standalone candiacy. Basically flag our content as being possibly standalone
        // so our parent can determine if we actually are standalone
        openStandalone: isNextWhitespace(program.statements),
        closeStandalone: isPrevWhitespace((inverse || program).statements)
      };

      if (mustache.strip.right) {
        omitRight(program.statements, null, true);
      }

      if (inverse) {
        var inverseStrip = inverseAndProgram.strip;

        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)
            && isNextWhitespace(inverse.statements)) {

          omitLeft(program.statements);
          omitRight(inverse.statements);
        }
      } else {
        if (close.strip.left) {
          omitLeft(program.statements, null, true);
        }
      }

      if (inverted) {
        return new this.BlockNode(mustache, inverse, program, strip, locInfo);
      } else {
        return new this.BlockNode(mustache, program, inverse, strip, locInfo);
      }
    }

    exports.prepareBlock = prepareBlock;
    function prepareProgram(statements, isRoot) {
      for (var i = 0, l = statements.length; i < l; i++) {
        var current = statements[i],
            strip = current.strip;

        if (!strip) {
          continue;
        }

        var _isPrevWhitespace = isPrevWhitespace(statements, i, isRoot, current.type === 'partial'),
            _isNextWhitespace = isNextWhitespace(statements, i, isRoot),

            openStandalone = strip.openStandalone && _isPrevWhitespace,
            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);

          if (omitLeft(statements, i)) {
            // If we are on a standalone node, save the indent info for partials
            if (current.type === 'partial') {
              current.indent = (/([ \t]+$)/).exec(statements[i-1].original) ? RegExp.$1 : '';
            }
          }
        }
        if (openStandalone) {
          omitRight((current.program || current.inverse).statements);

          // Strip out the previous content node if it's whitespace only
          omitLeft(statements, i);
        }
        if (closeStandalone) {
          // Always strip the next node
          omitRight(statements, i);

          omitLeft((current.inverse || current.program).statements);
        }
      }

      return statements;
    }

    exports.prepareProgram = prepareProgram;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],
          sibling = statements[i-2];
      if (!prev) {
        return isRoot;
      }

      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;
      }

      var next = statements[i+1],
          sibling = statements[i+2];
      if (!next) {
        return isRoot;
      }

      if (next.type === 'content') {
        return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);
      }
    }

    // Marks the node to the right of the position as omitted.
    // I.e. {{foo}}' ' will mark the ' ' node as omitted.
    //
    // If i is undefined, then the first child will be marked as such.
    //
    // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
    // content is met.
    function omitRight(statements, i, multiple) {
      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.
    // I.e. ' '{{foo}} will mark the ' ' node as omitted.
    //
    // If i is undefined then the last child will be marked as such.
    //
    // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
    // content is met.
    function omitLeft(statements, i, multiple) {
      var current = statements[i == null ? statements.length - 1 : i - 1];
      if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) {
        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;
    }