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