forked from sveltejs/language-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
event-handler.ts
80 lines (67 loc) · 2.52 KB
/
event-handler.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
70
71
72
73
74
75
76
77
78
79
80
import { Node } from 'estree-walker';
export class EventHandler {
private bubbledEvents = new Map<string, string | string[]>();
private callees: Array<{ name: string; parent: Node }> = [];
handleEventHandler(node: Node, parent: Node): void {
const eventName = node.name;
// pass-through/ bubble
if (!node.expression) {
if (parent.type === 'InlineComponent') {
if (parent.name !== 'svelte:self') {
this.handleEventHandlerBubble(parent, eventName);
}
return;
}
this.bubbledEvents.set(
eventName,
getEventDefExpressionForNonComponent(eventName, parent)
);
}
}
handleIdentifier(node: Node, parent: Node, prop: string): void {
if (prop === 'callee') {
this.callees.push({ name: node.name, parent });
}
}
getBubbledEvents() {
return this.bubbledEvents;
}
getDispatchedEventsForIdentifier(name: string) {
const eventNames = new Set<string>();
this.callees.forEach((callee) => {
if (callee.name === name) {
const [name] = callee.parent.arguments;
if (name.value !== undefined) {
eventNames.add(name.value);
}
}
});
return eventNames;
}
bubbledEventsAsStrings() {
return Array.from(this.bubbledEvents.entries()).map(eventMapEntryToString);
}
private handleEventHandlerBubble(parent: Node, eventName: string): void {
const componentEventDef = `__sveltets_1_instanceOf(${parent.name})`;
const exp = `__sveltets_1_bubbleEventDef(${componentEventDef}.$$events_def, '${eventName}')`;
const exist = this.bubbledEvents.get(eventName);
this.bubbledEvents.set(eventName, exist ? [].concat(exist, exp) : exp);
}
}
function getEventDefExpressionForNonComponent(eventName: string, ele: Node) {
switch (ele.type) {
case 'Element':
return `__sveltets_1_mapElementEvent('${eventName}')`;
case 'Body':
return `__sveltets_1_mapBodyEvent('${eventName}')`;
case 'Window':
return `__sveltets_1_mapWindowEvent('${eventName}')`;
default:
break;
}
}
function eventMapEntryToString([eventName, expression]: [string, string | string[]]) {
return `'${eventName}':${
Array.isArray(expression) ? `__sveltets_1_unionType(${expression.join(',')})` : expression
}`;
}