##// END OF EJS Templates
working on support commonjs modules format
working on support commonjs modules format

File last commit:

r59:ba3ff79c2832 default
r59:ba3ff79c2832 default
Show More
TemplateCompiler.ts
104 lines | 2.8 KiB | video/mp2t | TypeScriptLexer
/ src / amd / ts / text / TemplateCompiler.ts
cin
working on support commonjs modules format
r59 import { format } from "./StringFormat";
import { TraceSource, DebugLevel } from "../log/TraceSource";
import { ITemplateParser, TokenType } from "./TemplateParser";
import m = require("module");
const trace = TraceSource.get(m.id);
type TemplateFn = (obj: object) => string;
export class TemplateCompiler {
_data: string[];
_code: string[];
_wrapWith = true;
constructor() {
this._code = [];
this._data = [];
}
compile(parser: ITemplateParser): TemplateFn {
this.preamble();
this.visitTemplate(parser);
this.postamble();
const text = this._code.join("\n");
try {
// tslint:disable-next-line:function-constructor
const compiled = new Function("obj, format, $data", text);
/**
* Функция форматирования по шаблону
*
* @type{Function}
* @param{Object} obj объект с параметрами для подстановки
*/
return (obj: object) => compiled(obj || {}, format, this._data);
} catch (e) {
trace.traceEvent(DebugLevel, [e, text, this._data]);
throw e;
}
}
preamble() {
this._code.push(
"var $p = [];",
"var print = function(){",
" $p.push(format.apply(null,arguments));",
"};"
);
if (this._wrapWith)
this._code.push("with(obj){");
}
postamble() {
if (this._wrapWith)
this._code.push("}");
this._code.push("return $p.join('');");
}
visitTemplate(parser: ITemplateParser) {
while (parser.next()) {
switch (parser.token()) {
case TokenType.OpenBlock:
this.visitCode(parser);
break;
case TokenType.OpenInlineBlock:
this.visitInline(parser);
break;
default:
this.visitTextFragment(parser);
break;
}
}
}
visitInline(parser: ITemplateParser) {
const code = ["$p.push("];
while (parser.next()) {
if (parser.token() === TokenType.CloseBlock)
break;
code.push(parser.value());
}
code.push(");");
this._code.push(code.join(""));
}
visitCode(parser: ITemplateParser) {
const code = [];
while (parser.next()) {
if (parser.token() === TokenType.CloseBlock)
break;
code.push(parser.value());
}
this._code.push(code.join(""));
}
visitTextFragment(parser: ITemplateParser) {
const i = this._data.push(parser.value());
this._code.push("$p.push($data[" + i + "]);");
}
}