@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/jsenv_navi.js
CHANGED
|
@@ -13832,7 +13832,9 @@ const isRenderingPageChange = () => renderingPageChange;
|
|
|
13832
13832
|
* outside its own nodes (a slot in a bar, the document a list scrolls) steps
|
|
13833
13833
|
* out rather than showing with, or moving, the page arriving. Every box of it
|
|
13834
13834
|
* measures 0×0 by then. Set after the render keeping the page, so that render
|
|
13835
|
-
* and what it builds can only ask `hasLeft()`.
|
|
13835
|
+
* and what it builds can only ask `hasLeft()`. Cleared by the render showing
|
|
13836
|
+
* the page again, before anything below it renders: what mounts then never
|
|
13837
|
+
* reads its page as leaving.
|
|
13836
13838
|
*/
|
|
13837
13839
|
const RoutePageContext = createContext(null);
|
|
13838
13840
|
|
|
@@ -37287,8 +37289,16 @@ const RouteRowPane = ({
|
|
|
37287
37289
|
value: page
|
|
37288
37290
|
}, branch.node));
|
|
37289
37291
|
}
|
|
37292
|
+
// Back on screen before what it holds renders: built here, or mounted again under
|
|
37293
|
+
// it, that content runs its layout effects before this component's, and would
|
|
37294
|
+
// otherwise read its page as leaving.
|
|
37295
|
+
if (shown) {
|
|
37296
|
+
page.ownLeavingSignal.value = false;
|
|
37297
|
+
}
|
|
37290
37298
|
useLayoutEffect(() => {
|
|
37291
|
-
|
|
37299
|
+
if (!shown) {
|
|
37300
|
+
page.ownLeavingSignal.value = true;
|
|
37301
|
+
}
|
|
37292
37302
|
}, [shown]);
|
|
37293
37303
|
return jsx("div", {
|
|
37294
37304
|
"data-route-row-pane": "",
|
|
@@ -41358,7 +41368,7 @@ const css$16 = /* css */`.navi_route_travel {
|
|
|
41358
41368
|
display: flex;
|
|
41359
41369
|
}
|
|
41360
41370
|
|
|
41361
|
-
& > [data-route-row-pane][inert] {
|
|
41371
|
+
& > [data-route-row-pane][inert]:not([data-route-row-held]), &:has( > [data-route-row-held]) > [data-route-row-pane]:not([data-route-row-held]) {
|
|
41362
41372
|
top: var(--navi-route-row-pin, 0);
|
|
41363
41373
|
contain: paint;
|
|
41364
41374
|
max-height: 100dvh;
|
|
@@ -41408,6 +41418,12 @@ const ROW_READING = {
|
|
|
41408
41418
|
// How far a scroll position written can read back from what was written: rounded to
|
|
41409
41419
|
// the device's pixels.
|
|
41410
41420
|
const WRITE_ROUNDING = 1;
|
|
41421
|
+
// The most one frame of a travel plays: a frame of a 30fps screen, which is what a
|
|
41422
|
+
// browser saving power gives (an iPhone in Low Power Mode, Chrome's Energy Saver).
|
|
41423
|
+
// A frame later than that is a main thread busy elsewhere (the page arriving builds,
|
|
41424
|
+
// a list fills its budget), and the travel takes longer rather than jump by it. Not a
|
|
41425
|
+
// frame of a 60Hz screen: that would play every travel in slow motion at 30fps.
|
|
41426
|
+
const TRAVEL_FRAME_MAX_MS = 1000 / 30;
|
|
41411
41427
|
|
|
41412
41428
|
/**
|
|
41413
41429
|
* @type {import("preact").FunctionComponent<{
|
|
@@ -41683,18 +41699,22 @@ const RouteTravel = ({
|
|
|
41683
41699
|
// hesitates, then peaks at 1.65 times this one's speed): two rows of tabs in one
|
|
41684
41700
|
// app would not move alike. The scroll position is written at every frame, so the
|
|
41685
41701
|
// row stays a scroller all the way: what follows it (a Nav's bar) reads it as it
|
|
41686
|
-
// reads a hand, and a finger landing finds it where it is.
|
|
41687
|
-
//
|
|
41702
|
+
// reads a hand, and a finger landing finds it where it is. That is played on the
|
|
41703
|
+
// main thread: a transform on the panes would play on the compositor, but it would
|
|
41704
|
+
// capture what the page on screen holds in position: fixed. Hence a clock of its
|
|
41705
|
+
// own, which a busy main thread slows down rather than makes jump.
|
|
41688
41706
|
const playTravel = (pane, movement) => {
|
|
41689
41707
|
const row = rowRef.current;
|
|
41690
41708
|
// Already moving, so there is no ease-in to play: it would stall the row for an
|
|
41691
41709
|
// instant right where the eye is following it.
|
|
41692
41710
|
const replaced = movement.playing;
|
|
41693
41711
|
const inFlight = Boolean(replaced) || Boolean(movement.rowTaken);
|
|
41712
|
+
// Before the row is read: let go of for an instant, it would be snapped to the
|
|
41713
|
+
// nearest page by that read, and the travel would start from there.
|
|
41714
|
+
row.setAttribute("data-route-row-travelling", "");
|
|
41694
41715
|
if (replaced) {
|
|
41695
|
-
|
|
41696
|
-
|
|
41697
|
-
replaced.cancelFrame();
|
|
41716
|
+
replaced.cancel();
|
|
41717
|
+
movement.playing = null;
|
|
41698
41718
|
}
|
|
41699
41719
|
const from = row.scrollLeft;
|
|
41700
41720
|
const {
|
|
@@ -41706,56 +41726,88 @@ const RouteTravel = ({
|
|
|
41706
41726
|
const travelMs = boxes < 1 ? durationMs * boxes : durationMs;
|
|
41707
41727
|
if (!travelMs) {
|
|
41708
41728
|
row.scrollLeft = pane.offsetLeft;
|
|
41729
|
+
letRowGo(movement);
|
|
41709
41730
|
// A write that changes nothing is followed by no scroll event to say the row
|
|
41710
41731
|
// stopped. After the commit that asked, which goes on to say the row moves.
|
|
41711
41732
|
Promise.resolve().then(landRow);
|
|
41712
41733
|
return;
|
|
41713
41734
|
}
|
|
41714
41735
|
const curve = inFlight ? CSS_EASE_OUT : CSS_EASE;
|
|
41715
|
-
let start = null;
|
|
41716
41736
|
let frame = null;
|
|
41737
|
+
// How much of the travel has played, frame by frame. A travel setting off plays
|
|
41738
|
+
// nothing at its first frame, which may have begun while the press was still being
|
|
41739
|
+
// handled: that is no travel. One taking over goes on from the last frame of the
|
|
41740
|
+
// one it replaces, or the row would stand still for a frame where the eye follows it.
|
|
41741
|
+
let played = 0;
|
|
41717
41742
|
const playing = {
|
|
41718
41743
|
// Where this travel put the row, for a scroll event to tell it from a hand.
|
|
41719
41744
|
written: from,
|
|
41720
|
-
|
|
41745
|
+
lastFrame: replaced ? replaced.lastFrame : null,
|
|
41746
|
+
cancel: () => {
|
|
41721
41747
|
cancelAnimationFrame(frame);
|
|
41722
|
-
},
|
|
41723
|
-
stop: () => {
|
|
41724
|
-
playing.cancelFrame();
|
|
41725
|
-
if (movement.playing === playing) {
|
|
41726
|
-
movement.playing = null;
|
|
41727
|
-
row.removeAttribute("data-route-row-travelling");
|
|
41728
|
-
}
|
|
41729
41748
|
}
|
|
41730
41749
|
};
|
|
41731
41750
|
const step = now => {
|
|
41732
|
-
if (
|
|
41733
|
-
|
|
41734
|
-
|
|
41735
|
-
|
|
41751
|
+
if (playing.lastFrame !== null) {
|
|
41752
|
+
const gap = now - playing.lastFrame;
|
|
41753
|
+
if (gap > TRAVEL_FRAME_MAX_MS) {
|
|
41754
|
+
played += TRAVEL_FRAME_MAX_MS;
|
|
41755
|
+
} else if (gap > 0) {
|
|
41756
|
+
played += gap;
|
|
41757
|
+
}
|
|
41736
41758
|
}
|
|
41737
|
-
|
|
41738
|
-
const elapsed =
|
|
41759
|
+
playing.lastFrame = now;
|
|
41760
|
+
const elapsed = played / travelMs;
|
|
41739
41761
|
// Read at every frame: the layout may move under the travel (a scrollbar
|
|
41740
41762
|
// coming in narrows the row), and it goes where the page stands.
|
|
41741
41763
|
const to = pane.offsetLeft;
|
|
41742
41764
|
const arrived = elapsed >= 1;
|
|
41743
41765
|
playing.written = arrived ? to : from + (to - from) * easedProgress(elapsed, curve);
|
|
41744
41766
|
row.scrollLeft = playing.written;
|
|
41767
|
+
// In the frame it is written: the scroll event saying so comes a frame later,
|
|
41768
|
+
// and what follows the row would be drawn a frame behind it.
|
|
41769
|
+
sayRowMoves();
|
|
41745
41770
|
if (!arrived) {
|
|
41746
41771
|
frame = requestAnimationFrame(step);
|
|
41747
41772
|
return;
|
|
41748
41773
|
}
|
|
41749
|
-
|
|
41774
|
+
letRowGo(movement);
|
|
41750
41775
|
// Said here rather than waited for: the last frames of a curve can move the row
|
|
41751
41776
|
// by less than a pixel, and nothing then says it has stopped.
|
|
41752
41777
|
landRow();
|
|
41753
41778
|
};
|
|
41754
41779
|
movement.playing = playing;
|
|
41755
|
-
row.setAttribute("data-route-row-travelling", "");
|
|
41756
41780
|
frame = requestAnimationFrame(step);
|
|
41757
41781
|
};
|
|
41758
41782
|
|
|
41783
|
+
// The row given back to the browser: no travel writes it any more, and it snaps
|
|
41784
|
+
// again. A travel replacing another keeps it (playTravel).
|
|
41785
|
+
const letRowGo = movement => {
|
|
41786
|
+
if (movement.playing) {
|
|
41787
|
+
movement.playing.cancel();
|
|
41788
|
+
movement.playing = null;
|
|
41789
|
+
}
|
|
41790
|
+
rowRef.current.removeAttribute("data-route-row-travelling");
|
|
41791
|
+
};
|
|
41792
|
+
|
|
41793
|
+
// The address runs ahead of a hand to build the page it pulls towards (onScroll):
|
|
41794
|
+
// the pane under the hand stays laid out as the page on screen until the hand lets
|
|
41795
|
+
// go, whatever `inert` says (see the CSS). What reads the page held is told apart
|
|
41796
|
+
// (route_travel_hold.js), and both are let go of together.
|
|
41797
|
+
const heldPaneRef = useRef(null);
|
|
41798
|
+
const holdPaneOnScreen = pane => {
|
|
41799
|
+
heldPaneRef.current = pane;
|
|
41800
|
+
pane.setAttribute("data-route-row-held", "");
|
|
41801
|
+
};
|
|
41802
|
+
const releaseHold = () => {
|
|
41803
|
+
releaseHeldPage();
|
|
41804
|
+
const heldPane = heldPaneRef.current;
|
|
41805
|
+
if (heldPane) {
|
|
41806
|
+
heldPaneRef.current = null;
|
|
41807
|
+
heldPane.removeAttribute("data-route-row-held");
|
|
41808
|
+
}
|
|
41809
|
+
};
|
|
41810
|
+
|
|
41759
41811
|
// Every column back where the map says, and the row on the page of the address, in
|
|
41760
41812
|
// one go: that page stands at the same place on screen either way.
|
|
41761
41813
|
const putRowBack = movement => {
|
|
@@ -41784,7 +41836,7 @@ const RouteTravel = ({
|
|
|
41784
41836
|
const position = row.scrollLeft;
|
|
41785
41837
|
movement.rowTaken = true;
|
|
41786
41838
|
// A travel no hand set off holds nothing: it goes where it goes.
|
|
41787
|
-
|
|
41839
|
+
releaseHold();
|
|
41788
41840
|
row.style.setProperty("--navi-route-row-stand", `${-position}px`);
|
|
41789
41841
|
row.setAttribute("data-route-row-taken", "");
|
|
41790
41842
|
afterFrames(2, () => {
|
|
@@ -41812,14 +41864,11 @@ const RouteTravel = ({
|
|
|
41812
41864
|
return;
|
|
41813
41865
|
}
|
|
41814
41866
|
movementRef.current = null;
|
|
41815
|
-
|
|
41816
|
-
movement.playing.stop();
|
|
41817
|
-
}
|
|
41867
|
+
letRowGo(movement);
|
|
41818
41868
|
putRowBack(movement);
|
|
41819
|
-
row.removeAttribute("data-route-row-travelling");
|
|
41820
41869
|
row.removeAttribute("data-route-row-taken");
|
|
41821
41870
|
publishRouteRowMove(null);
|
|
41822
|
-
|
|
41871
|
+
releaseHold();
|
|
41823
41872
|
if (liveRef.current) {
|
|
41824
41873
|
liveRef.current.style.top = "";
|
|
41825
41874
|
}
|
|
@@ -41993,7 +42042,7 @@ const RouteTravel = ({
|
|
|
41993
42042
|
// Not where the travel put it: a hand has taken the row (a trackpad, a wheel),
|
|
41994
42043
|
// and the travel lets it go, snapping included, as the browser's own scroll does.
|
|
41995
42044
|
if (moving?.playing && Math.abs(row.scrollLeft - moving.playing.written) > WRITE_ROUNDING) {
|
|
41996
|
-
moving
|
|
42045
|
+
letRowGo(moving);
|
|
41997
42046
|
}
|
|
41998
42047
|
const pane = panes[currentIndex];
|
|
41999
42048
|
if (!moving && pane && restsOn(row, pane, ROW_READING)) {
|
|
@@ -42039,8 +42088,12 @@ const RouteTravel = ({
|
|
|
42039
42088
|
return;
|
|
42040
42089
|
}
|
|
42041
42090
|
leavePictureOfLive(movement);
|
|
42042
|
-
} else
|
|
42043
|
-
|
|
42091
|
+
} else {
|
|
42092
|
+
if (paneTowards.hasAttribute("data-built")) {
|
|
42093
|
+
return;
|
|
42094
|
+
}
|
|
42095
|
+
// Before the address moves: the render that makes it inert must find it held.
|
|
42096
|
+
holdPaneOnScreen(pane);
|
|
42044
42097
|
}
|
|
42045
42098
|
holdPage(pages[currentIndex], page);
|
|
42046
42099
|
askFor(page);
|
|
@@ -42072,7 +42125,7 @@ const RouteTravel = ({
|
|
|
42072
42125
|
}
|
|
42073
42126
|
// After the address: a pull coming back to its page must not light the tab the
|
|
42074
42127
|
// address ran ahead to, even for a render.
|
|
42075
|
-
|
|
42128
|
+
releaseHold();
|
|
42076
42129
|
};
|
|
42077
42130
|
const stopWatching = watchRowScroll(row, {
|
|
42078
42131
|
onScroll,
|
|
@@ -42122,12 +42175,13 @@ const RouteTravel = ({
|
|
|
42122
42175
|
});
|
|
42123
42176
|
const movement = movementRef.current;
|
|
42124
42177
|
if (movement) {
|
|
42125
|
-
movement.playing?.
|
|
42178
|
+
movement.playing?.cancel();
|
|
42126
42179
|
movement.resumeScrollRecording?.();
|
|
42127
42180
|
}
|
|
42181
|
+
row.removeAttribute("data-route-row-travelling");
|
|
42128
42182
|
movementRef.current = null;
|
|
42129
42183
|
publishRouteRowMove(null);
|
|
42130
|
-
|
|
42184
|
+
releaseHold();
|
|
42131
42185
|
};
|
|
42132
42186
|
}, [windowed]);
|
|
42133
42187
|
|