-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstateBindings.js
82 lines (82 loc) · 3 KB
/
stateBindings.js
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
import { getConstructor, unwrapAccessor } from './utils.js';
export const stateBindings = {
'component': async ({node, component}) => {
if (component && getConstructor(component) === 'Component') {
node.replaceWith(component.fragment);
component.doOnMounts();
}
else node.remove();
},
'list': ({node, list}) => {
if (list && list.every(l => getConstructor(l) === 'Component')) {
const aggregate = new DocumentFragment();
const deferreds = list.flatMap(({applyDeferreds, doOnMounts}) => [applyDeferreds, doOnMounts]);
list.forEach(({fragment}) => {
aggregate.append(fragment);
});
node.replaceWith(aggregate);
deferreds.forEach(deferred => {deferred()});
} else node.remove();
},
'event': ({node, event, handler}) => {
node.addEventListener(event, handler);
},
'textinput': ({node, state}) => {
if (node.tagName === 'TEXTAREA') node.value = state.is();
else node.setAttribute('value', state.is());
},
'if': ({nodeArr, accessor, parentNode, initializing, siblings}) => {
const value = unwrapAccessor(accessor);
const inDocument = parentNode.isConnected && nodeArr.every(node => parentNode.contains(node));
if ((inDocument || initializing) && value === false) nodeArr.forEach(node => {node.remove()});
else if (!initializing && !inDocument && value === true) {
const {prev, next} = siblings;
const frag = new DocumentFragment();
nodeArr.forEach(node => {frag.appendChild(node)});
if (parentNode.contains(next)) parentNode.insertBefore(frag, next);
else if (parentNode.contains(prev)) parentNode.insertBefore(frag, prev.nextSibling);
}
},
'class': ({node, baseClassList, is}) => {
const result = is.evaluate();
const rawList = typeof result === 'string' ? result.split(' ') : Array.isArray(result) ? result : [];
const classList = rawList.filter(item => typeof item === 'string' && item !== '');
Array.from(node.classList).forEach(className => {node.classList.remove(className)});
[...baseClassList, ...classList].forEach(className => {node.classList.add(className)})
},
'attr': (({node, attr, accessor}) => {
let result;
switch (typeof accessor) {
case 'object':
switch(getConstructor(accessor)) {
case 'StateManager':
result = accessor.is();
break;
case 'Is':
result = accessor.evaluate();
break;
default:
break;
}
break;
case 'function':
result = accessor();
break;
case 'number':
case 'boolean':
result = accessor.toString();
break;
default:
result = accessor;
break;
}
if (['string', 'number'].includes(typeof result)) node.setAttribute(attr, result);
}),
'text': ({node, textMap}) => {
node.textContent = textMap.map(item => {
if (typeof item === 'string') return item;
else if (unwrapAccessor(item)) return unwrapAccessor(item);
else return '';
}).join('');
}
};