-
Notifications
You must be signed in to change notification settings - Fork 0
/
pass.ts
152 lines (148 loc) · 5.5 KB
/
pass.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import {AP, Link} from './types';
import {IBE} from 'be-enhanced/types';
import {findRealm} from 'trans-render/lib/findRealm.js';
import {getVal} from 'trans-render/lib/getVal.js';
import {setProp} from 'trans-render/lib/setProp.js';
export async function pass(ibe: IBE, downlink: Link): Promise<ET>{
const et = new ET();
const {enhancedElement} = ibe;
const {
upstreamCamelQry, skipInit, upstreamPropPath, localInstance,
downstreamPropPath, negate, translate, parseOption, handler,
conditionValue, newValue, on, debug, nudge, increment, passDirection,
enhancement, invoke, fire, toggle, assign, inferTriggerEvent
} = downlink;
let src: EventTarget | null = null;
let dest: Element;
let srcPropPath: string;
let destPropPath: string | undefined;
//let destEnhancement: string | undefined;
const upstreamRealm = await findRealm(enhancedElement, upstreamCamelQry);
//const downstreamInstance = localInstance === 'local' ? enhancedElement :
const downstreamInstance = enhancedElement;
switch(passDirection){
case 'towards':
src = upstreamRealm;
if(enhancement === undefined){
dest = downstreamInstance;
}else{
const {applyEnh} = await import('./applyEnh.js');
dest = await applyEnh(downstreamInstance, enhancement);
}
srcPropPath = upstreamPropPath;
destPropPath = downstreamPropPath;
break;
case 'away':
src = downstreamInstance;
srcPropPath = downstreamPropPath!;
destPropPath = upstreamPropPath;
dest = upstreamRealm as Element;
break;
}
if(src === null) throw 'bL.404';
const doPass = async (e?: Event) => {
if(debug) debugger;
switch(passDirection){
case 'away':
if(dest === null) dest = await findRealm(enhancedElement, upstreamCamelQry) as Element;
break;
}
if(increment){
const val = await getVal({host: dest}, destPropPath!);
const newVal = val + 1;
await setProp(dest, destPropPath!, newVal);
et.value = newVal;
}else if(handler !== undefined){
const objToAssign = await handler({
remoteInstance: upstreamRealm!,
$0: enhancedElement,
event: e,
});
Object.assign(dest, objToAssign);
et.value = objToAssign;
}else if(invoke !== undefined){
(<any>dest)[invoke](dest, src, e);
}else if(toggle){
const val = await getVal({host: dest}, destPropPath!);
const newVal = !val;
await setProp(dest, destPropPath!, newVal);
et.value = newVal;
}else if(assign){
const val = await getVal({host: src}, srcPropPath!);
if(typeof val === 'object'){
Object.assign(dest as any, val);
}
et.value = val;
}else{
let val = await getVal({host: src}, srcPropPath);
if(parseOption){
const {parseVal} = await import('./parseVal.js');
val = parseVal(val, parseOption);
}
if(negate) val = !val;
if(translate) val = Number(val) + translate;
if(conditionValue !== undefined){
if(val.toString() !== conditionValue.toString()) return;
if(newValue !== undefined) val = newValue;
}
if(destPropPath !== undefined){
await setProp(dest, destPropPath, val);
}
et.value = val;
}
if(fire !== undefined){
for(const fireInstance of fire){
dest.dispatchEvent(new Event(fireInstance));
}
}
}
if(!skipInit){
await doPass();
}
let upstreamPropName = downlink.upstreamPropName;
if(upstreamPropName === undefined && upstreamPropPath !== undefined){
upstreamPropName = upstreamPropPath.split('.')[0];
downlink.upstreamPropName = upstreamPropName;
}
if(on !== undefined || inferTriggerEvent){
let type = on;
const eventTarget = passDirection === 'towards' ? src : enhancedElement;
if(on === undefined){
if(eventTarget instanceof Element){
const {inferEvent} = await import('./inferEvent.js');
type = inferEvent(eventTarget);
}else{
type = upstreamPropName;
}
}
eventTarget.addEventListener(type!, async e => {
await doPass();
});
}else{
let propagator: EventTarget | null = null;
if(!(<any>src)._isPropagating){
import('be-propagating/be-propagating.js');
const aSrc = src as any;
const bePropagating = await aSrc.beEnhanced.whenResolved('be-propagating');
propagator = bePropagating.propagators.get('self') as EventTarget;
}else{
propagator = src;
}
propagator.addEventListener(upstreamPropName!, async e => {
await doPass();
});
}
if(nudge && src instanceof Element){
const {nudge} = await import('trans-render/lib/nudge.js');
nudge(src);
}
return et;
}
class ET extends EventTarget{
#value: any;
get value(){return this.#value;}
set value(nv: any){
this.#value = nv;
this.dispatchEvent(new Event('value'));
}
}