2 * template.js v0.7.1 (https://github.com/yanhaijing/template.js)
3 * API https://github.com/yanhaijing/template.js/blob/master/doc/api.md
4 * Copyright 2015 yanhaijing. All Rights Reserved
5 * Licensed under MIT (https://github.com/yanhaijing/template.js/blob/master/MIT-LICENSE.txt)
7 ;(function(root, factory) {
8 var template = factory(root);
9 if (typeof define === 'function' && define.amd) {
11 define('template', function() {
14 } else if (typeof exports === 'object') {
16 module.exports = template;
19 var _template = root.template;
21 template.noConflict = function() {
22 if (root.template === template) {
23 root.template = _template;
28 root.template = template;
30 }(this, function(root) {
35 compress: false,//是否压缩html
36 escape: true, //默认输出是否进行HTML转义
37 error: function (e) {}//错误回调
39 var functionMap = {}; //内部函数对象
42 '': function (param) {return nothing(param)},
43 'h': function (param) {return encodeHTML(param)},
44 'u': function (param) {return encodeURI(param)}
47 var toString = {}.toString;
60 var c = toString.call(x).slice(8, -1).toLowerCase();
65 if(x.constructor==Object){
72 function isObject(obj) {
73 return type(obj) === 'object';
75 function isFunction(fn) {
76 return type(fn) === 'function';
78 function isString(str) {
79 return type(str) === 'string';
82 var target = arguments[0] || {};
83 var arrs = slice.call(arguments, 1);
84 var len = arrs.length;
86 for (var i = 0; i < len; i++) {
88 for (var name in arr) {
89 target[name] = arr[name];
96 var args = slice.call(arguments);
97 return extend.apply(null, [{}].concat(args));
99 function nothing(param) {
102 function encodeHTML(source) {
103 return String(source)
104 .replace(/&/g,'&')
105 .replace(/</g,'<')
106 .replace(/>/g,'>')
107 .replace(/\\/g,'\')
108 .replace(/"/g,'"')
109 .replace(/'/g,''');
111 function compress(html) {
112 return html.replace(/\s+/g, ' ').replace(/<!--[\w\W]*?-->/g, '');
114 function consoleAdapter(cmd, msg) {
115 typeof console !== 'undefined' && console[cmd] && console[cmd](msg);
117 function handelError(e) {
118 var message = 'template.js error\n\n';
121 message += '<' + key + '>\n' + e[key] + '\n\n';
123 message += '<message>\n' + e.message + '\n\n';
124 consoleAdapter('error', message);
128 return 'template.js error';
130 error.toString = function () {
131 return '__code__ = "template.js error"';
135 function parse(tpl, opt) {
139 var escape = opt.escape;
140 function parsehtml(line) {
142 line = line.replace(/('|")/g, '\\$1').replace(/\n/g, ' ');
143 return ';__code__ += ("' + line + '")\n';
145 function parsejs(line) {
146 //var reg = /^(:?)(.*?)=(.*)$/;
147 var reg = /^(?:=|(:.*?)=)(.*)$/
153 // :h=123 [':h=123', 'h', '123']
154 if (arr = reg.exec(line)) {
156 if (Boolean(arr[1])) {
158 modifier = arr[1].slice(1);
161 modifier = escape ? 'h' : '';
164 return ';__code__ += __modifierMap__["' + modifier + '"](typeof (' + html + ') !== "undefined" ? (' + html + ') : "")\n';
168 return ';' + line + '\n';
171 var tokens = tpl.split(sTag);
173 for (var i = 0, len = tokens.length; i < len; i++) {
174 var token = tokens[i].split(eTag);
176 if (token.length === 1) {
177 code += parsehtml(token[0]);
179 code += parsejs(token[0], true);
181 code += parsehtml(token[1]);
188 function compiler(tpl, opt) {
189 var mainCode = parse(tpl, opt);
191 var headerCode = '\n' +
192 ' var html = (function (__data__, __modifierMap__) {\n' +
193 ' var __str__ = "", __code__ = "";\n' +
194 ' for(var key in __data__) {\n' +
195 ' __str__+=("var " + key + "=__data__[\'" + key + "\'];");\n' +
197 ' eval(__str__);\n\n';
199 var footerCode = '\n' +
200 ' ;return __code__;\n' +
201 ' }(__data__, __modifierMap__));\n' +
204 var code = headerCode + mainCode + footerCode;
205 code = code.replace(/[\r]/g, ' '); // ie 7 8 会报错,不知道为什么
207 var Render = new Function('__data__', '__modifierMap__', code);
208 Render.toString = function () {
213 e.temp = 'function anonymous(__data__, __modifierMap__) {' + code + '}';
217 function compile(tpl, opt) {
221 var Render = compiler(tpl, opt);
223 e.name = 'CompileError';
227 return handelError(e);
230 function render(data) {
231 data = clone(functionMap, data);
233 var html = Render(data, modifierMap);
234 html = opt.compress ? compress(html) : html;
237 e.name = 'RenderError';
239 e.render = Render.toString();
240 return handelError(e)();
244 render.toString = function () {
245 return Render.toString();
249 function template(tpl, data) {
250 if (typeof tpl !== 'string') {
254 var fn = compile(tpl);
255 if (!isObject(data)) {
262 template.config = function (option) {
263 if (isObject(option)) {
264 o = extend(o, option);
269 template.registerFunction = function(name, fn) {
270 if (!isString(name)) {
271 return clone(functionMap);
273 if (!isFunction(fn)) {
274 return functionMap[name];
277 return functionMap[name] = fn;
279 template.unregisterFunction = function (name) {
280 if (!isString(name)) {
283 delete functionMap[name];
287 template.registerModifier = function(name, fn) {
288 if (!isString(name)) {
289 return clone(modifierMap);
291 if (!isFunction(fn)) {
292 return modifierMap[name];
295 return modifierMap[name] = fn;
297 template.unregisterModifier = function (name) {
298 if (!isString(name)) {
301 delete modifierMap[name];
305 template.__encodeHTML = encodeHTML;
306 template.__compress = compress;
307 template.__handelError = handelError;
308 template.__compile = compile;
309 template.version = '0.7.1';