@thi.ng/rdom 0.13.3 → 0.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -1
- package/README.md +1 -1
- package/api.js +0 -1
- package/checks.js +8 -23
- package/compile.js +57 -87
- package/component.js +143 -133
- package/dom.js +197 -373
- package/event.js +14 -51
- package/idgen.js +4 -2
- package/klist.js +105 -161
- package/list.js +64 -108
- package/object.js +34 -97
- package/package.json +14 -11
- package/promise.js +24 -40
- package/replace.js +30 -58
- package/scheduler.js +36 -51
- package/sub.js +49 -47
- package/switch.js +66 -135
- package/wrap.js +31 -47
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2023-12-
|
|
3
|
+
- **Last updated**: 2023-12-11T10:07:09Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,12 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
### [0.13.4](https://github.com/thi-ng/umbrella/tree/@thi.ng/rdom@0.13.4) (2023-12-11)
|
|
13
|
+
|
|
14
|
+
#### ♻️ Refactoring
|
|
15
|
+
|
|
16
|
+
- update boolean attrib handling in setAttrib() ([96a21ab](https://github.com/thi-ng/umbrella/commit/96a21ab))
|
|
17
|
+
|
|
12
18
|
### [0.13.3](https://github.com/thi-ng/umbrella/tree/@thi.ng/rdom@0.13.3) (2023-12-09)
|
|
13
19
|
|
|
14
20
|
#### 🩹 Bug fixes
|
package/README.md
CHANGED
package/api.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/checks.js
CHANGED
|
@@ -1,25 +1,10 @@
|
|
|
1
1
|
import { implementsFunction } from "@thi.ng/checks/implements-function";
|
|
2
2
|
import { COMMENT } from "@thi.ng/hiccup/api";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* @param tree
|
|
12
|
-
*/
|
|
13
|
-
export const isComment = (tree) => tree[0] === COMMENT;
|
|
14
|
-
/**
|
|
15
|
-
* Returns true if given value has a {@link IComponent.mount} function.
|
|
16
|
-
*
|
|
17
|
-
* @param x
|
|
18
|
-
*/
|
|
19
|
-
export const isComponent = (x) => implementsFunction(x, "mount");
|
|
20
|
-
/**
|
|
21
|
-
* Returns true if given value is a DOM element.
|
|
22
|
-
*
|
|
23
|
-
* @param x
|
|
24
|
-
*/
|
|
25
|
-
export const isElement = (x) => x instanceof Element;
|
|
3
|
+
const isComment = (tree) => tree[0] === COMMENT;
|
|
4
|
+
const isComponent = (x) => implementsFunction(x, "mount");
|
|
5
|
+
const isElement = (x) => x instanceof Element;
|
|
6
|
+
export {
|
|
7
|
+
isComment,
|
|
8
|
+
isComponent,
|
|
9
|
+
isElement
|
|
10
|
+
};
|
package/compile.js
CHANGED
|
@@ -6,101 +6,71 @@ import { $el, $remove, $tree } from "./dom.js";
|
|
|
6
6
|
import { SCHEDULER } from "./scheduler.js";
|
|
7
7
|
import { $SubA, $sub } from "./sub.js";
|
|
8
8
|
import { $wrapEl, $wrapText } from "./wrap.js";
|
|
9
|
-
|
|
10
|
-
* Compiles a tree of components given in any supported format incl. reactive
|
|
11
|
-
* state values into a single, nested {@link IComponent}.
|
|
12
|
-
*
|
|
13
|
-
* @remarks
|
|
14
|
-
* Supported formats/values:
|
|
15
|
-
*
|
|
16
|
-
* - hiccup component trees, i.e. `["tag#id.class", attribs, [...]]`
|
|
17
|
-
* - {@link IComponent} instances
|
|
18
|
-
* - pre-existing DOM elements
|
|
19
|
-
* - [`ISubscribable`](https://docs.thi.ng/umbrella/rstream/interfaces/ISubscribable.html)
|
|
20
|
-
* instances
|
|
21
|
-
* - [`IDeref`](https://docs.thi.ng/umbrella/api/interfaces/IDeref.html)
|
|
22
|
-
* instances
|
|
23
|
-
*
|
|
24
|
-
* Any other value type will be wrapped in a `<span>` element. Reactive
|
|
25
|
-
* `ISubscribable` values can be used as element attributes or element
|
|
26
|
-
* body/children. For the former, a subscription will be added to update the
|
|
27
|
-
* target attribute. If used as element body, the reactive value will be wrapped
|
|
28
|
-
* using a {@link $sub} `<span>` with the value as its reactive body.
|
|
29
|
-
*
|
|
30
|
-
* @param tree -
|
|
31
|
-
*/
|
|
32
|
-
export const $compile = (tree) => isArray(tree)
|
|
33
|
-
? isComplexComponent(tree)
|
|
34
|
-
? complexComponent(tree)
|
|
35
|
-
: basicComponent(tree)
|
|
36
|
-
: isComponent(tree)
|
|
37
|
-
? tree
|
|
38
|
-
: isSubscribable(tree)
|
|
39
|
-
? $sub(tree, "span")
|
|
40
|
-
: tree instanceof Element
|
|
41
|
-
? $wrapEl(tree)
|
|
42
|
-
: $wrapText("span", null, tree);
|
|
9
|
+
const $compile = (tree) => isArray(tree) ? isComplexComponent(tree) ? complexComponent(tree) : basicComponent(tree) : isComponent(tree) ? tree : isSubscribable(tree) ? $sub(tree, "span") : tree instanceof Element ? $wrapEl(tree) : $wrapText("span", null, tree);
|
|
43
10
|
const walk = (f, x, path = []) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
11
|
+
if (isPlainObject(x)) {
|
|
12
|
+
for (const k in x) {
|
|
13
|
+
walk(f, x[k], [...path, k]);
|
|
48
14
|
}
|
|
49
|
-
|
|
15
|
+
}
|
|
16
|
+
f(x, path);
|
|
50
17
|
};
|
|
51
18
|
const isComplexComponent = (x) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
19
|
+
if (isPlainObject(x)) {
|
|
20
|
+
for (const k in x) {
|
|
21
|
+
if (isComplexComponent(x[k]))
|
|
22
|
+
return true;
|
|
57
23
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
24
|
+
} else if (isArray(x)) {
|
|
25
|
+
for (let i = 0, n = x.length; i < n; i++) {
|
|
26
|
+
if (isComplexComponent(x[i]))
|
|
27
|
+
return true;
|
|
63
28
|
}
|
|
64
|
-
|
|
29
|
+
}
|
|
30
|
+
return isSubscribable(x) || isComponent(x) || isElement(x);
|
|
65
31
|
};
|
|
66
32
|
const complexComponent = (tree) => ({
|
|
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
|
-
|
|
33
|
+
async mount(parent, index = -1) {
|
|
34
|
+
this.subs = [];
|
|
35
|
+
walk((x, path) => {
|
|
36
|
+
isSubscribable(x) && this.subs.push(x.subscribe(new $SubA(this, path)));
|
|
37
|
+
}, tree[1]);
|
|
38
|
+
this.children = [];
|
|
39
|
+
this.el = $el(tree[0], tree[1], null, parent, index);
|
|
40
|
+
for (let i = 2; i < tree.length; i++) {
|
|
41
|
+
const child = $compile(tree[i]);
|
|
42
|
+
child.mount(this.el, i - 2);
|
|
43
|
+
this.children.push(child);
|
|
44
|
+
}
|
|
45
|
+
return this.el;
|
|
46
|
+
},
|
|
47
|
+
async unmount() {
|
|
48
|
+
SCHEDULER.cancel(this);
|
|
49
|
+
if (this.children) {
|
|
50
|
+
for (let c of this.children) {
|
|
51
|
+
await c.unmount();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
this.subs && this.subs.forEach((s) => s.unsubscribe());
|
|
55
|
+
$remove(this.el);
|
|
56
|
+
this.children = void 0;
|
|
57
|
+
this.subs = void 0;
|
|
58
|
+
this.el = void 0;
|
|
59
|
+
},
|
|
60
|
+
update() {
|
|
61
|
+
}
|
|
96
62
|
});
|
|
97
63
|
const basicComponent = (tree) => ({
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
64
|
+
async mount(parent, index = -1) {
|
|
65
|
+
return this.el = await $tree(tree, parent, index);
|
|
66
|
+
},
|
|
67
|
+
async unmount() {
|
|
68
|
+
$remove(this.el);
|
|
69
|
+
this.el = void 0;
|
|
70
|
+
},
|
|
71
|
+
update() {
|
|
72
|
+
}
|
|
106
73
|
});
|
|
74
|
+
export {
|
|
75
|
+
$compile
|
|
76
|
+
};
|
package/component.js
CHANGED
|
@@ -1,135 +1,145 @@
|
|
|
1
1
|
import { $compile } from "./compile.js";
|
|
2
|
-
import {
|
|
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
|
-
|
|
2
|
+
import {
|
|
3
|
+
$attribs,
|
|
4
|
+
$clear,
|
|
5
|
+
$comment,
|
|
6
|
+
$el,
|
|
7
|
+
$html,
|
|
8
|
+
$moveTo,
|
|
9
|
+
$remove,
|
|
10
|
+
$style,
|
|
11
|
+
$text,
|
|
12
|
+
$tree
|
|
13
|
+
} from "./dom.js";
|
|
14
|
+
class Component {
|
|
15
|
+
el;
|
|
16
|
+
async unmount() {
|
|
17
|
+
this.$remove();
|
|
18
|
+
this.el = void 0;
|
|
19
|
+
}
|
|
20
|
+
// @ts-ignore args
|
|
21
|
+
update(state) {
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Syntax sugar for {@link $el}, using this component's
|
|
25
|
+
* {@link IComponent.el} as default `parent`.
|
|
26
|
+
*
|
|
27
|
+
* @param tag
|
|
28
|
+
* @param attribs
|
|
29
|
+
* @param body
|
|
30
|
+
* @param parent
|
|
31
|
+
* @param idx
|
|
32
|
+
*/
|
|
33
|
+
$el(tag, attribs, body, parent = this.el, idx) {
|
|
34
|
+
return $el(tag, attribs, body, parent, idx);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Syntax sugar for {@link $comment}, creates a new comment DOM node using
|
|
38
|
+
* this component's {@link IComponent.el} as default `parent`.
|
|
39
|
+
*
|
|
40
|
+
* @param body
|
|
41
|
+
* @param parent
|
|
42
|
+
* @param idx
|
|
43
|
+
*/
|
|
44
|
+
$comment(body, parent = this.el, idx) {
|
|
45
|
+
return $comment(body, parent, idx);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Syntax sugar for {@link $clear}, using this component's
|
|
49
|
+
* {@link IComponent.el} as default element to clear.
|
|
50
|
+
*
|
|
51
|
+
* @param el
|
|
52
|
+
*/
|
|
53
|
+
$clear(el = this.el) {
|
|
54
|
+
return $clear(el);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Same as {@link $compile}.
|
|
58
|
+
*
|
|
59
|
+
* @param tree
|
|
60
|
+
*/
|
|
61
|
+
$compile(tree) {
|
|
62
|
+
return $compile(tree);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Same as {@link $tree}.
|
|
66
|
+
*
|
|
67
|
+
* @param tree
|
|
68
|
+
* @param root
|
|
69
|
+
* @param index
|
|
70
|
+
*/
|
|
71
|
+
$tree(tree, root = this.el, index) {
|
|
72
|
+
return $tree(tree, root, index);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Syntax sugar for {@link $text}, using this component's
|
|
76
|
+
* {@link IComponent.el} as default element to edit.
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* If using the default element, assumes `this.el` is an existing
|
|
80
|
+
* `HTMLElement`.
|
|
81
|
+
*
|
|
82
|
+
* @param body
|
|
83
|
+
* @param el
|
|
84
|
+
*/
|
|
85
|
+
$text(body, el = this.el) {
|
|
86
|
+
$text(el, body);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Syntax sugar for {@link $html}, using this component's
|
|
90
|
+
* {@link IComponent.el} as default element to edit.
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* If using the default element, assumes `this.el` is an existing
|
|
94
|
+
* `HTMLElement` or `SVGElement`.
|
|
95
|
+
*
|
|
96
|
+
* @param body
|
|
97
|
+
* @param el
|
|
98
|
+
*/
|
|
99
|
+
$html(body, el = this.el) {
|
|
100
|
+
$html(el, body);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Syntax sugar for {@link $attribs}, using this component's
|
|
104
|
+
* {@link IComponent.el} as default element to edit.
|
|
105
|
+
*
|
|
106
|
+
* @param attribs
|
|
107
|
+
* @param el
|
|
108
|
+
*/
|
|
109
|
+
$attribs(attribs, el = this.el) {
|
|
110
|
+
$attribs(el, attribs);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Syntax sugar for {@link $style}, using this component's
|
|
114
|
+
* {@link IComponent.el} as default element to edit.
|
|
115
|
+
*
|
|
116
|
+
* @param rules
|
|
117
|
+
* @param el
|
|
118
|
+
*/
|
|
119
|
+
$style(rules, el = this.el) {
|
|
120
|
+
$style(el, rules);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Syntax sugar for {@link $remove}, using this component's
|
|
124
|
+
* {@link IComponent.el} as default element to remove.
|
|
125
|
+
*
|
|
126
|
+
* @param el
|
|
127
|
+
*/
|
|
128
|
+
$remove(el = this.el) {
|
|
129
|
+
$remove(el);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Syntax sugar for {@link $moveTo}, using this component's
|
|
133
|
+
* {@link IComponent.el} as default element to migrate.
|
|
134
|
+
*
|
|
135
|
+
* @param newParent
|
|
136
|
+
* @param el
|
|
137
|
+
* @param idx
|
|
138
|
+
*/
|
|
139
|
+
$moveTo(newParent, el = this.el, idx) {
|
|
140
|
+
$moveTo(newParent, el, idx);
|
|
141
|
+
}
|
|
135
142
|
}
|
|
143
|
+
export {
|
|
144
|
+
Component
|
|
145
|
+
};
|