ripple 0.3.128 → 0.4.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 +294 -0
- package/package.json +11 -4
- package/src/jsx-runtime.d.ts +12 -2
- package/src/runtime/element.js +23 -6
- package/src/runtime/index-client.js +81 -41
- package/src/runtime/index-server.js +1 -0
- package/src/runtime/internal/client/blocks.js +173 -91
- package/src/runtime/internal/client/component.js +4 -30
- package/src/runtime/internal/client/composite.js +12 -13
- package/src/runtime/internal/client/constants.js +9 -0
- package/src/runtime/internal/client/context.js +12 -19
- package/src/runtime/internal/client/css.js +7 -9
- package/src/runtime/internal/client/events.js +178 -90
- package/src/runtime/internal/client/expression.js +45 -25
- package/src/runtime/internal/client/for.js +409 -129
- package/src/runtime/internal/client/head.js +10 -5
- package/src/runtime/internal/client/html.js +1 -0
- package/src/runtime/internal/client/hydration.js +152 -10
- package/src/runtime/internal/client/if.js +239 -50
- package/src/runtime/internal/client/index.js +4 -12
- package/src/runtime/internal/client/operations.js +40 -61
- package/src/runtime/internal/client/portal.js +163 -85
- package/src/runtime/internal/client/render.js +44 -43
- package/src/runtime/internal/client/rpc.js +3 -3
- package/src/runtime/internal/client/runtime.js +592 -433
- package/src/runtime/internal/client/selector.js +5 -2
- package/src/runtime/internal/client/template.js +133 -158
- package/src/runtime/internal/client/transport.js +38 -0
- package/src/runtime/internal/client/try.js +465 -426
- package/src/runtime/internal/client/types.d.ts +56 -23
- package/src/runtime/internal/client/utils.js +1 -3
- package/src/runtime/internal/server/dynamic.js +20 -21
- package/src/runtime/internal/server/index.js +329 -277
- package/src/runtime/internal/server/rpc.js +3 -2
- package/src/runtime/internal/server/transport.js +16 -0
- package/src/runtime/transport.js +21 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +0 -5
- package/tests/client/array/array.copy-within.test.tsrx +12 -12
- package/tests/client/array/array.derived.test.tsrx +46 -46
- package/tests/client/array/array.iteration.test.tsrx +10 -10
- package/tests/client/array/array.mutations.test.tsrx +20 -20
- package/tests/client/array/array.static.test.tsrx +11 -11
- package/tests/client/array/array.to-methods.test.tsrx +6 -6
- package/tests/client/async-suspend.test.tsrx +74 -75
- package/tests/client/basic/basic.attributes.test.tsrx +123 -83
- package/tests/client/basic/basic.collections.test.tsrx +12 -12
- package/tests/client/basic/basic.components.test.tsrx +99 -25
- package/tests/client/basic/basic.errors.test.tsrx +18 -18
- package/tests/client/basic/basic.events.test.tsrx +42 -42
- package/tests/client/basic/basic.get-set.test.tsrx +8 -8
- package/tests/client/basic/basic.reactivity.test.tsrx +73 -38
- package/tests/client/basic/basic.rendering.test.tsrx +25 -25
- package/tests/client/basic/basic.utilities.test.tsrx +3 -3
- package/tests/client/boundaries.test.tsrx +8 -8
- package/tests/client/boxed-locals.test.tsrx +452 -0
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +6 -6
- package/tests/client/compiler/compiler.assignments.test.tsrx +9 -73
- package/tests/client/compiler/compiler.attributes.test.tsrx +23 -23
- package/tests/client/compiler/compiler.basic.test.tsrx +15 -60
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +18 -43
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +2 -2
- package/tests/client/composite/__snapshots__/composite.render.test.tsrx.snap +0 -1
- package/tests/client/composite/composite.dynamic-components.test.tsrx +77 -6
- package/tests/client/composite/composite.props.test.tsrx +149 -12
- package/tests/client/composite/composite.reactivity.test.tsrx +51 -52
- package/tests/client/composite/composite.render.test.tsrx +26 -9
- package/tests/client/css/scoped-styles.test.tsrx +8 -8
- package/tests/client/date.test.tsrx +42 -42
- package/tests/client/derived-release.test.tsrx +370 -0
- package/tests/client/dynamic-elements.test.tsrx +45 -45
- package/tests/client/events.test.tsrx +97 -71
- package/tests/client/for-selector.test.tsrx +14 -14
- package/tests/client/for-single-root-items.test.tsrx +118 -3
- package/tests/client/for.test.tsrx +332 -31
- package/tests/client/head.test.tsrx +19 -19
- package/tests/client/html.test.tsrx +11 -9
- package/tests/client/if-block.test.tsrx +80 -0
- package/tests/client/map.test.tsrx +16 -16
- package/tests/client/media-query.test.tsrx +7 -7
- package/tests/client/portal.test.tsrx +224 -26
- package/tests/client/primitive-text.test.tsrx +50 -0
- package/tests/client/prop-kind-switch.test.tsrx +141 -0
- package/tests/client/ref.test.tsrx +17 -17
- package/tests/client/return.test.tsrx +26 -3
- package/tests/client/root-boundary.test.tsrx +42 -0
- package/tests/client/scoped-flush.test.tsrx +8 -8
- package/tests/client/set.test.tsrx +6 -6
- package/tests/client/svg.test.tsrx +11 -11
- package/tests/client/switch.test.tsrx +44 -44
- package/tests/client/track-async-hydration.test.tsrx +4 -4
- package/tests/client/try.test.tsrx +151 -83
- package/tests/client/tsx.test.tsrx +43 -40
- package/tests/client/url/url.derived.test.tsrx +6 -6
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +10 -10
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +10 -10
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +18 -18
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +2 -2
- package/tests/hydration/basic.test.js +74 -1
- package/tests/hydration/build-components.js +22 -1
- package/tests/hydration/compiled/client/basic.js +1142 -713
- package/tests/hydration/compiled/client/composite.js +151 -100
- package/tests/hydration/compiled/client/events.js +184 -171
- package/tests/hydration/compiled/client/for.js +1472 -1132
- package/tests/hydration/compiled/client/fragment-cursor.js +2341 -0
- package/tests/hydration/compiled/client/head.js +254 -201
- package/tests/hydration/compiled/client/hmr.js +54 -41
- package/tests/hydration/compiled/client/html-in-template.js +54 -39
- package/tests/hydration/compiled/client/html.js +1633 -1263
- package/tests/hydration/compiled/client/if-children.js +420 -270
- package/tests/hydration/compiled/client/if-fragment-controlflow.js +363 -317
- package/tests/hydration/compiled/client/if.js +229 -219
- package/tests/hydration/compiled/client/mixed-control-flow.js +420 -404
- package/tests/hydration/compiled/client/nested-control-flow.js +1326 -1277
- package/tests/hydration/compiled/client/portal.js +87 -95
- package/tests/hydration/compiled/client/reactivity.js +135 -101
- package/tests/hydration/compiled/client/return.js +28 -19
- package/tests/hydration/compiled/client/streaming.js +390 -306
- package/tests/hydration/compiled/client/switch.js +258 -266
- package/tests/hydration/compiled/client/track-async-serialization.js +448 -280
- package/tests/hydration/compiled/client/try.js +173 -129
- package/tests/hydration/compiled/client/typed-text.js +71 -0
- package/tests/hydration/compiled/fixtures/money.js +10 -0
- package/tests/hydration/compiled/server/basic.js +123 -6
- package/tests/hydration/compiled/server/composite.js +16 -30
- package/tests/hydration/compiled/server/events.js +66 -18
- package/tests/hydration/compiled/server/for.js +117 -41
- package/tests/hydration/compiled/server/fragment-cursor.js +1687 -0
- package/tests/hydration/compiled/server/head.js +20 -20
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +70 -238
- package/tests/hydration/compiled/server/if-children.js +107 -15
- package/tests/hydration/compiled/server/if.js +11 -15
- package/tests/hydration/compiled/server/mixed-control-flow.js +8 -8
- package/tests/hydration/compiled/server/portal.js +14 -22
- package/tests/hydration/compiled/server/reactivity.js +14 -14
- package/tests/hydration/compiled/server/streaming.js +19 -19
- package/tests/hydration/compiled/server/switch.js +8 -8
- package/tests/hydration/compiled/server/track-async-serialization.js +150 -23
- package/tests/hydration/compiled/server/try.js +8 -8
- package/tests/hydration/compiled/server/typed-text.js +17 -0
- package/tests/hydration/components/basic.tsrx +44 -8
- package/tests/hydration/components/composite.tsrx +2 -2
- package/tests/hydration/components/events.tsrx +25 -25
- package/tests/hydration/components/for.tsrx +115 -67
- package/tests/hydration/components/fragment-cursor.tsrx +650 -0
- package/tests/hydration/components/head.tsrx +16 -16
- package/tests/hydration/components/hmr.tsrx +2 -2
- package/tests/hydration/components/html.tsrx +7 -7
- package/tests/hydration/components/if-children.tsrx +72 -25
- package/tests/hydration/components/if.tsrx +18 -18
- package/tests/hydration/components/mixed-control-flow.tsrx +11 -11
- package/tests/hydration/components/portal.tsrx +3 -3
- package/tests/hydration/components/reactivity.tsrx +16 -16
- package/tests/hydration/components/streaming.tsrx +20 -20
- package/tests/hydration/components/switch.tsrx +20 -20
- package/tests/hydration/components/text-types.ts +4 -0
- package/tests/hydration/components/track-async-serialization.tsrx +80 -26
- package/tests/hydration/components/try.tsrx +8 -8
- package/tests/hydration/components/typed-text.tsrx +22 -0
- package/tests/hydration/fixtures/money.js +10 -0
- package/tests/hydration/for.test.js +36 -0
- package/tests/hydration/fragment-cursor.test.js +111 -0
- package/tests/hydration/if-children.test.js +24 -0
- package/tests/hydration/streaming.test.js +19 -0
- package/tests/hydration/track-async-serialization.test.js +87 -2
- package/tests/hydration/tsconfig.text-types.json +10 -0
- package/tests/hydration/typed-text.test.js +34 -0
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +70 -42
- package/tests/server/basic.components.test.tsrx +64 -8
- package/tests/server/basic.test.tsrx +34 -32
- package/tests/server/compiler.test.tsrx +1 -70
- package/tests/server/composite.props.test.tsrx +6 -6
- package/tests/server/dynamic-elements.test.tsrx +31 -8
- package/tests/server/for.test.tsrx +94 -0
- package/tests/server/head.test.tsrx +11 -11
- package/tests/server/scoped-styles.test.tsrx +2 -2
- package/tests/server/streaming-ssr.test.tsrx +48 -43
- package/tests/server/track-async-serialization.test.tsrx +204 -21
- package/tests/server/try.test.tsrx +48 -48
- package/tests/types/transport.ts +40 -0
- package/tests/utils/jsx-runtime-types.test.js +67 -2
- package/tests/utils/tracked-types.test.js +117 -0
- package/tests/utils/vite-plugin-config.test.js +23 -0
- package/types/index.d.ts +49 -9
- package/types/server.d.ts +3 -0
- package/types/transport.d.ts +15 -0
- package/src/runtime/internal/client/switch.js +0 -113
- package/src/utils/errors.js +0 -13
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +0 -12
- package/tests/client/compiler/__snapshots__/compiler.typescript.test.rsrx.snap +0 -46
- package/tests/client/lazy-array.test.tsrx +0 -31
- package/tests/client/lazy-destructuring.test.tsrx +0 -438
- package/tests/client/tracked-index-access.test.tsrx +0 -113
- package/tests/server/lazy-destructuring.test.tsrx +0 -595
- package/tests/server/tracked-index-access.test.tsrx +0 -76
|
@@ -16,14 +16,15 @@ import {
|
|
|
16
16
|
set_tracking,
|
|
17
17
|
tracking,
|
|
18
18
|
} from './runtime.js';
|
|
19
|
-
import {
|
|
19
|
+
import { define_property, is_array } from '@tsrx/core/runtime/language-helpers';
|
|
20
20
|
import { render } from './blocks.js';
|
|
21
21
|
|
|
22
22
|
/** @type {Set<string>} */
|
|
23
23
|
var all_registered_events = new Set();
|
|
24
24
|
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {{ count: number, registered_events: Set<string>, target: Element }} RootTargetRef
|
|
27
|
+
*/
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Active root delegation targets, ref-counted per target. Multiple callers of
|
|
@@ -32,10 +33,13 @@ var root_event_handles = new Set();
|
|
|
32
33
|
* nested mounts. The shared delegated listeners for a target may only be torn
|
|
33
34
|
* down once every caller for that target has released it, otherwise
|
|
34
35
|
* unmounting one Portal silently kills event delegation for its siblings.
|
|
35
|
-
* @type {Map<Element,
|
|
36
|
+
* @type {Map<Element, RootTargetRef>}
|
|
36
37
|
*/
|
|
37
38
|
var root_target_refs = new Map();
|
|
38
39
|
|
|
40
|
+
/** @type {RootTargetRef | null} */
|
|
41
|
+
var last_root_ref = null;
|
|
42
|
+
|
|
39
43
|
/**
|
|
40
44
|
* Delegated handling only works for elements strictly below a root delegation
|
|
41
45
|
* target: the root listener's propagation walk never visits the target itself
|
|
@@ -271,30 +275,10 @@ function create_event(event_name, dom, handler, options) {
|
|
|
271
275
|
if (is_delegated) {
|
|
272
276
|
var prop = '__' + event_name;
|
|
273
277
|
var target = /** @type {DelegatedEventTarget} */ (dom);
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if (current === undefined) {
|
|
277
|
-
target[prop] = handler;
|
|
278
|
-
} else if (is_array(current)) {
|
|
279
|
-
if (!current.includes(handler)) {
|
|
280
|
-
current.push(handler);
|
|
281
|
-
}
|
|
282
|
-
} else {
|
|
283
|
-
if (current !== handler) {
|
|
284
|
-
target[prop] = [current, handler];
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
278
|
+
add_delegated_handler(target, prop, handler);
|
|
288
279
|
delegate([event_name]);
|
|
289
280
|
return () => {
|
|
290
|
-
|
|
291
|
-
if (is_array(handlers)) {
|
|
292
|
-
var filtered = handlers.filter((h) => h !== handler);
|
|
293
|
-
target[prop] =
|
|
294
|
-
filtered.length === 0 ? undefined : filtered.length === 1 ? filtered[0] : filtered;
|
|
295
|
-
} else {
|
|
296
|
-
target[prop] = undefined;
|
|
297
|
-
}
|
|
281
|
+
remove_delegated_handler(target, prop, handler);
|
|
298
282
|
};
|
|
299
283
|
}
|
|
300
284
|
|
|
@@ -336,12 +320,107 @@ function create_event(event_name, dom, handler, options) {
|
|
|
336
320
|
}
|
|
337
321
|
|
|
338
322
|
/**
|
|
323
|
+
* Delegated event name resolution per compiler-emitted name (`"Click"`,
|
|
324
|
+
* `"PointerMove"`, ...): the lowercase DOM name, or null when the event cannot
|
|
325
|
+
* be delegated (capture variants, non-bubbling events).
|
|
326
|
+
* @type {Map<string, string | null>}
|
|
327
|
+
*/
|
|
328
|
+
var delegated_event_names = new Map();
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* @param {string} event_name
|
|
332
|
+
* @returns {string | null}
|
|
333
|
+
*/
|
|
334
|
+
function get_delegated_event_name(event_name) {
|
|
335
|
+
var name = delegated_event_names.get(event_name);
|
|
336
|
+
|
|
337
|
+
if (name === undefined) {
|
|
338
|
+
if (is_capture_event(event_name)) {
|
|
339
|
+
name = null;
|
|
340
|
+
} else {
|
|
341
|
+
name = event_name.toLowerCase();
|
|
342
|
+
if (is_non_delegated(name)) {
|
|
343
|
+
name = null;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
delegated_event_names.set(event_name, name);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return name;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* @param {DelegatedEventTarget} target
|
|
354
|
+
* @param {string} prop
|
|
355
|
+
* @param {EventListener} handler
|
|
356
|
+
* @returns {void}
|
|
357
|
+
*/
|
|
358
|
+
function add_delegated_handler(target, prop, handler) {
|
|
359
|
+
var current = target[prop];
|
|
360
|
+
|
|
361
|
+
if (current === undefined) {
|
|
362
|
+
target[prop] = handler;
|
|
363
|
+
} else if (is_array(current)) {
|
|
364
|
+
if (!current.includes(handler)) {
|
|
365
|
+
current.push(handler);
|
|
366
|
+
}
|
|
367
|
+
} else {
|
|
368
|
+
if (current !== handler) {
|
|
369
|
+
target[prop] = [current, handler];
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @param {DelegatedEventTarget} target
|
|
376
|
+
* @param {string} prop
|
|
377
|
+
* @param {EventListener} handler
|
|
378
|
+
* @returns {void}
|
|
379
|
+
*/
|
|
380
|
+
function remove_delegated_handler(target, prop, handler) {
|
|
381
|
+
var handlers = target[prop];
|
|
382
|
+
if (is_array(handlers)) {
|
|
383
|
+
var filtered = handlers.filter((h) => h !== handler);
|
|
384
|
+
target[prop] =
|
|
385
|
+
filtered.length === 0 ? undefined : filtered.length === 1 ? filtered[0] : filtered;
|
|
386
|
+
} else {
|
|
387
|
+
target[prop] = undefined;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Compiler-emitted one-shot listener for a static `onEvent={handler}`: the
|
|
393
|
+
* element's lifetime owns the handler, so nothing is returned for cleanup.
|
|
339
394
|
* @param {string} event_name
|
|
340
395
|
* @param {Element} dom
|
|
341
396
|
* @param {EventListener | AddEventObject} handler
|
|
342
|
-
* @returns {
|
|
397
|
+
* @returns {void}
|
|
343
398
|
*/
|
|
344
399
|
export function event(event_name, dom, handler) {
|
|
400
|
+
if (typeof handler === 'function') {
|
|
401
|
+
// Plain handler: the common compiled `onClick={fn}` shape. Resolve the
|
|
402
|
+
// delegated name from the cache and skip the options plumbing.
|
|
403
|
+
var name = get_delegated_event_name(event_name);
|
|
404
|
+
|
|
405
|
+
if (name !== null) {
|
|
406
|
+
add_delegated_handler(/** @type {DelegatedEventTarget} */ (dom), '__' + name, handler);
|
|
407
|
+
delegate([name]);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
event_listener(event_name, dom, handler);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Attaches a listener and returns its remover; `event()` is the one-shot
|
|
417
|
+
* compiled form of this.
|
|
418
|
+
* @param {string} event_name
|
|
419
|
+
* @param {Element} dom
|
|
420
|
+
* @param {EventListener | AddEventObject} handler
|
|
421
|
+
* @returns {() => void}
|
|
422
|
+
*/
|
|
423
|
+
export function event_listener(event_name, dom, handler) {
|
|
345
424
|
/** @type AddEventOptions */
|
|
346
425
|
var options = {};
|
|
347
426
|
/** @type {EventListener} */
|
|
@@ -350,7 +429,7 @@ export function event(event_name, dom, handler) {
|
|
|
350
429
|
if (typeof handler === 'object' && 'handleEvent' in handler) {
|
|
351
430
|
({ handleEvent: event_handler, ...options } = handler);
|
|
352
431
|
} else {
|
|
353
|
-
event_handler = handler;
|
|
432
|
+
event_handler = /** @type {EventListener} */ (handler);
|
|
354
433
|
}
|
|
355
434
|
|
|
356
435
|
return create_event(event_name, dom, event_handler, options);
|
|
@@ -381,7 +460,7 @@ export function render_event(event_name, dom, get_handler) {
|
|
|
381
460
|
prev = handler;
|
|
382
461
|
|
|
383
462
|
if (handler) {
|
|
384
|
-
remove_listener =
|
|
463
|
+
remove_listener = event_listener(event_name, dom, handler);
|
|
385
464
|
}
|
|
386
465
|
}
|
|
387
466
|
});
|
|
@@ -392,77 +471,86 @@ export function render_event(event_name, dom, get_handler) {
|
|
|
392
471
|
* @returns {void}
|
|
393
472
|
*/
|
|
394
473
|
export function delegate(events) {
|
|
474
|
+
var added = false;
|
|
475
|
+
|
|
395
476
|
for (var i = 0; i < events.length; i++) {
|
|
396
|
-
|
|
477
|
+
var event_name = events[i];
|
|
478
|
+
|
|
479
|
+
if (!all_registered_events.has(event_name)) {
|
|
480
|
+
all_registered_events.add(event_name);
|
|
481
|
+
added = true;
|
|
482
|
+
}
|
|
397
483
|
}
|
|
398
484
|
|
|
399
|
-
for
|
|
400
|
-
|
|
485
|
+
// Every root target already listens for every previously registered event,
|
|
486
|
+
// so only a new event name needs to fan out to the targets.
|
|
487
|
+
if (added) {
|
|
488
|
+
for (var ref of root_target_refs.values()) {
|
|
489
|
+
register_root_events(ref, events);
|
|
490
|
+
}
|
|
401
491
|
}
|
|
402
492
|
}
|
|
403
493
|
|
|
404
|
-
/**
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
};
|
|
410
|
-
ref.count += 1;
|
|
411
|
-
root_target_refs.set(target, ref);
|
|
494
|
+
/**
|
|
495
|
+
* @param {RootTargetRef} ref
|
|
496
|
+
* @param {Iterable<string>} events
|
|
497
|
+
*/
|
|
498
|
+
function register_root_events(ref, events) {
|
|
412
499
|
var registered_events = ref.registered_events;
|
|
500
|
+
var target = ref.target;
|
|
413
501
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
*/
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
* @typedef {(
|
|
421
|
-
* events: Array<string>
|
|
422
|
-
* ) => void} EventHandle
|
|
423
|
-
*/
|
|
424
|
-
|
|
425
|
-
/** @type {EventHandle} */
|
|
426
|
-
var event_handle = (/** @type {Array<string>} */ events) => {
|
|
427
|
-
for (var i = 0; i < events.length; i++) {
|
|
428
|
-
var event_name = events[i];
|
|
429
|
-
|
|
430
|
-
if (registered_events.has(event_name)) continue;
|
|
431
|
-
registered_events.add(event_name);
|
|
502
|
+
for (var event_name of events) {
|
|
503
|
+
if (registered_events.has(event_name)) continue;
|
|
504
|
+
registered_events.add(event_name);
|
|
432
505
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
target.addEventListener(event_name, handle_event_propagation, options);
|
|
440
|
-
}
|
|
441
|
-
};
|
|
506
|
+
target.addEventListener(event_name, handle_event_propagation, {
|
|
507
|
+
passive: is_passive_event(event_name),
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
}
|
|
442
511
|
|
|
443
|
-
|
|
444
|
-
|
|
512
|
+
/**
|
|
513
|
+
* Acquires the delegated root listeners for `target` and returns the shared
|
|
514
|
+
* ref; every acquire must be paired with one `release_root_events` call.
|
|
515
|
+
* @param {Element} target
|
|
516
|
+
* @returns {RootTargetRef}
|
|
517
|
+
*/
|
|
518
|
+
export function handle_root_events(target) {
|
|
519
|
+
// Sibling portals mostly share one target, so check the last ref first.
|
|
520
|
+
/** @type {RootTargetRef | undefined} */
|
|
521
|
+
var ref =
|
|
522
|
+
last_root_ref !== null && last_root_ref.target === target
|
|
523
|
+
? last_root_ref
|
|
524
|
+
: root_target_refs.get(target);
|
|
525
|
+
|
|
526
|
+
if (ref === undefined) {
|
|
527
|
+
ref = { count: 0, registered_events: new Set(), target };
|
|
528
|
+
root_target_refs.set(target, ref);
|
|
529
|
+
register_root_events(ref, all_registered_events);
|
|
530
|
+
}
|
|
445
531
|
|
|
446
|
-
|
|
532
|
+
ref.count += 1;
|
|
533
|
+
last_root_ref = ref;
|
|
534
|
+
return ref;
|
|
535
|
+
}
|
|
447
536
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
};
|
|
537
|
+
/**
|
|
538
|
+
* @param {RootTargetRef} ref
|
|
539
|
+
* @returns {void}
|
|
540
|
+
*/
|
|
541
|
+
export function release_root_events(ref) {
|
|
542
|
+
// The map entry for `ref.target` is always this `ref`: it is only deleted
|
|
543
|
+
// when the count hits 0, which requires every acquirer to have released.
|
|
544
|
+
ref.count -= 1;
|
|
545
|
+
if (ref.count > 0) return;
|
|
546
|
+
|
|
547
|
+
// Last caller for this target: actually tear down the shared listeners.
|
|
548
|
+
var target = ref.target;
|
|
549
|
+
root_target_refs.delete(target);
|
|
550
|
+
if (last_root_ref === ref) {
|
|
551
|
+
last_root_ref = null;
|
|
552
|
+
}
|
|
553
|
+
for (var event_name of ref.registered_events) {
|
|
554
|
+
target.removeEventListener(event_name, /** @type {EventListener} */ (handle_event_propagation));
|
|
555
|
+
}
|
|
468
556
|
}
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
/** @import { Block } from '#client' */
|
|
1
|
+
/** @import { AppendIntoAnchor, Block } from '#client' */
|
|
2
2
|
|
|
3
3
|
import { is_array } from '@tsrx/core/runtime/language-helpers';
|
|
4
4
|
import { branch, destroy_block, render } from './blocks.js';
|
|
5
|
-
import { BRANCH_BLOCK, UNINITIALIZED } from './constants.js';
|
|
5
|
+
import { BRANCH_BLOCK, IF_BLOCK, UNINITIALIZED } from './constants.js';
|
|
6
6
|
import { create_text, get_next_sibling } from './operations.js';
|
|
7
7
|
import { assign_nodes } from './template.js';
|
|
8
8
|
import { active_block } from './runtime.js';
|
|
9
9
|
import { hydrate_node, hydrating, set_hydrate_node } from './hydration.js';
|
|
10
10
|
import { COMMENT_NODE, HYDRATION_END, HYDRATION_START, TEXT_NODE } from '../../../constants.js';
|
|
11
|
-
import { is_tsrx_element } from '../../element.js';
|
|
11
|
+
import { is_tsrx_element, TSRX_ELEMENT } from '../../element.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Finds the nearest enclosing
|
|
14
|
+
* Finds the nearest enclosing block that owns a DOM range (a branch or an if
|
|
15
|
+
* block) in the block hierarchy.
|
|
15
16
|
* @param {Block | null} block
|
|
16
17
|
* @returns {Block | null}
|
|
17
18
|
*/
|
|
18
19
|
function find_enclosing_branch(block) {
|
|
19
20
|
while (block !== null) {
|
|
20
|
-
if ((block.f & BRANCH_BLOCK) !== 0) {
|
|
21
|
+
if ((block.f & (BRANCH_BLOCK | IF_BLOCK)) !== 0) {
|
|
21
22
|
return block;
|
|
22
23
|
}
|
|
23
24
|
block = block.p;
|
|
@@ -32,13 +33,19 @@ function find_enclosing_branch(block) {
|
|
|
32
33
|
* @returns {void}
|
|
33
34
|
*/
|
|
34
35
|
export function render_value(value, anchor, block) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
// render_tsrx_element, inline: an element's render may return another
|
|
37
|
+
// element (a wrapper), an array, or text.
|
|
38
|
+
var rendered = false;
|
|
39
|
+
// is_tsrx_element, inline: every component render passes through here.
|
|
40
|
+
while (value != null && value[TSRX_ELEMENT] === true) {
|
|
41
|
+
value = value.render(anchor, block, value.p);
|
|
42
|
+
rendered = true;
|
|
43
|
+
}
|
|
44
|
+
if (is_array(value)) {
|
|
38
45
|
render_tsrx_collection(value, anchor, block);
|
|
39
46
|
} else if (value != null) {
|
|
40
47
|
var text = value + '';
|
|
41
|
-
if (text !== '') {
|
|
48
|
+
if (rendered || text !== '') {
|
|
42
49
|
render_tsrx_collection_text(text, anchor, true);
|
|
43
50
|
}
|
|
44
51
|
}
|
|
@@ -60,11 +67,27 @@ function render_tsrx_collection(value, anchor, block) {
|
|
|
60
67
|
var start = document.createComment('');
|
|
61
68
|
var end = document.createComment('');
|
|
62
69
|
|
|
63
|
-
anchor
|
|
70
|
+
insert_before(anchor, start);
|
|
71
|
+
insert_before(anchor, end);
|
|
64
72
|
assign_nodes(start, end);
|
|
65
73
|
render_tsrx_collection_items(value, end, block);
|
|
66
74
|
}
|
|
67
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Inserts `node` before `anchor`, or appends it into the parent when `anchor`
|
|
78
|
+
* is an append-into sentinel (see `append_into`).
|
|
79
|
+
* @param {ChildNode | AppendIntoAnchor} anchor
|
|
80
|
+
* @param {Node} node
|
|
81
|
+
* @returns {void}
|
|
82
|
+
*/
|
|
83
|
+
function insert_before(anchor, node) {
|
|
84
|
+
if (/** @type {AppendIntoAnchor} */ (anchor).into === true) {
|
|
85
|
+
/** @type {AppendIntoAnchor} */ (anchor).parent.appendChild(node);
|
|
86
|
+
} else {
|
|
87
|
+
/** @type {ChildNode} */ (anchor).before(node);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
68
91
|
/**
|
|
69
92
|
* @param {any[]} value
|
|
70
93
|
* @param {ChildNode} anchor
|
|
@@ -92,7 +115,7 @@ function render_tsrx_collection_items(value, anchor, block) {
|
|
|
92
115
|
* @returns {void}
|
|
93
116
|
*/
|
|
94
117
|
function render_tsrx_element(value, anchor, block) {
|
|
95
|
-
var result = value.render(anchor, block);
|
|
118
|
+
var result = value.render(anchor, block, value.p);
|
|
96
119
|
|
|
97
120
|
if (is_tsrx_element(result)) {
|
|
98
121
|
render_tsrx_element(result, anchor, block);
|
|
@@ -112,7 +135,7 @@ function render_tsrx_element(value, anchor, block) {
|
|
|
112
135
|
function render_tsrx_collection_text(value, anchor, assign = false) {
|
|
113
136
|
if (!hydrating) {
|
|
114
137
|
var text = create_text(value);
|
|
115
|
-
anchor
|
|
138
|
+
insert_before(anchor, text);
|
|
116
139
|
if (assign) {
|
|
117
140
|
assign_nodes(text, text);
|
|
118
141
|
}
|
|
@@ -241,7 +264,7 @@ function run_expression(s) {
|
|
|
241
264
|
if (next_is_collection || is_tsrx_element(next_value)) {
|
|
242
265
|
if (s.i && s.e && s.v === next_value) {
|
|
243
266
|
if (end !== null) {
|
|
244
|
-
|
|
267
|
+
settle_hydration(end);
|
|
245
268
|
}
|
|
246
269
|
return;
|
|
247
270
|
}
|
|
@@ -310,7 +333,7 @@ function run_expression(s) {
|
|
|
310
333
|
s.e = true;
|
|
311
334
|
s.i = true;
|
|
312
335
|
if (end !== null) {
|
|
313
|
-
|
|
336
|
+
settle_hydration(end);
|
|
314
337
|
}
|
|
315
338
|
return;
|
|
316
339
|
}
|
|
@@ -320,7 +343,7 @@ function run_expression(s) {
|
|
|
320
343
|
|
|
321
344
|
if (s.i && !s.e && s.v === next_text) {
|
|
322
345
|
if (end !== null) {
|
|
323
|
-
|
|
346
|
+
settle_hydration(end);
|
|
324
347
|
}
|
|
325
348
|
return;
|
|
326
349
|
}
|
|
@@ -368,7 +391,7 @@ function run_expression(s) {
|
|
|
368
391
|
s.e = false;
|
|
369
392
|
s.i = true;
|
|
370
393
|
if (end !== null) {
|
|
371
|
-
|
|
394
|
+
settle_hydration(end);
|
|
372
395
|
}
|
|
373
396
|
}
|
|
374
397
|
|
|
@@ -457,17 +480,14 @@ function clear_expression_range(anchor, end) {
|
|
|
457
480
|
}
|
|
458
481
|
|
|
459
482
|
/**
|
|
483
|
+
* Leaves the hydration cursor on the expression's end marker, the last node
|
|
484
|
+
* the expression owns: the parent steps past it with its own sibling
|
|
485
|
+
* navigation, exactly as it does after an element or a control-flow block.
|
|
460
486
|
* @param {Comment} end
|
|
461
487
|
* @returns {void}
|
|
462
488
|
*/
|
|
463
|
-
function
|
|
464
|
-
if (
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
var next = get_next_sibling(end);
|
|
469
|
-
|
|
470
|
-
if (next !== null) {
|
|
471
|
-
set_hydrate_node(next);
|
|
489
|
+
function settle_hydration(end) {
|
|
490
|
+
if (hydrating) {
|
|
491
|
+
set_hydrate_node(end);
|
|
472
492
|
}
|
|
473
493
|
}
|