Skip to content

Instantly share code, notes, and snippets.

@staydecent
Created March 14, 2015 04:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save staydecent/ef152be939e109791adf to your computer and use it in GitHub Desktop.
Save staydecent/ef152be939e109791adf to your computer and use it in GitHub Desktop.
proof of minimal DOM updates based on a strict atom/state rather than output of vdom functions.
var atom = {"things": []};
function Thing() {
this.isNew = true;
}
function thingView(thing) {
var cls = ['thing'];
cls.push(thing.isNew ? 'new' : 'notNew');
return ['li', {className: cls.join(' ')}, 'Content of thing!'];
}
initModule(document.body, atom, {
controller: function() {
return {"things": atom.things};
},
view: function(ctrl) {
return [
['button', {
onclick: function() {
ctrl.things.push(new Thing);
console.debug('onclick!', atom);
}
}, 'Add a thing'],
['ul', ctrl.things.map(thingView)]
];
}
});
function initModule(elem, atom, module) {
var prevAtom = JSON.stringify(atom);
var ctrl = new (module.controller || function() {});
buildTree(elem, module.view(ctrl));
setInterval(function () {
var newAtom = JSON.stringify(atom)
if (prevAtom !== newAtom) {
prevAtom = newAtom;
buildTree(elem, module.view(ctrl));
}
}, 1000);
}
function buildTree(elem, vtree) {
if (!vtree || !vtree.length) {
return;
}
var vnode;
for (var x=0; x < vtree.length; x++) {
vnode = vtree[x];
if (!vnode.length) {
console.error('Invalid vnode');
break;
}
elem.appendChild(createNode(vnode));
}
}
function createNode(vnode) {
var tag = vnode[0],
opts = vnode[1],
children = vnode[2];
if (children === undefined) {
children = opts;
opts = undefined;
}
var node = document.createElement(tag);
if (opts && typeof opts === 'object') {
var optKeys = Object.keys(opts);
for (var k=0; k < optKeys.length; k++) {
if (optKeys[k].indexOf('on') === 0) {
node.addEventListener(optKeys[k].substr(2), opts[optKeys[k]]);
} else {
node.setAttribute(optKeys[k], opts[optKeys[k]]);
}
}
}
if (children) {
if (typeof children === 'string') {
node.appendChild(document.createTextNode(children));
} else {
// assume array
for (var n=0; n < children.length; n++) {
node.appendChild(createNode(children[n]));
}
}
}
return node;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment