1 | import {h, VNode, VNodeData} from 'snabbdom';
|
2 |
|
3 | export interface ThunkData extends VNodeData {
|
4 | fn(): VNode;
|
5 | args: Array<any>;
|
6 | }
|
7 |
|
8 | export interface Thunk extends VNode {
|
9 | data: ThunkData;
|
10 | }
|
11 |
|
12 | function copyToThunk(vnode: VNode, thunkVNode: Thunk): void {
|
13 | thunkVNode.elm = vnode.elm;
|
14 | (vnode.data as ThunkData).fn = thunkVNode.data.fn;
|
15 | (vnode.data as ThunkData).args = thunkVNode.data.args;
|
16 | (vnode.data as ThunkData).isolate = thunkVNode.data.isolate;
|
17 | thunkVNode.data = vnode.data as ThunkData;
|
18 | thunkVNode.children = vnode.children;
|
19 | thunkVNode.text = vnode.text;
|
20 | thunkVNode.elm = vnode.elm;
|
21 | }
|
22 |
|
23 | function init(thunkVNode: Thunk): void {
|
24 | const cur = thunkVNode.data as VNodeData;
|
25 | const vnode = (cur.fn as any).apply(undefined, cur.args);
|
26 | copyToThunk(vnode, thunkVNode);
|
27 | }
|
28 |
|
29 | function prepatch(oldVnode: Thunk, thunkVNode: Thunk): void {
|
30 | const old = oldVnode.data as VNodeData,
|
31 | cur = thunkVNode.data as VNodeData;
|
32 | let i: number;
|
33 | const oldArgs = old.args,
|
34 | args = cur.args;
|
35 | if (old.fn !== cur.fn || (oldArgs as any).length !== (args as any).length) {
|
36 | copyToThunk((cur.fn as any).apply(undefined, args), thunkVNode);
|
37 | }
|
38 | for (i = 0; i < (args as any).length; ++i) {
|
39 | if ((oldArgs as any)[i] !== (args as any)[i]) {
|
40 | copyToThunk((cur.fn as any).apply(undefined, args), thunkVNode);
|
41 | return;
|
42 | }
|
43 | }
|
44 | copyToThunk(oldVnode, thunkVNode);
|
45 | }
|
46 |
|
47 | export function thunk(sel: string, fn: Function, args: Array<any>): Thunk;
|
48 | export function thunk(
|
49 | sel: string,
|
50 | key: any,
|
51 | fn: Function,
|
52 | args: Array<any>
|
53 | ): Thunk;
|
54 | export function thunk(sel: string, key?: any, fn?: any, args?: any): VNode {
|
55 | if (args === undefined) {
|
56 | args = fn;
|
57 | fn = key;
|
58 | key = undefined;
|
59 | }
|
60 | return h(sel, {
|
61 | key: key,
|
62 | hook: {init: init, prepatch: prepatch},
|
63 | fn: fn,
|
64 | args: args,
|
65 | } as VNodeData);
|
66 | }
|
67 |
|
68 | export default thunk;
|