PageRenderTime 45ms CodeModel.GetById 19ms app.highlight 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/honeynet_web/honeywall/static/twitter-bootstrap/docs/build/node_modules/hogan.js/web/builds/1.0.5/hogan-1.0.5.js

https://bitbucket.org/cpdean/pig
JavaScript | 572 lines | 434 code | 98 blank | 40 comment | 154 complexity | b4308bfebf8e9e58fac4c2605aaf0048 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1
  1/*
  2 *  Copyright 2011 Twitter, Inc.
  3 *  Licensed under the Apache License, Version 2.0 (the "License");
  4 *  you may not use this file except in compliance with the License.
  5 *  You may obtain a copy of the License at
  6 *
  7 *  http://www.apache.org/licenses/LICENSE-2.0
  8 *
  9 *  Unless required by applicable law or agreed to in writing, software
 10 *  distributed under the License is distributed on an "AS IS" BASIS,
 11 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12 *  See the License for the specific language governing permissions and
 13 *  limitations under the License.
 14 */
 15
 16
 17
 18var Hogan = {};
 19
 20(function (Hogan) {
 21  Hogan.Template = function constructor(renderFunc, text, compiler) {
 22    if (renderFunc) {
 23      this.r = renderFunc;
 24    }
 25    this.c = compiler;
 26    this.text = text || '';
 27  }
 28
 29  Hogan.Template.prototype = {
 30    // render: replaced by generated code.
 31    r: function (context, partials, indent) { return ''; },
 32
 33    // variable escaping
 34    v: hoganEscape,
 35
 36    render: function render(context, partials, indent) {
 37      return this.ri([context], partials || {}, indent);
 38    },
 39
 40    // render internal -- a hook for overrides that catches partials too
 41    ri: function (context, partials, indent) {
 42      return this.r(context, partials, indent);
 43    },
 44
 45    // tries to find a partial in the curent scope and render it
 46    rp: function(name, context, partials, indent) {
 47      var partial = partials[name];
 48
 49      if (!partial) {
 50        return '';
 51      }
 52
 53      if (this.c && typeof partial == 'string') {
 54        partial = this.c.compile(partial);
 55      }
 56
 57      return partial.ri(context, partials, indent);
 58    },
 59
 60    // render a section
 61    rs: function(context, partials, section) {
 62      var buf = '',
 63          tail = context[context.length - 1];
 64
 65      if (!isArray(tail)) {
 66        return buf = section(context, partials);
 67      }
 68
 69      for (var i = 0; i < tail.length; i++) {
 70        context.push(tail[i]);
 71        buf += section(context, partials);
 72        context.pop();
 73      }
 74
 75      return buf;
 76    },
 77
 78    // maybe start a section
 79    s: function(val, ctx, partials, inverted, start, end, tags) {
 80      var pass;
 81
 82      if (isArray(val) && val.length === 0) {
 83        return false;
 84      }
 85
 86      if (typeof val == 'function') {
 87        val = this.ls(val, ctx, partials, inverted, start, end, tags);
 88      }
 89
 90      pass = (val === '') || !!val;
 91
 92      if (!inverted && pass && ctx) {
 93        ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);
 94      }
 95
 96      return pass;
 97    },
 98
 99    // find values with dotted names
100    d: function(key, ctx, partials, returnFound) {
101      var names = key.split('.'),
102          val = this.f(names[0], ctx, partials, returnFound),
103          cx = null;
104
105      if (key === '.' && isArray(ctx[ctx.length - 2])) {
106        return ctx[ctx.length - 1];
107      }
108
109      for (var i = 1; i < names.length; i++) {
110        if (val && typeof val == 'object' && names[i] in val) {
111          cx = val;
112          val = val[names[i]];
113        } else {
114          val = '';
115        }
116      }
117
118      if (returnFound && !val) {
119        return false;
120      }
121
122      if (!returnFound && typeof val == 'function') {
123        ctx.push(cx);
124        val = this.lv(val, ctx, partials);
125        ctx.pop();
126      }
127
128      return val;
129    },
130
131    // find values with normal names
132    f: function(key, ctx, partials, returnFound) {
133      var val = false,
134          v = null,
135          found = false;
136
137      for (var i = ctx.length - 1; i >= 0; i--) {
138        v = ctx[i];
139        if (v && typeof v == 'object' && key in v) {
140          val = v[key];
141          found = true;
142          break;
143        }
144      }
145
146      if (!found) {
147        return (returnFound) ? false : "";
148      }
149
150      if (!returnFound && typeof val == 'function') {
151        val = this.lv(val, ctx, partials);
152      }
153
154      return val;
155    },
156
157    // higher order templates
158    ho: function(val, cx, partials, text, tags) {
159      var compiler = this.c;
160      var t = val.call(cx, text, function(t) {
161        return compiler.compile(t, {delimiters: tags}).render(cx, partials);
162      });
163      var s = compiler.compile(t.toString(), {delimiters: tags}).render(cx, partials);
164      this.b = s;
165      return false;
166    },
167
168    // higher order template result buffer
169    b: '',
170
171    // lambda replace section
172    ls: function(val, ctx, partials, inverted, start, end, tags) {
173      var cx = ctx[ctx.length - 1],
174          t = null;
175
176      if (!inverted && this.c && val.length > 0) {
177        return this.ho(val, cx, partials, this.text.substring(start, end), tags);
178      }
179
180      t = val.call(cx);
181
182      if (typeof t == 'function') {
183        if (inverted) {
184          return true;
185        } else if (this.c) {
186          return this.ho(t, cx, partials, this.text.substring(start, end), tags);
187        }
188      }
189
190      return t;
191    },
192
193    // lambda replace variable
194    lv: function(val, ctx, partials) {
195      var cx = ctx[ctx.length - 1];
196      var result = val.call(cx);
197      if (typeof result == 'function') {
198        result = result.call(cx);
199      }
200      result = result.toString();
201
202      if (this.c && ~result.indexOf("{{")) {
203        return this.c.compile(result).render(cx, partials);
204      }
205
206      return result;
207    }
208
209  };
210
211  var rAmp = /&/g,
212      rLt = /</g,
213      rGt = />/g,
214      rApos =/\'/g,
215      rQuot = /\"/g,
216      hChars =/[&<>\"\']/;
217
218  function hoganEscape(str) {
219    str = String((str === null || str === undefined) ? '' : str);
220    return hChars.test(str) ?
221      str
222        .replace(rAmp,'&amp;')
223        .replace(rLt,'&lt;')
224        .replace(rGt,'&gt;')
225        .replace(rApos,'&#39;')
226        .replace(rQuot, '&quot;') :
227      str;
228  }
229
230  var isArray = Array.isArray || function(a) {
231    return Object.prototype.toString.call(a) === '[object Array]';
232  };
233
234})(typeof exports !== 'undefined' ? exports : Hogan);
235
236
237
238
239(function (Hogan) {
240  // Setup regex  assignments
241  // remove whitespace according to Mustache spec
242  var rIsWhitespace = /\S/,
243      rQuot = /\"/g,
244      rNewline =  /\n/g,
245      rCr = /\r/g,
246      rSlash = /\\/g,
247      tagTypes = {
248        '#': 1, '^': 2, '/': 3,  '!': 4, '>': 5,
249        '<': 6, '=': 7, '_v': 8, '{': 9, '&': 10
250      };
251
252  Hogan.scan = function scan(text, delimiters) {
253    var len = text.length,
254        IN_TEXT = 0,
255        IN_TAG_TYPE = 1,
256        IN_TAG = 2,
257        state = IN_TEXT,
258        tagType = null,
259        tag = null,
260        buf = '',
261        tokens = [],
262        seenTag = false,
263        i = 0,
264        lineStart = 0,
265        otag = '{{',
266        ctag = '}}';
267
268    function addBuf() {
269      if (buf.length > 0) {
270        tokens.push(new String(buf));
271        buf = '';
272      }
273    }
274
275    function lineIsWhitespace() {
276      var isAllWhitespace = true;
277      for (var j = lineStart; j < tokens.length; j++) {
278        isAllWhitespace =
279          (tokens[j].tag && tagTypes[tokens[j].tag] < tagTypes['_v']) ||
280          (!tokens[j].tag && tokens[j].match(rIsWhitespace) === null);
281        if (!isAllWhitespace) {
282          return false;
283        }
284      }
285
286      return isAllWhitespace;
287    }
288
289    function filterLine(haveSeenTag, noNewLine) {
290      addBuf();
291
292      if (haveSeenTag && lineIsWhitespace()) {
293        for (var j = lineStart, next; j < tokens.length; j++) {
294          if (!tokens[j].tag) {
295            if ((next = tokens[j+1]) && next.tag == '>') {
296              // set indent to token value
297              next.indent = tokens[j].toString()
298            }
299            tokens.splice(j, 1);
300          }
301        }
302      } else if (!noNewLine) {
303        tokens.push({tag:'\n'});
304      }
305
306      seenTag = false;
307      lineStart = tokens.length;
308    }
309
310    function changeDelimiters(text, index) {
311      var close = '=' + ctag,
312          closeIndex = text.indexOf(close, index),
313          delimiters = trim(
314            text.substring(text.indexOf('=', index) + 1, closeIndex)
315          ).split(' ');
316
317      otag = delimiters[0];
318      ctag = delimiters[1];
319
320      return closeIndex + close.length - 1;
321    }
322
323    if (delimiters) {
324      delimiters = delimiters.split(' ');
325      otag = delimiters[0];
326      ctag = delimiters[1];
327    }
328
329    for (i = 0; i < len; i++) {
330      if (state == IN_TEXT) {
331        if (tagChange(otag, text, i)) {
332          --i;
333          addBuf();
334          state = IN_TAG_TYPE;
335        } else {
336          if (text.charAt(i) == '\n') {
337            filterLine(seenTag);
338          } else {
339            buf += text.charAt(i);
340          }
341        }
342      } else if (state == IN_TAG_TYPE) {
343        i += otag.length - 1;
344        tag = tagTypes[text.charAt(i + 1)];
345        tagType = tag ? text.charAt(i + 1) : '_v';
346        if (tagType == '=') {
347          i = changeDelimiters(text, i);
348          state = IN_TEXT;
349        } else {
350          if (tag) {
351            i++;
352          }
353          state = IN_TAG;
354        }
355        seenTag = i;
356      } else {
357        if (tagChange(ctag, text, i)) {
358          tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag,
359                       i: (tagType == '/') ? seenTag - ctag.length : i + otag.length});
360          buf = '';
361          i += ctag.length - 1;
362          state = IN_TEXT;
363          if (tagType == '{') {
364            if (ctag == '}}') {
365              i++;
366            } else {
367              cleanTripleStache(tokens[tokens.length - 1]);
368            }
369          }
370        } else {
371          buf += text.charAt(i);
372        }
373      }
374    }
375
376    filterLine(seenTag, true);
377
378    return tokens;
379  }
380
381  function cleanTripleStache(token) {
382    if (token.n.substr(token.n.length - 1) === '}') {
383      token.n = token.n.substring(0, token.n.length - 1);
384    }
385  }
386
387  function trim(s) {
388    if (s.trim) {
389      return s.trim();
390    }
391
392    return s.replace(/^\s*|\s*$/g, '');
393  }
394
395  function tagChange(tag, text, index) {
396    if (text.charAt(index) != tag.charAt(0)) {
397      return false;
398    }
399
400    for (var i = 1, l = tag.length; i < l; i++) {
401      if (text.charAt(index + i) != tag.charAt(i)) {
402        return false;
403      }
404    }
405
406    return true;
407  }
408
409  function buildTree(tokens, kind, stack, customTags) {
410    var instructions = [],
411        opener = null,
412        token = null;
413
414    while (tokens.length > 0) {
415      token = tokens.shift();
416      if (token.tag == '#' || token.tag == '^' || isOpener(token, customTags)) {
417        stack.push(token);
418        token.nodes = buildTree(tokens, token.tag, stack, customTags);
419        instructions.push(token);
420      } else if (token.tag == '/') {
421        if (stack.length === 0) {
422          throw new Error('Closing tag without opener: /' + token.n);
423        }
424        opener = stack.pop();
425        if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) {
426          throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n);
427        }
428        opener.end = token.i;
429        return instructions;
430      } else {
431        instructions.push(token);
432      }
433    }
434
435    if (stack.length > 0) {
436      throw new Error('missing closing tag: ' + stack.pop().n);
437    }
438
439    return instructions;
440  }
441
442  function isOpener(token, tags) {
443    for (var i = 0, l = tags.length; i < l; i++) {
444      if (tags[i].o == token.n) {
445        token.tag = '#';
446        return true;
447      }
448    }
449  }
450
451  function isCloser(close, open, tags) {
452    for (var i = 0, l = tags.length; i < l; i++) {
453      if (tags[i].c == close && tags[i].o == open) {
454        return true;
455      }
456    }
457  }
458
459  function writeCode(tree) {
460    return 'i = i || "";var b = i + "";var _ = this;' + walk(tree) + 'return b;';
461  }
462
463  Hogan.generate = function (code, text, options) {
464    if (options.asString) {
465      return 'function(c,p,i){' + code + ';}';
466    }
467
468    return new Hogan.Template(new Function('c', 'p', 'i', code), text, Hogan);
469  }
470
471  function esc(s) {
472    return s.replace(rSlash, '\\\\')
473            .replace(rQuot, '\\\"')
474            .replace(rNewline, '\\n')
475            .replace(rCr, '\\r');
476  }
477
478  function chooseMethod(s) {
479    return (~s.indexOf('.')) ? 'd' : 'f';
480  }
481
482  function walk(tree) {
483    var code = '';
484    for (var i = 0, l = tree.length; i < l; i++) {
485      var tag = tree[i].tag;
486      if (tag == '#') {
487        code += section(tree[i].nodes, tree[i].n, chooseMethod(tree[i].n),
488                        tree[i].i, tree[i].end, tree[i].otag + " " + tree[i].ctag);
489      } else if (tag == '^') {
490        code += invertedSection(tree[i].nodes, tree[i].n,
491                                chooseMethod(tree[i].n));
492      } else if (tag == '<' || tag == '>') {
493        code += partial(tree[i]);
494      } else if (tag == '{' || tag == '&') {
495        code += tripleStache(tree[i].n, chooseMethod(tree[i].n));
496      } else if (tag == '\n') {
497        code += text('"\\n"' + (tree.length-1 == i ? '' : ' + i'));
498      } else if (tag == '_v') {
499        code += variable(tree[i].n, chooseMethod(tree[i].n));
500      } else if (tag === undefined) {
501        code += text('"' + esc(tree[i]) + '"');
502      }
503    }
504    return code;
505  }
506
507  function section(nodes, id, method, start, end, tags) {
508    return 'if(_.s(_.' + method + '("' + esc(id) + '",c,p,1),' +
509           'c,p,0,' + start + ',' + end + ', "' + tags + '")){' +
510           'b += _.rs(c,p,' +
511           'function(c,p){ var b = "";' +
512           walk(nodes) +
513           'return b;});c.pop();}' +
514           'else{b += _.b; _.b = ""};';
515  }
516
517  function invertedSection(nodes, id, method) {
518    return 'if (!_.s(_.' + method + '("' + esc(id) + '",c,p,1),c,p,1,0,0,"")){' +
519           walk(nodes) +
520           '};';
521  }
522
523  function partial(tok) {
524    return 'b += _.rp("' +  esc(tok.n) + '",c,p,"' + (tok.indent || '') + '");';
525  }
526
527  function tripleStache(id, method) {
528    return 'b += (_.' + method + '("' + esc(id) + '",c,p,0));';
529  }
530
531  function variable(id, method) {
532    return 'b += (_.v(_.' + method + '("' + esc(id) + '",c,p,0)));';
533  }
534
535  function text(id) {
536    return 'b += ' + id + ';';
537  }
538
539  Hogan.parse = function(tokens, options) {
540    options = options || {};
541    return buildTree(tokens, '', [], options.sectionTags || []);
542  },
543
544  Hogan.cache = {};
545
546  Hogan.compile = function(text, options) {
547    // options
548    //
549    // asString: false (default)
550    //
551    // sectionTags: [{o: '_foo', c: 'foo'}]
552    // An array of object with o and c fields that indicate names for custom
553    // section tags. The example above allows parsing of {{_foo}}{{/foo}}.
554    //
555    // delimiters: A string that overrides the default delimiters.
556    // Example: "<% %>"
557    //
558    options = options || {};
559
560    var key = text + '||' + !!options.asString;
561
562    var t = this.cache[key];
563
564    if (t) {
565      return t;
566    }
567
568    t = this.generate(writeCode(this.parse(this.scan(text, options.delimiters), options)), text, options);
569    return this.cache[key] = t;
570  };
571})(typeof exports !== 'undefined' ? exports : Hogan);
572