Skip to content

Commit

Permalink
First working version
Browse files Browse the repository at this point in the history
  • Loading branch information
internalfx committed Aug 23, 2016
1 parent 3d4119d commit e8f6ab1
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 4 deletions.
55 changes: 53 additions & 2 deletions src/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -1018,13 +1018,64 @@ var Compiler = Object.extend({
this.emitLine('parentTemplate = _parentTemplate');

this.emitLine('for(var ' + k + ' in parentTemplate.blocks) {');
this.emitLine('context.addBlock(' + k +
', parentTemplate.blocks[' + k + ']);');
this.emitLine('context.addBlock(' + k + ', parentTemplate.blocks[' + k + ']);');
this.emitLine('}');

this.addScopeLevel();
},

compileEmbed: function(node, frame) {
var rawCode = this.tmpid();
var id1 = this.tmpid();
var id3 = this.tmpid();

var blockList = [];
var currentId, idx, iName, iBlock, blocks = parser.parse(node.rawCode).findAll(nodes.Block);
for (idx = 0; idx < blocks.length; idx += 1) {
currentId = this.tmpid();
iBlock = blocks[idx];
iName = iBlock.name.value;
blockList.push({id: currentId, name: iName})

this.emitFuncBegin('b_' + currentId);

var tmpFrame = new Frame();
this.emitLine('var frame = frame.push(true);');
this.compile(iBlock.body, tmpFrame);
this.emitFuncEnd();
}
this.buffer = 'output'
// this.emitLine('var ' + rawCode + ' = "' + node.rawCode.replace(/\n/g, '" + "') + '"');

this.emitLine('var tasks = [];');
this.emitLine('tasks.push(function(callback) {');
this.emit('env.getTemplate(');
this._compileExpression(node.template, frame);
this.emitLine(', true, '+this._templateName()+', false, ' + this.makeCallback(id1));
this.emitLine('callback(null, ' + id1 + ');});');
this.emitLine('});');

this.emitLine('tasks.push(function(template, callback){');
blockList.forEach(function (block) {
this.emitLine('template.blocks["' + block.name + '"] = b_' + block.id);
}.bind(this))
this.emitLine('callback(null, template);');
this.emitLine('});');

this.emitLine('tasks.push(function(template, callback){');
this.emitLine('template.render(context.getVariables(), frame, ' + this.makeCallback(id3));
this.emitLine('callback(null,' + id3 + ');});');
this.emitLine('});');

this.emitLine('tasks.push(function(result, callback){');
this.emitLine(this.buffer + ' += result;');
this.emitLine('callback();');
this.emitLine('});');

this.emitLine('env.waterfall(tasks, function(){');
this.addScopeLevel();
},

compileInclude: function(node, frame) {
var id = this.tmpid();
var id2 = this.tmpid();
Expand Down
3 changes: 1 addition & 2 deletions src/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,7 @@ Template = Obj.extend({
if (typeof ctx === 'function') {
cb = ctx;
ctx = {};
}
else if (typeof parentFrame === 'function') {
} else if (typeof parentFrame === 'function') {
cb = parentFrame;
parentFrame = null;
}
Expand Down
2 changes: 2 additions & 0 deletions src/nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ var Super = Node.extend('Super', { fields: ['blockName', 'symbol'] });
var TemplateRef = Node.extend('TemplateRef', { fields: ['template'] });
var Extends = TemplateRef.extend('Extends');
var Include = Node.extend('Include', { fields: ['template', 'ignoreMissing'] });
var Embed = Node.extend('Embed', { fields: ['template'] });
var Set = Node.extend('Set', { fields: ['targets', 'value'] });
var Output = NodeList.extend('Output');
var Capture = Node.extend('Capture', { fields: ['body'] });
Expand Down Expand Up @@ -276,6 +277,7 @@ module.exports = {
Super: Super,
Extends: Extends,
Include: Include,
Embed: Embed,
Set: Set,
LookupVal: LookupVal,
BinOp: BinOp,
Expand Down
69 changes: 69 additions & 0 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,74 @@ var Parser = Object.extend({
return node;
},

parseEmbed: function() {
var tag = this.peekToken();
if(!this.skipSymbol('embed')) {
this.fail('parseEmbed: expected embed', tag.lineno, tag.colno);
}

var args = this.parseSignature(true, true).children;
this.advanceAfterBlockEnd(tag.value);

var node = new nodes.Embed(tag.lineno, tag.colno);
node.template = args[0]
node.contextVar = null

if (args.length === 2) {
node.contextVar = args[1]
}

// node.body = this.parseUntilBlocks('endembed');

// Look for upcoming raw blocks (ignore all other kinds of blocks)
var rawBlockRegex = /([\s\S]*?){%\s*(embed|endembed)\s*(?=%})%}/;
var rawLevel = 1;
var str = '';
var matches = null;

// Skip opening raw token
// Keep this token to track line and column numbers
// var begun = this.advanceAfterBlockEnd();

// Exit when there's nothing to match
// or when we've found the matching "endraw" block
while((matches = this.tokens._extractRegex(rawBlockRegex)) && rawLevel > 0) {
var all = matches[0];
var pre = matches[1];
var blockName = matches[2];

// Adjust rawlevel
if(blockName === 'embed') {
rawLevel += 1;
} else if(blockName === 'endembed') {
rawLevel -= 1;
}

// Add to str
if(rawLevel === 0) {
// We want to exclude the last "endraw"
str += pre;
// Move tokenizer to beginning of endraw block
this.tokens.backN(all.length - pre.length);
} else {
str += all;
}
}

node.rawCode = str


// return new nodes.Output(
// begun.lineno,
// begun.colno,
// [new nodes.TemplateData(begun.lineno, begun.colno, str)]
// );

// this.advanceAfterBlockEnd();

return node;
},

parseIf: function() {
var tag = this.peekToken();
var node;
Expand Down Expand Up @@ -553,6 +621,7 @@ var Parser = Object.extend({
case 'block': return this.parseBlock();
case 'extends': return this.parseExtends();
case 'include': return this.parseInclude();
case 'embed': return this.parseEmbed();
case 'set': return this.parseSet();
case 'macro': return this.parseMacro();
case 'call': return this.parseCall();
Expand Down

0 comments on commit e8f6ab1

Please sign in to comment.