@jsenv/navi 0.29.515 → 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 +67 -34
- package/dist/dev/jsenv_navi.js.map +7 -7
- package/dist/jsenv_navi.js +67 -34
- package/dist/jsenv_navi.js.map +7 -7
- 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
|
|
@@ -13422,10 +13429,17 @@ const isRenderingPageChange = () => renderingPageChange;
|
|
|
13422
13429
|
* outside any render — by a subscription deciding whether to re-render, by
|
|
13423
13430
|
* the scroll restoration when a position is due — and it reads the routes
|
|
13424
13431
|
* untracked, so asking subscribes nobody to them.
|
|
13425
|
-
* - `
|
|
13426
|
-
*
|
|
13427
|
-
*
|
|
13428
|
-
*
|
|
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()`.
|
|
13429
13443
|
*/
|
|
13430
13444
|
const RoutePageContext = createContext(null);
|
|
13431
13445
|
|
|
@@ -36635,7 +36649,7 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
36635
36649
|
continue;
|
|
36636
36650
|
}
|
|
36637
36651
|
entry.hidden = true;
|
|
36638
|
-
entry.page.
|
|
36652
|
+
entry.page.ownLeavingSignal.value = true;
|
|
36639
36653
|
// The page renders on its own while kept (a component reading a signal
|
|
36640
36654
|
// the address moved), never through this container: a top node it
|
|
36641
36655
|
// replaces lands between the markers unmarked, a text it writes shows
|
|
@@ -36723,11 +36737,21 @@ const hideNodesBetween = (start, end, observer) => {
|
|
|
36723
36737
|
// page it sits in is shown itself. Never again once kept while leaving: coming
|
|
36724
36738
|
// back to its route mounts the page anew.
|
|
36725
36739
|
const createRoutePage = (readShownBranch, parentPage) => {
|
|
36740
|
+
const ownLeavingSignal = signal(false);
|
|
36726
36741
|
const page = {
|
|
36727
36742
|
branchId: null,
|
|
36728
36743
|
element: undefined,
|
|
36729
36744
|
left: false,
|
|
36730
|
-
|
|
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
|
+
},
|
|
36731
36755
|
isShown: () => {
|
|
36732
36756
|
if (page.left) {
|
|
36733
36757
|
return false;
|
|
@@ -85597,27 +85621,35 @@ const useListScrollSync = ({
|
|
|
85597
85621
|
// landing or resizing — and said again when it reads differently (`ifChanged`):
|
|
85598
85622
|
// the same scroll, the screen said right.
|
|
85599
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);
|
|
85600
85628
|
const reportPosition = ({
|
|
85601
85629
|
ifChanged
|
|
85602
85630
|
} = {}) => {
|
|
85603
85631
|
if (!ref.current) {
|
|
85604
85632
|
return;
|
|
85605
85633
|
}
|
|
85606
|
-
if (ifChanged && !announcedRef.current) {
|
|
85634
|
+
if (ifChanged && !announcedRef.current && !reportOwedRef.current) {
|
|
85607
85635
|
return;
|
|
85608
85636
|
}
|
|
85609
85637
|
const remember = rememberScrollRef.current;
|
|
85610
85638
|
const onScrolledChange = onScrolledChangeRef.current;
|
|
85611
85639
|
const position = captureListAnchor(remember || Boolean(onScrolledChange));
|
|
85612
85640
|
if (!position) {
|
|
85641
|
+
if (!ifChanged) {
|
|
85642
|
+
reportOwedRef.current = true;
|
|
85643
|
+
}
|
|
85613
85644
|
return;
|
|
85614
85645
|
}
|
|
85646
|
+
reportOwedRef.current = false;
|
|
85615
85647
|
positionRef.current = position;
|
|
85616
85648
|
if (!remember && !onScrolledChange) {
|
|
85617
85649
|
return;
|
|
85618
85650
|
}
|
|
85619
85651
|
const scrolledNow = toScrolledPosition(position);
|
|
85620
|
-
if (ifChanged && isSamePosition(scrolledNow, announcedRef.current)) {
|
|
85652
|
+
if (ifChanged && announcedRef.current && isSamePosition(scrolledNow, announcedRef.current)) {
|
|
85621
85653
|
return;
|
|
85622
85654
|
}
|
|
85623
85655
|
announcedRef.current = scrolledNow;
|
|
@@ -86163,10 +86195,9 @@ const useListScrollSync = ({
|
|
|
86163
86195
|
// ends the hold like a wheel does — the ones that come with no input event
|
|
86164
86196
|
// at all: the status bar tap on iOS, find in page, a script.
|
|
86165
86197
|
// Only once the list has stood where it holds itself, though. Until then
|
|
86166
|
-
// the page is still settling around it, and
|
|
86167
|
-
//
|
|
86168
|
-
//
|
|
86169
|
-
// (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.
|
|
86170
86201
|
const letGoUnlessHeldScroll = () => {
|
|
86171
86202
|
const place = startPlaceRef.current;
|
|
86172
86203
|
const way = place.way;
|
|
@@ -106919,9 +106950,9 @@ SidePanel.Foot = SidePanelFoot;
|
|
|
106919
106950
|
* mount, or the first to render into an empty slot; later renders of a
|
|
106920
106951
|
* `SlotFill` that is not the filler leave the slot alone. A `SlotFill`
|
|
106921
106952
|
* unmounting empties the slot only while it is still that one, and so does one
|
|
106922
|
-
* in a page a route transition keeps while leaving (see
|
|
106923
|
-
* nav/route.jsx): still mounted, hidden, it must neither
|
|
106924
|
-
* 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.
|
|
106925
106956
|
*
|
|
106926
106957
|
* **One `SlotFill`, rendered where the choice is made.** `isFilled` follows
|
|
106927
106958
|
* the fills as they mount and unmount, in the order the tree walks them. A
|
|
@@ -106986,8 +107017,10 @@ const createSlot = (SlotRenderer = Box) => {
|
|
|
106986
107017
|
}, []);
|
|
106987
107018
|
// In a page kept while leaving: out of the slot as if unmounted, since
|
|
106988
107019
|
// the page arriving is what the slot must show — or nothing, when it
|
|
106989
|
-
// fills none.
|
|
106990
|
-
|
|
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())) {
|
|
106991
107024
|
if (filler === fillerRef) {
|
|
106992
107025
|
filler = null;
|
|
106993
107026
|
slotPropsSignal.value = null;
|