Marko v3: Added support for node.onBeforeGenerateCode and node.onAfterGenerateCode

This commit is contained in:
Patrick Steele-Idem 2016-02-02 16:01:00 -07:00
parent 4c6d4d0661
commit 176ee2bc9b
2 changed files with 71 additions and 2 deletions

View File

@ -9,6 +9,27 @@ const Container = require('./ast/Container');
const util = require('util');
const isValidJavaScriptIdentifier = require('./util/isValidJavaScriptIdentifier');
class GeneratorEvent {
constructor(node, codegen) {
this.node = node;
this.codegen = codegen;
this.isBefore = true;
this.builder = codegen.builder;
this.context = codegen.context;
}
insertCode(newCode) {
this.codegen.generateStatements(newCode);
if (this.isBefore) {
if (!this.codegen._code.endsWith(this.codegen.currentIndent)) {
this.codegen.writeLineIndent();
}
}
}
}
class Slot {
constructor(codegen, slotNode) {
this._content = null;
@ -80,7 +101,6 @@ class Generator {
this._bufferedWrites = null;
this.builder = context.builder;
this.walker = context.walker;
this.outputType = options.output || 'html';
this.context = context;
@ -138,6 +158,17 @@ class Generator {
let generateCodeFunc;
var isStatement = node.statement;
var beforeAfterEvent;
if (node.listenerCount('beforeGenerateCode') || node.listenerCount('beforeGenerateCode')) {
beforeAfterEvent = new GeneratorEvent(node, this);
}
if (beforeAfterEvent) {
beforeAfterEvent.isBefore = true;
beforeAfterEvent.node.emit('beforeGenerateCode', beforeAfterEvent);
}
if (node.getCodeGenerator) {
generateCodeFunc = node.getCodeGenerator(this.outputType);
if (generateCodeFunc) {
@ -191,6 +222,11 @@ class Generator {
}
}
if (beforeAfterEvent) {
beforeAfterEvent.isBefore = false;
beforeAfterEvent.node.emit('afterGenerateCode', beforeAfterEvent);
}
this._currentNode = oldCurrentNode;
}
@ -484,7 +520,7 @@ class Generator {
this.decIndent();
this.writeLineIndent();
this.write(']\n');
this.write(']');
} else if (typeof value === 'number') {
this.write(value.toString());
} else if (typeof value === 'object') {

View File

@ -4,6 +4,7 @@ var ArrayContainer = require('./ArrayContainer');
var ok = require('assert').ok;
var extend = require('raptor-util/extend');
var inspect = require('util').inspect;
var EventEmitter = require('events').EventEmitter;
class Node {
constructor(type) {
@ -16,9 +17,40 @@ class Node {
this._flags = {};
this._transformersApplied = {};
this._preserveWhitespace = null;
this._events = null;
this.data = {};
}
on(event, listener) {
if (!this._events) {
this._events = new EventEmitter();
}
this._events.on(event, listener);
}
emit(event, args) {
if (this._events) {
this._events.emit.apply(this._events, arguments);
}
}
listenerCount(event) {
if (this._events) {
return this._events.listenerCount(event);
} else {
return 0;
}
}
onBeforeGenerateCode(listener) {
this.on('beforeGenerateCode', listener);
}
onAfterGenerateCode(listener) {
this.on('afterGenerateCode', listener);
}
wrap(wrapperNode) {
ok(this.container, 'Node does not belong to a container: ' + this);
var replaced = this.container.replaceChild(wrapperNode, this);
@ -81,6 +113,7 @@ class Node {
delete result.data;
delete result.tagDef;
delete result._preserveWhitespace;
delete result._events;
return result;
}