-
Notifications
You must be signed in to change notification settings - Fork 52
Expand file tree
/
Copy pathupdate.js
More file actions
133 lines (118 loc) · 3.52 KB
/
Copy pathupdate.js
File metadata and controls
133 lines (118 loc) · 3.52 KB
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
import {
ATTRIBUTE as TEMPLATE_ATTRIBUTE,
COMMENT as TEMPLATE_COMMENT,
TEXT as TEMPLATE_TEXT,
COMPONENT as TEMPLATE_COMPONENT,
Node, Text, Fragment,
props, children,
} from '../dom/ish.js';
import { isArray, keys } from '../utils.js';
const get = node => {
if (node.props === props) node.props = {};
return node.props;
};
const set = (props, name, value) => {
if (value == null) delete props[name];
else props[name] = value;
};
export const ARIA = 0;
const aria = (node, values) => {
const props = get(node);
for (const key in values) {
const name = key === 'role' ? key : `aria-${key}`;
const value = values[key];
set(props, name, value);
}
if (keys(props).length === 0) node.props = props;
};
export const ATTRIBUTE = 1;
const attribute = name => (node, value) => {
const props = get(node);
set(props, name, value);
if (keys(props).length === 0) node.props = props;
};
export const COMMENT = 2;
export const comment = (node, value) => {
const { children } = node.parent;
const i = children.indexOf(node);
if (isArray(value)) {
const fragment = new Fragment;
fragment.children = value;
value = fragment;
}
else if (!(value instanceof Node)) value = new Text(value == null ? '' : value);
children[i] = value;
};
export const COMPONENT = 3;
const component = (node, value) => [node, value];
export const DATA = 4;
const data = (node, values) => {
const props = get(node);
for (const key in values) {
const name = `data-${key}`;
const value = values[key];
set(props, name, value);
}
if (keys(props).length === 0) node.props = props;
};
export const DIRECT = 5;
const direct = name => (node, value) => {
const props = get(node);
set(props, name, value);
if (keys(props).length === 0) node.props = props;
};
export const DOTS = 6;
const dots = isComponent => (node, value) => {
if (isComponent) {
// TODO: assign props to component parameter
}
else {
// TODO: assign(node, value) ???
}
};
export const EVENT = 7;
const event = at => (node, value) => {
const props = get(node);
if (value == null) delete props[at];
else props[at] = value;
};
export const KEY = 8;
export const TEXT = 9;
const text = (node, value) => {
if (value == null) node.children = children;
else node.children = [new Text(value)];
};
export const TOGGLE = 10;
const toggle = name => (node, value) => {
const props = get(node);
if (!value) {
delete props[name];
if (keys(props).length === 0) node.props = props;
}
else props[name] = !!value;
};
export const update = (node, type, path, name) => {
switch (type) {
case TEMPLATE_COMPONENT: {
return [path, component, COMPONENT];
}
case TEMPLATE_COMMENT: {
return [path, comment, COMMENT];
}
case TEMPLATE_ATTRIBUTE: {
switch (name.at(0)) {
case '@': return [path, event(Symbol(name)), EVENT];
case '?': return [path, toggle(name.slice(1)), TOGGLE];
case '.': return name === '...' ?
[path, dots(node.type === TEMPLATE_COMPONENT), DOTS] :
[path, direct(name.slice(1)), DIRECT]
;
case 'a': if (name === 'aria') return [path, aria, ARIA];
case 'd': if (name === 'data') return [path, data, DATA];
case 'k': if (name === 'key') return [path, Object, KEY];
default: return [path, attribute(name), ATTRIBUTE];
}
}
case TEMPLATE_TEXT: return [path, text, TEXT];
}
};