var things = [{text: "Hello"}, {text: "World"}];
with(HTML) {
var html = div({
id: "foo",
content: a({
href: "#",
content: ["test", span("bar")]
})
}) +
div({
className: "baz",
content: map(things, function (thing) {
return p(thing.text)
})
});
alert(html)
document.write(html)
}Yes, I know, with is very evil but it is cool in this situation.
Here is the full source. I hacked it up in 30 minutes and it is in bad need for a cleanup, but otherwise it seems to work alright.
var HTML = (function () {
function encode(text) {
text = text.replace(/&/g, "&", "g");
text = text.replace(/</g, "<", "g");
text = text.replace(/>/g, ">", "g");
text = text.replace(/"/g, """, "g");
text = text.replace(/'/g, "'", "g");
return text;
}
function renderAttr(attr) {
if(!attr) return '';
var html = '';
for(var name in attr) {
var value = attr[name];
if(name === "className") name == "class";
if(name === "content") continue;
html += ' '+name+'="'+encode(value)+'"'
}
html.encoded = true;
return html
}
function makeTag (name) {
return function (paras, content) {
if(arguments.length < 2) {
content = [];
}
if(typeof content === "string") content = [content]
var attr = {};
if(typeof paras === "string") {
content = [encode(paras)];
} else if(paras == null) {
content = [];
} else if(paras.content) {
var c = paras.content;
delete paras.content;
return arguments.callee(paras, c);
} else if(paras.length > 0) {
content = paras;
} else {
attr = paras;
}
var empty = content.length === 0 ? true : false;
var html = '<'+name+renderAttr(attr)+(empty ? '/' : '')+'>';
if(!empty) {
html += content.join("");
html += ''+name+'>';
}
return html;
}
}
function map(enumerable, fn) {
var result = [];
for(var i = 0, len = enumerable.length; i < len; ++i) {
result.push(fn(enumerable[i]))
}
return result;
}
var tags = ["div", "a", "p", "span"]
var HTML = {
map: map,
encode: encode
};
map(tags, function (name) {
HTML[name] = makeTag(name)
});
return HTML;
})();
