@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/dev/jsenv_navi.js
CHANGED
|
@@ -489,32 +489,33 @@ const MountAfterPaint = ({
|
|
|
489
489
|
/**
|
|
490
490
|
* Builds, now, every box still waiting whose top is above `bottom` (in the
|
|
491
491
|
* document's coordinates): what the document will show once scrolled so that
|
|
492
|
-
* `bottom` is the bottom of the screen.
|
|
493
|
-
*
|
|
494
|
-
*
|
|
492
|
+
* `bottom` is the bottom of the screen.
|
|
493
|
+
*
|
|
494
|
+
* Each box is read once those before it have their height. A box has no height
|
|
495
|
+
* until it is built, so read together they would all stand at the end of what
|
|
496
|
+
* is built, above `bottom` as soon as the offset is worth a screen: a page of
|
|
497
|
+
* sections would be built whole before its first frame. A box found below
|
|
498
|
+
* `bottom` waits: a build only pushes it further down, and where it stands
|
|
499
|
+
* already makes the document tall enough for the offset.
|
|
500
|
+
*
|
|
501
|
+
* The walk follows the set live, in mount order: a box mounted by a build is
|
|
502
|
+
* read too. One standing higher than boxes built before it (mounted later) can
|
|
503
|
+
* leave a few built that the offset does not show, never one missing that it
|
|
504
|
+
* does.
|
|
495
505
|
*
|
|
496
506
|
* Renders synchronously, so it must be called outside a Preact commit: a render
|
|
497
507
|
* flushed from a layout effect runs inside the commit still walking the tree.
|
|
498
508
|
*/
|
|
499
509
|
const buildDeferredBoxesAbove = bottom => {
|
|
500
|
-
if (deferredBoxes.size === 0) {
|
|
501
|
-
return;
|
|
502
|
-
}
|
|
503
|
-
const toBuild = [];
|
|
504
510
|
for (const deferredBox of deferredBoxes) {
|
|
505
511
|
const top = readTopInWindow(deferredBox.getElement());
|
|
506
|
-
if (top
|
|
507
|
-
|
|
512
|
+
if (top === null || top + window.scrollY >= bottom) {
|
|
513
|
+
continue;
|
|
508
514
|
}
|
|
509
|
-
|
|
510
|
-
if (toBuild.length === 0) {
|
|
511
|
-
return;
|
|
512
|
-
}
|
|
513
|
-
flushSyncRendering(() => {
|
|
514
|
-
for (const deferredBox of toBuild) {
|
|
515
|
+
flushSyncRendering(() => {
|
|
515
516
|
deferredBox.build();
|
|
516
|
-
}
|
|
517
|
-
}
|
|
517
|
+
});
|
|
518
|
+
}
|
|
518
519
|
};
|
|
519
520
|
|
|
520
521
|
// null for a box nothing draws (a closed popup, a hidden tab): no frame shows
|
|
@@ -10839,6 +10840,12 @@ const startAtTop = (url, { from } = {}) => {
|
|
|
10839
10840
|
// position to come back to — the return would keep the offset of the page
|
|
10840
10841
|
// being left.
|
|
10841
10842
|
positionByUrl.set(href, { x: 0, y: 0 });
|
|
10843
|
+
// A list holding the document on the page arriving has placed it already: a
|
|
10844
|
+
// navigation holding the rendering gets here after that render, and nothing
|
|
10845
|
+
// owes the list another commit to put it back (see holdDocumentScroll).
|
|
10846
|
+
if (isDocumentHeld()) {
|
|
10847
|
+
return;
|
|
10848
|
+
}
|
|
10842
10849
|
window.scrollTo({ top: 0, left: 0, behavior: "instant" });
|
|
10843
10850
|
};
|
|
10844
10851
|
// Also what decides whether a push carries the state of the page it keeps
|
|
@@ -14023,10 +14030,17 @@ const isRenderingPageChange = () => renderingPageChange;
|
|
|
14023
14030
|
* outside any render — by a subscription deciding whether to re-render, by
|
|
14024
14031
|
* the scroll restoration when a position is due — and it reads the routes
|
|
14025
14032
|
* untracked, so asking subscribes nobody to them.
|
|
14026
|
-
* - `
|
|
14027
|
-
*
|
|
14028
|
-
*
|
|
14029
|
-
*
|
|
14033
|
+
* - `hasLeft()` — whether the page, or a page it sits in, is kept while leaving.
|
|
14034
|
+
* Written by the container's render, before anything below it renders, and
|
|
14035
|
+
* final. `isShown()` can answer false for a page that stays on screen (the
|
|
14036
|
+
* address coming back, a container first rendered while the routes are
|
|
14037
|
+
* frozen), so what cannot be undone asks this one.
|
|
14038
|
+
* - `leavingSignal` — true once the page, or a page it sits in, is hidden and
|
|
14039
|
+
* kept while the movement plays: still mounted, so what it fills or moves
|
|
14040
|
+
* outside its own nodes (a slot in a bar, the document a list scrolls) steps
|
|
14041
|
+
* out rather than showing with, or moving, the page arriving. Every box of it
|
|
14042
|
+
* measures 0×0 by then. Set after the render keeping the page, so that render
|
|
14043
|
+
* and what it builds can only ask `hasLeft()`.
|
|
14030
14044
|
*/
|
|
14031
14045
|
const RoutePageContext = createContext(null);
|
|
14032
14046
|
|
|
@@ -37886,7 +37900,7 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
37886
37900
|
continue;
|
|
37887
37901
|
}
|
|
37888
37902
|
entry.hidden = true;
|
|
37889
|
-
entry.page.
|
|
37903
|
+
entry.page.ownLeavingSignal.value = true;
|
|
37890
37904
|
// The page renders on its own while kept (a component reading a signal
|
|
37891
37905
|
// the address moved), never through this container: a top node it
|
|
37892
37906
|
// replaces lands between the markers unmarked, a text it writes shows
|
|
@@ -37974,11 +37988,21 @@ const hideNodesBetween = (start, end, observer) => {
|
|
|
37974
37988
|
// page it sits in is shown itself. Never again once kept while leaving: coming
|
|
37975
37989
|
// back to its route mounts the page anew.
|
|
37976
37990
|
const createRoutePage = (readShownBranch, parentPage) => {
|
|
37991
|
+
const ownLeavingSignal = signal(false);
|
|
37977
37992
|
const page = {
|
|
37978
37993
|
branchId: null,
|
|
37979
37994
|
element: undefined,
|
|
37980
37995
|
left: false,
|
|
37981
|
-
|
|
37996
|
+
ownLeavingSignal,
|
|
37997
|
+
// A page nested in one that left is hidden with it, even while its own
|
|
37998
|
+
// container goes on picking it (a route matching on both sides).
|
|
37999
|
+
leavingSignal: parentPage ? computed(() => ownLeavingSignal.value || parentPage.leavingSignal.value) : ownLeavingSignal,
|
|
38000
|
+
hasLeft: () => {
|
|
38001
|
+
if (page.left) {
|
|
38002
|
+
return true;
|
|
38003
|
+
}
|
|
38004
|
+
return parentPage ? parentPage.hasLeft() : false;
|
|
38005
|
+
},
|
|
37982
38006
|
isShown: () => {
|
|
37983
38007
|
if (page.left) {
|
|
37984
38008
|
return false;
|
|
@@ -87454,27 +87478,35 @@ const useListScrollSync = ({
|
|
|
87454
87478
|
// landing or resizing — and said again when it reads differently (`ifChanged`):
|
|
87455
87479
|
// the same scroll, the screen said right.
|
|
87456
87480
|
const announcedRef = useRef(null);
|
|
87481
|
+
// A scroll landing past everything drawn (a key sending the list to its end,
|
|
87482
|
+
// a hand on the scrollbar) has no item to read a position from: it is said by
|
|
87483
|
+
// that re-read, even when it is the first thing the list has to say.
|
|
87484
|
+
const reportOwedRef = useRef(false);
|
|
87457
87485
|
const reportPosition = ({
|
|
87458
87486
|
ifChanged
|
|
87459
87487
|
} = {}) => {
|
|
87460
87488
|
if (!ref.current) {
|
|
87461
87489
|
return;
|
|
87462
87490
|
}
|
|
87463
|
-
if (ifChanged && !announcedRef.current) {
|
|
87491
|
+
if (ifChanged && !announcedRef.current && !reportOwedRef.current) {
|
|
87464
87492
|
return;
|
|
87465
87493
|
}
|
|
87466
87494
|
const remember = rememberScrollRef.current;
|
|
87467
87495
|
const onScrolledChange = onScrolledChangeRef.current;
|
|
87468
87496
|
const position = captureListAnchor(remember || Boolean(onScrolledChange));
|
|
87469
87497
|
if (!position) {
|
|
87498
|
+
if (!ifChanged) {
|
|
87499
|
+
reportOwedRef.current = true;
|
|
87500
|
+
}
|
|
87470
87501
|
return;
|
|
87471
87502
|
}
|
|
87503
|
+
reportOwedRef.current = false;
|
|
87472
87504
|
positionRef.current = position;
|
|
87473
87505
|
if (!remember && !onScrolledChange) {
|
|
87474
87506
|
return;
|
|
87475
87507
|
}
|
|
87476
87508
|
const scrolledNow = toScrolledPosition(position);
|
|
87477
|
-
if (ifChanged && isSamePosition(scrolledNow, announcedRef.current)) {
|
|
87509
|
+
if (ifChanged && announcedRef.current && isSamePosition(scrolledNow, announcedRef.current)) {
|
|
87478
87510
|
return;
|
|
87479
87511
|
}
|
|
87480
87512
|
announcedRef.current = scrolledNow;
|
|
@@ -88030,10 +88062,9 @@ const useListScrollSync = ({
|
|
|
88030
88062
|
// ends the hold like a wheel does — the ones that come with no input event
|
|
88031
88063
|
// at all: the status bar tap on iOS, find in page, a script.
|
|
88032
88064
|
// Only once the list has stood where it holds itself, though. Until then
|
|
88033
|
-
// the page is still settling around it, and
|
|
88034
|
-
//
|
|
88035
|
-
//
|
|
88036
|
-
// (whenRenderingResumes), and the hold puts it back at its next commit.
|
|
88065
|
+
// the page is still settling around it, and what that moves (a document
|
|
88066
|
+
// still too short for the offset clamps it) the hold puts back at its next
|
|
88067
|
+
// commit.
|
|
88037
88068
|
const letGoUnlessHeldScroll = () => {
|
|
88038
88069
|
const place = startPlaceRef.current;
|
|
88039
88070
|
const way = place.way;
|
|
@@ -109061,9 +109092,9 @@ SidePanel.Foot = SidePanelFoot;
|
|
|
109061
109092
|
* mount, or the first to render into an empty slot; later renders of a
|
|
109062
109093
|
* `SlotFill` that is not the filler leave the slot alone. A `SlotFill`
|
|
109063
109094
|
* unmounting empties the slot only while it is still that one, and so does one
|
|
109064
|
-
* in a page a route transition keeps while leaving (see
|
|
109065
|
-
* nav/route.jsx): still mounted, hidden, it must neither
|
|
109066
|
-
* take it back from the page arriving.
|
|
109095
|
+
* in or below a page a route transition keeps while leaving (see
|
|
109096
|
+
* keepLeavingPages in nav/route.jsx): still mounted, hidden, it must neither
|
|
109097
|
+
* stay in the slot nor take it back from the page arriving.
|
|
109067
109098
|
*
|
|
109068
109099
|
* **One `SlotFill`, rendered where the choice is made.** `isFilled` follows
|
|
109069
109100
|
* the fills as they mount and unmount, in the order the tree walks them. A
|
|
@@ -109128,8 +109159,10 @@ const createSlot = (SlotRenderer = Box) => {
|
|
|
109128
109159
|
}, []);
|
|
109129
109160
|
// In a page kept while leaving: out of the slot as if unmounted, since
|
|
109130
109161
|
// the page arriving is what the slot must show — or nothing, when it
|
|
109131
|
-
// fills none.
|
|
109132
|
-
|
|
109162
|
+
// fills none. The signal brings the render that steps out; hasLeft() refuses
|
|
109163
|
+
// a fill built in a kept page (a wrapper changing shape rebuilds what it
|
|
109164
|
+
// holds), which renders before that signal is set.
|
|
109165
|
+
if (routePage && (routePage.leavingSignal.value || routePage.hasLeft())) {
|
|
109133
109166
|
if (filler === fillerRef) {
|
|
109134
109167
|
filler = null;
|
|
109135
109168
|
slotPropsSignal.value = null;
|