[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/template-micro/ -> template-micro-debug.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('template-micro', function (Y, NAME) {
   9  
  10  /*jshint expr:true */
  11  
  12  /**
  13  Adds the `Y.Template.Micro` template engine, which provides fast, simple
  14  string-based micro-templating similar to ERB or Underscore templates.
  15  
  16  @module template
  17  @submodule template-micro
  18  @since 3.8.0
  19  **/
  20  
  21  /**
  22  Fast, simple string-based micro-templating engine similar to ERB or Underscore
  23  templates.
  24  
  25  @class Template.Micro
  26  @static
  27  @since 3.8.0
  28  **/
  29  
  30  // This code was heavily inspired by Underscore.js's _.template() method
  31  // (written by Jeremy Ashkenas), which was in turn inspired by John Resig's
  32  // micro-templating implementation.
  33  
  34  var Micro = Y.namespace('Template.Micro');
  35  
  36  /**
  37  Default options for `Y.Template.Micro`.
  38  
  39  @property {Object} options
  40  
  41      @param {RegExp} [options.code] Regex that matches code blocks like
  42          `<% ... %>`.
  43      @param {RegExp} [options.escapedOutput] Regex that matches escaped output
  44          tags like `<%= ... %>`.
  45      @param {RegExp} [options.rawOutput] Regex that matches raw output tags like
  46          `<%== ... %>`.
  47      @param {RegExp} [options.stringEscape] Regex that matches characters that
  48          need to be escaped inside single-quoted JavaScript string literals.
  49      @param {Object} [options.stringReplace] Hash that maps characters matched by
  50          `stringEscape` to the strings they should be replaced with. If you add
  51          a character to the `stringEscape` regex, you need to add it here too or
  52          it will be replaced with an empty string.
  53  
  54  @static
  55  @since 3.8.0
  56  **/
  57  Micro.options = {
  58      code         : /<%([\s\S]+?)%>/g,
  59      escapedOutput: /<%=([\s\S]+?)%>/g,
  60      rawOutput    : /<%==([\s\S]+?)%>/g,
  61      stringEscape : /\\|'|\r|\n|\t|\u2028|\u2029/g,
  62  
  63      stringReplace: {
  64          '\\'    : '\\\\',
  65          "'"     : "\\'",
  66          '\r'    : '\\r',
  67          '\n'    : '\\n',
  68          '\t'    : '\\t',
  69          '\u2028': '\\u2028',
  70          '\u2029': '\\u2029'
  71      }
  72  };
  73  
  74  /**
  75  Compiles a template string into a JavaScript function. Pass a data object to the
  76  function to render the template using the given data and get back a rendered
  77  string.
  78  
  79  Within a template, use `<%= ... %>` to output the value of an expression (where
  80  `...` is the JavaScript expression or data variable to evaluate). The output
  81  will be HTML-escaped by default. To output a raw value without escaping, use
  82  `<%== ... %>`, but be careful not to do this with untrusted user input.
  83  
  84  To execute arbitrary JavaScript code within the template without rendering its
  85  output, use `<% ... %>`, where `...` is the code to be executed. This allows the
  86  use of if/else blocks, loops, function calls, etc., although it's recommended
  87  that you avoid embedding anything beyond basic flow control logic in your
  88  templates.
  89  
  90  Properties of the data object passed to a template function are made available
  91  on a `data` variable within the scope of the template. So, if you pass in
  92  the object `{message: 'hello!'}`, you can print the value of the `message`
  93  property using `<%= data.message %>`.
  94  
  95  @example
  96  
  97      YUI().use('template-micro', function (Y) {
  98          var template = '<ul class="<%= data.classNames.list %>">' +
  99                             '<% Y.Array.each(data.items, function (item) { %>' +
 100                                 '<li><%= item %></li>' +
 101                             '<% }); %>' +
 102                         '</ul>';
 103  
 104          // Compile the template into a function.
 105          var compiled = Y.Template.Micro.compile(template);
 106  
 107          // Render the template to HTML, passing in the data to use.
 108          var html = compiled({
 109              classNames: {list: 'demo'},
 110              items     : ['one', 'two', 'three', 'four']
 111          });
 112      });
 113  
 114  @method compile
 115  @param {String} text Template text to compile.
 116  @param {Object} [options] Options. If specified, these options will override the
 117      default options defined in `Y.Template.Micro.options`. See the documentation
 118      for that property for details on which options are available.
 119  @return {Function} Compiled template function. Execute this function and pass in
 120      a data object to render the template with the given data.
 121  @static
 122  @since 3.8.0
 123  **/
 124  Micro.compile = function (text, options) {
 125      /*jshint evil:true */
 126  
 127      var blocks     = [],
 128          tokenClose = "\uffff",
 129          tokenOpen  = "\ufffe",
 130          source;
 131  
 132      options = Y.merge(Micro.options, options);
 133  
 134      // Parse the input text into a string of JavaScript code, with placeholders
 135      // for code blocks. Text outside of code blocks will be escaped for safe
 136      // usage within a double-quoted string literal.
 137      //
 138      // $b is a blank string, used to avoid creating lots of string objects.
 139      //
 140      // $v is a function that returns the supplied value if the value is truthy
 141      // or the number 0, or returns an empty string if the value is falsy and not
 142      // 0.
 143      //
 144      // $t is the template string.
 145      source = "var $b='', $v=function (v){return v || v === 0 ? v : $b;}, $t='" +
 146  
 147          // U+FFFE and U+FFFF are guaranteed to represent non-characters, so no
 148          // valid UTF-8 string should ever contain them. That means we can freely
 149          // strip them out of the input text (just to be safe) and then use them
 150          // for our own nefarious purposes as token placeholders!
 151          //
 152          // See http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Noncharacters
 153          text.replace(/\ufffe|\uffff/g, '')
 154  
 155          .replace(options.rawOutput, function (match, code) {
 156              return tokenOpen + (blocks.push("'+\n$v(" + code + ")+\n'") - 1) + tokenClose;
 157          })
 158  
 159          .replace(options.escapedOutput, function (match, code) {
 160              return tokenOpen + (blocks.push("'+\n$e($v(" + code + "))+\n'") - 1) + tokenClose;
 161          })
 162  
 163          .replace(options.code, function (match, code) {
 164              return tokenOpen + (blocks.push("';\n" + code + "\n$t+='") - 1) + tokenClose;
 165          })
 166  
 167          .replace(options.stringEscape, function (match) {
 168              return options.stringReplace[match] || '';
 169          })
 170  
 171          // Replace the token placeholders with code.
 172          .replace(/\ufffe(\d+)\uffff/g, function (match, index) {
 173              return blocks[parseInt(index, 10)];
 174          })
 175  
 176          // Remove noop string concatenations that have been left behind.
 177          .replace(/\n\$t\+='';\n/g, '\n') +
 178  
 179          "';\nreturn $t;";
 180  
 181      // If compile() was called from precompile(), return precompiled source.
 182      if (options.precompile) {
 183          return "function (Y, $e, data) {\n" + source + "\n}";
 184      }
 185  
 186      // Otherwise, return an executable function.
 187      return this.revive(new Function('Y', '$e', 'data', source));
 188  };
 189  
 190  /**
 191  Precompiles the given template text into a string of JavaScript source code that
 192  can be evaluated later in another context (or on another machine) to render the
 193  template.
 194  
 195  A common use case is to precompile templates at build time or on the server,
 196  then evaluate the code on the client to render a template. The client only needs
 197  to revive and render the template, avoiding the work of the compilation step.
 198  
 199  @method precompile
 200  @param {String} text Template text to precompile.
 201  @param {Object} [options] Options. If specified, these options will override the
 202      default options defined in `Y.Template.Micro.options`. See the documentation
 203      for that property for details on which options are available.
 204  @return {String} Source code for the precompiled template.
 205  @static
 206  @since 3.8.0
 207  **/
 208  Micro.precompile = function (text, options) {
 209      options || (options = {});
 210      options.precompile = true;
 211  
 212      return this.compile(text, options);
 213  };
 214  
 215  /**
 216  Compiles and renders the given template text in a single step.
 217  
 218  This can be useful for single-use templates, but if you plan to render the same
 219  template multiple times, it's much better to use `compile()` to compile it once,
 220  then simply call the compiled function multiple times to avoid recompiling.
 221  
 222  @method render
 223  @param {String} text Template text to render.
 224  @param {Object} data Data to pass to the template.
 225  @param {Object} [options] Options. If specified, these options will override the
 226      default options defined in `Y.Template.Micro.options`. See the documentation
 227      for that property for details on which options are available.
 228  @return {String} Rendered result.
 229  @static
 230  @since 3.8.0
 231  **/
 232  Micro.render = function (text, data, options) {
 233      return this.compile(text, options)(data);
 234  };
 235  
 236  /**
 237  Revives a precompiled template function into a normal compiled template function
 238  that can be called to render the template. The precompiled function must already
 239  have been evaluated to a function -- you can't pass raw JavaScript code to
 240  `revive()`.
 241  
 242  @method revive
 243  @param {Function} precompiled Precompiled template function.
 244  @return {Function} Revived template function, ready to be rendered.
 245  @static
 246  @since 3.8.0
 247  **/
 248  Micro.revive = function (precompiled) {
 249      return function (data) {
 250          data || (data = {});
 251          return precompiled.call(data, Y, Y.Escape.html, data);
 252      };
 253  };
 254  
 255  
 256  }, '3.17.2', {"requires": ["escape"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1