src/cm/media/js/lib/yui/yui_3.10.3/build/template-micro/template-micro-debug.js
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     1 /*
       
     2 YUI 3.10.3 (build 2fb5187)
       
     3 Copyright 2013 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.10.3', {"requires": ["escape"]});