dynamictemplate
Version:
Δt - async & dynamic templating engine
292 lines (255 loc) • 10 kB
JavaScript
(function() {
var DefaultBuilder, EVENTS, EventEmitter, Template, aliases, doctype, ff, pp, schema, self_closing;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }, __slice = Array.prototype.slice;
EventEmitter = require('events').EventEmitter;
DefaultBuilder = require('asyncxml').Builder;
EVENTS = ['new', 'add', 'attach', 'detach', 'attr', 'attr:remove', 'text', 'remove', 'data', 'close', 'end'];
schema = {
'xml': function() {
return "";
},
'html': function() {
return ("" + (schema.xml()) + " " + (schema['html-obsolete']()) + " iframe label legend ") + ("" + (self_closing.html()) + " html body div ul li a b body button colgroup ") + "dfn div dl dt em dd del form h1 h2 h3 h4 h5 h6 head hgroup html ins " + "li map i mark menu meter nav noscript object ol optgroup option p " + "pre script select small span strong style sub sup table tbody tfoot " + "td textarea th thead title tr u ul";
},
'html5': function() {
return ("" + (schema.html()) + " " + (self_closing.html5()) + " section article video q s ") + "audio abbr address aside bdi bdo blockquote canvas caption cite code " + "datalist details fieldset figcaption figure footer header kbd output " + "progress rp rt ruby samp summary time";
},
'strict': function() {
return "" + (schema.html());
},
'xhtml1.1': function() {
return "" + (schema.xhtml());
},
'xhtml': function() {
return "" + (schema.xhtml());
},
'frameset': function() {
return "" + (schema.xhtml());
},
'transitional': function() {
return "" + (schema.xhtml());
},
'mobile': function() {
return "" + (schema.xhtml());
},
'html-ce': function() {
return "" + (schema.xhtml());
},
'html-obsolete': function() {
return "applet acronym bgsound dir frameset noframes isindex listing nextid " + "noembed plaintext rb strike xmp big blink center font marquee nobr " + "multicol spacer tt";
}
};
self_closing = {
'xml': function() {
return true;
},
'html': function() {
return "area br col embed hr img input link meta param";
},
'html5': function() {
return "" + (self_closing.html()) + " base command keygen source track wbr";
},
'mobile': function() {
return "" + (self_closing.xhtml());
},
'html-ce': function() {
return "" + (self_closing.xhtml());
},
'strict': function() {
return "" + (self_closing.xhtml());
},
'xhtml1.1': function() {
return "" + (self_closing.xhtml());
},
'xhtml': function() {
return "" + (self_closing.xhtml());
},
'frameset': function() {
return "" + (self_closing.xhtml());
},
'transitional': function() {
return "" + (self_closing.xhtml());
}
};
doctype = {
'xml': function(_arg) {
var encoding;
encoding = _arg.encoding;
return "<?xml version=\"1.0\" encoding=\"" + encoding + "\" ?>";
},
'html': function() {
return "<!DOCTYPE html>";
},
'html5': function() {
return "" + (doctype.html());
},
'mobile': function() {
return '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD ' + 'XHTML Mobile 1.2//EN" ' + '"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">';
},
'html-ce': function() {
return '<!DOCTYPE html PUBLIC ' + '"-//W3C//DTD XHTML 1.0 Transitional//EN" ' + '"ce-html-1.0-transitional.dtd">';
},
'strict': function() {
return '<!DOCTYPE html PUBLIC ' + '"-//W3C//DTD XHTML 1.0 Strict//EN" ' + '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
},
'xhtml1.1': function() {
return '<!DOCTYPE html PUBLIC ' + '"-//W3C//DTD XHTML 1.1//EN" ' + '"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
},
'xhtml': function() {
return '<!DOCTYPE html PUBLIC ' + '"-//W3C//DTD XHTML Basic 1.1//EN" ' + '"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">';
},
'frameset': function() {
return '<!DOCTYPE html PUBLIC ' + '"-//W3C//DTD XHTML 1.0 Frameset//EN" ' + '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';
},
'transitional': function() {
return '<!DOCTYPE html PUBLIC ' + '"-//W3C//DTD XHTML 1.0 Transitional//EN" ' + '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
}
};
aliases = {
'default': 'xml',
'5': 'html5',
5: 'html5',
'ce': 'html-ce',
'1.1': 'xhtml1.1',
'html11': 'xhtml1.1',
'basic': 'xhtml',
'xhtml1': 'xhtml',
'xhtml-basic': 'xhtml',
'xhtml-strict': 'strict',
'xhtml-mobile': 'mobile',
'xhtml-frameset': 'frameset',
'xhtml-trasitional': 'transitional'
};
pp = function(proto, name) {
proto[name] = function() {
var _ref;
return this.tag.apply(this, (_ref = [name]).concat.apply(_ref, arguments));
};
return proto["$" + name] = function() {
var _ref;
return this.$tag.apply(this, (_ref = [name]).concat.apply(_ref, arguments));
};
};
ff = function(proto, tags) {
var tagname, _i, _len;
for (_i = 0, _len = tags.length; _i < _len; _i++) {
tagname = tags[_i];
if (tagname) pp(proto, tagname);
}
};
Template = (function() {
__extends(Template, EventEmitter);
function Template(opts, template) {
var Builder, ExtendedBuilder, ExtendedTag, Tag, end_tag, s, schema_input, _ref, _ref2, _ref3, _ref4, _ref5;
var _this = this;
if (opts == null) opts = {};
this.ready = __bind(this.ready, this);
this.end = __bind(this.end, this);
this.register = __bind(this.register, this);
if (typeof opts === 'function') {
_ref = [opts, {}], template = _ref[0], opts = _ref[1];
}
if ((_ref2 = opts.encoding) == null) opts.encoding = 'utf-8';
if ((_ref3 = opts.doctype) == null) opts.doctype = false;
if ((_ref4 = opts.end) == null) opts.end = true;
schema_input = opts.schema;
s = aliases[schema_input] || schema_input || 'xml';
opts.self_closing = typeof self_closing[s] === "function" ? self_closing[s](opts) : void 0;
opts.schema = typeof schema[s] === "function" ? schema[s](opts).split(' ') : void 0;
Builder = (_ref5 = opts.Builder) != null ? _ref5 : DefaultBuilder;
ExtendedBuilder = (function() {
__extends(ExtendedBuilder, Builder);
function ExtendedBuilder() {
ExtendedBuilder.__super__.constructor.apply(this, arguments);
}
return ExtendedBuilder;
})();
ff(ExtendedBuilder.prototype, opts.schema);
this.xml = new ExtendedBuilder(opts);
Tag = this.xml.Tag;
ExtendedTag = (function() {
__extends(ExtendedTag, Tag);
function ExtendedTag() {
ExtendedTag.__super__.constructor.apply(this, arguments);
}
return ExtendedTag;
})();
ff(ExtendedTag.prototype, opts.schema);
this.xml.Tag = this.xml.opts.Tag = ExtendedTag;
end_tag = Tag.prototype.end;
this.xml.Tag.prototype.end = function() {
if (opts.self_closing === true || opts.self_closing.match(this.name)) {
return end_tag.call.apply(end_tag, [this].concat(__slice.call(arguments)));
} else {
if (this.isempty) {
this.text("", {
force: true
});
}
return end_tag.call.apply(end_tag, [this].concat(__slice.call(arguments)));
}
};
EVENTS.forEach(function(event) {
return _this.xml.on(event, function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return _this.emit.apply(_this, [event].concat(__slice.call(args)));
});
});
process.nextTick(function() {
var d, dt;
if (opts.doctype === true) opts.doctype = 'html';
d = aliases[opts.doctype] || opts.doctype;
if (opts.doctype && (dt = typeof doctype[d] === "function" ? doctype[d](opts) : void 0)) {
if (opts.pretty) dt += "\n";
_this.xml.emit('data', dt);
}
if (typeof template === 'function') {
template.call(_this.xml);
if (opts.end) return _this.end();
} else {
return _this.end(template);
}
});
}
Template.prototype.register = function() {
var _ref;
return (_ref = this.xml).register.apply(_ref, arguments);
};
Template.prototype.end = function() {
var _ref;
return (_ref = this.xml).end.apply(_ref, arguments);
};
Template.prototype.ready = function(callback) {
if (this.xml.closed === true) {
return callback();
} else {
return this.xml.once('end', callback);
}
};
return Template;
})();
Template.schema = schema;
Template.doctype = doctype;
module.exports = Template;
Template.self_closing = self_closing;
/*
fallbeispiel: (als liste)
tag A
tag B (anderes template)
tag C
3 anwendungsfälle:
1. alles auf serverseite:
- C muss warten bis B fertig ist
- kein jqueryify
- nur on data zum client streamen
2. leeres layout auf server site und rest mit content auf client side:
- anstatt B sollte ein dummy tag kommen
- jqueryify auf client side und dummy tag replacen
- on data für leeres layout und jquery objects auf client side
3. alles auf client side:
- kein on data (oder doch in jqueryify?)
- nur jqueryify
- anstatt tag B kommt dummy, der replaced wird wenn dieses template zu ende ist (also nach tag C)
*/
}).call(this);