@jsenv/navi 0.29.515 → 0.29.517
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 +101 -34
- package/dist/dev/jsenv_navi.js.map +9 -9
- package/dist/jsenv_navi.js +101 -34
- package/dist/jsenv_navi.js.map +9 -9
- 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;
|
|
@@ -39810,6 +39834,12 @@ const css$17 = /* css */`@property --navi-route-transition-leave {
|
|
|
39810
39834
|
inherits: false
|
|
39811
39835
|
}
|
|
39812
39836
|
|
|
39837
|
+
@property --navi-furniture-fade {
|
|
39838
|
+
syntax: "<number>";
|
|
39839
|
+
inherits: true;
|
|
39840
|
+
initial-value: 1;
|
|
39841
|
+
}
|
|
39842
|
+
|
|
39813
39843
|
:root::view-transition, :root::view-transition-group(*), :root::view-transition-image-pair(*), :root::view-transition-old(*), :root::view-transition-new(*) {
|
|
39814
39844
|
--navi-route-transition-leave: inherit;
|
|
39815
39845
|
--navi-route-transition-enter: inherit;
|
|
@@ -39891,6 +39921,24 @@ const css$17 = /* css */`@property --navi-route-transition-leave {
|
|
|
39891
39921
|
&::view-transition-group(*), &::view-transition-old(*), &::view-transition-new(*) {
|
|
39892
39922
|
animation-duration: var(--navi-route-transition-duration, .3s);
|
|
39893
39923
|
}
|
|
39924
|
+
|
|
39925
|
+
&::view-transition-image-pair(.navi_furniture_shared) {
|
|
39926
|
+
animation: navi-furniture-fade
|
|
39927
|
+
var(--navi-route-transition-duration, .3s) ease both;
|
|
39928
|
+
}
|
|
39929
|
+
|
|
39930
|
+
&::view-transition-old(.navi_furniture_shared), &::view-transition-new(.navi_furniture_shared) {
|
|
39931
|
+
mix-blend-mode: plus-lighter;
|
|
39932
|
+
animation-name: none;
|
|
39933
|
+
}
|
|
39934
|
+
|
|
39935
|
+
&::view-transition-old(.navi_furniture_shared) {
|
|
39936
|
+
opacity: calc(1 - var(--navi-furniture-fade));
|
|
39937
|
+
}
|
|
39938
|
+
|
|
39939
|
+
&::view-transition-new(.navi_furniture_shared) {
|
|
39940
|
+
opacity: var(--navi-furniture-fade);
|
|
39941
|
+
}
|
|
39894
39942
|
}
|
|
39895
39943
|
|
|
39896
39944
|
&::view-transition-old(root), &::view-transition-new(root), &::view-transition-old(navi-route-transition), &::view-transition-new(navi-route-transition) {
|
|
@@ -40177,6 +40225,16 @@ const css$17 = /* css */`@property --navi-route-transition-leave {
|
|
|
40177
40225
|
opacity: 0;
|
|
40178
40226
|
}
|
|
40179
40227
|
}
|
|
40228
|
+
|
|
40229
|
+
@keyframes navi-furniture-fade {
|
|
40230
|
+
from {
|
|
40231
|
+
--navi-furniture-fade: 0;
|
|
40232
|
+
}
|
|
40233
|
+
|
|
40234
|
+
to {
|
|
40235
|
+
--navi-furniture-fade: 1;
|
|
40236
|
+
}
|
|
40237
|
+
}
|
|
40180
40238
|
`;
|
|
40181
40239
|
|
|
40182
40240
|
/**
|
|
@@ -87454,27 +87512,35 @@ const useListScrollSync = ({
|
|
|
87454
87512
|
// landing or resizing — and said again when it reads differently (`ifChanged`):
|
|
87455
87513
|
// the same scroll, the screen said right.
|
|
87456
87514
|
const announcedRef = useRef(null);
|
|
87515
|
+
// A scroll landing past everything drawn (a key sending the list to its end,
|
|
87516
|
+
// a hand on the scrollbar) has no item to read a position from: it is said by
|
|
87517
|
+
// that re-read, even when it is the first thing the list has to say.
|
|
87518
|
+
const reportOwedRef = useRef(false);
|
|
87457
87519
|
const reportPosition = ({
|
|
87458
87520
|
ifChanged
|
|
87459
87521
|
} = {}) => {
|
|
87460
87522
|
if (!ref.current) {
|
|
87461
87523
|
return;
|
|
87462
87524
|
}
|
|
87463
|
-
if (ifChanged && !announcedRef.current) {
|
|
87525
|
+
if (ifChanged && !announcedRef.current && !reportOwedRef.current) {
|
|
87464
87526
|
return;
|
|
87465
87527
|
}
|
|
87466
87528
|
const remember = rememberScrollRef.current;
|
|
87467
87529
|
const onScrolledChange = onScrolledChangeRef.current;
|
|
87468
87530
|
const position = captureListAnchor(remember || Boolean(onScrolledChange));
|
|
87469
87531
|
if (!position) {
|
|
87532
|
+
if (!ifChanged) {
|
|
87533
|
+
reportOwedRef.current = true;
|
|
87534
|
+
}
|
|
87470
87535
|
return;
|
|
87471
87536
|
}
|
|
87537
|
+
reportOwedRef.current = false;
|
|
87472
87538
|
positionRef.current = position;
|
|
87473
87539
|
if (!remember && !onScrolledChange) {
|
|
87474
87540
|
return;
|
|
87475
87541
|
}
|
|
87476
87542
|
const scrolledNow = toScrolledPosition(position);
|
|
87477
|
-
if (ifChanged && isSamePosition(scrolledNow, announcedRef.current)) {
|
|
87543
|
+
if (ifChanged && announcedRef.current && isSamePosition(scrolledNow, announcedRef.current)) {
|
|
87478
87544
|
return;
|
|
87479
87545
|
}
|
|
87480
87546
|
announcedRef.current = scrolledNow;
|
|
@@ -88030,10 +88096,9 @@ const useListScrollSync = ({
|
|
|
88030
88096
|
// ends the hold like a wheel does — the ones that come with no input event
|
|
88031
88097
|
// at all: the status bar tap on iOS, find in page, a script.
|
|
88032
88098
|
// 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.
|
|
88099
|
+
// the page is still settling around it, and what that moves (a document
|
|
88100
|
+
// still too short for the offset clamps it) the hold puts back at its next
|
|
88101
|
+
// commit.
|
|
88037
88102
|
const letGoUnlessHeldScroll = () => {
|
|
88038
88103
|
const place = startPlaceRef.current;
|
|
88039
88104
|
const way = place.way;
|
|
@@ -109061,9 +109126,9 @@ SidePanel.Foot = SidePanelFoot;
|
|
|
109061
109126
|
* mount, or the first to render into an empty slot; later renders of a
|
|
109062
109127
|
* `SlotFill` that is not the filler leave the slot alone. A `SlotFill`
|
|
109063
109128
|
* 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.
|
|
109129
|
+
* in or below a page a route transition keeps while leaving (see
|
|
109130
|
+
* keepLeavingPages in nav/route.jsx): still mounted, hidden, it must neither
|
|
109131
|
+
* stay in the slot nor take it back from the page arriving.
|
|
109067
109132
|
*
|
|
109068
109133
|
* **One `SlotFill`, rendered where the choice is made.** `isFilled` follows
|
|
109069
109134
|
* the fills as they mount and unmount, in the order the tree walks them. A
|
|
@@ -109128,8 +109193,10 @@ const createSlot = (SlotRenderer = Box) => {
|
|
|
109128
109193
|
}, []);
|
|
109129
109194
|
// In a page kept while leaving: out of the slot as if unmounted, since
|
|
109130
109195
|
// the page arriving is what the slot must show — or nothing, when it
|
|
109131
|
-
// fills none.
|
|
109132
|
-
|
|
109196
|
+
// fills none. The signal brings the render that steps out; hasLeft() refuses
|
|
109197
|
+
// a fill built in a kept page (a wrapper changing shape rebuilds what it
|
|
109198
|
+
// holds), which renders before that signal is set.
|
|
109199
|
+
if (routePage && (routePage.leavingSignal.value || routePage.hasLeft())) {
|
|
109133
109200
|
if (filler === fillerRef) {
|
|
109134
109201
|
filler = null;
|
|
109135
109202
|
slotPropsSignal.value = null;
|