Вход Регистрация
Файл: module-assets/admin/uniform/www/javascripts/mustache.js
Строк: 699
<?php
/*!
 * mustache.js - Logic-less {{mustache}} templates with JavaScript
 * http://github.com/janl/mustache.js
 */

/*global define: false*/

var Mustache;

(function (
exports) {
  if (
typeof module !== "undefined" && module.exports) {
    
module.exports exports// CommonJS
  
} else if (typeof define === "function") {
    
define(exports); // AMD
  
} else {
    
Mustache exports// <script>
  
}
}((function () {

  var 
exports = {};

  
exports.name "mustache.js";
  
exports.version "0.7.0";
  
exports.tags = ["{{""}}"];

  
exports.Scanner Scanner;
  
exports.Context Context;
  
exports.Writer Writer;

  var 
whiteRe = /s*/;
  var 
spaceRe = /s+/;
  var 
nonSpaceRe = /S/;
  var 
eqRe = /s*=/;
  var 
curlyRe = /s*}/;
  var 
tagRe = /#|^|/|>|{|&|=|!/;

  // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
  // See https://github.com/janl/mustache.js/issues/189
  
function testRe(restring) {
    return 
RegExp.prototype.test.call(restring);
  }

  function 
isWhitespace(string) {
    return !
testRe(nonSpaceRestring);
  }

  var 
isArray = Array.isArray || function (obj) {
    return 
Object.prototype.toString.call(obj) === "[object Array]";
  };

  function 
escapeRe(string) {
    return 
string.replace(/[-[]{}()*+?.,\^$|#s]/g, "\$&");
  
}

  var 
entityMap = {
    
"&""&amp;",
    
"<""&lt;",
    
">""&gt;",
    
'"''&quot;',
    
"'"'&#39;',
    
"/"'&#x2F;'
  
};

  function 
escapeHtml(string) {
    return 
String(string).replace(/[&<>"'/]/g, function (s) {
      return entityMap[s];
    });
  }

  // Export the escaping function so that the user may override it.
  // See https://github.com/janl/mustache.js/issues/244
  exports.escape = escapeHtml;

  function Scanner(string) {
    this.string = string;
    this.tail = string;
    this.pos = 0;
  }

  /**
   * Returns `true` if the tail is empty (end of string).
   */
  Scanner.prototype.eos = function () {
    return this.tail === "";
  };

  /**
   * Tries to match the given regular expression at the current position.
   * Returns the matched text if it can match, the empty string otherwise.
   */
  Scanner.prototype.scan = function (re) {
    var match = this.tail.match(re);

    if (match && match.index === 0) {
      this.tail = this.tail.substring(match[0].length);
      this.pos += match[0].length;
      return match[0];
    }

    return "";
  };

  /**
   * Skips all text until the given regular expression can be matched. Returns
   * the skipped string, which is the entire tail if no match can be made.
   */
  Scanner.prototype.scanUntil = function (re) {
    var match, pos = this.tail.search(re);

    switch (pos) {
    case -1:
      match = this.tail;
      this.pos += this.tail.length;
      this.tail = "";
      break;
    case 0:
      match = "";
      break;
    default:
      match = this.tail.substring(0, pos);
      this.tail = this.tail.substring(pos);
      this.pos += pos;
    }

    return match;
  };

  function Context(view, parent) {
    this.view = view;
    this.parent = parent;
    this.clearCache();
  }

  Context.make = function (view) {
    return (view instanceof Context) ? view : new Context(view);
  };

  Context.prototype.clearCache = function () {
    this._cache = {};
  };

  Context.prototype.push = function (view) {
    return new Context(view, this);
  };

  Context.prototype.lookup = function (name) {
    var value = this._cache[name];

    if (!value) {
      if (name === "
.") {
        value = this.view;
      } else {
        var context = this;

        while (context) {
          if (name.indexOf("
.") > 0) {
            var names = name.split("
."), i = 0;

            value = context.view;

            while (value && i < names.length) {
              value = value[names[i++]];
            }
          } else {
            value = context.view[name];
          }

          if (value != null) {
            break;
          }

          context = context.parent;
        }
      }

      this._cache[name] = value;
    }

    if (typeof value === "
function") {
      value = value.call(this.view);
    }

    return value;
  };

  function Writer() {
    this.clearCache();
  }

  Writer.prototype.clearCache = function () {
    this._cache = {};
    this._partialCache = {};
  };

  Writer.prototype.compile = function (template, tags) {
    var fn = this._cache[template];

    if (!fn) {
      var tokens = exports.parse(template, tags);
      fn = this._cache[template] = this.compileTokens(tokens, template);
    }

    return fn;
  };

  Writer.prototype.compilePartial = function (name, template, tags) {
    var fn = this.compile(template, tags);
    this._partialCache[name] = fn;
    return fn;
  };

  Writer.prototype.compileTokens = function (tokens, template) {
    var fn = compileTokens(tokens);
    var self = this;

    return function (view, partials) {
      if (partials) {
        if (typeof partials === "
function") {
          self._loadPartial = partials;
        } else {
          for (var name in partials) {
            self.compilePartial(name, partials[name]);
          }
        }
      }

      return fn(self, Context.make(view), template);
    };
  };

  Writer.prototype.render = function (template, view, partials) {
    return this.compile(template)(view, partials);
  };

  Writer.prototype._section = function (name, context, text, callback) {
    var value = context.lookup(name);

    switch (typeof value) {
    case "
object":
      if (isArray(value)) {
        var buffer = "";

        for (var i = 0, len = value.length; i < len; ++i) {
          buffer += callback(this, context.push(value[i]));
        }

        return buffer;
      }

      return value ? callback(this, context.push(value)) : "";
    case "
function":
      var self = this;
      var scopedRender = function (template) {
        return self.render(template, context);
      };

      var result = value.call(context.view, text, scopedRender);
      return result != null ? result : "";
    default:
      if (value) {
        return callback(this, context);
      }
    }

    return "";
  };

  Writer.prototype._inverted = function (name, context, callback) {
    var value = context.lookup(name);

    // Use JavaScript's definition of falsy. Include empty arrays.
    // See https://github.com/janl/mustache.js/issues/186
    if (!value || (isArray(value) && value.length === 0)) {
      return callback(this, context);
    }

    return "";
  };

  Writer.prototype._partial = function (name, context) {
    if (!(name in this._partialCache) && this._loadPartial) {
      this.compilePartial(name, this._loadPartial(name));
    }

    var fn = this._partialCache[name];

    return fn ? fn(context) : "";
  };

  Writer.prototype._name = function (name, context) {
    var value = context.lookup(name);

    if (typeof value === "
function") {
      value = value.call(context.view);
    }

    return (value == null) ? "" : String(value);
  };

  Writer.prototype._escaped = function (name, context) {
    return exports.escape(this._name(name, context));
  };

  /**
   * Calculates the bounds of the section represented by the given `token` in
   * the original template by drilling down into nested sections to find the
   * last token that is part of that section. Returns an array of [start, end].
   */
  function sectionBounds(token) {
    var start = token[3];
    var end = start;

    var tokens;
    while ((tokens = token[4]) && tokens.length) {
      token = tokens[tokens.length - 1];
      end = token[3];
    }

    return [start, end];
  }

  /**
   * Low-level function that compiles the given `tokens` into a function
   * that accepts three arguments: a Writer, a Context, and the template.
   */
  function compileTokens(tokens) {
    var subRenders = {};

    function subRender(i, tokens, template) {
      if (!subRenders[i]) {
        var fn = compileTokens(tokens);
        subRenders[i] = function (writer, context) {
          return fn(writer, context, template);
        };
      }

      return subRenders[i];
    }

    return function (writer, context, template) {
      var buffer = "";
      var token, sectionText;

      for (var i = 0, len = tokens.length; i < len; ++i) {
        token = tokens[i];

        switch (token[0]) {
        case "
#":
          
sectionText template.slice.apply(templatesectionBounds(token));
          
buffer += writer._section(token[1], contextsectionTextsubRender(itoken[4], template));
          break;
        case 
"^":
          
buffer += writer._inverted(token[1], contextsubRender(itoken[4], template));
          break;
        case 
">":
          
buffer += writer._partial(token[1], context);
          break;
        case 
"&":
          
buffer += writer._name(token[1], context);
          break;
        case 
"name":
          
buffer += writer._escaped(token[1], context);
          break;
        case 
"text":
          
buffer += token[1];
          break;
        }
      }

      return 
buffer;
    };
  }

  
/**
   * Forms the given array of `tokens` into a nested tree structure where
   * tokens that represent a section have a fifth item: an array that contains
   * all tokens in that section.
   */
  
function nestTokens(tokens) {
    var 
tree = [];
    var 
collector tree;
    var 
sections = [];
    var 
tokensection;

    for (var 
0tokens.length; ++i) {
      
token tokens[i];

      switch (
token[0]) {
      case 
"#":
      case 
"^":
        
token[4] = [];
        
sections.push(token);
        
collector.push(token);
        
collector token[4];
        break;
      case 
"/":
        if (
sections.length === 0) {
          throw new 
Error("Unopened section: " token[1]);
        }

        
section sections.pop();

        if (
section[1] !== token[1]) {
          throw new 
Error("Unclosed section: " section[1]);
        }

        if (
sections.length 0) {
          
collector sections[sections.length 1][4];
        } else {
          
collector tree;
        }
        break;
      default:
        
collector.push(token);
      }
    }

    
// Make sure there were no open sections when we're done.
    
section sections.pop();

    if (
section) {
      throw new 
Error("Unclosed section: " section[1]);
    }

    return 
tree;
  }

  
/**
   * Combines the values of consecutive text tokens in the given `tokens` array
   * to a single token.
   */
  
function squashTokens(tokens) {
    var 
tokenlastTokensquashedTokens = [];

    for (var 
0tokens.length; ++i) {
      
token tokens[i];

      if (
lastToken && lastToken[0] === "text" && token[0] === "text") {
        
lastToken[1] += token[1];
        
lastToken[3] = token[3];
      } else {
        
lastToken token;
        
squashedTokens.push(token);
      }
    }

    return 
squashedTokens
  }

  function 
escapeTags(tags) {
    if (
tags.length !== 2) {
      throw new 
Error("Invalid tags: " tags.join(" "));
    }

    return [
      new 
RegExp(escapeRe(tags[0]) + "\s*"),
      new 
RegExp("\s*" escapeRe(tags[1]))
    ];
  }

  
/**
   * Breaks up the given `template` string into a tree of token objects. If
   * `tags` is given here it must be an array with two string values: the
   * opening and closing tags used in the template (e.g. ["<%", "%>"]). Of
   * course, the default is to use mustaches (i.e. Mustache.tags).
   */
  
exports.parse = function (templatetags) {
    
tags tags || exports.tags;

    var 
tagRes escapeTags(tags);
    var 
scanner = new Scanner(template);

    var 
tokens = [],      // Buffer to hold the tokens
        
spaces = [],      // Indices of whitespace tokens on the current line
        
hasTag false,   // Is there a {{tag}} on the current line?
        
nonSpace false// Is there a non-space char on the current line?

    // Strips all whitespace tokens array for the current line
    // if there was a {{#tag}} on it and otherwise only space.
    
function stripSpace() {
      if (
hasTag && !nonSpace) {
        while (
spaces.length) {
          
tokens.splice(spaces.pop(), 1);
        }
      } else {
        
spaces = [];
      }

      
hasTag false;
      
nonSpace false;
    }

    var 
starttypevaluechr;

    while (!
scanner.eos()) {
      
start scanner.pos;
      
value scanner.scanUntil(tagRes[0]);

      if (
value) {
        for (var 
0len value.lengthlen; ++i) {
          
chr value.charAt(i);

          if (
isWhitespace(chr)) {
            
spaces.push(tokens.length);
          } else {
            
nonSpace true;
          }

          
tokens.push(["text"chrstartstart 1]);
          
start += 1;

          if (
chr === "n") {
            
stripSpace(); // Check for whitespace on the current line.
          
}
        }
      }

      
start scanner.pos;

      
// Match the opening tag.
      
if (!scanner.scan(tagRes[0])) {
        break;
      }

      
hasTag true;
      
type scanner.scan(tagRe) || "name";

      
// Skip any whitespace between tag and value.
      
scanner.scan(whiteRe);

      
// Extract the tag value.
      
if (type === "=") {
        
value scanner.scanUntil(eqRe);
        
scanner.scan(eqRe);
        
scanner.scanUntil(tagRes[1]);
      } else if (
type === "{") {
        var 
closeRe = new RegExp("\s*" escapeRe("}" tags[1]));
        
value scanner.scanUntil(closeRe);
        
scanner.scan(curlyRe);
        
scanner.scanUntil(tagRes[1]);
        
type "&";
      } else {
        
value scanner.scanUntil(tagRes[1]);
      }

      
// Match the closing tag.
      
if (!scanner.scan(tagRes[1])) {
        throw new 
Error("Unclosed tag at " scanner.pos);
      }

      
tokens.push([typevaluestartscanner.pos]);

      if (
type === "name" || type === "{" || type === "&") {
        
nonSpace true;
      }

      
// Set the tags for the next time around.
      
if (type === "=") {
        
tags value.split(spaceRe);
        
tagRes escapeTags(tags);
      }
    }

    
tokens squashTokens(tokens);

    return 
nestTokens(tokens);
  };

  
// The high-level clearCache, compile, compilePartial, and render functions
  // use this default writer.
  
var _writer = new Writer();

  
/**
   * Clears all cached templates and partials in the default writer.
   */
  
exports.clearCache = function () {
    return 
_writer.clearCache();
  };

  
/**
   * Compiles the given `template` to a reusable function using the default
   * writer.
   */
  
exports.compile = function (templatetags) {
    return 
_writer.compile(templatetags);
  };

  
/**
   * Compiles the partial with the given `name` and `template` to a reusable
   * function using the default writer.
   */
  
exports.compilePartial = function (nametemplatetags) {
    return 
_writer.compilePartial(nametemplatetags);
  };

  
/**
   * Compiles the given array of tokens (the output of a parse) to a reusable
   * function using the default writer.
   */
  
exports.compileTokens = function (tokenstemplate) {
    return 
_writer.compileTokens(tokenstemplate);
  };

  
/**
   * Renders the `template` with the given `view` and `partials` using the
   * default writer.
   */
  
exports.render = function (templateviewpartials) {
    return 
_writer.render(templateviewpartials);
  };

  
// This is here for backwards compatibility with 0.4.x.
  
exports.to_html = function (templateviewpartialssend) {
    var 
result exports.render(templateviewpartials);

    if (
typeof send === "function") {
      
send(result);
    } else {
      return 
result;
    }
  };

  return 
exports;

}())));
?>
Онлайн: 1
Реклама