OSDN Git Service

new repo
[bytom/vapor.git] / tools / side_chain_tool / web / assets / template.js
1 /*!
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)
6  */
7 ;(function(root, factory) {
8     var template = factory(root);
9     if (typeof define === 'function' && define.amd) {
10         // AMD
11         define('template', function() {
12             return template;
13         });
14     } else if (typeof exports === 'object') {
15         // Node.js
16         module.exports = template;
17     } else {
18         // Browser globals
19         var _template = root.template;
20
21         template.noConflict = function() {
22             if (root.template === template) {
23                 root.template = _template;
24             }
25
26             return template;
27         };
28         root.template = template;
29     }
30 }(this, function(root) {
31     'use strict';
32     var o = {
33         sTag: '<%',//开始标签
34         eTag: '%>',//结束标签
35         compress: false,//是否压缩html
36         escape: true, //默认输出是否进行HTML转义
37         error: function (e) {}//错误回调
38     };
39     var functionMap = {}; //内部函数对象
40     //修饰器前缀
41     var modifierMap = {
42         '': function (param) {return nothing(param)},
43         'h': function (param) {return encodeHTML(param)},
44         'u': function (param) {return encodeURI(param)}
45     };
46
47     var toString = {}.toString;
48     var slice = [].slice;
49     function type(x) {
50         if(x === null){
51             return 'null';
52         }
53
54         var t= typeof x;
55
56         if(t !== 'object'){
57             return t;
58         }
59
60         var c = toString.call(x).slice(8, -1).toLowerCase();
61         if(c !== 'object'){
62             return c;
63         }
64
65         if(x.constructor==Object){
66             return c;
67         }
68
69         return 'unkonw';
70     }
71
72     function isObject(obj) {
73         return type(obj) === 'object';
74     }
75     function isFunction(fn) {
76         return type(fn) === 'function';
77     }
78     function isString(str) {
79         return type(str) === 'string';
80     }
81     function extend() {
82         var target = arguments[0] || {};
83         var arrs = slice.call(arguments, 1);
84         var len = arrs.length;
85      
86         for (var i = 0; i < len; i++) {
87             var arr = arrs[i];
88             for (var name in arr) {
89                 target[name] = arr[name];
90             }
91      
92         }
93         return target;
94     }
95     function clone() {
96         var args = slice.call(arguments);
97         return extend.apply(null, [{}].concat(args));
98     }
99     function nothing(param) {
100         return param;
101     }
102     function encodeHTML(source) {
103         return String(source)
104             .replace(/&/g,'&amp;')
105             .replace(/</g,'&lt;')
106             .replace(/>/g,'&gt;')
107             .replace(/\\/g,'&#92;')
108             .replace(/"/g,'&quot;')
109             .replace(/'/g,'&#39;');
110     }
111     function compress(html) {
112         return html.replace(/\s+/g, ' ').replace(/<!--[\w\W]*?-->/g, '');
113     }
114     function consoleAdapter(cmd, msg) {
115         typeof console !== 'undefined' && console[cmd] && console[cmd](msg);
116     }
117     function handelError(e) {
118         var message = 'template.js error\n\n';
119
120         for (var key in e) {
121             message += '<' + key + '>\n' + e[key] + '\n\n';
122         }
123         message += '<message>\n' + e.message + '\n\n';
124         consoleAdapter('error', message);
125
126         o.error(e);
127         function error() {
128             return 'template.js error';
129         }
130         error.toString = function () {
131             return '__code__ = "template.js error"';
132         }
133         return error;
134     }
135     function parse(tpl, opt) {
136         var code = '';
137         var sTag = opt.sTag;
138         var eTag = opt.eTag;
139         var escape = opt.escape;
140         function parsehtml(line) {
141             // 单双引号转义,换行符替换为空格
142             line = line.replace(/('|")/g, '\\$1').replace(/\n/g, ' ');
143             return ';__code__ += ("' + line + '")\n';
144         }
145         function parsejs(line) {              
146             //var reg = /^(:?)(.*?)=(.*)$/;
147             var reg = /^(?:=|(:.*?)=)(.*)$/
148             var html;
149             var arr;
150             var modifier;
151
152             // = := :*=
153             // :h=123 [':h=123', 'h', '123']
154             if (arr = reg.exec(line)) {
155                 html = arr[2]; // 输出
156                 if (Boolean(arr[1])) {
157                     // :开头
158                     modifier = arr[1].slice(1);
159                 } else {
160                     // = 开头
161                     modifier = escape ? 'h' : '';
162                 }
163
164                 return ';__code__ += __modifierMap__["' + modifier + '"](typeof (' + html + ') !== "undefined" ? (' + html + ') : "")\n';
165             }
166             
167             //原生js
168             return ';' + line + '\n';
169         }
170
171         var tokens = tpl.split(sTag);
172
173         for (var i = 0, len = tokens.length; i < len; i++) {
174             var token = tokens[i].split(eTag);
175
176             if (token.length === 1) {
177                 code += parsehtml(token[0]);
178             } else {
179                 code += parsejs(token[0], true);
180                 if (token[1]) {
181                     code += parsehtml(token[1]);
182                 }
183             }
184         }
185
186         return code;
187     }
188     function compiler(tpl, opt) {
189         var mainCode = parse(tpl, opt);
190
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' + 
196         '        }\n' + 
197         '        eval(__str__);\n\n';
198
199         var footerCode = '\n' + 
200         '        ;return __code__;\n' + 
201         '    }(__data__, __modifierMap__));\n' + 
202         '    return html;\n';
203
204         var code = headerCode + mainCode + footerCode;
205         code = code.replace(/[\r]/g, ' '); // ie 7 8 会报错,不知道为什么
206         try {
207             var Render = new Function('__data__', '__modifierMap__', code); 
208             Render.toString = function () {
209                 return mainCode;
210             }
211             return Render;
212         } catch(e) {
213             e.temp = 'function anonymous(__data__, __modifierMap__) {' + code + '}';
214             throw e;
215         }  
216     }
217     function compile(tpl, opt) {
218         opt = clone(o, opt);
219
220         try {
221             var Render = compiler(tpl, opt);
222         } catch(e) {
223             e.name = 'CompileError';
224             e.tpl = tpl;
225             e.render = e.temp;
226             delete e.temp;
227             return handelError(e);
228         }
229
230         function render(data) {
231             data = clone(functionMap, data);
232             try {
233                 var html = Render(data, modifierMap);
234                 html = opt.compress ? compress(html) : html;
235                 return html;
236             } catch(e) {
237                 e.name = 'RenderError';
238                 e.tpl = tpl;
239                 e.render = Render.toString();
240                 return handelError(e)();
241             }            
242         }
243
244         render.toString = function () {
245             return Render.toString();
246         };
247         return render;
248     }
249     function template(tpl, data) {
250         if (typeof tpl !== 'string') {
251             return '';
252         }
253
254         var fn = compile(tpl);
255         if (!isObject(data)) {
256             return fn;
257         }
258
259         return fn(data);
260     }
261
262     template.config = function (option) {
263         if (isObject(option)) {
264             o = extend(o, option);
265         }
266         return clone(o);
267     };
268
269     template.registerFunction = function(name, fn) {
270         if (!isString(name)) {
271             return clone(functionMap);
272         }
273         if (!isFunction(fn)) {
274             return functionMap[name];
275         }
276
277         return functionMap[name] = fn;
278     }
279     template.unregisterFunction = function (name) {
280         if (!isString(name)) {
281             return false;
282         }
283         delete functionMap[name];
284         return true;
285     }
286
287     template.registerModifier = function(name, fn) {
288         if (!isString(name)) {
289             return clone(modifierMap);
290         }
291         if (!isFunction(fn)) {
292             return modifierMap[name];
293         }
294
295         return modifierMap[name] = fn;
296     }
297     template.unregisterModifier = function (name) {
298         if (!isString(name)) {
299             return false;
300         }
301         delete modifierMap[name];
302         return true;
303     }
304
305     template.__encodeHTML = encodeHTML;
306     template.__compress = compress;
307     template.__handelError = handelError;
308     template.__compile = compile;
309     template.version = '0.7.1';
310     return template;
311 }));