@jsenv/navi 0.29.514 → 0.29.516
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/dist/dev/jsenv_navi.js +138 -37
- package/dist/dev/jsenv_navi.js.map +7 -7
- package/dist/jsenv_navi.js +138 -37
- package/dist/jsenv_navi.js.map +7 -7
- package/docs/scroll.md +31 -0
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -462,32 +462,33 @@ const MountAfterPaint = ({
|
|
|
462
462
|
/**
|
|
463
463
|
* Builds, now, every box still waiting whose top is above `bottom` (in the
|
|
464
464
|
* document's coordinates): what the document will show once scrolled so that
|
|
465
|
-
* `bottom` is the bottom of the screen.
|
|
466
|
-
*
|
|
467
|
-
*
|
|
465
|
+
* `bottom` is the bottom of the screen.
|
|
466
|
+
*
|
|
467
|
+
* Each box is read once those before it have their height. A box has no height
|
|
468
|
+
* until it is built, so read together they would all stand at the end of what
|
|
469
|
+
* is built, above `bottom` as soon as the offset is worth a screen: a page of
|
|
470
|
+
* sections would be built whole before its first frame. A box found below
|
|
471
|
+
* `bottom` waits: a build only pushes it further down, and where it stands
|
|
472
|
+
* already makes the document tall enough for the offset.
|
|
473
|
+
*
|
|
474
|
+
* The walk follows the set live, in mount order: a box mounted by a build is
|
|
475
|
+
* read too. One standing higher than boxes built before it (mounted later) can
|
|
476
|
+
* leave a few built that the offset does not show, never one missing that it
|
|
477
|
+
* does.
|
|
468
478
|
*
|
|
469
479
|
* Renders synchronously, so it must be called outside a Preact commit: a render
|
|
470
480
|
* flushed from a layout effect runs inside the commit still walking the tree.
|
|
471
481
|
*/
|
|
472
482
|
const buildDeferredBoxesAbove = bottom => {
|
|
473
|
-
if (deferredBoxes.size === 0) {
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
const toBuild = [];
|
|
477
483
|
for (const deferredBox of deferredBoxes) {
|
|
478
484
|
const top = readTopInWindow(deferredBox.getElement());
|
|
479
|
-
if (top
|
|
480
|
-
|
|
485
|
+
if (top === null || top + window.scrollY >= bottom) {
|
|
486
|
+
continue;
|
|
481
487
|
}
|
|
482
|
-
|
|
483
|
-
if (toBuild.length === 0) {
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
flushSyncRendering(() => {
|
|
487
|
-
for (const deferredBox of toBuild) {
|
|
488
|
+
flushSyncRendering(() => {
|
|
488
489
|
deferredBox.build();
|
|
489
|
-
}
|
|
490
|
-
}
|
|
490
|
+
});
|
|
491
|
+
}
|
|
491
492
|
};
|
|
492
493
|
|
|
493
494
|
// null for a box nothing draws (a closed popup, a hidden tab): no frame shows
|
|
@@ -10434,6 +10435,12 @@ const startAtTop = (url, { from } = {}) => {
|
|
|
10434
10435
|
// position to come back to — the return would keep the offset of the page
|
|
10435
10436
|
// being left.
|
|
10436
10437
|
positionByUrl.set(href, { x: 0, y: 0 });
|
|
10438
|
+
// A list holding the document on the page arriving has placed it already: a
|
|
10439
|
+
// navigation holding the rendering gets here after that render, and nothing
|
|
10440
|
+
// owes the list another commit to put it back (see holdDocumentScroll).
|
|
10441
|
+
if (isDocumentHeld()) {
|
|
10442
|
+
return;
|
|
10443
|
+
}
|
|
10437
10444
|
window.scrollTo({ top: 0, left: 0, behavior: "instant" });
|
|
10438
10445
|
};
|
|
10439
10446
|
// Also what decides whether a push carries the state of the page it keeps
|
|
@@ -10568,6 +10575,19 @@ const recallScrollerPosition = (name) => {
|
|
|
10568
10575
|
return positionByName.get(name);
|
|
10569
10576
|
};
|
|
10570
10577
|
|
|
10578
|
+
// Said by a scroller sent back to its start while it stays mounted: where it
|
|
10579
|
+
// was is a place in what it no longer shows, so nothing is carried and nothing
|
|
10580
|
+
// is come back to under this address until it says where it is again. What it
|
|
10581
|
+
// said under another address stays, for the way back to that address.
|
|
10582
|
+
const forgetScrollerPosition = (name) => {
|
|
10583
|
+
loadStore();
|
|
10584
|
+
saidByScrollerName.delete(name);
|
|
10585
|
+
const positionByName = scrollerPositionsByUrl.get(readShownUrl());
|
|
10586
|
+
if (positionByName) {
|
|
10587
|
+
positionByName.delete(name);
|
|
10588
|
+
}
|
|
10589
|
+
};
|
|
10590
|
+
|
|
10571
10591
|
// Said by a scroller as it unmounts. Its page is being left when the url is
|
|
10572
10592
|
// already another one — the history is written before the page it names is
|
|
10573
10593
|
// taken down — and then its position is kept for the way back. The url still
|
|
@@ -13409,10 +13429,17 @@ const isRenderingPageChange = () => renderingPageChange;
|
|
|
13409
13429
|
* outside any render — by a subscription deciding whether to re-render, by
|
|
13410
13430
|
* the scroll restoration when a position is due — and it reads the routes
|
|
13411
13431
|
* untracked, so asking subscribes nobody to them.
|
|
13412
|
-
* - `
|
|
13413
|
-
*
|
|
13414
|
-
*
|
|
13415
|
-
*
|
|
13432
|
+
* - `hasLeft()` — whether the page, or a page it sits in, is kept while leaving.
|
|
13433
|
+
* Written by the container's render, before anything below it renders, and
|
|
13434
|
+
* final. `isShown()` can answer false for a page that stays on screen (the
|
|
13435
|
+
* address coming back, a container first rendered while the routes are
|
|
13436
|
+
* frozen), so what cannot be undone asks this one.
|
|
13437
|
+
* - `leavingSignal` — true once the page, or a page it sits in, is hidden and
|
|
13438
|
+
* kept while the movement plays: still mounted, so what it fills or moves
|
|
13439
|
+
* outside its own nodes (a slot in a bar, the document a list scrolls) steps
|
|
13440
|
+
* out rather than showing with, or moving, the page arriving. Every box of it
|
|
13441
|
+
* measures 0×0 by then. Set after the render keeping the page, so that render
|
|
13442
|
+
* and what it builds can only ask `hasLeft()`.
|
|
13416
13443
|
*/
|
|
13417
13444
|
const RoutePageContext = createContext(null);
|
|
13418
13445
|
|
|
@@ -36622,7 +36649,7 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
36622
36649
|
continue;
|
|
36623
36650
|
}
|
|
36624
36651
|
entry.hidden = true;
|
|
36625
|
-
entry.page.
|
|
36652
|
+
entry.page.ownLeavingSignal.value = true;
|
|
36626
36653
|
// The page renders on its own while kept (a component reading a signal
|
|
36627
36654
|
// the address moved), never through this container: a top node it
|
|
36628
36655
|
// replaces lands between the markers unmarked, a text it writes shows
|
|
@@ -36710,11 +36737,21 @@ const hideNodesBetween = (start, end, observer) => {
|
|
|
36710
36737
|
// page it sits in is shown itself. Never again once kept while leaving: coming
|
|
36711
36738
|
// back to its route mounts the page anew.
|
|
36712
36739
|
const createRoutePage = (readShownBranch, parentPage) => {
|
|
36740
|
+
const ownLeavingSignal = signal(false);
|
|
36713
36741
|
const page = {
|
|
36714
36742
|
branchId: null,
|
|
36715
36743
|
element: undefined,
|
|
36716
36744
|
left: false,
|
|
36717
|
-
|
|
36745
|
+
ownLeavingSignal,
|
|
36746
|
+
// A page nested in one that left is hidden with it, even while its own
|
|
36747
|
+
// container goes on picking it (a route matching on both sides).
|
|
36748
|
+
leavingSignal: parentPage ? computed(() => ownLeavingSignal.value || parentPage.leavingSignal.value) : ownLeavingSignal,
|
|
36749
|
+
hasLeft: () => {
|
|
36750
|
+
if (page.left) {
|
|
36751
|
+
return true;
|
|
36752
|
+
}
|
|
36753
|
+
return parentPage ? parentPage.hasLeft() : false;
|
|
36754
|
+
},
|
|
36718
36755
|
isShown: () => {
|
|
36719
36756
|
if (page.left) {
|
|
36720
36757
|
return false;
|
|
@@ -84055,6 +84092,7 @@ const ListUI = props => {
|
|
|
84055
84092
|
scroller = "self",
|
|
84056
84093
|
hoverWhileScrolling = false,
|
|
84057
84094
|
scrollResetOnNavigation = false,
|
|
84095
|
+
scrollResetKey,
|
|
84058
84096
|
lockSize,
|
|
84059
84097
|
columns,
|
|
84060
84098
|
itemColumns,
|
|
@@ -84173,6 +84211,7 @@ const ListUI = props => {
|
|
|
84173
84211
|
scrolled,
|
|
84174
84212
|
defaultScrolled,
|
|
84175
84213
|
onScrolledChange,
|
|
84214
|
+
scrollResetKey,
|
|
84176
84215
|
rememberScroll,
|
|
84177
84216
|
listId: rest.id,
|
|
84178
84217
|
scroller,
|
|
@@ -84504,6 +84543,7 @@ const useListScrollSync = ({
|
|
|
84504
84543
|
scrolled,
|
|
84505
84544
|
defaultScrolled,
|
|
84506
84545
|
onScrolledChange,
|
|
84546
|
+
scrollResetKey,
|
|
84507
84547
|
rememberScroll,
|
|
84508
84548
|
listId,
|
|
84509
84549
|
scroller,
|
|
@@ -84512,6 +84552,8 @@ const useListScrollSync = ({
|
|
|
84512
84552
|
columns
|
|
84513
84553
|
}) => {
|
|
84514
84554
|
const debugScroll = useDebugScroll();
|
|
84555
|
+
// The offset a search gives back once emptied (see below).
|
|
84556
|
+
const savedScrollRef = useRef(null);
|
|
84515
84557
|
// Where the list must be: what the caller holds it at (`scrolled`), or where
|
|
84516
84558
|
// it opens and then lets go (`defaultScrolled`). A `scrolled` that changes is
|
|
84517
84559
|
// the caller moving the list, so the hold is armed again — that is what makes
|
|
@@ -84520,7 +84562,9 @@ const useListScrollSync = ({
|
|
|
84520
84562
|
// one kept from the previous visit): followed for as long as nobody has
|
|
84521
84563
|
// moved the list, and compared by value, since it is said at every render.
|
|
84522
84564
|
// Nothing to hold it at (a position not saved yet) is not a position: the
|
|
84523
|
-
// list opens where it opens.
|
|
84565
|
+
// list opens where it opens. A `scrollResetKey` that changes sends it back to
|
|
84566
|
+
// its start ("back_to_start", see placeBackAtStart), unless a `scrolled`
|
|
84567
|
+
// changing in the same render says where it goes.
|
|
84524
84568
|
const startPlaceRef = useRef(null);
|
|
84525
84569
|
if (startPlaceRef.current === null) {
|
|
84526
84570
|
startPlaceRef.current = {
|
|
@@ -84528,6 +84572,7 @@ const useListScrollSync = ({
|
|
|
84528
84572
|
wanted: scrolled ?? defaultScrolled,
|
|
84529
84573
|
scrolled,
|
|
84530
84574
|
defaultScrolled,
|
|
84575
|
+
scrollResetKey,
|
|
84531
84576
|
way: null,
|
|
84532
84577
|
arrived: false,
|
|
84533
84578
|
// Whether the hold's writes glide (--navi-scroll:smooth).
|
|
@@ -84535,6 +84580,20 @@ const useListScrollSync = ({
|
|
|
84535
84580
|
};
|
|
84536
84581
|
} else {
|
|
84537
84582
|
const place = startPlaceRef.current;
|
|
84583
|
+
if (!compareTwoJsValues(place.scrollResetKey, scrollResetKey)) {
|
|
84584
|
+
place.scrollResetKey = scrollResetKey;
|
|
84585
|
+
place.wanted = "back_to_start";
|
|
84586
|
+
place.userTookOver = false;
|
|
84587
|
+
place.way = null;
|
|
84588
|
+
place.arrived = false;
|
|
84589
|
+
place.smooth = false;
|
|
84590
|
+
// What the list said it was reading, and what a search would give back,
|
|
84591
|
+
// are places in what it no longer shows.
|
|
84592
|
+
savedScrollRef.current = null;
|
|
84593
|
+
if (rememberScroll) {
|
|
84594
|
+
forgetScrollerPosition(listId);
|
|
84595
|
+
}
|
|
84596
|
+
}
|
|
84538
84597
|
if (place.scrolled !== scrolled) {
|
|
84539
84598
|
place.scrolled = scrolled;
|
|
84540
84599
|
place.defaultScrolled = defaultScrolled;
|
|
@@ -84543,7 +84602,7 @@ const useListScrollSync = ({
|
|
|
84543
84602
|
place.smooth = false;
|
|
84544
84603
|
} else if ((scrolled === undefined || scrolled === null) && !compareTwoJsValues(place.defaultScrolled, defaultScrolled)) {
|
|
84545
84604
|
place.defaultScrolled = defaultScrolled;
|
|
84546
|
-
if (!place.userTookOver) {
|
|
84605
|
+
if (!place.userTookOver && place.wanted !== "back_to_start") {
|
|
84547
84606
|
place.wanted = defaultScrolled;
|
|
84548
84607
|
// Placed again from where it stands: the way to the previous place
|
|
84549
84608
|
// says nothing about whose the next scrolls are.
|
|
@@ -84876,6 +84935,8 @@ const useListScrollSync = ({
|
|
|
84876
84935
|
wantedStart = total - windowSize;
|
|
84877
84936
|
} else if (typeof scrolledWanted === "number") {
|
|
84878
84937
|
heldItem = scrolledWanted;
|
|
84938
|
+
} else if (scrolledWanted === "back_to_start") {
|
|
84939
|
+
heldItem = 0;
|
|
84879
84940
|
} else if (scrolledWanted && scrolledWanted.id !== undefined) {
|
|
84880
84941
|
const itemIndex = listItems.locateItem(scrolledWanted.id);
|
|
84881
84942
|
if (itemIndex !== null) {
|
|
@@ -85110,7 +85171,6 @@ const useListScrollSync = ({
|
|
|
85110
85171
|
// Lorsqu'on selectionne quelque chose pendant une recherche, alors ensuite meme si on clear
|
|
85111
85172
|
// on veut pas revenir a la position scroll précédente car on veut garde l'item qu'on a selectionné visible
|
|
85112
85173
|
// (pour l'instant pas grave car on travaille pour le mode select qui fermera le dialog au select)
|
|
85113
|
-
const savedScrollRef = useRef(null);
|
|
85114
85174
|
const topMatchScoresKeyRef = useRef("");
|
|
85115
85175
|
const restoreScrollRafRef = useRef(null);
|
|
85116
85176
|
useLayoutEffect(() => {
|
|
@@ -85219,6 +85279,10 @@ const useListScrollSync = ({
|
|
|
85219
85279
|
if (scrolledWanted === "start" || scrolledWanted === undefined || startPlaceRef.current.userTookOver || !ref.current) {
|
|
85220
85280
|
return;
|
|
85221
85281
|
}
|
|
85282
|
+
if (scrolledWanted === "back_to_start") {
|
|
85283
|
+
placeBackAtStart();
|
|
85284
|
+
return;
|
|
85285
|
+
}
|
|
85222
85286
|
if (listItems.totalSignal.peek() === 0 || virtualItemSizeSignal.peek() === 0) {
|
|
85223
85287
|
return;
|
|
85224
85288
|
}
|
|
@@ -85317,6 +85381,24 @@ const useListScrollSync = ({
|
|
|
85317
85381
|
}
|
|
85318
85382
|
sendHeldScroll(scrollNow + delta);
|
|
85319
85383
|
};
|
|
85384
|
+
// The start of the list, what comes before its first item included, not an
|
|
85385
|
+
// item: a box of its own goes to 0. A box the list is further down of also
|
|
85386
|
+
// shows what stands above it, the control that asked for this among others, so
|
|
85387
|
+
// the list is brought back to the box's start and never sent forward to it.
|
|
85388
|
+
const placeBackAtStart = () => {
|
|
85389
|
+
const scrollerEl = getScroller();
|
|
85390
|
+
if (ref.current.contains(scrollerEl)) {
|
|
85391
|
+
sendHeldScroll(0);
|
|
85392
|
+
return;
|
|
85393
|
+
}
|
|
85394
|
+
const scale = readScrollerScale(scrollerEl, horizontal);
|
|
85395
|
+
const viewportRect = getScrollerViewportRect(scrollerEl);
|
|
85396
|
+
const listRect = ref.current.getBoundingClientRect();
|
|
85397
|
+
const offsetNow = (horizontal ? listRect.left - viewportRect.left : listRect.top - viewportRect.top) / scale;
|
|
85398
|
+
const delta = offsetNow - getItemScrollInset(scrollerEl, ref.current, horizontal);
|
|
85399
|
+
const scrollNow = horizontal ? scrollerEl.scrollLeft : scrollerEl.scrollTop;
|
|
85400
|
+
sendHeldScroll(delta < 0 ? scrollNow + delta : scrollNow);
|
|
85401
|
+
};
|
|
85320
85402
|
// Every placement goes through here, the ones that find the list in place
|
|
85321
85403
|
// too: it keeps the way from where the scroller was to where it is sent,
|
|
85322
85404
|
// which is how a scroll event tells the hold's own scrolls from anyone
|
|
@@ -85539,27 +85621,35 @@ const useListScrollSync = ({
|
|
|
85539
85621
|
// landing or resizing — and said again when it reads differently (`ifChanged`):
|
|
85540
85622
|
// the same scroll, the screen said right.
|
|
85541
85623
|
const announcedRef = useRef(null);
|
|
85624
|
+
// A scroll landing past everything drawn (a key sending the list to its end,
|
|
85625
|
+
// a hand on the scrollbar) has no item to read a position from: it is said by
|
|
85626
|
+
// that re-read, even when it is the first thing the list has to say.
|
|
85627
|
+
const reportOwedRef = useRef(false);
|
|
85542
85628
|
const reportPosition = ({
|
|
85543
85629
|
ifChanged
|
|
85544
85630
|
} = {}) => {
|
|
85545
85631
|
if (!ref.current) {
|
|
85546
85632
|
return;
|
|
85547
85633
|
}
|
|
85548
|
-
if (ifChanged && !announcedRef.current) {
|
|
85634
|
+
if (ifChanged && !announcedRef.current && !reportOwedRef.current) {
|
|
85549
85635
|
return;
|
|
85550
85636
|
}
|
|
85551
85637
|
const remember = rememberScrollRef.current;
|
|
85552
85638
|
const onScrolledChange = onScrolledChangeRef.current;
|
|
85553
85639
|
const position = captureListAnchor(remember || Boolean(onScrolledChange));
|
|
85554
85640
|
if (!position) {
|
|
85641
|
+
if (!ifChanged) {
|
|
85642
|
+
reportOwedRef.current = true;
|
|
85643
|
+
}
|
|
85555
85644
|
return;
|
|
85556
85645
|
}
|
|
85646
|
+
reportOwedRef.current = false;
|
|
85557
85647
|
positionRef.current = position;
|
|
85558
85648
|
if (!remember && !onScrolledChange) {
|
|
85559
85649
|
return;
|
|
85560
85650
|
}
|
|
85561
85651
|
const scrolledNow = toScrolledPosition(position);
|
|
85562
|
-
if (ifChanged && isSamePosition(scrolledNow, announcedRef.current)) {
|
|
85652
|
+
if (ifChanged && announcedRef.current && isSamePosition(scrolledNow, announcedRef.current)) {
|
|
85563
85653
|
return;
|
|
85564
85654
|
}
|
|
85565
85655
|
announcedRef.current = scrolledNow;
|
|
@@ -86105,10 +86195,9 @@ const useListScrollSync = ({
|
|
|
86105
86195
|
// ends the hold like a wheel does — the ones that come with no input event
|
|
86106
86196
|
// at all: the status bar tap on iOS, find in page, a script.
|
|
86107
86197
|
// Only once the list has stood where it holds itself, though. Until then
|
|
86108
|
-
// the page is still settling around it, and
|
|
86109
|
-
//
|
|
86110
|
-
//
|
|
86111
|
-
// (whenRenderingResumes), and the hold puts it back at its next commit.
|
|
86198
|
+
// the page is still settling around it, and what that moves (a document
|
|
86199
|
+
// still too short for the offset clamps it) the hold puts back at its next
|
|
86200
|
+
// commit.
|
|
86112
86201
|
const letGoUnlessHeldScroll = () => {
|
|
86113
86202
|
const place = startPlaceRef.current;
|
|
86114
86203
|
const way = place.way;
|
|
@@ -90034,6 +90123,7 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
|
|
|
90034
90123
|
* scroller?: "self" | "parent" | "document" | Element | {current: Element},
|
|
90035
90124
|
* hoverWhileScrolling?: boolean,
|
|
90036
90125
|
* scrollResetOnNavigation?: boolean,
|
|
90126
|
+
* scrollResetKey?: any,
|
|
90037
90127
|
* fallback?: import("preact").ComponentChildren,
|
|
90038
90128
|
* searchFallback?: import("preact").ComponentChildren,
|
|
90039
90129
|
* searchText?: string,
|
|
@@ -90278,6 +90368,15 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
|
|
|
90278
90368
|
* overwrite each other (see docs/scroll.md). A fresh arrival at the page
|
|
90279
90369
|
* opens at `defaultScrolled` either way, and so does a list the caller holds
|
|
90280
90370
|
* through `scrolled`.
|
|
90371
|
+
* @param {any} [props.scrollResetKey]
|
|
90372
|
+
* What the list shows, said as a value: another order, another filter. When
|
|
90373
|
+
* it changes after mount (compared by value: `[order, filter]` can be written
|
|
90374
|
+
* at every render) the list goes back to its start before the paint, in
|
|
90375
|
+
* whichever box `scroller` names, and is held there until the user reaches
|
|
90376
|
+
* for it. A list whose start is in view in a box that also shows what stands
|
|
90377
|
+
* above it does not move. A `scrolled` changing in the same render wins. The
|
|
90378
|
+
* position remembered under the `id` for the address shown is dropped; see
|
|
90379
|
+
* docs/scroll.md.
|
|
90281
90380
|
* @param {boolean} [props.deselectable]
|
|
90282
90381
|
* A single-select list allowed to hold nothing: the selected item, pressed
|
|
90283
90382
|
* again, lets go. Without it the list is a radio group — a choice, once
|
|
@@ -106851,9 +106950,9 @@ SidePanel.Foot = SidePanelFoot;
|
|
|
106851
106950
|
* mount, or the first to render into an empty slot; later renders of a
|
|
106852
106951
|
* `SlotFill` that is not the filler leave the slot alone. A `SlotFill`
|
|
106853
106952
|
* unmounting empties the slot only while it is still that one, and so does one
|
|
106854
|
-
* in a page a route transition keeps while leaving (see
|
|
106855
|
-
* nav/route.jsx): still mounted, hidden, it must neither
|
|
106856
|
-
* take it back from the page arriving.
|
|
106953
|
+
* in or below a page a route transition keeps while leaving (see
|
|
106954
|
+
* keepLeavingPages in nav/route.jsx): still mounted, hidden, it must neither
|
|
106955
|
+
* stay in the slot nor take it back from the page arriving.
|
|
106857
106956
|
*
|
|
106858
106957
|
* **One `SlotFill`, rendered where the choice is made.** `isFilled` follows
|
|
106859
106958
|
* the fills as they mount and unmount, in the order the tree walks them. A
|
|
@@ -106918,8 +107017,10 @@ const createSlot = (SlotRenderer = Box) => {
|
|
|
106918
107017
|
}, []);
|
|
106919
107018
|
// In a page kept while leaving: out of the slot as if unmounted, since
|
|
106920
107019
|
// the page arriving is what the slot must show — or nothing, when it
|
|
106921
|
-
// fills none.
|
|
106922
|
-
|
|
107020
|
+
// fills none. The signal brings the render that steps out; hasLeft() refuses
|
|
107021
|
+
// a fill built in a kept page (a wrapper changing shape rebuilds what it
|
|
107022
|
+
// holds), which renders before that signal is set.
|
|
107023
|
+
if (routePage && (routePage.leavingSignal.value || routePage.hasLeft())) {
|
|
106923
107024
|
if (filler === fillerRef) {
|
|
106924
107025
|
filler = null;
|
|
106925
107026
|
slotPropsSignal.value = null;
|