function TreeBuilder(element_factory) { this._data = []; this._elem = []; this._last = null; this._tail = null; if (!element_factory) { /* evil circular dep */ element_factory = require('./elementtree').Element; } this._factory = element_factory; } TreeBuilder.prototype.close = function() { return this._last; }; TreeBuilder.prototype._flush = function() { if (this._data) { if (this._last !== null) { var text = this._data.join(""); if (this._tail) { this._last.tail = text; } else { this._last.text = text; } } this._data = []; } }; TreeBuilder.prototype.data = function(data) { this._data.push(data); }; TreeBuilder.prototype.start = function(tag, attrs) { this._flush(); var elem = this._factory(tag, attrs); this._last = elem; if (this._elem.length) { this._elem[this._elem.length - 1].append(elem); } this._elem.push(elem); this._tail = null; }; TreeBuilder.prototype.end = function(tag) { this._flush(); this._last = this._elem.pop(); if (this._last.tag !== tag) { throw new Error("end tag mismatch"); } this._tail = 1; return this._last; }; exports.TreeBuilder = TreeBuilder;