UNPKG

atpl

Version:

A complete and fast template engine fully compatible with twig and similar to jinja with zero dependencies.

556 lines (555 loc) 24.3 kB
///<reference path='../imports.d.ts'/> "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var ParserNode = (function () { function ParserNode() { this.type = '-'; } ParserNode.prototype.generateCode = function (context) { return '<invalid>'; }; ParserNode.prototype.iterate = function (handler) { handler(this); }; return ParserNode; }()); exports.ParserNode = ParserNode; var ParserNodeExpression = (function (_super) { __extends(ParserNodeExpression, _super); function ParserNodeExpression() { _super.apply(this, arguments); } return ParserNodeExpression; }(ParserNode)); exports.ParserNodeExpression = ParserNodeExpression; var ParserNodeWriteExpression = (function (_super) { __extends(ParserNodeWriteExpression, _super); function ParserNodeWriteExpression(expression) { _super.call(this); this.expression = expression; } ParserNodeWriteExpression.prototype.generateCode = function (context) { if (!context.doWrite) { throw (new Error('A template that extends another one cannot have a body')); } return 'runtimeContext.writeExpression(' + this.expression.generateCode(context) + ')'; }; ParserNodeWriteExpression.prototype.iterate = function (handler) { handler(this); this.expression.iterate(handler); }; return ParserNodeWriteExpression; }(ParserNodeExpression)); exports.ParserNodeWriteExpression = ParserNodeWriteExpression; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var ParserNodeContainer = (function (_super) { __extends(ParserNodeContainer, _super); function ParserNodeContainer(nodes) { _super.call(this); this.nodes = nodes; this.type = 'ParserNodeContainer'; if (this.nodes == null) this.nodes = []; } ParserNodeContainer.prototype.add = function (node) { this.nodes.push(node); }; ParserNodeContainer.prototype.generateCode = function (context) { var output = ''; for (var n in this.nodes) { output += this.nodes[n].generateCode(context); } return output; }; ParserNodeContainer.prototype.iterate = function (handler) { handler(this); for (var n in this.nodes) { this.nodes[n].iterate(handler); } }; return ParserNodeContainer; }(ParserNode)); exports.ParserNodeContainer = ParserNodeContainer; var ParserNodeContainerExpression = (function (_super) { __extends(ParserNodeContainerExpression, _super); function ParserNodeContainerExpression(nodes) { _super.call(this); this.nodes = nodes; this.type = 'ParserNodeContainerExpression'; if (this.nodes == null) this.nodes = []; } ParserNodeContainerExpression.prototype.add = function (node) { this.nodes.push(node); }; ParserNodeContainerExpression.prototype.generateCode = function (context) { var output = ''; for (var n in this.nodes) { output += this.nodes[n].generateCode(context); } return output; }; ParserNodeContainerExpression.prototype.iterate = function (handler) { handler(this); for (var n in this.nodes) { this.nodes[n].iterate(handler); } }; return ParserNodeContainerExpression; }(ParserNodeExpression)); exports.ParserNodeContainerExpression = ParserNodeContainerExpression; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var ParserNodeObjectItem = (function (_super) { __extends(ParserNodeObjectItem, _super); function ParserNodeObjectItem(key, value) { _super.call(this); this.key = key; this.value = value; this.type = 'ParserNodeObjectItem'; } ParserNodeObjectItem.prototype.generateCode = function (context) { return this.key.generateCode(context) + ' : ' + this.value.generateCode(context); }; ParserNodeObjectItem.prototype.iterate = function (handler) { handler(this); this.key.iterate(handler); this.value.iterate(handler); }; return ParserNodeObjectItem; }(ParserNode)); exports.ParserNodeObjectItem = ParserNodeObjectItem; var ParserNodeObjectContainer = (function (_super) { __extends(ParserNodeObjectContainer, _super); function ParserNodeObjectContainer(items) { _super.call(this); this.items = items; this.type = 'ParserNodeObjectContainer'; } ParserNodeObjectContainer.prototype.generateCode = function (context) { return '{' + this.items.map(function (node) { return node.generateCode(context); }).join(', ') + '}'; }; ParserNodeObjectContainer.prototype.iterate = function (handler) { handler(this); for (var n in this.items) this.items[n].iterate(handler); }; return ParserNodeObjectContainer; }(ParserNodeExpression)); exports.ParserNodeObjectContainer = ParserNodeObjectContainer; var ParserNodeArrayContainer = (function (_super) { __extends(ParserNodeArrayContainer, _super); function ParserNodeArrayContainer(items) { _super.call(this); this.items = items; this.type = 'ParserNodeArrayContainer'; } ParserNodeArrayContainer.prototype.generateCode = function (context) { return '[' + this.items.map(function (node) { return node.generateCode(context); }).join(', ') + ']'; }; ParserNodeArrayContainer.prototype.iterate = function (handler) { handler(this); for (var n in this.items) this.items[n].iterate(handler); }; return ParserNodeArrayContainer; }(ParserNodeExpression)); exports.ParserNodeArrayContainer = ParserNodeArrayContainer; var ParserNodeLiteral = (function (_super) { __extends(ParserNodeLiteral, _super); function ParserNodeLiteral(value) { _super.call(this); this.value = value; this.type = 'ParserNodeLiteral'; } ParserNodeLiteral.prototype.generateCode = function (context) { return JSON.stringify(this.value); }; ParserNodeLiteral.prototype.iterate = function (handler) { handler(this); }; return ParserNodeLiteral; }(ParserNodeExpression)); exports.ParserNodeLiteral = ParserNodeLiteral; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var ParserNodeLeftValue = (function (_super) { __extends(ParserNodeLeftValue, _super); function ParserNodeLeftValue() { _super.apply(this, arguments); this.type = 'ParserNodeLeftValue'; } ParserNodeLeftValue.prototype.generateAssign = function (context, expr) { throw (new Error("Must implement")); }; return ParserNodeLeftValue; }(ParserNodeExpression)); exports.ParserNodeLeftValue = ParserNodeLeftValue; var ParserNodeIdentifier = (function (_super) { __extends(ParserNodeIdentifier, _super); function ParserNodeIdentifier(value) { _super.call(this); this.value = value; this.type = 'ParserNodeIdentifier'; } ParserNodeIdentifier.prototype.generateAssign = function (context, expr) { return 'runtimeContext.scopeSet(' + JSON.stringify(this.value) + ', ' + expr.generateCode(context) + ')'; }; ParserNodeIdentifier.prototype.generateCode = function (context) { return 'runtimeContext.scopeGet(' + JSON.stringify(this.value) + ')'; }; return ParserNodeIdentifier; }(ParserNodeLeftValue)); exports.ParserNodeIdentifier = ParserNodeIdentifier; var ParserNodeStatement = (function (_super) { __extends(ParserNodeStatement, _super); function ParserNodeStatement() { _super.apply(this, arguments); this.type = 'ParserNodeStatement'; } return ParserNodeStatement; }(ParserNode)); exports.ParserNodeStatement = ParserNodeStatement; var ParserNodeRaw = (function (_super) { __extends(ParserNodeRaw, _super); function ParserNodeRaw(value, putAlways) { if (putAlways === void 0) { putAlways = true; } _super.call(this); this.value = value; this.putAlways = putAlways; this.type = 'ParserNodeRaw'; } ParserNodeRaw.prototype.generateCode = function (context) { if (!context.doWrite && !this.putAlways) return ''; return this.value; }; return ParserNodeRaw; }(ParserNodeExpression)); exports.ParserNodeRaw = ParserNodeRaw; var ParserNodeStatementExpression = (function (_super) { __extends(ParserNodeStatementExpression, _super); function ParserNodeStatementExpression(expression) { _super.call(this); this.expression = expression; this.type = 'ParserNodeStatementExpression'; } ParserNodeStatementExpression.prototype.generateCode = function (context) { return this.expression.generateCode(context) + ';'; }; ParserNodeStatementExpression.prototype.iterate = function (handler) { handler(this); this.expression.iterate(handler); }; return ParserNodeStatementExpression; }(ParserNodeStatement)); exports.ParserNodeStatementExpression = ParserNodeStatementExpression; var ParserNodeAssignment = (function (_super) { __extends(ParserNodeAssignment, _super); function ParserNodeAssignment(leftValue, rightValue) { _super.call(this); this.leftValue = leftValue; this.rightValue = rightValue; this.type = 'ParserNodeAssignment'; } ParserNodeAssignment.prototype.generateCode = function (context) { return this.leftValue.generateAssign(context, this.rightValue); }; ParserNodeAssignment.prototype.iterate = function (handler) { handler(this); this.leftValue.iterate(handler); this.rightValue.iterate(handler); }; return ParserNodeAssignment; }(ParserNodeExpression)); exports.ParserNodeAssignment = ParserNodeAssignment; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var ParserNodeCommaExpression = (function (_super) { __extends(ParserNodeCommaExpression, _super); function ParserNodeCommaExpression(expressions, names) { if (names === void 0) { names = null; } _super.call(this); this.expressions = expressions; this.names = names; this.type = 'ParserNodeCommaExpression'; } ParserNodeCommaExpression.prototype.generateCode = function (context) { return this.expressions.map(function (item) { return item.generateCode(context); }).join(', '); }; ParserNodeCommaExpression.prototype.iterate = function (handler) { handler(this); for (var n in this.expressions) this.expressions[n].iterate(handler); }; return ParserNodeCommaExpression; }(ParserNode)); exports.ParserNodeCommaExpression = ParserNodeCommaExpression; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var ParserNodeArrayAccess = (function (_super) { __extends(ParserNodeArrayAccess, _super); function ParserNodeArrayAccess(object, key) { _super.call(this); this.object = object; this.key = key; this.type = 'ParserNodeArrayAccess'; } ParserNodeArrayAccess.prototype.generateCode = function (context) { return 'runtimeContext.access(' + this.object.generateCode(context) + ', ' + this.key.generateCode(context) + ')'; }; ParserNodeArrayAccess.prototype.iterate = function (handler) { handler(this); this.object.iterate(handler); this.key.iterate(handler); }; return ParserNodeArrayAccess; }(ParserNodeExpression)); exports.ParserNodeArrayAccess = ParserNodeArrayAccess; var ParserNodeArraySlice = (function (_super) { __extends(ParserNodeArraySlice, _super); function ParserNodeArraySlice(object, left, right) { _super.call(this); this.object = object; this.left = left; this.right = right; this.type = 'ParserNodeArraySlice'; } ParserNodeArraySlice.prototype.generateCode = function (context) { return 'runtimeContext.slice(' + this.object.generateCode(context) + ', ' + this.left.generateCode(context) + ', ' + this.right.generateCode(context) + ')'; }; ParserNodeArraySlice.prototype.iterate = function (handler) { handler(this); this.object.iterate(handler); this.left.iterate(handler); this.right.iterate(handler); }; return ParserNodeArraySlice; }(ParserNodeExpression)); exports.ParserNodeArraySlice = ParserNodeArraySlice; var ParserNodeFunctionCall = (function (_super) { __extends(ParserNodeFunctionCall, _super); function ParserNodeFunctionCall(functionExpr, args) { _super.call(this); this.functionExpr = functionExpr; this.args = args; this.type = 'ParserNodeFunctionCall'; } ParserNodeFunctionCall.prototype.generateCode = function (context) { if (this.functionExpr instanceof ParserNodeArrayAccess) { var arrayAccess = this.functionExpr; return 'runtimeContext.callContext(' + arrayAccess.object.generateCode(context) + ', ' + arrayAccess.key.generateCode(context) + ', [' + this.args.generateCode(context) + '], ' + JSON.stringify(this.args.names) + ')'; } else { return 'runtimeContext.call(' + this.functionExpr.generateCode(context) + ', [' + this.args.generateCode(context) + '], ' + JSON.stringify(this.args.names) + ')'; } }; ParserNodeFunctionCall.prototype.iterate = function (handler) { handler(this); this.functionExpr.iterate(handler); this.args.iterate(handler); }; return ParserNodeFunctionCall; }(ParserNodeExpression)); exports.ParserNodeFunctionCall = ParserNodeFunctionCall; var ParserNodeFilterCall = (function (_super) { __extends(ParserNodeFilterCall, _super); function ParserNodeFilterCall(filterName, args) { _super.call(this); this.filterName = filterName; this.args = args; this.type = 'ParserNodeFilterCall'; } ParserNodeFilterCall.prototype.generateCode = function (context) { return 'runtimeContext.filter(' + JSON.stringify(this.filterName) + ', [' + this.args.generateCode(context) + '])'; }; ParserNodeFilterCall.prototype.iterate = function (handler) { handler(this); this.args.iterate(handler); }; return ParserNodeFilterCall; }(ParserNodeExpression)); exports.ParserNodeFilterCall = ParserNodeFilterCall; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var ParserNodeUnaryOperation = (function (_super) { __extends(ParserNodeUnaryOperation, _super); function ParserNodeUnaryOperation(operator, right) { _super.call(this); this.operator = operator; this.right = right; this.type = 'ParserNodeUnaryOperation'; } ParserNodeUnaryOperation.prototype.generateCode = function (context) { switch (this.operator) { case 'not': return '!(' + this.right.generateCode(context) + ')'; default: return this.operator + '(' + this.right.generateCode(context) + ')'; } }; ParserNodeUnaryOperation.prototype.iterate = function (handler) { handler(this); this.right.iterate(handler); }; return ParserNodeUnaryOperation; }(ParserNodeExpression)); exports.ParserNodeUnaryOperation = ParserNodeUnaryOperation; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var ParserNodeBinaryOperation = (function (_super) { __extends(ParserNodeBinaryOperation, _super); function ParserNodeBinaryOperation(operator, left, right) { _super.call(this); this.operator = operator; this.left = left; this.right = right; this.type = 'ParserNodeBinaryOperation'; } ParserNodeBinaryOperation.prototype.iterate = function (handler) { handler(this); this.left.iterate(handler); this.right.iterate(handler); }; ParserNodeBinaryOperation.prototype.generateCode = function (context) { switch (this.operator) { case 'b-or': return '("" + ' + this.left.generateCode(context) + ' | ' + this.right.generateCode(context) + ')'; case 'b-and': return '("" + ' + this.left.generateCode(context) + ' & ' + this.right.generateCode(context) + ')'; case 'b-xor': return '("" + ' + this.left.generateCode(context) + ' ^ ' + this.right.generateCode(context) + ')'; case '~': return '("" + ' + this.left.generateCode(context) + ' + ' + this.right.generateCode(context) + ')'; case '..': return 'runtimeContext.range(' + this.left.generateCode(context) + ', ' + this.right.generateCode(context) + ')'; case '?:': return 'runtimeContext.ternaryShortcut(' + this.left.generateCode(context) + ', ' + this.right.generateCode(context) + ')'; case '//': return 'Math.floor(' + this.left.generateCode(context) + ' / ' + this.right.generateCode(context) + ')'; case '**': return 'Math.pow(' + this.left.generateCode(context) + ',' + this.right.generateCode(context) + ')'; case 'not in': case 'in': var ret = 'runtimeContext.inArray(' + this.left.generateCode(context) + ',' + this.right.generateCode(context) + ')'; if ((this.operator == 'not in')) ret = '!(' + ret + ')'; return ret; case 'is': case 'is not': var ret = ''; var left = this.left; var right = this.right; if (this.right instanceof ParserNodeUnaryOperation) { right = this.right.right; } if (right instanceof ParserNodeFunctionCall) { //throw (new Error("Not implemented ParserNodeFunctionCall")); ret = 'runtimeContext.test(' + right.functionExpr.generateCode(context) + ', [' + left.generateCode(context) + ',' + right.args.generateCode(context) + '])'; } else if (right instanceof ParserNodeIdentifier) { ret = 'runtimeContext.test(' + JSON.stringify(right.value) + ', [' + left.generateCode(context) + '])'; } else if (right instanceof ParserNodeLiteral && right.value === null) { ret = 'runtimeContext.test("null", [' + left.generateCode(context) + '])'; } else { throw (new Error("ParserNodeBinaryOperation: Not implemented 'is' operator for tests with " + JSON.stringify(right))); } if (this.operator == 'is not') ret = '!(' + ret + ')'; return ret; default: return ('(' + this.left.generateCode(context) + ' ' + this.operator + ' ' + this.right.generateCode(context) + ')'); } }; return ParserNodeBinaryOperation; }(ParserNodeExpression)); exports.ParserNodeBinaryOperation = ParserNodeBinaryOperation; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var ParserNodeTernaryOperation = (function (_super) { __extends(ParserNodeTernaryOperation, _super); function ParserNodeTernaryOperation(cond, exprTrue, exprFalse) { _super.call(this); this.cond = cond; this.exprTrue = exprTrue; this.exprFalse = exprFalse; this.type = 'ParserNodeTernaryOperation'; } ParserNodeTernaryOperation.prototype.iterate = function (handler) { handler(this); this.cond.iterate(handler); this.exprTrue.iterate(handler); this.exprFalse.iterate(handler); }; ParserNodeTernaryOperation.prototype.generateCode = function (context) { return ('(' + this.cond.generateCode(context) + " ? " + this.exprTrue.generateCode(context) + " : " + this.exprFalse.generateCode(context) + ')'); }; return ParserNodeTernaryOperation; }(ParserNodeExpression)); exports.ParserNodeTernaryOperation = ParserNodeTernaryOperation; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// var ParserNodeOutputText = (function (_super) { __extends(ParserNodeOutputText, _super); function ParserNodeOutputText(text) { _super.call(this); this.text = ''; this.type = 'ParserNodeOutputText'; this.text = String(text); } ParserNodeOutputText.prototype.generateCode = function (context) { if (!context.doWrite) { if (this.text.match(/\S/)) throw (new Error('A template that extends another one cannot have a body')); return ''; } return 'runtimeContext.write(' + JSON.stringify(this.text) + ');'; }; return ParserNodeOutputText; }(ParserNode)); exports.ParserNodeOutputText = ParserNodeOutputText; var ParserNodeOutputNodeExpression = (function (_super) { __extends(ParserNodeOutputNodeExpression, _super); function ParserNodeOutputNodeExpression(expression) { _super.call(this); this.expression = expression; this.type = 'ParserNodeOutputNodeExpression'; } ParserNodeOutputNodeExpression.prototype.iterate = function (handler) { handler(this); this.expression.iterate(handler); }; ParserNodeOutputNodeExpression.prototype.generateCode = function (context) { if (!context.doWrite) return ''; return 'runtimeContext.write(' + this.expression.generateCode(context) + ')'; }; return ParserNodeOutputNodeExpression; }(ParserNodeExpression)); exports.ParserNodeOutputNodeExpression = ParserNodeOutputNodeExpression; var ParserNodeReturnStatement = (function (_super) { __extends(ParserNodeReturnStatement, _super); function ParserNodeReturnStatement(expression) { _super.call(this); this.expression = expression; this.type = 'ParserNodeReturnStatement'; } ParserNodeReturnStatement.prototype.iterate = function (handler) { handler(this); this.expression.iterate(handler); }; ParserNodeReturnStatement.prototype.generateCode = function (context) { return 'return ' + this.expression.generateCode(context) + ';'; }; return ParserNodeReturnStatement; }(ParserNodeStatement)); exports.ParserNodeReturnStatement = ParserNodeReturnStatement; /////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////