Mercurial > pub > ImplabJs
annotate core/src/js/text/template-compile.js @ 30:2dfba21cd879
sync
author | cin |
---|---|
date | Wed, 27 Jun 2018 02:46:14 +0300 |
parents | acdcdf1a8d21 |
children |
rev | line source |
---|---|
0 | 1 define( |
24
f750c89976d3
Added trace tools, implab/log/trace!<channel-name>, <channel-name> is optional
cin
parents:
21
diff
changeset
|
2 ["dojo/request", "./format", "../log/trace!"], |
f750c89976d3
Added trace tools, implab/log/trace!<channel-name>, <channel-name> is optional
cin
parents:
21
diff
changeset
|
3 function (request, format, trace) { |
21 | 4 |
5 // разбивает строку шаблона на токены, возвращает контекст для | |
6 // дальнейшей обработки в visitTemplate | |
7 var parseTemplate = function (str) { | |
26 | 8 var tokens = str.split(/(<%=|\[%=|<%|\[%|%\]|%>)/); |
21 | 9 var pos = -1; |
10 var data = [], | |
11 code = []; | |
0 | 12 |
21 | 13 return { |
14 next: function () { | |
15 pos++; | |
16 return pos < tokens.length; | |
17 }, | |
18 token: function () { | |
19 return tokens[pos]; | |
20 }, | |
21 pushData: function () { | |
22 var i = data.length; | |
23 data.push.apply(data, arguments); | |
24 return i; | |
25 }, | |
26 pushCode : function() { | |
27 var i = code.length; | |
28 code.push.apply(code, arguments); | |
29 return i; | |
30 }, | |
31 compile: function () { | |
32 var text = "var $p = [];\n" + | |
33 "var print = function(){\n" + | |
34 " $p.push(format.apply(null,arguments));\n" + | |
35 "};\n" + | |
36 // Introduce the data as local variables using with(){} | |
37 "with(obj){\n" + | |
38 code.join("\n") + | |
39 "}\n" + | |
40 "return $p.join('');"; | |
41 | |
42 try { | |
43 var compiled = new Function("obj, format, $data", text); | |
44 /** | |
45 * Функция форматирования по шаблону | |
46 * | |
47 * @type{Function} | |
48 * @param{Object} obj объект с параметрами для подстановки | |
49 */ | |
50 return function (obj) { | |
51 return compiled(obj || {}, format, data); | |
52 }; | |
53 } catch (e) { | |
24
f750c89976d3
Added trace tools, implab/log/trace!<channel-name>, <channel-name> is optional
cin
parents:
21
diff
changeset
|
54 trace.error([e]); |
f750c89976d3
Added trace tools, implab/log/trace!<channel-name>, <channel-name> is optional
cin
parents:
21
diff
changeset
|
55 trace.log([text, data]); |
f750c89976d3
Added trace tools, implab/log/trace!<channel-name>, <channel-name> is optional
cin
parents:
21
diff
changeset
|
56 throw e; |
21 | 57 } |
0 | 58 } |
59 } | |
60 }; | |
61 | |
21 | 62 function visitTemplate(context) { |
63 while (context.next()) { | |
64 switch (context.token()) { | |
65 case "<%": | |
26 | 66 case "[%": |
21 | 67 visitCode(context); |
68 break; | |
69 case "<%=": | |
26 | 70 case "[%=": |
21 | 71 visitInline(context); |
72 break; | |
73 default: | |
74 visitTextFragment(context); | |
75 break; | |
76 } | |
77 } | |
78 } | |
79 | |
80 function visitInline(context) { | |
81 var code = ["$p.push("]; | |
82 while (context.next()) { | |
26 | 83 if (context.token() == "%>" || context.token() == "%]") |
21 | 84 break; |
85 code.push(context.token()); | |
86 } | |
87 code.push(");"); | |
88 context.pushCode(code.join('')); | |
89 } | |
90 | |
91 function visitCode(context) { | |
92 var code = []; | |
93 while (context.next()) { | |
26 | 94 if (context.token() == "%>" || context.token() == "%]") |
21 | 95 break; |
96 code.push(context.token()); | |
97 } | |
98 context.pushCode(code.join('')); | |
99 } | |
100 | |
101 function visitTextFragment(context) { | |
102 var i = context.pushData(context.token()); | |
103 context.pushCode("$p.push($data["+i+"]);"); | |
104 } | |
105 | |
106 var compile = function (str) { | |
107 if (!str) | |
108 return function() { return "";}; | |
109 | |
110 var ctx = parseTemplate(str); | |
111 visitTemplate(ctx); | |
112 return ctx.compile(); | |
113 }; | |
114 | |
0 | 115 var cache = {}; |
116 | |
21 | 117 compile.load = function (id, require, callback) { |
0 | 118 var url = require.toUrl(id); |
119 if (url in cache) { | |
120 callback(cache[url]); | |
121 } else { | |
21 | 122 request(url).then(compile).then(function (tc) { |
0 | 123 callback(cache[url] = tc); |
21 | 124 }, function (err) { |
125 require.signal("error", [{ | |
126 error: err, | |
127 src: 'implab/text/template-compile' | |
128 }]); | |
0 | 129 }); |
130 } | |
131 }; | |
132 | |
133 return compile; | |
134 }); |