This commit is contained in:
2018-12-20 18:10:52 +01:00
commit 92eab0bf74
2 changed files with 93 additions and 0 deletions

4
README.md Normal file
View File

@@ -0,0 +1,4 @@
# v
An experiment in building a minimal virtual DOM, [following this little
tutorial](https://medium.com/@deathmood/how-to-write-your-own-virtual-dom-ee74acc13060).

89
main.js Normal file
View File

@@ -0,0 +1,89 @@
function setProp(t, n, v) {
if (isCProp(n)) return
else if (n === 'className') t.setAttribute('class', v);
else if (typeof value === 'boolean') setBProp(t, n, v);
else t.setAttribute(n, v);
}
function unsetProp(t, n, v) {
if (isCProp(n)) return;
else if (n === 'className') t.removeAttribute('class');
else if (typeof value === 'boolean') unsetBProp(t, n);
else t.removeAttribute(n);
}
function setBProp(t, n, v) {
if (v) t.setAttribute(n, v);
t[n] = !!v;
}
function unsetBProp(t, n) {
t.removeAttribute(n);
t[n] = false;
}
function isCProp(n) {
return isEProp(n) || name === 'forceUpdate';
}
function isEProp(n) {
return /^on/.test(name);
}
function addEListeners(t, p) {
Object.keys(p).filter(isEProp).forEach(n => t.addEventListener(n.slice(2).toLowerCase(), p[name]));
}
function setProps(t, p) {
Object.keys(p).forEach(n => setProp(t, n, p[n]));
}
function updateProp(t, n, nv, ov) {
if (!nv) unsetProp(t, n, ov);
else if(!ov || nv !== ov) setProp(t, n, nv);
}
function updateProps(t, n, o = {}) {
const p = Object.assign({}, n, o);
Object.keys(p).forEach(nm => updateProp(t, nm, n[nm], o[nm]);
}
function createElement(n) {
if (typeof node === 'string') return document.createTextNode(n);
const e = document.createElement(n.type);
setProps(e, n.props);
addEListeners(e, n.props);
n.children.map(createElement).forEach(e.appendChild.bind(e));
return e;
}
function changed(n, o) {
return typeof n !== typeof o || typeof n === 'string' && n !== o || n.type !== o.type || n.props.forceUpdate;
}
function updateElement(p, n, o, i=0) {
if (!o) p.appendChild(createElement(n));
else if (!n) p.removeChild(p.childNodes[i]);
else if (changed(n, o)) p.replaceChild(createElement(n), p.childNodes[i]);
else if (n.type) {
updateProps(p.childNode[i], n.props, o.props);
for (let j = 0; j < Math.min(n.children.length, o.children.length); j++) {
updateElement(p.childNodes[i], n.children[j], o.children[j], j);
}
}
}
function h(type, props, ...children) {
return { type, props: props || {}, children };
}