@thi.ng/hdom 9.2.0 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2022-12-16T12:52:25Z
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.
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
- * user context and any other args when the component is first used,
6
- * but **after** `render()` has been called once already AND all of
7
- * the components children have been realized. Therefore, if any
8
- * children have their own `init` lifecycle method, these hooks will
9
- * be executed before that of the parent.
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
- * Note: Always will be called first (prior to `init`/`release`)
15
- * to obtain the actual component definition used for diffing.
16
- * Therefore might have to include checks if any local state
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
- * must obtain the component's hdom tree first before it can
22
- * determine if an `init` is necessary. `init` itself will be
23
- * called from `diffTree`, `createDOM` or `hydrateDOM()` in a later
24
- * phase of processing.
25
- *
26
- * `render` should ALWAYS return an array or another function,
27
- * else the component's `init` or `release` fns will NOT be able
28
- * to be called later. E.g. If the return value of `render`
29
- * evaluates as a string or number, the return value should be
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
- * (or replaced). Intended for cleanup tasks.
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
- * will be fully processed by `diffTree()`. If false, no diff will
44
- * be computed and the `replaceChild()` operation will be called in
45
- * the currently active hdom target implementation.
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
- * diffed and simply skipped. IMPORTANT: This attribute is only
51
- * intended for cases when a component / tree branch should not be
52
- * updated, but MUST NEVER be enabled when that component is first
53
- * included in the tree. Doing so will result in undefined future
54
- * behavior.
55
- *
56
- * Note, skipped elements and their children are being normalized,
57
- * but are ignored during diffing. Therefore, if this attribute is
58
- * enabled the element should either have no children OR the
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
- * of its children will be processed by the given
66
- * `HDOMImplementation` instead of the default implementation.
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
- * element's children will not be normalized. Use this when you're
72
- * sure that all children are already in canonical format (incl.
73
- * `key` attributes). See `normalizeTree()` for details.
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
- * attempt to call `release()` lifecycle methods on this element or
79
- * any of its children.
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 {@link @thi.ng/hiccup# | @thi.ng/hiccup}. No relevance for hdom. If
84
- * `false`, the element and its children will be omitted from the
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
- * embedded in the tree.
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
- * context object (`ctx` option) prior to *each* tree normalization.
112
- * All of these values should implement the
113
- * {@link @thi.ng/api#IDeref} interface (e.g. atoms, cursors, views,
114
- * rstreams etc.). This feature can be used to define dynamic
115
- * contexts linked to the main app state, e.g. using derived views
116
- * provided by {@link @thi.ng/atom# | @thi.ng/atom}.
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
- * `key` attribute (unless one already exists).
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
- * elements. Spans will never be created inside <option>, <textarea>
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
- * listeners, using the `hydrateDOM()` function.
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
- * (minus event listeners) already exists (e.g. generated via SSR /
142
- * hiccup's `serialize()`) when hdom's `start()` function is called.
143
- * Any other discrepancies between the pre-existing DOM and the hdom
144
- * trees will cause undefined behavior.
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
- * by `diffTree()` and `createDOM()`. It allows {@link @thi.ng/hdom# | @thi.ng/hdom} to
157
- * be used as general purpose tree definition & differential update
158
- * mechanism, rather than being restricted to only work with an HTML
159
- * DOM. See {@link DEFAULT_IMPL} for the default implementations dealing
160
- * with the latter. Note: Depending on use case and tree configuration,
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
- * special `__impl` hdom element/component attribute. In this case the
165
- * element itself and all of its children will be processed with those
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
- * iterables, component functions, component objects with life cycle
172
- * methods and injects `key` attributes for `diffTree()` to later
173
- * identify changes in nesting order. During normalization any
174
- * embedded component functions are called with the given (optional)
175
- * user `ctx` object as first argument. For further details of the
176
- * default implementation, please see `normalizeTree()` in
177
- * `normalize.ts`.
178
- *
179
- * Implementations MUST check for the presence of the `__impl`
180
- * control attribute on each branch. If given, the current
181
- * implementation MUST delegate to the `normalizeTree()` method of
182
- * the specified implementation and not descent into that branch
183
- * further itself.
184
- *
185
- * Furthermore, if (and only if) an element has the `__normalize`
186
- * control attrib set to `false`, the normalization of that
187
- * element's children MUST be skipped.
188
- *
189
- * Calling this function is a prerequisite before passing a
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
- * values (if given), e.g. `["div.foo", { class: "bar" }]` =>
201
- * `["div", {class: "bar foo" }]`
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 `toHiccup()` on elements implementing the `IToHiccup`
210
- * interface and uses returned results
211
- * - calls `.toString()` on any other non-component value and by
212
- * default wraps it in `["span", x]`. The only exceptions to this
213
- * are: `button`, `option`, `textarea` and SVG `text` elements,
214
- * for which spans are never created.
215
- *
216
- * Additionally, unless the `keys` option is explicitly set to
217
- * false, an unique `key` attribute is created for each node in the
218
- * tree. This attribute is used by `diffTree` to determine if a
219
- * changed node can be patched or will need to be moved, replaced or
220
- * removed.
221
- *
222
- * In terms of life cycle methods: `render` should ALWAYS return an
223
- * array or another function, else the component's `init` or
224
- * `release` fns will NOT be able to be called. E.g. If the return
225
- * value of `render` evaluates as a string or number, it should be
226
- * wrapped as `["span", "foo"]` or an equivalent wrapper node. If no
227
- * `init` or `release` methods are used, this requirement is
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
- * node, e.g. in the case of the browser DOM, creates all required
240
- * DOM elements encoded by the given hdom tree.
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
- * parent. If `child` is given, the new elements will be inserted at
245
- * given child index.
246
- *
247
- * For any components with `init` life cycle methods, the
248
- * implementation MUST call `init` with the created element, the
249
- * user provided context (obtained from `opts`) and any other args.
250
- * `createTree()` returns the created root element(s) - usually only
251
- * a single one, but can be an array of elements, if the provided
252
- * tree is an iterable of multiple roots. The default implementation
253
- * creates text nodes for non-component values. Returns `parent` if
254
- * tree is `null` or `undefined`.
255
- *
256
- * Implementations MUST check for the presence of the `__impl`
257
- * control attribute on each branch. If given, the current
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
- * tree and initializes any event listeners and components with life
271
- * cycle `init` methods. Assumes that an equivalent "DOM" (minus
272
- * listeners) already exists when this function is called. Any other
273
- * discrepancies between the pre-existing DOM and the hdom tree
274
- * might cause undefined behavior.
275
- *
276
- * Implementations MUST check for the presence of the `__impl`
277
- * control attribute on each branch. If given, the current
278
- * implementation MUST delegate to the `hydrateTree()` method of the
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
- * normalized hiccup trees, `prev` and `curr`. Recursively computes
291
- * diff between both trees and applies any necessary changes to
292
- * reflect `curr` tree, based on the differences to `prev`, in
293
- * target (browser DOM when using the `DEFAULT_IMPL`
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
- * attributes need to be created, updated or removed and this NEVER
299
- * involves any form of tracking of the actual underlying target
300
- * data structure (e.g. the real browser DOM). hdom in general and
301
- * `diffTree()` specifically are stateless. The only state available
302
- * is implicitly defined by the two trees given (prev / curr).
303
- *
304
- * Implementations MUST check for the presence of the `__impl`
305
- * control attribute on each branch. If present AND different than
306
- * the current implementation, the latter MUST delegate to the
307
- * `diffTree()` method of the specified implementation and not
308
- * descent into that branch further itself.
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
- * skipped
315
- * 2) The implementation MUST recursively call any `release` life
316
- * cycle methods present anywhere in the current `prev` tree
317
- * (branch). The recursive release process itself is implemented
318
- * by the exported `releaseDeep()` function in `diff.ts`. Custom
319
- * implementations are encouraged to reuse this, since that
320
- * function also takes care of handling the `__release` attrib:
321
- * if the attrib is present and set to false, `releaseDeep()`
322
- * will not descend into the branch any further.
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
- * `parent` is not `null`, the new element will be inserted as child
336
- * at given `insert` index. If `child` is missing, the element will
337
- * be appended to the `parent`'s list of children. Returns new
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
- * name, the new element will be created with the proper SVG XML
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
- * `parent` in the target.
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
- * merely delegated to `document.getElementById()`.
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
- * itself can be a function and if so, the default behavior is to
397
- * call this function with the also provided `attribs` object to
398
- * allow it to produce a derived value. See `setAttrib()` (dom.ts)
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
- * from the previous tree are provided for reference (e.g. to be
410
- * able to remove DOM event listeners).
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
- * browser DOM implementation, this will implicitly remove any
420
- * existing child elements in the target. In practice this function
421
- * is only applied to `["span"]` elements, since (by default) any
422
- * body content is automatically wrapped in such by
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 {@link @thi.ng/equiv#equiv} which takes `__diff`
39
- * attributes into account (at any nesting level). If an hdom element's
40
- * attribute object contains `__diff: false`, the object will ALWAYS be
41
- * considered unequal, even if all other attributes in the object are
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 {@link @thi.ng/equiv#equiv} which takes `__diff`
225
- * attributes into account (at any nesting level). If an hdom element's
226
- * attribute object contains `__diff: false`, the object will ALWAYS be
227
- * considered unequal, even if all other attributes in the object are
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.2.0",
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",
@@ -37,18 +37,18 @@
37
37
  "test": "testament test"
38
38
  },
39
39
  "dependencies": {
40
- "@thi.ng/api": "^8.6.0",
40
+ "@thi.ng/api": "^8.6.1",
41
41
  "@thi.ng/checks": "^3.3.5",
42
- "@thi.ng/diff": "^5.1.19",
42
+ "@thi.ng/diff": "^5.1.20",
43
43
  "@thi.ng/equiv": "^2.1.15",
44
44
  "@thi.ng/errors": "^2.2.6",
45
- "@thi.ng/hiccup": "^4.2.26",
45
+ "@thi.ng/hiccup": "^4.2.27",
46
46
  "@thi.ng/logger": "^1.4.5",
47
47
  "@thi.ng/prefixes": "^2.1.15"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@microsoft/api-extractor": "^7.33.7",
51
- "@thi.ng/atom": "^5.1.25",
51
+ "@thi.ng/atom": "^5.1.26",
52
52
  "@thi.ng/testament": "^0.3.7",
53
53
  "rimraf": "^3.0.2",
54
54
  "tools": "^0.0.1",
@@ -131,5 +131,5 @@
131
131
  "status": "completed",
132
132
  "year": 2015
133
133
  },
134
- "gitHead": "f445a9cc8022bcdebbf6ff91fd66ced016d72f01\n"
134
+ "gitHead": "7b2af448da8a63fb21704a79cc4cdf1f3d7d7a64\n"
135
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
- * cycle methods) and an optional object of DOM update options. Starts
5
- * RAF update loop, in each iteration first normalizing given tree, then
6
- * computing diff to previous frame's tree and applying any changes to
7
- * the real DOM. The `ctx` option can be used for passing arbitrary
8
- * config data or state down into the hiccup component tree. Any
9
- * embedded component function in the tree will receive this context
10
- * object (shallow copy) as first argument, as will life cycle methods
11
- * in component objects. If the `autoDerefKeys` option is given,
12
- * attempts to auto-expand/deref the given keys in the user supplied
13
- * context object (`ctx` option) prior to *each* tree normalization. All
14
- * of these values should implement the {@link @thi.ng/api#IDeref}
15
- * interface (e.g. atoms, cursors, views, rstreams etc.). This feature
16
- * can be used to define dynamic contexts linked to the main app state,
17
- * e.g. using derived views provided by {@link @thi.ng/atom# | @thi.ng/atom}.
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
- * tree is `undefined` or `null` or a root component function returns no
21
- * value. This way a given root function can do some state handling of
22
- * its own and implement fail-fast checks to determine no DOM updates
23
- * are necessary, save effort re-creating a new hiccup tree and request
24
- * skipping DOM updates via this function. In this case, the previous
25
- * DOM tree is kept around until the root function returns a tree again,
26
- * which then is diffed and applied against the previous tree kept as
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
- * element given is assumed to have NO children at the time when
31
- * `start()` is called. Since hdom does NOT track the real DOM, the
32
- * resulting changes will result in potentially undefined behavior if
33
- * the parent element wasn't empty. Likewise, if `hydrate` is enabled,
34
- * it is assumed that an equivalent DOM (minus listeners) already exists
35
- * (i.e. generated via SSR) when `start()` is called. Any other
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
- * cycle methods) and an optional object of DOM update options. Starts
7
- * RAF update loop, in each iteration first normalizing given tree, then
8
- * computing diff to previous frame's tree and applying any changes to
9
- * the real DOM. The `ctx` option can be used for passing arbitrary
10
- * config data or state down into the hiccup component tree. Any
11
- * embedded component function in the tree will receive this context
12
- * object (shallow copy) as first argument, as will life cycle methods
13
- * in component objects. If the `autoDerefKeys` option is given,
14
- * attempts to auto-expand/deref the given keys in the user supplied
15
- * context object (`ctx` option) prior to *each* tree normalization. All
16
- * of these values should implement the {@link @thi.ng/api#IDeref}
17
- * interface (e.g. atoms, cursors, views, rstreams etc.). This feature
18
- * can be used to define dynamic contexts linked to the main app state,
19
- * e.g. using derived views provided by {@link @thi.ng/atom# | @thi.ng/atom}.
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
- * tree is `undefined` or `null` or a root component function returns no
23
- * value. This way a given root function can do some state handling of
24
- * its own and implement fail-fast checks to determine no DOM updates
25
- * are necessary, save effort re-creating a new hiccup tree and request
26
- * skipping DOM updates via this function. In this case, the previous
27
- * DOM tree is kept around until the root function returns a tree again,
28
- * which then is diffed and applied against the previous tree kept as
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
- * element given is assumed to have NO children at the time when
33
- * `start()` is called. Since hdom does NOT track the real DOM, the
34
- * resulting changes will result in potentially undefined behavior if
35
- * the parent element wasn't empty. Likewise, if `hydrate` is enabled,
36
- * it is assumed that an equivalent DOM (minus listeners) already exists
37
- * (i.e. generated via SSR) when `start()` is called. Any other
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