-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
95 lines (78 loc) · 2.01 KB
/
index.js
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
85
86
87
88
89
90
91
92
93
94
95
const d = document;
function patch(a, b, p) {
let re, e = (!!a * 2) + !!b;
return e > 0 ? (
re = e > 2 && a.k === b.k,
(e > 1 && !re) && p.removeChild(a.n),
e > 2 && re && a.update(b, p),
(e == 1 || (b && !re)) ? (b.create(p), b) : (b && a)
) : null;
}
function patchList(a, b, p) {
let inner = Math.max(a.length, b.length);
const cs = [];
for (let i = 0; i < inner; i++) {
const u = patch(a[i], b[i], p);
u && cs.push(u);
}
return cs;
}
function applyAttr(a, re) {
return function (n, m, b) {
for (let attr in { ...m, ...b }) {
let o = m[attr], r = b[attr], e = (!!o * 2) + !!r;
e > 1 && re(n, attr, o);
(e == 1 || r) && a(n, attr, r);
m[attr] = r;
}
}
}
const manageAttr = applyAttr(
(n, attr, v) => (attr === 'style' ?
(n.style.cssText = v) :
n.setAttribute(attr, v), v),
(n, attr, v) => (attr === 'style' ?
(n.style.cssText = "") :
n.removeAttribute(attr))
);
const manageListeners = applyAttr(
(n, t, f) => n.addEventListener(t, f),
(n, t, f) => n.removeEventListener(t, f)
);
function VNode(k, o, l, c) {
this.k = k, this.o = o, this.c = c, this.l = l, this.n = null;
}
const N = (k, o, l, c) => new VNode(k, o, l, c);
const np = VNode.prototype;
np.create = function(p) {
const { k, o, c, l } = this;
const el = d.createElement(k);
manageAttr(el, o, o);
manageListeners(el, {}, l);
for (let ch of c) { ch.create(el); }
p.appendChild(el);
this.n = el;
}
np.update = function(b, p) {
const { o, c, l, n } = this;
manageAttr(n, o, b.o);
manageListeners(n, l, b.l);
this.c = patchList(c, b.c || [], n);
}
function VNodeText(s) {
if (!(this instanceof VNodeText)) return new VNodeText(s);
this.s = s, this.n = null;
}
const T = (s) => new VNodeText(s);
const tp = VNodeText.prototype;
tp.create = function(p) {
const c = d.createTextNode(this.s);
p.appendChild(c);
this.n = c;
}
tp.update = function(b, p) {
this.s != b.s && (this.n.textContent = (this.s = b.s));
}
module.exports = {
T, N, patch,
}