-
Notifications
You must be signed in to change notification settings - Fork 0
/
be-prop-slotting.ts
112 lines (100 loc) · 3.44 KB
/
be-prop-slotting.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
import {BE, propDefaults, propInfo} from 'be-enhanced/BE.js';
import {BEConfig} from 'be-enhanced/types';
import {XE} from 'xtal-element/XE.js';
import {Actions, AllProps, AP, PAP, ProPAP, POA, PropSlotRule} from './types';
import {register} from 'be-hive/register.js';
import {getRemoteEl} from 'be-linked/getRemoteEl.js';
import {getSignalVal} from 'be-linked/getSignalVal.js';
import {getRemoteProp, getLocalSignal} from 'be-linked/defaults.js';
export class BePropSlotting extends BE<AP, Actions, HTMLSlotElement> implements Actions{
#hydrated: WeakSet<Element> = new WeakSet();
#abortControllers: Array<AbortController> = [];
detach(detachedElement: Element): void {
for(const ac of this.#abortControllers){
ac.abort();
}
}
static override get beConfig(){
return {
parse: true,
parseAndCamelize: true,
isParsedProp: 'isParsed'
} as BEConfig;
}
async noAttrs(self: this): ProPAP {
return {
propSlotRules: []
};
}
async onCamelized(self: this) {
const {of, Of} = self;
let propSlotRules: Array<PropSlotRule> = [];
if((of || Of) !== undefined){
const {prsOf} = await import('./prsOf.js');
propSlotRules = prsOf(self);
}
return {
propSlotRules
}
}
hydrate(self: this): POA{
const {enhancedElement} = self;
return [{},
{getProps: {on: 'slotchange', of: enhancedElement, doInit: true}}
]
}
async getProps(self: this, e?: Event){
const {propSlotRules, enhancedElement} = self;
const assignedElements = enhancedElement.assignedElements();
console.log({assignedElements, e});
for(const assignedElement of assignedElements){
if(this.#hydrated.has(assignedElement)) continue;
this.#hydrated.add(assignedElement);
const remoteProp = getRemoteProp(assignedElement);
const remoteEl = await getRemoteEl(enhancedElement, '/', remoteProp);
const lightChildSignal = await getLocalSignal(assignedElement, true);
const {signal, type} = lightChildSignal;
const fn = () => {
//TODO: this is creating a difficult to garbage collect reference to remoteEl, eventTarget
const srcVal = getSignalVal(signal);
(<any>remoteEl)[remoteProp] = srcVal;
}
const ab = new AbortController();
this.#abortControllers.push(ab);
signal.addEventListener(type, e => {
fn();
}, {signal: ab.signal});
fn();
}
return {resolved: true};
}
}
export interface BePropSlotting extends AllProps{}
const tagName = 'be-prop-slotting';
const ifWantsToBe = 'prop-slotting';
const upgrade = 'slot';
const xe = new XE<AP, Actions>({
config: {
tagName,
isEnh: true,
propDefaults:{
...propDefaults,
},
propInfo: {
...propInfo,
},
actions: {
noAttrs: {
ifAllOf: ['isParsed'],
ifNoneOf: ['of', 'Of']
},
onCamelized: {
ifAllOf: ['isParsed'],
ifAtLeastOneOf: ['of', 'Of']
},
hydrate: 'propSlotRules'
}
},
superclass: BePropSlotting
});
register(ifWantsToBe, upgrade, tagName);