[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |