@thi.ng/hdom 9.1.27 → 9.2.1
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 +19 -19
- package/api.d.ts +204 -229
- package/diff.d.ts +5 -4
- package/diff.js +5 -4
- package/package.json +23 -16
- package/start.d.ts +31 -34
- package/start.js +31 -34
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2022-
|
|
3
|
+
- **Last updated**: 2022-12-20T16:33:11Z
|
|
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
|
+
## [9.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/hdom@9.2.0) (2022-12-16)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- fix [#358](https://github.com/thi-ng/umbrella/issues/358) add "completed" project status, update pkgs/readmes ([d35fa52](https://github.com/thi-ng/umbrella/commit/d35fa52))
|
|
17
|
+
|
|
12
18
|
### [9.1.6](https://github.com/thi-ng/umbrella/tree/@thi.ng/hdom@9.1.6) (2022-04-07)
|
|
13
19
|
|
|
14
20
|
#### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
<!-- This file is generated - DO NOT EDIT! -->
|
|
2
2
|
|
|
3
|
-
# 
|
|
3
|
+
# 
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@thi.ng/hdom)
|
|
6
6
|

|
|
7
|
-
[](https://mastodon.thi.ng/@toxi)
|
|
8
8
|
|
|
9
9
|
This project is part of the
|
|
10
10
|
[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo.
|
|
11
11
|
|
|
12
|
+
**Update 12/2022: This package is considered completed and no longer being
|
|
13
|
+
updated with new features. Please consider using
|
|
14
|
+
[@thi.ng/rdom](https://github.com/thi-ng/umbrella/tree/develop/packages/rdom)
|
|
15
|
+
instead...**
|
|
16
|
+
|
|
12
17
|
- [About](#about)
|
|
13
18
|
- [Status](#status)
|
|
14
19
|
- [Support packages](#support-packages)
|
|
20
|
+
- [Related packages](#related-packages)
|
|
15
21
|
- [Blog posts](#blog-posts)
|
|
16
22
|
- [Installation](#installation)
|
|
17
23
|
- [Dependencies](#dependencies)
|
|
@@ -52,13 +58,11 @@ This project is part of the
|
|
|
52
58
|
- [\_\_skip](#__skip)
|
|
53
59
|
- [Benchmarks](#benchmarks)
|
|
54
60
|
- [Authors](#authors)
|
|
55
|
-
- [Maintainer](#maintainer)
|
|
56
|
-
- [Contributors](#contributors)
|
|
57
61
|
- [License](#license)
|
|
58
62
|
|
|
59
63
|
## About
|
|
60
64
|
|
|
61
|
-
Lightweight vanilla ES6 UI component trees with customizable branch-local behaviors
|
|
65
|
+
Lightweight vanilla ES6 UI component trees with customizable branch-local behaviors
|
|
62
66
|
|
|
63
67
|
Lightweight UI component tree definition syntax, DOM creation and
|
|
64
68
|
differential updates using only vanilla JS data structures (arrays,
|
|
@@ -98,7 +102,7 @@ Benefits:
|
|
|
98
102
|
|
|
99
103
|
## Status
|
|
100
104
|
|
|
101
|
-
**
|
|
105
|
+
**COMPLETED** - no further development planned
|
|
102
106
|
|
|
103
107
|
[Search or submit any issues for this package](https://github.com/thi-ng/umbrella/issues?q=%5Bhdom%5D+in%3Atitle)
|
|
104
108
|
|
|
@@ -108,6 +112,10 @@ Benefits:
|
|
|
108
112
|
- [@thi.ng/hdom-components](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom-components) - Raw, skinnable UI & SVG components for [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom)
|
|
109
113
|
- [@thi.ng/hdom-mock](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom-mock) - Mock base implementation for [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom) API
|
|
110
114
|
|
|
115
|
+
## Related packages
|
|
116
|
+
|
|
117
|
+
- [@thi.ng/rdom](https://github.com/thi-ng/umbrella/tree/develop/packages/rdom) - Lightweight, reactive, VDOM-less UI/DOM components with async lifecycle and [@thi.ng/hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup) compatible
|
|
118
|
+
|
|
111
119
|
### Blog posts
|
|
112
120
|
|
|
113
121
|
- [How to UI in 2018](https://medium.com/@thi.ng/how-to-ui-in-2018-ac2ae02acdf3)
|
|
@@ -129,11 +137,8 @@ ES module import:
|
|
|
129
137
|
|
|
130
138
|
For Node.js REPL:
|
|
131
139
|
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
node --experimental-repl-await
|
|
135
|
-
|
|
136
|
-
> const hdom = await import("@thi.ng/hdom");
|
|
140
|
+
```js
|
|
141
|
+
const hdom = await import("@thi.ng/hdom");
|
|
137
142
|
```
|
|
138
143
|
|
|
139
144
|
You can use the
|
|
@@ -1239,13 +1244,8 @@ Some stress test benchmarks are here:
|
|
|
1239
1244
|
|
|
1240
1245
|
## Authors
|
|
1241
1246
|
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
- Karsten Schmidt ([@postspectacular](https://github.com/postspectacular))
|
|
1245
|
-
|
|
1246
|
-
### Contributors
|
|
1247
|
-
|
|
1248
|
-
- Kevin Nolan ([@allforabit](https://github.com/allforabit))
|
|
1247
|
+
- [Karsten Schmidt](https://thi.ng) (Main author)
|
|
1248
|
+
- [Kevin Nolan](https://github.com/allforabit)
|
|
1249
1249
|
|
|
1250
1250
|
If this project contributes to an academic publication, please cite it as:
|
|
1251
1251
|
|
|
@@ -1260,4 +1260,4 @@ If this project contributes to an academic publication, please cite it as:
|
|
|
1260
1260
|
|
|
1261
1261
|
## License
|
|
1262
1262
|
|
|
1263
|
-
© 2015 - 2022 Karsten Schmidt // Apache
|
|
1263
|
+
© 2015 - 2022 Karsten Schmidt // Apache License 2.0
|
package/api.d.ts
CHANGED
|
@@ -1,88 +1,83 @@
|
|
|
1
1
|
import type { IObjectOf } from "@thi.ng/api";
|
|
2
2
|
export interface ILifecycle {
|
|
3
3
|
/**
|
|
4
|
-
* Component init method. Called with the actual DOM element, hdom
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* Component init method. Called with the actual DOM element, hdom user
|
|
5
|
+
* context and any other args when the component is first used, but
|
|
6
|
+
* **after** `render()` has been called once already AND all of the
|
|
7
|
+
* components children have been realized. Therefore, if any children have
|
|
8
|
+
* their own `init` lifecycle method, these hooks will be executed before
|
|
9
|
+
* that of the parent.
|
|
10
10
|
*/
|
|
11
11
|
init?(el: Element, ctx: any, ...args: any[]): void;
|
|
12
12
|
/**
|
|
13
|
-
* Returns the hdom tree of this component.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* has already been initialized via `init`. This is the only
|
|
13
|
+
* Returns the hdom tree of this component. Note: Always will be called
|
|
14
|
+
* first (prior to `init`/`release`) to obtain the actual component
|
|
15
|
+
* definition used for diffing. Therefore might have to include checks if
|
|
16
|
+
* any local state has already been initialized via `init`. This is the only
|
|
18
17
|
* mandatory method which MUST be implemented.
|
|
19
18
|
*
|
|
20
|
-
* `render` is executed before `init` because `normalizeTree()`
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* `
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* wrapped as `["span", "foo"]`. If no `init` or `release` are
|
|
31
|
-
* used, this requirement is relaxed.
|
|
19
|
+
* `render` is executed before `init` because `normalizeTree()` must obtain
|
|
20
|
+
* the component's hdom tree first before it can determine if an `init` is
|
|
21
|
+
* necessary. `init` itself will be called from `diffTree`, `createDOM` or
|
|
22
|
+
* `hydrateDOM()` in a later phase of processing.
|
|
23
|
+
*
|
|
24
|
+
* `render` should ALWAYS return an array or another function, else the
|
|
25
|
+
* component's `init` or `release` fns will NOT be able to be called later.
|
|
26
|
+
* E.g. If the return value of `render` evaluates as a string or number, the
|
|
27
|
+
* return value should be wrapped as `["span", "foo"]`. If no `init` or
|
|
28
|
+
* `release` are used, this requirement is relaxed.
|
|
32
29
|
*/
|
|
33
30
|
render(ctx: any, ...args: any[]): any;
|
|
34
31
|
/**
|
|
35
|
-
* Called when the underlying DOM of this component is removed
|
|
36
|
-
*
|
|
32
|
+
* Called when the underlying DOM of this component is removed (or
|
|
33
|
+
* replaced). Intended for cleanup tasks.
|
|
37
34
|
*/
|
|
38
35
|
release?(ctx: any, ...args: any[]): void;
|
|
39
36
|
}
|
|
40
37
|
export interface HDOMBehaviorAttribs {
|
|
41
38
|
/**
|
|
42
|
-
* HDOM behavior control attribute. If true (default), the element
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
39
|
+
* HDOM behavior control attribute. If true (default), the element will be
|
|
40
|
+
* fully processed by `diffTree()`. If false, no diff will be computed and
|
|
41
|
+
* the `replaceChild()` operation will be called in the currently active
|
|
42
|
+
* hdom target implementation.
|
|
46
43
|
*/
|
|
47
44
|
__diff?: boolean;
|
|
48
45
|
/**
|
|
49
|
-
* HDOM behavior control attribute. If true, the element will not be
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* children are the same (type) as when the attribute is disabled
|
|
60
|
-
* (i.e. when `__skip` is falsy).
|
|
46
|
+
* HDOM behavior control attribute. If true, the element will not be diffed
|
|
47
|
+
* and simply skipped. IMPORTANT: This attribute is only intended for cases
|
|
48
|
+
* when a component / tree branch should not be updated, but MUST NEVER be
|
|
49
|
+
* enabled when that component is first included in the tree. Doing so will
|
|
50
|
+
* result in undefined future behavior.
|
|
51
|
+
*
|
|
52
|
+
* Note, skipped elements and their children are being normalized, but are
|
|
53
|
+
* ignored during diffing. Therefore, if this attribute is enabled the
|
|
54
|
+
* element should either have no children OR the children are the same
|
|
55
|
+
* (type) as when the attribute is disabled (i.e. when `__skip` is falsy).
|
|
61
56
|
*/
|
|
62
57
|
__skip?: boolean;
|
|
63
58
|
/**
|
|
64
|
-
* HDOM behavior control attribute. If present, the element and all
|
|
65
|
-
*
|
|
66
|
-
*
|
|
59
|
+
* HDOM behavior control attribute. If present, the element and all of its
|
|
60
|
+
* children will be processed by the given `HDOMImplementation` instead of
|
|
61
|
+
* the default implementation.
|
|
67
62
|
*/
|
|
68
63
|
__impl?: HDOMImplementation<any>;
|
|
69
64
|
/**
|
|
70
|
-
* HDOM behavior control attribute. If `false`, the current
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* `
|
|
65
|
+
* HDOM behavior control attribute. If `false`, the current element's
|
|
66
|
+
* children will not be normalized. Use this when you're sure that all
|
|
67
|
+
* children are already in canonical format (incl. `key` attributes). See
|
|
68
|
+
* `normalizeTree()` for details.
|
|
74
69
|
*/
|
|
75
70
|
__normalize?: boolean;
|
|
76
71
|
/**
|
|
77
|
-
* HDOM behavior control attribute. If `false`, hdom will not
|
|
78
|
-
*
|
|
79
|
-
*
|
|
72
|
+
* HDOM behavior control attribute. If `false`, hdom will not attempt to
|
|
73
|
+
* call `release()` lifecycle methods on this element or any of its
|
|
74
|
+
* children.
|
|
80
75
|
*/
|
|
81
76
|
__release?: boolean;
|
|
82
77
|
/**
|
|
83
|
-
* Currently only used by
|
|
84
|
-
* `false`, the element and its children will be
|
|
85
|
-
* serialized result.
|
|
78
|
+
* Currently only used by [`thi.ng/hiccup`](https://thi.ng/hiccup). No
|
|
79
|
+
* relevance for hdom. If `false`, the element and its children will be
|
|
80
|
+
* omitted from the serialized result.
|
|
86
81
|
*/
|
|
87
82
|
__serialize?: boolean;
|
|
88
83
|
}
|
|
@@ -102,46 +97,45 @@ export interface HDOMOpts {
|
|
|
102
97
|
*/
|
|
103
98
|
root?: Element | string;
|
|
104
99
|
/**
|
|
105
|
-
* Arbitrary user context object, passed to all component functions
|
|
106
|
-
*
|
|
100
|
+
* Arbitrary user context object, passed to all component functions embedded
|
|
101
|
+
* in the tree.
|
|
107
102
|
*/
|
|
108
103
|
ctx?: any;
|
|
109
104
|
/**
|
|
110
|
-
* Attempts to auto-expand/deref the given keys in the user supplied
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* rstreams etc.). This feature can
|
|
115
|
-
* contexts linked to the main app state, e.g.
|
|
116
|
-
* provided by
|
|
105
|
+
* Attempts to auto-expand/deref the given keys in the user supplied context
|
|
106
|
+
* object (`ctx` option) prior to *each* tree normalization. All of these
|
|
107
|
+
* values should implement the
|
|
108
|
+
* [`IDeref`](https://docs.thi.ng/umbrella/api/interfaces/IDeref.html)
|
|
109
|
+
* interface (e.g. atoms, cursors, views, rstreams etc.). This feature can
|
|
110
|
+
* be used to define dynamic contexts linked to the main app state, e.g.
|
|
111
|
+
* using derived views provided by [`thi.ng/atom`](https://thi.ng/atom).
|
|
117
112
|
*
|
|
118
113
|
* @defaultValue none
|
|
119
114
|
*/
|
|
120
115
|
autoDerefKeys: PropertyKey[];
|
|
121
116
|
/**
|
|
122
|
-
* If true, each elements will receive an auto-generated
|
|
123
|
-
*
|
|
117
|
+
* If true, each elements will receive an auto-generated `key` attribute
|
|
118
|
+
* (unless one already exists).
|
|
124
119
|
*
|
|
125
120
|
* @defaultValue true
|
|
126
121
|
*/
|
|
127
122
|
keys?: boolean;
|
|
128
123
|
/**
|
|
129
|
-
* If true, all text content will be wrapped in `<span>`
|
|
130
|
-
*
|
|
131
|
-
* or <text> elements.
|
|
124
|
+
* If true, all text content will be wrapped in `<span>` elements. Spans
|
|
125
|
+
* will never be created inside <option>, <textarea> or <text> elements.
|
|
132
126
|
*
|
|
133
127
|
* @defaultValue true
|
|
134
128
|
*/
|
|
135
129
|
span?: boolean;
|
|
136
130
|
/**
|
|
137
|
-
* If true, the first frame will only be used to inject event
|
|
138
|
-
*
|
|
131
|
+
* If true, the first frame will only be used to inject event listeners,
|
|
132
|
+
* using the `hydrateDOM()` function.
|
|
139
133
|
*
|
|
140
|
-
* *Important:* Enabling this option assumes that an equivalent DOM
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
134
|
+
* *Important:* Enabling this option assumes that an equivalent DOM (minus
|
|
135
|
+
* event listeners) already exists (e.g. generated via SSR / hiccup's
|
|
136
|
+
* `serialize()`) when hdom's `start()` function is called. Any other
|
|
137
|
+
* discrepancies between the pre-existing DOM and the hdom trees will cause
|
|
138
|
+
* undefined behavior.
|
|
145
139
|
*
|
|
146
140
|
* @defaultValue false
|
|
147
141
|
*/
|
|
@@ -152,43 +146,40 @@ export interface HDOMOpts {
|
|
|
152
146
|
[id: string]: any;
|
|
153
147
|
}
|
|
154
148
|
/**
|
|
155
|
-
* This interface defines the underlying target update operations used
|
|
156
|
-
*
|
|
157
|
-
* be used as general purpose tree
|
|
158
|
-
* mechanism, rather than being restricted to
|
|
159
|
-
* DOM. See {@link DEFAULT_IMPL} for the default
|
|
160
|
-
* with the latter. Note: Depending on use case and tree
|
|
161
|
-
* not all of these methods are required.
|
|
149
|
+
* This interface defines the underlying target update operations used by
|
|
150
|
+
* `diffTree()` and `createDOM()`. It allows
|
|
151
|
+
* [`thi.ng/hdom`](https://thi.ng/hdom) to be used as general purpose tree
|
|
152
|
+
* definition & differential update mechanism, rather than being restricted to
|
|
153
|
+
* only work with an HTML DOM. See {@link DEFAULT_IMPL} for the default
|
|
154
|
+
* implementations dealing with the latter. Note: Depending on use case and tree
|
|
155
|
+
* configuration, not all of these methods are required.
|
|
162
156
|
*
|
|
163
|
-
* Custom element-local implementations can also be provided via the
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* custom operations.
|
|
157
|
+
* Custom element-local implementations can also be provided via the special
|
|
158
|
+
* `__impl` hdom element/component attribute. In this case the element itself
|
|
159
|
+
* and all of its children will be processed with those custom operations.
|
|
167
160
|
*/
|
|
168
161
|
export interface HDOMImplementation<T> {
|
|
169
162
|
/**
|
|
170
|
-
* Normalizes given hdom tree, expands Emmet-style tags, embedded
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
* component tree to `diffTree()`. Recursively expands given hiccup
|
|
191
|
-
* component tree into its canonical form:
|
|
163
|
+
* Normalizes given hdom tree, expands Emmet-style tags, embedded iterables,
|
|
164
|
+
* component functions, component objects with life cycle methods and
|
|
165
|
+
* injects `key` attributes for `diffTree()` to later identify changes in
|
|
166
|
+
* nesting order. During normalization any embedded component functions are
|
|
167
|
+
* called with the given (optional) user `ctx` object as first argument. For
|
|
168
|
+
* further details of the default implementation, please see
|
|
169
|
+
* `normalizeTree()` in `normalize.ts`.
|
|
170
|
+
*
|
|
171
|
+
* Implementations MUST check for the presence of the `__impl` control
|
|
172
|
+
* attribute on each branch. If given, the current implementation MUST
|
|
173
|
+
* delegate to the `normalizeTree()` method of the specified implementation
|
|
174
|
+
* and not descent into that branch further itself.
|
|
175
|
+
*
|
|
176
|
+
* Furthermore, if (and only if) an element has the `__normalize` control
|
|
177
|
+
* attrib set to `false`, the normalization of that element's children MUST
|
|
178
|
+
* be skipped.
|
|
179
|
+
*
|
|
180
|
+
* Calling this function is a prerequisite before passing a component tree
|
|
181
|
+
* to `diffTree()`. Recursively expands given hiccup component tree into its
|
|
182
|
+
* canonical form:
|
|
192
183
|
*
|
|
193
184
|
* ```
|
|
194
185
|
* ["tag", { attribs }, ...body]
|
|
@@ -196,68 +187,62 @@ export interface HDOMImplementation<T> {
|
|
|
196
187
|
*
|
|
197
188
|
* - resolves Emmet-style tags (e.g. from `div#id.foo.bar`)
|
|
198
189
|
* - adds missing attribute objects (and `key` attribs)
|
|
199
|
-
* - merges Emmet-style classes with additional `class` attrib
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
* - evaluates embedded functions and replaces them with their
|
|
190
|
+
* - merges Emmet-style classes with additional `class` attrib values (if
|
|
191
|
+
* given), e.g. `["div.foo", { class: "bar" }]` => `["div", {class: "bar
|
|
192
|
+
* foo" }]`
|
|
193
|
+
* - evaluates embedded functions and replaces them with their result
|
|
194
|
+
* - calls the `render` life cycle method on component objects and uses
|
|
203
195
|
* result
|
|
204
|
-
* - calls the `render` life cycle method on component objects and
|
|
205
|
-
* uses result
|
|
206
196
|
* - consumes iterables and normalizes their individual values
|
|
207
|
-
* - calls `deref()` on elements implementing the `IDeref` interface
|
|
197
|
+
* - calls `deref()` on elements implementing the `IDeref` interface and
|
|
198
|
+
* uses returned results
|
|
199
|
+
* - calls `toHiccup()` on elements implementing the `IToHiccup` interface
|
|
208
200
|
* and uses returned results
|
|
209
|
-
* - calls
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
* relaxed.
|
|
229
|
-
*
|
|
230
|
-
* See `normalizeElement` (normalize.ts) for further details about
|
|
231
|
-
* the canonical element form.
|
|
201
|
+
* - calls `.toString()` on any other non-component value and by default
|
|
202
|
+
* wraps it in `["span", x]`. The only exceptions to this are: `button`,
|
|
203
|
+
* `option`, `textarea` and SVG `text` elements, for which spans are never
|
|
204
|
+
* created.
|
|
205
|
+
*
|
|
206
|
+
* Additionally, unless the `keys` option is explicitly set to false, an
|
|
207
|
+
* unique `key` attribute is created for each node in the tree. This
|
|
208
|
+
* attribute is used by `diffTree` to determine if a changed node can be
|
|
209
|
+
* patched or will need to be moved, replaced or removed.
|
|
210
|
+
*
|
|
211
|
+
* In terms of life cycle methods: `render` should ALWAYS return an array or
|
|
212
|
+
* another function, else the component's `init` or `release` fns will NOT
|
|
213
|
+
* be able to be called. E.g. If the return value of `render` evaluates as a
|
|
214
|
+
* string or number, it should be wrapped as `["span", "foo"]` or an
|
|
215
|
+
* equivalent wrapper node. If no `init` or `release` methods are used, this
|
|
216
|
+
* requirement is relaxed.
|
|
217
|
+
*
|
|
218
|
+
* See `normalizeElement` (normalize.ts) for further details about the
|
|
219
|
+
* canonical element form.
|
|
232
220
|
*
|
|
233
221
|
* @param tree - component tree
|
|
234
222
|
* @param opts - hdom config options
|
|
235
223
|
*/
|
|
236
224
|
normalizeTree(opts: Partial<HDOMOpts>, tree: any): any[];
|
|
237
225
|
/**
|
|
238
|
-
* Realizes the given hdom tree in the target below the `parent`
|
|
239
|
-
*
|
|
240
|
-
*
|
|
226
|
+
* Realizes the given hdom tree in the target below the `parent` node, e.g.
|
|
227
|
+
* in the case of the browser DOM, creates all required DOM elements encoded
|
|
228
|
+
* by the given hdom tree.
|
|
241
229
|
*
|
|
242
230
|
* @remarks
|
|
243
|
-
* If `parent` is null the result tree won't be attached to any
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
* implementation MUST delegate to the `createTree()` method of the
|
|
259
|
-
* specified implementation and not descent into that branch further
|
|
260
|
-
* itself.
|
|
231
|
+
* If `parent` is null the result tree won't be attached to any parent. If
|
|
232
|
+
* `child` is given, the new elements will be inserted at given child index.
|
|
233
|
+
*
|
|
234
|
+
* For any components with `init` life cycle methods, the implementation
|
|
235
|
+
* MUST call `init` with the created element, the user provided context
|
|
236
|
+
* (obtained from `opts`) and any other args. `createTree()` returns the
|
|
237
|
+
* created root element(s) - usually only a single one, but can be an array
|
|
238
|
+
* of elements, if the provided tree is an iterable of multiple roots. The
|
|
239
|
+
* default implementation creates text nodes for non-component values.
|
|
240
|
+
* Returns `parent` if tree is `null` or `undefined`.
|
|
241
|
+
*
|
|
242
|
+
* Implementations MUST check for the presence of the `__impl` control
|
|
243
|
+
* attribute on each branch. If given, the current implementation MUST
|
|
244
|
+
* delegate to the `createTree()` method of the specified implementation and
|
|
245
|
+
* not descent into that branch further itself.
|
|
261
246
|
*
|
|
262
247
|
* @param parent - parent node in target (e.g. DOM element)
|
|
263
248
|
* @param tree - component tree
|
|
@@ -266,18 +251,16 @@ export interface HDOMImplementation<T> {
|
|
|
266
251
|
*/
|
|
267
252
|
createTree(opts: Partial<HDOMOpts>, parent: T, tree: any, child?: number, init?: boolean): T | T[];
|
|
268
253
|
/**
|
|
269
|
-
* Takes a target root element and normalized hdom tree, then walks
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
* specified implementation and not descent into that branch further
|
|
280
|
-
* itself.
|
|
254
|
+
* Takes a target root element and normalized hdom tree, then walks tree and
|
|
255
|
+
* initializes any event listeners and components with life cycle `init`
|
|
256
|
+
* methods. Assumes that an equivalent "DOM" (minus listeners) already
|
|
257
|
+
* exists when this function is called. Any other discrepancies between the
|
|
258
|
+
* pre-existing DOM and the hdom tree might cause undefined behavior.
|
|
259
|
+
*
|
|
260
|
+
* Implementations MUST check for the presence of the `__impl` control
|
|
261
|
+
* attribute on each branch. If given, the current implementation MUST
|
|
262
|
+
* delegate to the `hydrateTree()` method of the specified implementation
|
|
263
|
+
* and not descent into that branch further itself.
|
|
281
264
|
*
|
|
282
265
|
* @param opts - hdom config options
|
|
283
266
|
* @param parent - parent node in target (e.g. DOM element)
|
|
@@ -286,42 +269,39 @@ export interface HDOMImplementation<T> {
|
|
|
286
269
|
*/
|
|
287
270
|
hydrateTree(opts: Partial<HDOMOpts>, parent: T, tree: any, child?: number): void;
|
|
288
271
|
/**
|
|
289
|
-
* Takes an `HDOMOpts` options object, a `parent` element and two
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
* implementation).
|
|
272
|
+
* Takes an `HDOMOpts` options object, a `parent` element and two normalized
|
|
273
|
+
* hiccup trees, `prev` and `curr`. Recursively computes diff between both
|
|
274
|
+
* trees and applies any necessary changes to reflect `curr` tree, based on
|
|
275
|
+
* the differences to `prev`, in target (browser DOM when using the
|
|
276
|
+
* `DEFAULT_IMPL` implementation).
|
|
295
277
|
*
|
|
296
278
|
* All target modification operations are delegated to the given
|
|
297
|
-
* implementation. `diffTree()` merely manages which elements or
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
* Implementations MUST check for the presence of the `__impl`
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
279
|
+
* implementation. `diffTree()` merely manages which elements or attributes
|
|
280
|
+
* need to be created, updated or removed and this NEVER involves any form
|
|
281
|
+
* of tracking of the actual underlying target data structure (e.g. the real
|
|
282
|
+
* browser DOM). hdom in general and `diffTree()` specifically are
|
|
283
|
+
* stateless. The only state available is implicitly defined by the two
|
|
284
|
+
* trees given (prev / curr).
|
|
285
|
+
*
|
|
286
|
+
* Implementations MUST check for the presence of the `__impl` control
|
|
287
|
+
* attribute on each branch. If present AND different than the current
|
|
288
|
+
* implementation, the latter MUST delegate to the `diffTree()` method of
|
|
289
|
+
* the specified implementation and not descent into that branch further
|
|
290
|
+
* itself.
|
|
309
291
|
*
|
|
310
292
|
* Furthermore, if (and only if) an element has the `__diff` control
|
|
311
293
|
* attribute set to `false`, then:
|
|
312
294
|
*
|
|
313
|
-
* 1) Computing the difference between old & new branch MUST be
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
* (
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
* 3) Call the current implementation's `replaceChild()` method to
|
|
324
|
-
* replace the old element / branch with the new one.
|
|
295
|
+
* 1) Computing the difference between old & new branch MUST be skipped
|
|
296
|
+
* 2) The implementation MUST recursively call any `release` life cycle
|
|
297
|
+
* methods present anywhere in the current `prev` tree (branch). The
|
|
298
|
+
* recursive release process itself is implemented by the exported
|
|
299
|
+
* `releaseDeep()` function in `diff.ts`. Custom implementations are
|
|
300
|
+
* encouraged to reuse this, since that function also takes care of
|
|
301
|
+
* handling the `__release` attrib: if the attrib is present and set to
|
|
302
|
+
* false, `releaseDeep()` will not descend into the branch any further.
|
|
303
|
+
* 3) Call the current implementation's `replaceChild()` method to replace
|
|
304
|
+
* the old element / branch with the new one.
|
|
325
305
|
*
|
|
326
306
|
* @param opts - hdom config options
|
|
327
307
|
* @param parent - parent node in target (e.g. DOM element)
|
|
@@ -331,15 +311,13 @@ export interface HDOMImplementation<T> {
|
|
|
331
311
|
*/
|
|
332
312
|
diffTree(opts: Partial<HDOMOpts>, parent: T, prev: any[], curr: any[], child?: number): void;
|
|
333
313
|
/**
|
|
334
|
-
* Creates a new element of type `tag` with optional `attribs`. If
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
* target DOM node.
|
|
314
|
+
* Creates a new element of type `tag` with optional `attribs`. If `parent`
|
|
315
|
+
* is not `null`, the new element will be inserted as child at given
|
|
316
|
+
* `insert` index. If `child` is missing, the element will be appended to
|
|
317
|
+
* the `parent`'s list of children. Returns new target DOM node.
|
|
339
318
|
*
|
|
340
|
-
* In the default implementation, if `tag` is a known SVG element
|
|
341
|
-
*
|
|
342
|
-
* namespace.
|
|
319
|
+
* In the default implementation, if `tag` is a known SVG element name, the
|
|
320
|
+
* new element will be created with the proper SVG XML namespace.
|
|
343
321
|
*
|
|
344
322
|
* @param parent - parent node in target (e.g. DOM element)
|
|
345
323
|
* @param tag - element tag name
|
|
@@ -348,8 +326,8 @@ export interface HDOMImplementation<T> {
|
|
|
348
326
|
*/
|
|
349
327
|
createElement(parent: T, tag: string, attribs?: any, child?: number): T;
|
|
350
328
|
/**
|
|
351
|
-
* Creates and appends the given `content` as text child node to
|
|
352
|
-
*
|
|
329
|
+
* Creates and appends the given `content` as text child node to `parent` in
|
|
330
|
+
* the target.
|
|
353
331
|
*
|
|
354
332
|
* @param parent - parent node in target (e.g. DOM element)
|
|
355
333
|
* @param content - content
|
|
@@ -357,15 +335,14 @@ export interface HDOMImplementation<T> {
|
|
|
357
335
|
createTextElement(parent: T, content: string): T;
|
|
358
336
|
/**
|
|
359
337
|
* Attempts to find an element with the given `id` attribute in the
|
|
360
|
-
* implementation's tree. In the default implementation this is
|
|
361
|
-
*
|
|
338
|
+
* implementation's tree. In the default implementation this is merely
|
|
339
|
+
* delegated to `document.getElementById()`.
|
|
362
340
|
*
|
|
363
341
|
* @param id - element ID
|
|
364
342
|
*/
|
|
365
343
|
getElementById(id: string): T | null;
|
|
366
344
|
/**
|
|
367
|
-
* A (potentially) optimized version of these 2 operations in
|
|
368
|
-
* sequence:
|
|
345
|
+
* A (potentially) optimized version of these 2 operations in sequence:
|
|
369
346
|
*
|
|
370
347
|
* ```
|
|
371
348
|
* impl.removeChild(parent, child);
|
|
@@ -392,11 +369,10 @@ export interface HDOMImplementation<T> {
|
|
|
392
369
|
*/
|
|
393
370
|
removeChild(parent: T, i: number): void;
|
|
394
371
|
/**
|
|
395
|
-
* Sets the given attribute `id` to new `value`. Note: `value`
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
* for details.
|
|
372
|
+
* Sets the given attribute `id` to new `value`. Note: `value` itself can be
|
|
373
|
+
* a function and if so, the default behavior is to call this function with
|
|
374
|
+
* the also provided `attribs` object to allow it to produce a derived
|
|
375
|
+
* value. See `setAttrib()` (dom.ts) for details.
|
|
400
376
|
*
|
|
401
377
|
* @param element - target element / DOM node
|
|
402
378
|
* @param id - attribute name
|
|
@@ -405,9 +381,9 @@ export interface HDOMImplementation<T> {
|
|
|
405
381
|
*/
|
|
406
382
|
setAttrib(element: T, id: string, value: any, attribs?: any): void;
|
|
407
383
|
/**
|
|
408
|
-
* Removes given `attribs` from target `element`. The attributes
|
|
409
|
-
*
|
|
410
|
-
*
|
|
384
|
+
* Removes given `attribs` from target `element`. The attributes from the
|
|
385
|
+
* previous tree are provided for reference (e.g. to be able to remove DOM
|
|
386
|
+
* event listeners).
|
|
411
387
|
*
|
|
412
388
|
* @param element - target element / DOM node
|
|
413
389
|
* @param attribs - element attributes
|
|
@@ -415,12 +391,11 @@ export interface HDOMImplementation<T> {
|
|
|
415
391
|
*/
|
|
416
392
|
removeAttribs(element: T, attribs: string[], prevAttribs: any): void;
|
|
417
393
|
/**
|
|
418
|
-
* Sets target `element`'s text / body content. Note: In the default
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
* `normalizeTree()`.
|
|
394
|
+
* Sets target `element`'s text / body content. Note: In the default browser
|
|
395
|
+
* DOM implementation, this will implicitly remove any existing child
|
|
396
|
+
* elements in the target. In practice this function is only applied to
|
|
397
|
+
* `["span"]` elements, since (by default) any body content is automatically
|
|
398
|
+
* wrapped in such by `normalizeTree()`.
|
|
424
399
|
*
|
|
425
400
|
* @param element - target element / DOM node
|
|
426
401
|
* @param value - new content
|
package/diff.d.ts
CHANGED
|
@@ -35,10 +35,11 @@ export declare const diffAttributes: <T>(impl: HDOMImplementation<T>, el: T, pre
|
|
|
35
35
|
*/
|
|
36
36
|
export declare const releaseTree: (tree: any) => void;
|
|
37
37
|
/**
|
|
38
|
-
* Customized version
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
* Customized version
|
|
39
|
+
* [`equiv()`](https://docs.thi.ng/umbrella/equiv/functions/equiv.html) which
|
|
40
|
+
* takes `__diff` attributes into account (at any nesting level). If an hdom
|
|
41
|
+
* element's attribute object contains `__diff: false`, the object will ALWAYS
|
|
42
|
+
* be considered unequal, even if all other attributes in the object are
|
|
42
43
|
* equivalent.
|
|
43
44
|
*
|
|
44
45
|
* @param a -
|
package/diff.js
CHANGED
|
@@ -221,10 +221,11 @@ const extractEquivElements = (edits) => {
|
|
|
221
221
|
return equiv;
|
|
222
222
|
};
|
|
223
223
|
/**
|
|
224
|
-
* Customized version
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
224
|
+
* Customized version
|
|
225
|
+
* [`equiv()`](https://docs.thi.ng/umbrella/equiv/functions/equiv.html) which
|
|
226
|
+
* takes `__diff` attributes into account (at any nesting level). If an hdom
|
|
227
|
+
* element's attribute object contains `__diff: false`, the object will ALWAYS
|
|
228
|
+
* be considered unequal, even if all other attributes in the object are
|
|
228
229
|
* equivalent.
|
|
229
230
|
*
|
|
230
231
|
* @param a -
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/hdom",
|
|
3
|
-
"version": "9.1
|
|
3
|
+
"version": "9.2.1",
|
|
4
4
|
"description": "Lightweight vanilla ES6 UI component trees with customizable branch-local behaviors",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -21,7 +21,10 @@
|
|
|
21
21
|
"url": "https://patreon.com/thing_umbrella"
|
|
22
22
|
}
|
|
23
23
|
],
|
|
24
|
-
"author": "Karsten Schmidt
|
|
24
|
+
"author": "Karsten Schmidt (https://thi.ng)",
|
|
25
|
+
"contributors": [
|
|
26
|
+
"Kevin Nolan (https://github.com/allforabit)"
|
|
27
|
+
],
|
|
25
28
|
"license": "Apache-2.0",
|
|
26
29
|
"scripts": {
|
|
27
30
|
"build": "yarn clean && tsc --declaration",
|
|
@@ -34,23 +37,23 @@
|
|
|
34
37
|
"test": "testament test"
|
|
35
38
|
},
|
|
36
39
|
"dependencies": {
|
|
37
|
-
"@thi.ng/api": "^8.
|
|
38
|
-
"@thi.ng/checks": "^3.3.
|
|
39
|
-
"@thi.ng/diff": "^5.1.
|
|
40
|
-
"@thi.ng/equiv": "^2.1.
|
|
41
|
-
"@thi.ng/errors": "^2.2.
|
|
42
|
-
"@thi.ng/hiccup": "^4.2.
|
|
43
|
-
"@thi.ng/logger": "^1.4.
|
|
44
|
-
"@thi.ng/prefixes": "^2.1.
|
|
40
|
+
"@thi.ng/api": "^8.6.1",
|
|
41
|
+
"@thi.ng/checks": "^3.3.5",
|
|
42
|
+
"@thi.ng/diff": "^5.1.20",
|
|
43
|
+
"@thi.ng/equiv": "^2.1.15",
|
|
44
|
+
"@thi.ng/errors": "^2.2.6",
|
|
45
|
+
"@thi.ng/hiccup": "^4.2.27",
|
|
46
|
+
"@thi.ng/logger": "^1.4.5",
|
|
47
|
+
"@thi.ng/prefixes": "^2.1.15"
|
|
45
48
|
},
|
|
46
49
|
"devDependencies": {
|
|
47
|
-
"@microsoft/api-extractor": "^7.33.
|
|
48
|
-
"@thi.ng/atom": "^5.1.
|
|
49
|
-
"@thi.ng/testament": "^0.3.
|
|
50
|
+
"@microsoft/api-extractor": "^7.33.7",
|
|
51
|
+
"@thi.ng/atom": "^5.1.26",
|
|
52
|
+
"@thi.ng/testament": "^0.3.7",
|
|
50
53
|
"rimraf": "^3.0.2",
|
|
51
54
|
"tools": "^0.0.1",
|
|
52
|
-
"typedoc": "^0.23.
|
|
53
|
-
"typescript": "^4.
|
|
55
|
+
"typedoc": "^0.23.22",
|
|
56
|
+
"typescript": "^4.9.4"
|
|
54
57
|
},
|
|
55
58
|
"keywords": [
|
|
56
59
|
"array",
|
|
@@ -122,7 +125,11 @@
|
|
|
122
125
|
"url": "https://medium.com/@thi.ng/of-umbrellas-transducers-reactive-streams-mushrooms-pt-1-a8717ce3a170"
|
|
123
126
|
}
|
|
124
127
|
],
|
|
128
|
+
"related": [
|
|
129
|
+
"rdom"
|
|
130
|
+
],
|
|
131
|
+
"status": "completed",
|
|
125
132
|
"year": 2015
|
|
126
133
|
},
|
|
127
|
-
"gitHead": "
|
|
134
|
+
"gitHead": "7b2af448da8a63fb21704a79cc4cdf1f3d7d7a64\n"
|
|
128
135
|
}
|
package/start.d.ts
CHANGED
|
@@ -1,43 +1,40 @@
|
|
|
1
1
|
import type { HDOMImplementation, HDOMOpts } from "./api.js";
|
|
2
2
|
/**
|
|
3
|
-
* Takes an hiccup tree (array, function or component object w/ life
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
3
|
+
* Takes an hiccup tree (array, function or component object w/ life cycle
|
|
4
|
+
* methods) and an optional object of DOM update options. Starts RAF update
|
|
5
|
+
* loop, in each iteration first normalizing given tree, then computing diff to
|
|
6
|
+
* previous frame's tree and applying any changes to the real DOM. The `ctx`
|
|
7
|
+
* option can be used for passing arbitrary config data or state down into the
|
|
8
|
+
* hiccup component tree. Any embedded component function in the tree will
|
|
9
|
+
* receive this context object (shallow copy) as first argument, as will life
|
|
10
|
+
* cycle methods in component objects. If the `autoDerefKeys` option is given,
|
|
11
|
+
* attempts to auto-expand/deref the given keys in the user supplied context
|
|
12
|
+
* object (`ctx` option) prior to *each* tree normalization. All of these values
|
|
13
|
+
* should implement the
|
|
14
|
+
* [`IDeref`](https://docs.thi.ng/umbrella/api/interfaces/IDeref.html) interface
|
|
15
|
+
* (e.g. atoms, cursors, views, rstreams etc.). This feature can be used to
|
|
16
|
+
* define dynamic contexts linked to the main app state, e.g. using derived
|
|
17
|
+
* views provided by [`thi.ng/atom`](https://thi.ng/atom).
|
|
18
18
|
*
|
|
19
|
-
* **Selective updates**: No updates will be applied if the given hiccup
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* usual. Any number of frames may be skipped this way.
|
|
19
|
+
* **Selective updates**: No updates will be applied if the given hiccup tree is
|
|
20
|
+
* `undefined` or `null` or a root component function returns no value. This way
|
|
21
|
+
* a given root function can do some state handling of its own and implement
|
|
22
|
+
* fail-fast checks to determine no DOM updates are necessary, save effort
|
|
23
|
+
* re-creating a new hiccup tree and request skipping DOM updates via this
|
|
24
|
+
* function. In this case, the previous DOM tree is kept around until the root
|
|
25
|
+
* function returns a tree again, which then is diffed and applied against the
|
|
26
|
+
* previous tree kept as usual. Any number of frames may be skipped this way.
|
|
28
27
|
*
|
|
29
|
-
* **Important:** Unless the `hydrate` option is enabled, the parent
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* discrepancies between the pre-existing DOM and the hdom trees will
|
|
28
|
+
* **Important:** Unless the `hydrate` option is enabled, the parent element
|
|
29
|
+
* given is assumed to have NO children at the time when `start()` is called.
|
|
30
|
+
* Since hdom does NOT track the real DOM, the resulting changes will result in
|
|
31
|
+
* potentially undefined behavior if the parent element wasn't empty. Likewise,
|
|
32
|
+
* if `hydrate` is enabled, it is assumed that an equivalent DOM (minus
|
|
33
|
+
* listeners) already exists (i.e. generated via SSR) when `start()` is called.
|
|
34
|
+
* Any other discrepancies between the pre-existing DOM and the hdom trees will
|
|
37
35
|
* cause undefined behavior.
|
|
38
36
|
*
|
|
39
|
-
* Returns a function, which when called, immediately cancels the update
|
|
40
|
-
* loop.
|
|
37
|
+
* Returns a function, which when called, immediately cancels the update loop.
|
|
41
38
|
*
|
|
42
39
|
* @param tree - hiccup DOM tree
|
|
43
40
|
* @param opts - options
|
package/start.js
CHANGED
|
@@ -2,44 +2,41 @@ import { derefContext } from "@thi.ng/hiccup/deref";
|
|
|
2
2
|
import { DEFAULT_IMPL } from "./default.js";
|
|
3
3
|
import { resolveRoot } from "./resolve.js";
|
|
4
4
|
/**
|
|
5
|
-
* Takes an hiccup tree (array, function or component object w/ life
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
5
|
+
* Takes an hiccup tree (array, function or component object w/ life cycle
|
|
6
|
+
* methods) and an optional object of DOM update options. Starts RAF update
|
|
7
|
+
* loop, in each iteration first normalizing given tree, then computing diff to
|
|
8
|
+
* previous frame's tree and applying any changes to the real DOM. The `ctx`
|
|
9
|
+
* option can be used for passing arbitrary config data or state down into the
|
|
10
|
+
* hiccup component tree. Any embedded component function in the tree will
|
|
11
|
+
* receive this context object (shallow copy) as first argument, as will life
|
|
12
|
+
* cycle methods in component objects. If the `autoDerefKeys` option is given,
|
|
13
|
+
* attempts to auto-expand/deref the given keys in the user supplied context
|
|
14
|
+
* object (`ctx` option) prior to *each* tree normalization. All of these values
|
|
15
|
+
* should implement the
|
|
16
|
+
* [`IDeref`](https://docs.thi.ng/umbrella/api/interfaces/IDeref.html) interface
|
|
17
|
+
* (e.g. atoms, cursors, views, rstreams etc.). This feature can be used to
|
|
18
|
+
* define dynamic contexts linked to the main app state, e.g. using derived
|
|
19
|
+
* views provided by [`thi.ng/atom`](https://thi.ng/atom).
|
|
20
20
|
*
|
|
21
|
-
* **Selective updates**: No updates will be applied if the given hiccup
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* usual. Any number of frames may be skipped this way.
|
|
21
|
+
* **Selective updates**: No updates will be applied if the given hiccup tree is
|
|
22
|
+
* `undefined` or `null` or a root component function returns no value. This way
|
|
23
|
+
* a given root function can do some state handling of its own and implement
|
|
24
|
+
* fail-fast checks to determine no DOM updates are necessary, save effort
|
|
25
|
+
* re-creating a new hiccup tree and request skipping DOM updates via this
|
|
26
|
+
* function. In this case, the previous DOM tree is kept around until the root
|
|
27
|
+
* function returns a tree again, which then is diffed and applied against the
|
|
28
|
+
* previous tree kept as usual. Any number of frames may be skipped this way.
|
|
30
29
|
*
|
|
31
|
-
* **Important:** Unless the `hydrate` option is enabled, the parent
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* discrepancies between the pre-existing DOM and the hdom trees will
|
|
30
|
+
* **Important:** Unless the `hydrate` option is enabled, the parent element
|
|
31
|
+
* given is assumed to have NO children at the time when `start()` is called.
|
|
32
|
+
* Since hdom does NOT track the real DOM, the resulting changes will result in
|
|
33
|
+
* potentially undefined behavior if the parent element wasn't empty. Likewise,
|
|
34
|
+
* if `hydrate` is enabled, it is assumed that an equivalent DOM (minus
|
|
35
|
+
* listeners) already exists (i.e. generated via SSR) when `start()` is called.
|
|
36
|
+
* Any other discrepancies between the pre-existing DOM and the hdom trees will
|
|
39
37
|
* cause undefined behavior.
|
|
40
38
|
*
|
|
41
|
-
* Returns a function, which when called, immediately cancels the update
|
|
42
|
-
* loop.
|
|
39
|
+
* Returns a function, which when called, immediately cancels the update loop.
|
|
43
40
|
*
|
|
44
41
|
* @param tree - hiccup DOM tree
|
|
45
42
|
* @param opts - options
|