atpl
Version:
A complete and fast template engine fully compatible with twig and similar to jinja with zero dependencies.
693 lines (692 loc) • 34.8 kB
JavaScript
;
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 ExpressionParser_1 = require('../parser/ExpressionParser');
var ParserNode_1 = require('../parser/ParserNode');
var TemplateParser_1 = require('../parser/TemplateParser');
var RuntimeContext_1 = require('../runtime/RuntimeContext');
function checkNoMoreTokens(expressionTokenReader) {
//console.log(expressionTokenReader);
//console.log(expressionTokenReader.hasMore());
if (expressionTokenReader.hasMore()) {
//console.log(expressionTokenReader);
throw (new Error("Unexpected token '" + JSON.stringify(expressionTokenReader.peek()) + "'"));
}
return expressionTokenReader;
}
function _flowexception(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
throw new TemplateParser_1.FlowException(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader);
}
function handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, handlers, innerNodeHandler) {
while (true) {
try {
var keys = [];
for (var key in handlers)
keys.push(key);
//console.log("[[");
var nodeStart = templateTokenReader.tokenizer.stringReader.position;
var node = templateParser.parseTemplateSyncOne(tokenParserContext, templateTokenReader);
var nodeEnd = templateTokenReader.tokenizer.stringReader.position;
if (node == null)
throw new Error("Unexpected end of '" + blockType + "' no any of [" + keys.map(function (key) { return "'" + key + "'"; }).join(', ') + "]");
//console.log("]]");
//console.log(node);
innerNodeHandler(node, nodeStart, nodeEnd);
}
catch (e) {
if (!(e instanceof TemplateParser_1.FlowException))
throw (e);
var handler = handlers[e.blockType];
if (handler !== undefined) {
if (handler(e))
return;
}
else {
throw (new Error("Unexpected '" + e.blockType + "' for '" + blockType + "'"));
}
}
}
}
function _self(expression, path) {
var self = DefaultTags._self;
var fileNameNode = expression;
if (fileNameNode.value === '_self') {
self.value = path;
fileNameNode = self;
}
DefaultTags._self = fileNameNode;
return fileNameNode;
}
var ParserNodeAutoescape = (function (_super) {
__extends(ParserNodeAutoescape, _super);
function ParserNodeAutoescape(expression, inner) {
_super.call(this);
this.expression = expression;
this.inner = inner;
}
ParserNodeAutoescape.prototype.iterate = function (handler) {
handler(this);
this.expression.iterate(handler);
this.inner.iterate(handler);
};
ParserNodeAutoescape.prototype.generateCode = function (context) {
return ('runtimeContext.autoescape(' + this.expression.generateCode(context) + ', function() {' +
this.inner.generateCode(context) +
'}, true);');
};
return ParserNodeAutoescape;
}(ParserNode_1.ParserNodeStatement));
var ParserNodeExpressionFilter = (function (_super) {
__extends(ParserNodeExpressionFilter, _super);
function ParserNodeExpressionFilter(inner) {
_super.call(this);
this.inner = inner;
this.filters = [];
}
ParserNodeExpressionFilter.prototype.iterate = function (handler) {
handler(this);
this.inner.iterate(handler);
this.filters.forEach(function (item) { return item.parameters.iterate(handler); });
};
ParserNodeExpressionFilter.prototype.addFilter = function (filterName, filterParameters) {
this.filters.push({
name: filterName,
parameters: filterParameters,
});
};
ParserNodeExpressionFilter.prototype.generateCode = function (context) {
var out = '';
this.filters.reverse().forEach(function (filter) {
out += 'runtimeContext.filter(' + JSON.stringify(filter.name) + ', [';
});
out += 'runtimeContext.captureOutput(function () {';
out += this.inner.generateCode(context);
out += '})';
this.filters.reverse().forEach(function (filter) {
if (filter.parameters && filter.parameters.expressions.length > 0) {
out += ',';
out += filter.parameters.generateCode(context);
}
out += '])';
});
return out;
};
return ParserNodeExpressionFilter;
}(ParserNode_1.ParserNodeExpression));
var ParserNodeScopeSet = (function (_super) {
__extends(ParserNodeScopeSet, _super);
function ParserNodeScopeSet(key, value) {
_super.call(this);
this.key = key;
this.value = value;
}
ParserNodeScopeSet.prototype.iterate = function (handler) {
handler(this);
this.value.iterate(handler);
};
ParserNodeScopeSet.prototype.generateCode = function (context) {
return 'runtimeContext.scope.setUpdate(' + JSON.stringify(this.key) + ', ' + this.value.generateCode(context) + ');';
};
return ParserNodeScopeSet;
}(ParserNode_1.ParserNodeStatement));
var ParserNodeIf = (function (_super) {
__extends(ParserNodeIf, _super);
function ParserNodeIf() {
_super.apply(this, arguments);
this.conditions = [];
}
ParserNodeIf.prototype.iterate = function (handler) {
handler(this);
this.conditions.forEach(function (node) { node.code.iterate(handler); node.expression.iterate(handler); });
};
ParserNodeIf.prototype.addCaseCondition = function (expression) {
this.conditions.push({
expression: expression,
code: new ParserNode_1.ParserNodeContainer([]),
});
};
ParserNodeIf.prototype.addElseCondition = function () {
this.conditions.push({
expression: null,
code: new ParserNode_1.ParserNodeContainer([]),
});
};
ParserNodeIf.prototype.addCodeToCondition = function (node) {
this.conditions[this.conditions.length - 1].code.add(node);
};
ParserNodeIf.prototype.generateCode = function (context) {
var out = '';
for (var n = 0; n < this.conditions.length; n++) {
var condition = this.conditions[n];
if (out != '')
out += 'else ';
if (condition.expression != null)
out += 'if (' + condition.expression.generateCode(context) + ')';
out += '{ ';
out += condition.code.generateCode(context);
out += '}';
}
return out;
};
return ParserNodeIf;
}(ParserNode_1.ParserNodeStatement));
var ParserNodeFor = (function (_super) {
__extends(ParserNodeFor, _super);
function ParserNodeFor(keyId, condId, valueId, nodeList, forCode, elseCode) {
_super.call(this);
this.keyId = keyId;
this.condId = condId;
this.valueId = valueId;
this.nodeList = nodeList;
this.forCode = forCode;
this.elseCode = elseCode;
}
ParserNodeFor.prototype.iterate = function (handler) {
handler(this);
this.valueId.iterate(handler);
this.nodeList.iterate(handler);
this.forCode.iterate(handler);
this.elseCode.iterate(handler);
};
ParserNodeFor.prototype.generateCode = function (context) {
var out = '';
out += ('runtimeContext.createScope((function() { ');
out += (' var list = ' + this.nodeList.generateCode(context) + ';');
out += (' if (!runtimeContext.emptyList(list)) {');
out += (' runtimeContext.each(list, function(k, v) { ');
out += (' ' + (new ParserNode_1.ParserNodeAssignment(this.valueId, new ParserNode_1.ParserNodeRaw("v"))).generateCode(context) + ';');
if (this.keyId !== undefined) {
out += (' ' + (new ParserNode_1.ParserNodeAssignment(this.keyId, new ParserNode_1.ParserNodeRaw("k"))).generateCode(context) + ';');
}
if (this.condId) {
out += (' if (' + this.condId.generateCode() + ') { ');
}
else {
out += (' if (true) { ');
}
out += this.forCode.generateCode(context);
out += ('}'); // if condition
out += (' });'); // each
out += ('} else {');
{
out += this.elseCode.generateCode(context);
}
out += ('} '); // if/else
out += ('}));'); // createScope
return out;
};
return ParserNodeFor;
}(ParserNode_1.ParserNodeStatement));
var DefaultTags = (function () {
function DefaultTags() {
}
DefaultTags.autoescape = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionNode = (new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext)).parseExpression();
checkNoMoreTokens(expressionTokenReader);
var innerNode = new ParserNode_1.ParserNodeContainer([]);
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'endautoescape': function (e) {
return true;
},
}, function (node, nodeStart, nodeEnd) {
innerNode.add(node);
});
return new ParserNodeAutoescape(expressionNode, innerNode);
};
DefaultTags.set = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionParser = new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext);
var nodeIds = expressionParser.parseIdentifierCommaList();
if (expressionTokenReader.checkAndMoveNext(['='])) {
var nodeValues = expressionParser.parseCommaExpression();
checkNoMoreTokens(expressionTokenReader);
if (nodeIds.length != nodeValues.expressions.length)
throw (new Error("variables doesn't match values"));
var container = new ParserNode_1.ParserNodeContainer([]);
for (var n = 0; n < nodeIds.length; n++) {
container.add(new ParserNodeScopeSet(String(nodeIds[n].value), nodeValues.expressions[n]));
}
return container;
}
else {
var innerNode = new ParserNode_1.ParserNodeContainer([]);
//console.log('************************');
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'endset': function (e) {
return true;
},
}, function (node, nodeStart, nodeEnd) {
//console.log(node);
innerNode.add(node);
});
//console.log('************************');
return new ParserNode_1.ParserNodeStatementExpression((new ParserNode_1.ParserNodeContainer([
new ParserNode_1.ParserNodeRaw('runtimeContext.scopeSetUpdate(' + JSON.stringify(nodeIds[0].value) + ', (runtimeContext.captureOutput(function() { '),
innerNode,
new ParserNode_1.ParserNodeRaw('})))')
])));
}
};
DefaultTags.$do = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionNode = (new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext)).parseExpression();
checkNoMoreTokens(expressionTokenReader);
return new ParserNode_1.ParserNodeStatementExpression(expressionNode);
};
DefaultTags.embed = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionString = expressionTokenReader.getSliceWithCallback(function () {
var includeName = (new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext)).parseExpression();
}).map(function (item) { return item.rawValue; });
checkNoMoreTokens(expressionTokenReader);
var offsetStart = templateTokenReader.getOffset();
var offsetEnd = offsetStart;
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'endembed': function (e) { offsetEnd = templateTokenReader.getOffset() - 1; return true; },
}, function (node, nodeStart, nodeEnd) {
});
var rawText = templateTokenReader.getSlice(offsetStart, offsetEnd).map(function (item) { return item.rawText; }).join('');
var templateString = '{% extends ' + expressionString + ' %}' + rawText;
return new ParserNode_1.ParserNodeRaw('runtimeContext.include(runtimeContext.compileString(' + JSON.stringify(templateString) + '));');
};
DefaultTags.filter = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var innerNode = new ParserNode_1.ParserNodeContainer([]);
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'endfilter': function (e) { return true; },
}, function (node, nodeStart, nodeEnd) {
innerNode.add(node);
});
var filterNode = new ParserNodeExpressionFilter(innerNode);
var expressionParser = new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext);
while (true) {
var filterName = expressionParser.parseIdentifier().value;
var parameters = null;
//console.log(filterName);
if (expressionTokenReader.checkAndMoveNext(['('])) {
parameters = expressionParser.parseCommaExpression();
//console.log(parameters);
expressionTokenReader.expectAndMoveNext([')']);
}
filterNode.addFilter(filterName, parameters);
if (!expressionTokenReader.checkAndMoveNext(['|'])) {
break;
}
}
checkNoMoreTokens(expressionTokenReader);
return new ParserNode_1.ParserNodeStatementExpression(new ParserNode_1.ParserNodeOutputNodeExpression(filterNode));
};
// FLUSH
// http://twig.sensiolabs.org/doc/tags/flush.html
DefaultTags.flush = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
// do nothing (all output is buffered and can't be flushed)
};
DefaultTags.macro = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionParser = new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext);
var macroName = expressionTokenReader.read().value;
var paramNames = [];
expressionTokenReader.expectAndMoveNext(['(']);
if (expressionTokenReader.peek().value != ")") {
while (true) {
paramNames.push(expressionParser.parseIdentifier());
if (expressionTokenReader.expectAndMoveNext([')', ',']) == ')')
break;
}
}
else {
expressionTokenReader.expectAndMoveNext([')']);
}
checkNoMoreTokens(expressionTokenReader);
var macroNode = new ParserNode_1.ParserNodeContainer([]);
macroNode.add(new ParserNode_1.ParserNodeRaw('var _arguments = arguments;'));
macroNode.add(new ParserNode_1.ParserNodeRaw('return runtimeContext.captureOutput(function() { '));
macroNode.add(new ParserNode_1.ParserNodeRaw('return runtimeContext.autoescape(false, function() { '));
macroNode.add(new ParserNode_1.ParserNodeRaw('runtimeContext.createScope(function() { '));
paramNames.forEach(function (paramName, index) {
var assign = new ParserNode_1.ParserNodeAssignment(paramName, new ParserNode_1.ParserNodeRaw('_arguments[' + index + ']'));
macroNode.add(new ParserNode_1.ParserNodeStatementExpression(assign));
});
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'endmacro': function (e) {
return true;
},
}, function (node, nodeStart, nodeEnd) {
macroNode.add(node);
});
macroNode.add(new ParserNode_1.ParserNodeRaw('});')); // createScope
macroNode.add(new ParserNode_1.ParserNodeRaw('});')); // autoescape
macroNode.add(new ParserNode_1.ParserNodeRaw('});')); // captureOutput
var macroCode = tokenParserContext.setMacro(macroName, macroNode);
//console.log(macroCode);
return new ParserNode_1.ParserNodeRaw('');
};
DefaultTags.from = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionParser = new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext);
var fileNameNode = _self(expressionParser.parseExpression(), templateParser.path);
expressionTokenReader.expectAndMoveNext(['import']);
var pairs = [];
while (expressionTokenReader.peek().value != null) {
var fromNode = expressionTokenReader.read().value;
var toNode = fromNode;
var token = expressionTokenReader.expectAndMoveNext(['as', ',', null]);
if (token == 'as') {
toNode = expressionTokenReader.read().value;
expressionTokenReader.expectAndMoveNext([',', null]);
}
pairs.push([fromNode, toNode]);
}
checkNoMoreTokens(expressionTokenReader);
return new ParserNode_1.ParserNodeContainer([
new ParserNode_1.ParserNodeRaw('runtimeContext.fromImport('),
fileNameNode,
new ParserNode_1.ParserNodeRaw(', ' + JSON.stringify(pairs) + ');')
]);
};
DefaultTags.$import = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionParser = new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext);
var fileNameNode = _self(expressionParser.parseExpression(), templateParser.path);
expressionTokenReader.expectAndMoveNext(['as']);
var aliasNode = expressionParser.parseIdentifier();
checkNoMoreTokens(expressionTokenReader);
return new ParserNode_1.ParserNodeStatementExpression(new ParserNode_1.ParserNodeAssignment(aliasNode, new ParserNode_1.ParserNodeContainerExpression([
new ParserNode_1.ParserNodeRaw('runtimeContext.import('),
fileNameNode,
new ParserNode_1.ParserNodeRaw(')'),
])));
};
// USE
// http://twig.sensiolabs.org/doc/tags/use.html
DefaultTags.use = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionParser = new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext);
var fileName = expressionParser.parseStringLiteral().value;
var pairs = {};
while (expressionTokenReader.checkAndMoveNext(['with'])) {
var fromNode = expressionParser.parseIdentifierOnly().value;
expressionTokenReader.expectAndMoveNext(['as']);
var toNode = expressionParser.parseIdentifierOnly().value;
pairs['block_' + fromNode] = 'block_' + toNode;
}
checkNoMoreTokens(expressionTokenReader);
var info = templateParser.getEvalCode(fileName, tokenParserContext.common);
info.tokenParserContext.iterateBlocks(function (node, name) {
if (name.match(/^block_/)) {
if (pairs[name]) {
tokenParserContext.setBlock(pairs[name], node);
}
else {
tokenParserContext.setBlock(name, node);
}
}
});
return new ParserNode_1.ParserNodeRaw('');
};
// INCLUDE
DefaultTags.include = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
//console.log(tokenParserContext.common);
var node = new ParserNode_1.ParserNodeContainer([]);
node.add(new ParserNode_1.ParserNodeRaw('runtimeContext.include('));
var expressionNode = (new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext)).parseExpression();
node.add(expressionNode);
if (expressionTokenReader.checkAndMoveNext(['with'])) {
node.add(new ParserNode_1.ParserNodeRaw(','));
node.add((new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext)).parseExpression());
}
else {
node.add(new ParserNode_1.ParserNodeRaw(', undefined'));
}
if (expressionTokenReader.checkAndMoveNext(['only'])) {
node.add(new ParserNode_1.ParserNodeRaw(', true'));
}
else {
node.add(new ParserNode_1.ParserNodeRaw(', false'));
}
node.add(new ParserNode_1.ParserNodeRaw(', ' + JSON.stringify(tokenParserContext.common.serialize())));
checkNoMoreTokens(expressionTokenReader);
node.add(new ParserNode_1.ParserNodeRaw(');'));
return node;
};
DefaultTags.raw = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
checkNoMoreTokens(expressionTokenReader);
//console.log(templateTokenReader);
//var rawText = templateTokenReader.tokens
var res = templateTokenReader.tokenizer.stringReader.findRegexp(/\{%\-?\s*end(verbatim|raw)\s*\-?%\}/);
if (res.position === null)
throw (new Error("Expecting endverbatim"));
var rawText = templateTokenReader.tokenizer.stringReader.readChars(res.position);
templateTokenReader.tokenizer.stringReader.skipChars(res.length);
return new ParserNode_1.ParserNodeOutputText(rawText);
};
DefaultTags.sandbox = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
checkNoMoreTokens(expressionTokenReader);
var innerNode = new ParserNode_1.ParserNodeContainer([]);
tokenParserContext.common.setSandbox(function () {
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'endsandbox': function (e) {
return true;
},
}, function (node, nodeStart, nodeEnd) {
innerNode.add(node);
});
});
return new ParserNode_1.ParserNodeContainer([
new ParserNode_1.ParserNodeRaw('runtimeContext.createScope(function() { '),
new ParserNode_1.ParserNodeRaw(' runtimeContext.scopeSet("__sandboxed", true);'),
innerNode,
new ParserNode_1.ParserNodeRaw('});')
]);
};
DefaultTags.spaceless = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
checkNoMoreTokens(expressionTokenReader);
var innerNode = new ParserNode_1.ParserNodeContainer([]);
//console.log('************************');
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'endspaceless': function (e) {
return true;
},
}, function (node) {
//console.log(node);
innerNode.add(node);
});
//console.log('************************');
return new ParserNode_1.ParserNodeStatementExpression(new ParserNode_1.ParserNodeOutputNodeExpression(new ParserNode_1.ParserNodeContainer([
new ParserNode_1.ParserNodeRaw('runtimeContext.filter("spaceless", [runtimeContext.captureOutput(function() { '),
innerNode,
new ParserNode_1.ParserNodeRaw('})])')
])));
};
DefaultTags.trans = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionNode = null;
if (expressionTokenReader.hasMore()) {
expressionNode = (new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext)).parseExpression();
}
checkNoMoreTokens(expressionTokenReader);
if (expressionNode != null) {
return new ParserNode_1.ParserNodeStatementExpression(new ParserNode_1.ParserNodeOutputNodeExpression(new ParserNode_1.ParserNodeContainer([
new ParserNode_1.ParserNodeRaw('runtimeContext.trans2('),
expressionNode,
new ParserNode_1.ParserNodeRaw(')')
])));
}
else {
var innerNode = new ParserNode_1.ParserNodeContainer([]);
var lastPos = templateTokenReader.tokenizer.stringReader.position;
var currentPos = lastPos;
var state = 'normal';
var pluralNode = new ParserNode_1.ParserNodeRaw("1");
var info = { 'normal': '', 'plural': '', 'notes': '' };
var flush = function (e) {
info[state] = e.templateTokenReader.tokenizer.stringReader.getSlice(lastPos, currentPos);
lastPos = e.templateTokenReader.tokenizer.stringReader.position;
};
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'plural': function (e) {
pluralNode = (new ExpressionParser_1.ExpressionParser(e.expressionTokenReader, tokenParserContext)).parseExpression();
checkNoMoreTokens(e.expressionTokenReader);
flush(e);
state = 'plural';
return false;
},
'notes': function (e) {
flush(e);
state = 'notes';
return false;
},
'endtrans': function (e) {
flush(e);
//console.log(e.templateTokenReader.getOffset());
return true;
},
}, function (node, nodeStart, nodeEnd) {
//console.log('node', node, nodeStart, nodeEnd);
currentPos = nodeEnd;
innerNode.add(node);
});
//console.log('************************');
//console.log(info);
return new ParserNode_1.ParserNodeStatementExpression(new ParserNode_1.ParserNodeOutputNodeExpression(new ParserNode_1.ParserNodeContainer([
new ParserNode_1.ParserNodeRaw('runtimeContext.trans2('),
new ParserNode_1.ParserNodeRaw(JSON.stringify(RuntimeContext_1.RuntimeContext.normalizeTrans(info['normal'])) + ","),
new ParserNode_1.ParserNodeRaw(JSON.stringify(RuntimeContext_1.RuntimeContext.normalizeTrans(info['plural'])) + ","),
pluralNode,
new ParserNode_1.ParserNodeRaw(')')
])));
}
};
DefaultTags.$if = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var didElse = false;
var expressionNode = (new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext)).parseExpression();
checkNoMoreTokens(expressionTokenReader);
var parserNodeIf = new ParserNodeIf();
parserNodeIf.addCaseCondition(expressionNode);
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'elseif': function (e) {
if (didElse)
throw new Error("Can't put 'elseif' after the 'else'");
var expressionNode = (new ExpressionParser_1.ExpressionParser(e.expressionTokenReader, tokenParserContext)).parseExpression();
checkNoMoreTokens(expressionTokenReader);
parserNodeIf.addCaseCondition(expressionNode);
return false;
},
'else': function (e) {
if (didElse)
throw new Error("Can't have two 'else'");
parserNodeIf.addElseCondition();
didElse = true;
return false;
},
'endif': function (e) {
return true;
},
}, function (node, nodeStart, nodeEnd) {
parserNodeIf.addCodeToCondition(node);
});
return parserNodeIf;
};
DefaultTags.block = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var blockName = 'block_' + expressionTokenReader.read().value;
var innerNode = new ParserNode_1.ParserNodeContainer([]);
if (expressionTokenReader.hasMore()) {
var expressionNode = (new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext)).parseExpression();
checkNoMoreTokens(expressionTokenReader);
innerNode.add(new ParserNode_1.ParserNodeReturnStatement(new ParserNode_1.ParserNodeWriteExpression(expressionNode)));
}
else {
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'endblock': function (e) {
return true;
},
}, function (node, nodeStart, nodeEnd) {
innerNode.add(node);
});
}
tokenParserContext.setBlock(blockName, innerNode);
return new ParserNode_1.ParserNodeRaw('runtimeContext.putBlock(' + JSON.stringify(blockName) + ');', false);
};
// EXTENDS
DefaultTags.$extends = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var expressionNode = (new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext)).parseExpression();
checkNoMoreTokens(expressionTokenReader);
tokenParserContext.addAfterMainNode(new ParserNode_1.ParserNodeContainer([
new ParserNode_1.ParserNodeRaw('return runtimeContext.extends('),
expressionNode,
new ParserNode_1.ParserNodeRaw(');')
]));
return new ParserNode_1.ParserNodeRaw('');
};
DefaultTags.$for = function (blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader) {
var didElse = false;
var expressionParser = new ExpressionParser_1.ExpressionParser(expressionTokenReader, tokenParserContext);
var valueId = expressionParser.parseIdentifier();
var keyId = undefined;
var condId = undefined;
var res = expressionTokenReader.expectAndMoveNext([',', 'in']);
if (res == ',') {
keyId = valueId;
valueId = expressionParser.parseIdentifier();
expressionTokenReader.expectAndMoveNext(['in']);
}
var nodeList = expressionParser.parseExpression();
// Since Twig 1.2
if (expressionTokenReader.checkAndMoveNext(['if'])) {
condId = expressionParser.parseExpression();
}
checkNoMoreTokens(expressionTokenReader);
var forCode = new ParserNode_1.ParserNodeContainer([]);
var elseCode = new ParserNode_1.ParserNodeContainer([]);
handleOpenedTag(blockType, templateParser, tokenParserContext, templateTokenReader, expressionTokenReader, {
'else': function (e) {
if (didElse)
throw (new Error("Can't have two 'else'"));
didElse = true;
return false;
},
'endfor': function (e) {
return true;
},
}, function (node, nodeStart, nodeEnd) {
if (!didElse) {
forCode.add(node);
}
else {
elseCode.add(node);
}
});
return new ParserNodeFor(keyId, condId, valueId, nodeList, forCode, elseCode);
};
DefaultTags.endautoescape = _flowexception;
// DO/SET
DefaultTags.endset = _flowexception;
// EMBED
// http://twig.sensiolabs.org/doc/tags/embed.html
DefaultTags.endembed = _flowexception;
// FILTER
// http://twig.sensiolabs.org/doc/tags/filter.html
DefaultTags.endfilter = _flowexception;
// MACRO/FROM/IMPORTUSE
DefaultTags.endmacro = _flowexception;
// RAW/VERBATIM
// http://twig.sensiolabs.org/doc/tags/verbatim.html
DefaultTags.endraw = _flowexception;
DefaultTags.endverbatim = _flowexception;
DefaultTags.verbatim = DefaultTags.raw;
// SANDBOX
// http://twig.sensiolabs.org/doc/tags/sandbox.html
DefaultTags.endsandbox = _flowexception;
// SPACELESS
// http://twig.sensiolabs.org/doc/tags/spaceless.html
DefaultTags.endspaceless = _flowexception;
// TRANS
// http://twig.sensiolabs.org/doc/extensions/i18n.html
DefaultTags.endtrans = _flowexception;
DefaultTags.plural = _flowexception;
DefaultTags.notes = _flowexception;
// IF/ELSEIF/ELSE/ENDIF
DefaultTags.$else = _flowexception;
DefaultTags.$elseif = _flowexception;
DefaultTags.$endif = _flowexception;
// BLOCK/ENDBLOCK
DefaultTags.endblock = _flowexception;
// http://twig.sensiolabs.org/doc/tags/for.html
DefaultTags.$endfor = _flowexception;
return DefaultTags;
}());
exports.DefaultTags = DefaultTags;