public
Last active

Dom Chain

  • Download Gist
domchain.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
// Proof of concept DOM utility library
//
// Usage
// ------------------------------------------------------------------
// var html = window.domchain;
// html().p('.foo#bar').span().text("Hello World").render();
// => <p class="foo" id="bar"><span>Hello World</span></p>
//
// Inspired by [htmlutils](https://github.com/jensl/critic/blob/master/htmlutils.py),
// [domo](https://github.com/jed/domo) and [Sugared DOM](https://gist.github.com/1532562);
 
(function () {
 
'use strict';
 
var directProps = {
checked: 'checked', 'class': 'className', className: 'className',
disabled: 'disabled', 'for': 'htmlFor', hidden: 'hidden', html: 'innerHTML',
id: 'id', multiple: 'multiple', name: 'name', src: 'src', value: 'value'
};
var setProperty = function (el, key, value) {
var prop = directProps[key];
if (prop) el[prop] = '' + value;
else el.setAttribute(key, '' + value);
};
 
var DomChain = function (doc) {
this._doc = doc || document;
this._dom = this._doc.createDocumentFragment();
this._tip = this._dom;
};
 
DomChain.prototype.render = function () {
return this._dom;
};
DomChain.prototype.text = function (str) {
this._tip.appendChild(this._doc.createTextNode(str));
return this;
};
var splitter = /(#|\.)/;
[ "a", "abbr", "acronym", "address", "area", "article", "aside",
"audio", "b", "bdi", "bdo", "big", "blockquote", "body", "br", "button",
"canvas", "caption", "cite", "code", "col", "colgroup", "command",
"datalist", "dd", "del", "details", "dfn", "div", "dl", "dt", "em", "embed",
"fieldset", "figcaption", "figure", "footer", "form", "frame", "frameset",
"h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html",
"i", "iframe", "img", "input", "ins", "kbd", "keygen", "label", "legend",
"li", "link", "map", "mark", "meta", "meter", "nav", "noscript", "object",
"ol", "optgroup", "option", "output", "p", "param", "pre", "progress", "q",
"rp", "rt", "ruby", "samp", "script", "section", "select", "small", "source",
"span", "split", "strong", "style", "sub", "summary", "sup", "table",
"tbody", "td", "textarea", "tfoot", "th", "thead", "time", "title", "tr",
"track", "tt", "ul", "var", "video", "wbr"
].forEach(function (tag) {
DomChain.prototype[tag] = function (sel, props) {
if (sel != null && typeof sel != 'string') {
props = sel;
sel = null;
} else if (splitter.test(sel)) {
var parts = sel.split(splitter);
if (!props) props = {};
for (var i = 1, j = 2, l = parts.length, name; j < l; i += 2, j += 2) {
name = parts[j];
if (parts[i] === '#') props.id = name;
else props.className = name;
}
}
var el = this._doc.createElement(tag);
if (props) {
for (var prop in props) {
setProperty(el, prop, props[prop]);
}
}
this._tip.appendChild(el);
this._tip = el;
return this;
};
});
 
this.domchain = function () {
return new DomChain();
};
 
}).call(this);

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.