Mercurial > pub > ImplabJs
view core/src/js/text/template-compile.js @ 30:2dfba21cd879
sync
author | cin |
---|---|
date | Wed, 27 Jun 2018 02:46:14 +0300 |
parents | acdcdf1a8d21 |
children |
line wrap: on
line source
define( ["dojo/request", "./format", "../log/trace!"], function (request, format, trace) { // разбивает строку шаблона на токены, возвращает контекст для // дальнейшей обработки в visitTemplate var parseTemplate = function (str) { var tokens = str.split(/(<%=|\[%=|<%|\[%|%\]|%>)/); var pos = -1; var data = [], code = []; return { next: function () { pos++; return pos < tokens.length; }, token: function () { return tokens[pos]; }, pushData: function () { var i = data.length; data.push.apply(data, arguments); return i; }, pushCode : function() { var i = code.length; code.push.apply(code, arguments); return i; }, compile: function () { var text = "var $p = [];\n" + "var print = function(){\n" + " $p.push(format.apply(null,arguments));\n" + "};\n" + // Introduce the data as local variables using with(){} "with(obj){\n" + code.join("\n") + "}\n" + "return $p.join('');"; try { var compiled = new Function("obj, format, $data", text); /** * Функция форматирования по шаблону * * @type{Function} * @param{Object} obj объект с параметрами для подстановки */ return function (obj) { return compiled(obj || {}, format, data); }; } catch (e) { trace.error([e]); trace.log([text, data]); throw e; } } } }; function visitTemplate(context) { while (context.next()) { switch (context.token()) { case "<%": case "[%": visitCode(context); break; case "<%=": case "[%=": visitInline(context); break; default: visitTextFragment(context); break; } } } function visitInline(context) { var code = ["$p.push("]; while (context.next()) { if (context.token() == "%>" || context.token() == "%]") break; code.push(context.token()); } code.push(");"); context.pushCode(code.join('')); } function visitCode(context) { var code = []; while (context.next()) { if (context.token() == "%>" || context.token() == "%]") break; code.push(context.token()); } context.pushCode(code.join('')); } function visitTextFragment(context) { var i = context.pushData(context.token()); context.pushCode("$p.push($data["+i+"]);"); } var compile = function (str) { if (!str) return function() { return "";}; var ctx = parseTemplate(str); visitTemplate(ctx); return ctx.compile(); }; var cache = {}; compile.load = function (id, require, callback) { var url = require.toUrl(id); if (url in cache) { callback(cache[url]); } else { request(url).then(compile).then(function (tc) { callback(cache[url] = tc); }, function (err) { require.signal("error", [{ error: err, src: 'implab/text/template-compile' }]); }); } }; return compile; });