-
Notifications
You must be signed in to change notification settings - Fork 1
/
passactions.ts
69 lines (57 loc) · 2.15 KB
/
passactions.ts
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
import { toArray } from 'txstate-utils'
export interface SvelteActionReturnType<P> {
update?: (newParams: P) => void
destroy?: () => void
}
export type SvelteHTMLActionType<P = any> = (
node: HTMLElement,
params?: P
) => SvelteActionReturnType<P> | undefined
export type HTMLActionEntry<P = any> =
| SvelteHTMLActionType<P>
| [SvelteHTMLActionType<P>, P]
export type SvelteSVGActionType<P = any> = (
node: SVGElement,
params?: P
) => SvelteActionReturnType<P> | undefined
export type SVGActionEntry<P = any> =
| SvelteSVGActionType<P>
| [SvelteSVGActionType<P>, P]
export function passActions (node: HTMLElement, actions: HTMLActionEntry[]): SvelteActionReturnType<HTMLActionEntry[]>
export function passActions (node: SVGElement, actions: SVGActionEntry[]): SvelteActionReturnType<SVGActionEntry[]>
export function passActions (
node: HTMLElement & SVGElement,
actions: HTMLActionEntry[] | SVGActionEntry[]
) {
let actionReturns = new Map<HTMLActionEntry | SVGActionEntry, SvelteActionReturnType<any> | undefined>()
for (const actionEntry of actions ?? []) {
const [action, params] = toArray(actionEntry)
actionReturns.set(action, action(node, params))
}
return {
update (actions: HTMLActionEntry[] | SVGActionEntry[]) {
const newActionReturns = new Map<HTMLActionEntry | SVGActionEntry, SvelteActionReturnType<any> | undefined>()
// accept new actions and update actions we already had
for (const actionEntry of actions ?? []) {
const [action, params] = toArray(actionEntry)
if (actionReturns.has(action)) {
const existing = actionReturns.get(action)
newActionReturns.set(action, existing)
existing?.update?.(params)
} else {
newActionReturns.set(action, action(node, params))
}
}
// destroy any actions that were removed
for (const [action, actionReturn] of actionReturns.entries()) {
if (!newActionReturns.has(action)) actionReturn?.destroy?.()
}
actionReturns = newActionReturns
},
destroy () {
for (const actionReturn of actionReturns.values()) {
actionReturn?.destroy?.()
}
}
}
}