You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
1.8 KiB
71 lines
1.8 KiB
import { VNode, VNodeData } from "./vnode";
|
|
import { h, addNS } from "./h";
|
|
|
|
export interface ThunkData extends VNodeData {
|
|
fn: () => VNode;
|
|
args: any[];
|
|
}
|
|
|
|
export interface Thunk extends VNode {
|
|
data: ThunkData;
|
|
}
|
|
|
|
export interface ThunkFn {
|
|
(sel: string, fn: (...args: any[]) => any, args: any[]): Thunk;
|
|
(sel: string, key: any, fn: (...args: any[]) => any, args: any[]): Thunk;
|
|
}
|
|
|
|
function copyToThunk(vnode: VNode, thunk: VNode): void {
|
|
const ns = thunk.data?.ns;
|
|
(vnode.data as VNodeData).fn = (thunk.data as VNodeData).fn;
|
|
(vnode.data as VNodeData).args = (thunk.data as VNodeData).args;
|
|
thunk.data = vnode.data;
|
|
thunk.children = vnode.children;
|
|
thunk.text = vnode.text;
|
|
thunk.elm = vnode.elm;
|
|
if (ns) addNS(thunk.data, thunk.children, thunk.sel);
|
|
}
|
|
|
|
function init(thunk: VNode): void {
|
|
const cur = thunk.data as VNodeData;
|
|
const vnode = (cur.fn as any)(...cur.args!);
|
|
copyToThunk(vnode, thunk);
|
|
}
|
|
|
|
function prepatch(oldVnode: VNode, thunk: VNode): void {
|
|
let i: number;
|
|
const old = oldVnode.data as VNodeData;
|
|
const cur = thunk.data as VNodeData;
|
|
const oldArgs = old.args;
|
|
const args = cur.args;
|
|
if (old.fn !== cur.fn || (oldArgs as any).length !== (args as any).length) {
|
|
copyToThunk((cur.fn as any)(...args!), thunk);
|
|
return;
|
|
}
|
|
for (i = 0; i < (args as any).length; ++i) {
|
|
if ((oldArgs as any)[i] !== (args as any)[i]) {
|
|
copyToThunk((cur.fn as any)(...args!), thunk);
|
|
return;
|
|
}
|
|
}
|
|
copyToThunk(oldVnode, thunk);
|
|
}
|
|
|
|
export const thunk = function thunk(
|
|
sel: string,
|
|
key?: any,
|
|
fn?: any,
|
|
args?: any
|
|
): VNode {
|
|
if (args === undefined) {
|
|
args = fn;
|
|
fn = key;
|
|
key = undefined;
|
|
}
|
|
return h(sel, {
|
|
key: key,
|
|
hook: { init, prepatch },
|
|
fn: fn,
|
|
args: args,
|
|
});
|
|
} as ThunkFn;
|
|
|