@jsenv/navi 0.30.32 → 0.30.34
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 +91 -37
- package/dist/dev/jsenv_navi.js.map +4 -4
- package/dist/jsenv_navi.js +91 -37
- package/dist/jsenv_navi.js.map +4 -4
- package/package.json +1 -1
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -14441,7 +14441,9 @@ const isRenderingPageChange = () => renderingPageChange;
|
|
|
14441
14441
|
* outside its own nodes (a slot in a bar, the document a list scrolls) steps
|
|
14442
14442
|
* out rather than showing with, or moving, the page arriving. Every box of it
|
|
14443
14443
|
* measures 0×0 by then. Set after the render keeping the page, so that render
|
|
14444
|
-
* and what it builds can only ask `hasLeft()`.
|
|
14444
|
+
* and what it builds can only ask `hasLeft()`. Cleared by the render showing
|
|
14445
|
+
* the page again, before anything below it renders: what mounts then never
|
|
14446
|
+
* reads its page as leaving.
|
|
14445
14447
|
*/
|
|
14446
14448
|
const RoutePageContext = createContext(null);
|
|
14447
14449
|
|
|
@@ -38547,8 +38549,16 @@ const RouteRowPane = ({
|
|
|
38547
38549
|
value: page
|
|
38548
38550
|
}, branch.node));
|
|
38549
38551
|
}
|
|
38552
|
+
// Back on screen before what it holds renders: built here, or mounted again under
|
|
38553
|
+
// it, that content runs its layout effects before this component's, and would
|
|
38554
|
+
// otherwise read its page as leaving.
|
|
38555
|
+
if (shown) {
|
|
38556
|
+
page.ownLeavingSignal.value = false;
|
|
38557
|
+
}
|
|
38550
38558
|
useLayoutEffect(() => {
|
|
38551
|
-
|
|
38559
|
+
if (!shown) {
|
|
38560
|
+
page.ownLeavingSignal.value = true;
|
|
38561
|
+
}
|
|
38552
38562
|
}, [shown]);
|
|
38553
38563
|
return jsx("div", {
|
|
38554
38564
|
"data-route-row-pane": "",
|
|
@@ -42658,7 +42668,7 @@ const css$16 = /* css */`.navi_route_travel {
|
|
|
42658
42668
|
display: flex;
|
|
42659
42669
|
}
|
|
42660
42670
|
|
|
42661
|
-
& > [data-route-row-pane][inert] {
|
|
42671
|
+
& > [data-route-row-pane][inert]:not([data-route-row-held]), &:has( > [data-route-row-held]) > [data-route-row-pane]:not([data-route-row-held]) {
|
|
42662
42672
|
top: var(--navi-route-row-pin, 0);
|
|
42663
42673
|
contain: paint;
|
|
42664
42674
|
max-height: 100dvh;
|
|
@@ -42708,6 +42718,12 @@ const ROW_READING = {
|
|
|
42708
42718
|
// How far a scroll position written can read back from what was written: rounded to
|
|
42709
42719
|
// the device's pixels.
|
|
42710
42720
|
const WRITE_ROUNDING = 1;
|
|
42721
|
+
// The most one frame of a travel plays: a frame of a 30fps screen, which is what a
|
|
42722
|
+
// browser saving power gives (an iPhone in Low Power Mode, Chrome's Energy Saver).
|
|
42723
|
+
// A frame later than that is a main thread busy elsewhere (the page arriving builds,
|
|
42724
|
+
// a list fills its budget), and the travel takes longer rather than jump by it. Not a
|
|
42725
|
+
// frame of a 60Hz screen: that would play every travel in slow motion at 30fps.
|
|
42726
|
+
const TRAVEL_FRAME_MAX_MS = 1000 / 30;
|
|
42711
42727
|
|
|
42712
42728
|
/**
|
|
42713
42729
|
* @type {import("preact").FunctionComponent<{
|
|
@@ -42983,18 +42999,22 @@ const RouteTravel = ({
|
|
|
42983
42999
|
// hesitates, then peaks at 1.65 times this one's speed): two rows of tabs in one
|
|
42984
43000
|
// app would not move alike. The scroll position is written at every frame, so the
|
|
42985
43001
|
// row stays a scroller all the way: what follows it (a Nav's bar) reads it as it
|
|
42986
|
-
// reads a hand, and a finger landing finds it where it is.
|
|
42987
|
-
//
|
|
43002
|
+
// reads a hand, and a finger landing finds it where it is. That is played on the
|
|
43003
|
+
// main thread: a transform on the panes would play on the compositor, but it would
|
|
43004
|
+
// capture what the page on screen holds in position: fixed. Hence a clock of its
|
|
43005
|
+
// own, which a busy main thread slows down rather than makes jump.
|
|
42988
43006
|
const playTravel = (pane, movement) => {
|
|
42989
43007
|
const row = rowRef.current;
|
|
42990
43008
|
// Already moving, so there is no ease-in to play: it would stall the row for an
|
|
42991
43009
|
// instant right where the eye is following it.
|
|
42992
43010
|
const replaced = movement.playing;
|
|
42993
43011
|
const inFlight = Boolean(replaced) || Boolean(movement.rowTaken);
|
|
43012
|
+
// Before the row is read: let go of for an instant, it would be snapped to the
|
|
43013
|
+
// nearest page by that read, and the travel would start from there.
|
|
43014
|
+
row.setAttribute("data-route-row-travelling", "");
|
|
42994
43015
|
if (replaced) {
|
|
42995
|
-
|
|
42996
|
-
|
|
42997
|
-
replaced.cancelFrame();
|
|
43016
|
+
replaced.cancel();
|
|
43017
|
+
movement.playing = null;
|
|
42998
43018
|
}
|
|
42999
43019
|
const from = row.scrollLeft;
|
|
43000
43020
|
const {
|
|
@@ -43006,56 +43026,88 @@ const RouteTravel = ({
|
|
|
43006
43026
|
const travelMs = boxes < 1 ? durationMs * boxes : durationMs;
|
|
43007
43027
|
if (!travelMs) {
|
|
43008
43028
|
row.scrollLeft = pane.offsetLeft;
|
|
43029
|
+
letRowGo(movement);
|
|
43009
43030
|
// A write that changes nothing is followed by no scroll event to say the row
|
|
43010
43031
|
// stopped. After the commit that asked, which goes on to say the row moves.
|
|
43011
43032
|
Promise.resolve().then(landRow);
|
|
43012
43033
|
return;
|
|
43013
43034
|
}
|
|
43014
43035
|
const curve = inFlight ? CSS_EASE_OUT : CSS_EASE;
|
|
43015
|
-
let start = null;
|
|
43016
43036
|
let frame = null;
|
|
43037
|
+
// How much of the travel has played, frame by frame. A travel setting off plays
|
|
43038
|
+
// nothing at its first frame, which may have begun while the press was still being
|
|
43039
|
+
// handled: that is no travel. One taking over goes on from the last frame of the
|
|
43040
|
+
// one it replaces, or the row would stand still for a frame where the eye follows it.
|
|
43041
|
+
let played = 0;
|
|
43017
43042
|
const playing = {
|
|
43018
43043
|
// Where this travel put the row, for a scroll event to tell it from a hand.
|
|
43019
43044
|
written: from,
|
|
43020
|
-
|
|
43045
|
+
lastFrame: replaced ? replaced.lastFrame : null,
|
|
43046
|
+
cancel: () => {
|
|
43021
43047
|
cancelAnimationFrame(frame);
|
|
43022
|
-
},
|
|
43023
|
-
stop: () => {
|
|
43024
|
-
playing.cancelFrame();
|
|
43025
|
-
if (movement.playing === playing) {
|
|
43026
|
-
movement.playing = null;
|
|
43027
|
-
row.removeAttribute("data-route-row-travelling");
|
|
43028
|
-
}
|
|
43029
43048
|
}
|
|
43030
43049
|
};
|
|
43031
43050
|
const step = now => {
|
|
43032
|
-
if (
|
|
43033
|
-
|
|
43034
|
-
|
|
43035
|
-
|
|
43051
|
+
if (playing.lastFrame !== null) {
|
|
43052
|
+
const gap = now - playing.lastFrame;
|
|
43053
|
+
if (gap > TRAVEL_FRAME_MAX_MS) {
|
|
43054
|
+
played += TRAVEL_FRAME_MAX_MS;
|
|
43055
|
+
} else if (gap > 0) {
|
|
43056
|
+
played += gap;
|
|
43057
|
+
}
|
|
43036
43058
|
}
|
|
43037
|
-
|
|
43038
|
-
const elapsed =
|
|
43059
|
+
playing.lastFrame = now;
|
|
43060
|
+
const elapsed = played / travelMs;
|
|
43039
43061
|
// Read at every frame: the layout may move under the travel (a scrollbar
|
|
43040
43062
|
// coming in narrows the row), and it goes where the page stands.
|
|
43041
43063
|
const to = pane.offsetLeft;
|
|
43042
43064
|
const arrived = elapsed >= 1;
|
|
43043
43065
|
playing.written = arrived ? to : from + (to - from) * easedProgress(elapsed, curve);
|
|
43044
43066
|
row.scrollLeft = playing.written;
|
|
43067
|
+
// In the frame it is written: the scroll event saying so comes a frame later,
|
|
43068
|
+
// and what follows the row would be drawn a frame behind it.
|
|
43069
|
+
sayRowMoves();
|
|
43045
43070
|
if (!arrived) {
|
|
43046
43071
|
frame = requestAnimationFrame(step);
|
|
43047
43072
|
return;
|
|
43048
43073
|
}
|
|
43049
|
-
|
|
43074
|
+
letRowGo(movement);
|
|
43050
43075
|
// Said here rather than waited for: the last frames of a curve can move the row
|
|
43051
43076
|
// by less than a pixel, and nothing then says it has stopped.
|
|
43052
43077
|
landRow();
|
|
43053
43078
|
};
|
|
43054
43079
|
movement.playing = playing;
|
|
43055
|
-
row.setAttribute("data-route-row-travelling", "");
|
|
43056
43080
|
frame = requestAnimationFrame(step);
|
|
43057
43081
|
};
|
|
43058
43082
|
|
|
43083
|
+
// The row given back to the browser: no travel writes it any more, and it snaps
|
|
43084
|
+
// again. A travel replacing another keeps it (playTravel).
|
|
43085
|
+
const letRowGo = movement => {
|
|
43086
|
+
if (movement.playing) {
|
|
43087
|
+
movement.playing.cancel();
|
|
43088
|
+
movement.playing = null;
|
|
43089
|
+
}
|
|
43090
|
+
rowRef.current.removeAttribute("data-route-row-travelling");
|
|
43091
|
+
};
|
|
43092
|
+
|
|
43093
|
+
// The address runs ahead of a hand to build the page it pulls towards (onScroll):
|
|
43094
|
+
// the pane under the hand stays laid out as the page on screen until the hand lets
|
|
43095
|
+
// go, whatever `inert` says (see the CSS). What reads the page held is told apart
|
|
43096
|
+
// (route_travel_hold.js), and both are let go of together.
|
|
43097
|
+
const heldPaneRef = useRef(null);
|
|
43098
|
+
const holdPaneOnScreen = pane => {
|
|
43099
|
+
heldPaneRef.current = pane;
|
|
43100
|
+
pane.setAttribute("data-route-row-held", "");
|
|
43101
|
+
};
|
|
43102
|
+
const releaseHold = () => {
|
|
43103
|
+
releaseHeldPage();
|
|
43104
|
+
const heldPane = heldPaneRef.current;
|
|
43105
|
+
if (heldPane) {
|
|
43106
|
+
heldPaneRef.current = null;
|
|
43107
|
+
heldPane.removeAttribute("data-route-row-held");
|
|
43108
|
+
}
|
|
43109
|
+
};
|
|
43110
|
+
|
|
43059
43111
|
// Every column back where the map says, and the row on the page of the address, in
|
|
43060
43112
|
// one go: that page stands at the same place on screen either way.
|
|
43061
43113
|
const putRowBack = movement => {
|
|
@@ -43084,7 +43136,7 @@ const RouteTravel = ({
|
|
|
43084
43136
|
const position = row.scrollLeft;
|
|
43085
43137
|
movement.rowTaken = true;
|
|
43086
43138
|
// A travel no hand set off holds nothing: it goes where it goes.
|
|
43087
|
-
|
|
43139
|
+
releaseHold();
|
|
43088
43140
|
row.style.setProperty("--navi-route-row-stand", `${-position}px`);
|
|
43089
43141
|
row.setAttribute("data-route-row-taken", "");
|
|
43090
43142
|
afterFrames(2, () => {
|
|
@@ -43112,14 +43164,11 @@ const RouteTravel = ({
|
|
|
43112
43164
|
return;
|
|
43113
43165
|
}
|
|
43114
43166
|
movementRef.current = null;
|
|
43115
|
-
|
|
43116
|
-
movement.playing.stop();
|
|
43117
|
-
}
|
|
43167
|
+
letRowGo(movement);
|
|
43118
43168
|
putRowBack(movement);
|
|
43119
|
-
row.removeAttribute("data-route-row-travelling");
|
|
43120
43169
|
row.removeAttribute("data-route-row-taken");
|
|
43121
43170
|
publishRouteRowMove(null);
|
|
43122
|
-
|
|
43171
|
+
releaseHold();
|
|
43123
43172
|
if (liveRef.current) {
|
|
43124
43173
|
liveRef.current.style.top = "";
|
|
43125
43174
|
}
|
|
@@ -43293,7 +43342,7 @@ const RouteTravel = ({
|
|
|
43293
43342
|
// Not where the travel put it: a hand has taken the row (a trackpad, a wheel),
|
|
43294
43343
|
// and the travel lets it go, snapping included, as the browser's own scroll does.
|
|
43295
43344
|
if (moving?.playing && Math.abs(row.scrollLeft - moving.playing.written) > WRITE_ROUNDING) {
|
|
43296
|
-
moving
|
|
43345
|
+
letRowGo(moving);
|
|
43297
43346
|
}
|
|
43298
43347
|
const pane = panes[currentIndex];
|
|
43299
43348
|
if (!moving && pane && restsOn(row, pane, ROW_READING)) {
|
|
@@ -43339,8 +43388,12 @@ const RouteTravel = ({
|
|
|
43339
43388
|
return;
|
|
43340
43389
|
}
|
|
43341
43390
|
leavePictureOfLive(movement);
|
|
43342
|
-
} else
|
|
43343
|
-
|
|
43391
|
+
} else {
|
|
43392
|
+
if (paneTowards.hasAttribute("data-built")) {
|
|
43393
|
+
return;
|
|
43394
|
+
}
|
|
43395
|
+
// Before the address moves: the render that makes it inert must find it held.
|
|
43396
|
+
holdPaneOnScreen(pane);
|
|
43344
43397
|
}
|
|
43345
43398
|
holdPage(pages[currentIndex], page);
|
|
43346
43399
|
askFor(page);
|
|
@@ -43372,7 +43425,7 @@ const RouteTravel = ({
|
|
|
43372
43425
|
}
|
|
43373
43426
|
// After the address: a pull coming back to its page must not light the tab the
|
|
43374
43427
|
// address ran ahead to, even for a render.
|
|
43375
|
-
|
|
43428
|
+
releaseHold();
|
|
43376
43429
|
};
|
|
43377
43430
|
const stopWatching = watchRowScroll(row, {
|
|
43378
43431
|
onScroll,
|
|
@@ -43422,12 +43475,13 @@ const RouteTravel = ({
|
|
|
43422
43475
|
});
|
|
43423
43476
|
const movement = movementRef.current;
|
|
43424
43477
|
if (movement) {
|
|
43425
|
-
movement.playing?.
|
|
43478
|
+
movement.playing?.cancel();
|
|
43426
43479
|
movement.resumeScrollRecording?.();
|
|
43427
43480
|
}
|
|
43481
|
+
row.removeAttribute("data-route-row-travelling");
|
|
43428
43482
|
movementRef.current = null;
|
|
43429
43483
|
publishRouteRowMove(null);
|
|
43430
|
-
|
|
43484
|
+
releaseHold();
|
|
43431
43485
|
};
|
|
43432
43486
|
}, [windowed]);
|
|
43433
43487
|
|