@jsenv/navi 0.29.502 → 0.29.504
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 +219 -77
- package/dist/dev/jsenv_navi.js.map +10 -8
- package/dist/jsenv_navi.js +219 -77
- package/dist/jsenv_navi.js.map +10 -8
- package/docs/route_transitions.md +46 -6
- package/package.json +1 -1
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -37811,7 +37811,8 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
37811
37811
|
hold: leavingPagesHold,
|
|
37812
37812
|
startRef: createRef(),
|
|
37813
37813
|
endRef: createRef(),
|
|
37814
|
-
hidden: false
|
|
37814
|
+
hidden: false,
|
|
37815
|
+
observer: null
|
|
37815
37816
|
});
|
|
37816
37817
|
leavingPagesHold.containers.add(rerender);
|
|
37817
37818
|
// Keyed apart from the page it takes the place of, which is still there.
|
|
@@ -37851,20 +37852,22 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
37851
37852
|
}
|
|
37852
37853
|
entry.hidden = true;
|
|
37853
37854
|
entry.page.leavingSignal.value = true;
|
|
37854
|
-
|
|
37855
|
-
|
|
37856
|
-
|
|
37857
|
-
|
|
37858
|
-
|
|
37859
|
-
|
|
37860
|
-
|
|
37861
|
-
|
|
37862
|
-
|
|
37863
|
-
focusedElement.blur();
|
|
37864
|
-
}
|
|
37855
|
+
hideNodesBetween(start, end);
|
|
37856
|
+
// The page renders on its own while kept (a component reading a signal
|
|
37857
|
+
// the address moved), never through this container: a top node it
|
|
37858
|
+
// replaces lands between the markers unmarked. Its mutation is heard
|
|
37859
|
+
// before the next frame.
|
|
37860
|
+
const observer = new MutationObserver(() => {
|
|
37861
|
+
if (entry.hold.released) {
|
|
37862
|
+
observer.disconnect();
|
|
37863
|
+
return;
|
|
37865
37864
|
}
|
|
37866
|
-
|
|
37867
|
-
}
|
|
37865
|
+
hideNodesBetween(start, end);
|
|
37866
|
+
});
|
|
37867
|
+
observer.observe(start.parentNode, {
|
|
37868
|
+
childList: true
|
|
37869
|
+
});
|
|
37870
|
+
entry.observer = observer;
|
|
37868
37871
|
}
|
|
37869
37872
|
});
|
|
37870
37873
|
// Also run when a Suspense boundary above parks this container — a page
|
|
@@ -37876,6 +37879,7 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
37876
37879
|
return () => {
|
|
37877
37880
|
for (const entry of leavingRef.current) {
|
|
37878
37881
|
entry.hold.containers.delete(rerender);
|
|
37882
|
+
entry.observer?.disconnect();
|
|
37879
37883
|
}
|
|
37880
37884
|
leavingRef.current = [];
|
|
37881
37885
|
};
|
|
@@ -37903,6 +37907,22 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
37903
37907
|
};
|
|
37904
37908
|
};
|
|
37905
37909
|
const countRenders = count => count + 1;
|
|
37910
|
+
const hideNodesBetween = (start, end) => {
|
|
37911
|
+
const focusedElement = document.activeElement;
|
|
37912
|
+
let node = start.nextSibling;
|
|
37913
|
+
while (node && node !== end) {
|
|
37914
|
+
if (node.nodeType === Node.ELEMENT_NODE && !node.hasAttribute(LEAVING_ATTRIBUTE)) {
|
|
37915
|
+
node.setAttribute(LEAVING_ATTRIBUTE, "");
|
|
37916
|
+
// What the keyboard held in it goes where the page's removal would
|
|
37917
|
+
// have sent it: a hidden element keeps the focus, and would go on
|
|
37918
|
+
// receiving the keys pressed during the movement.
|
|
37919
|
+
if (node.contains(focusedElement)) {
|
|
37920
|
+
focusedElement.blur();
|
|
37921
|
+
}
|
|
37922
|
+
}
|
|
37923
|
+
node = node.nextSibling;
|
|
37924
|
+
}
|
|
37925
|
+
};
|
|
37906
37926
|
// The page a container renders, as RoutePageContext hands it over (see
|
|
37907
37927
|
// route_page_context.js). Shown while the container would pick its branch, or
|
|
37908
37928
|
// a branch rendering the same element (it is then carried over), and while the
|
|
@@ -38114,6 +38134,14 @@ const collectBranches = (children, path = "") => {
|
|
|
38114
38134
|
const paramsMatching = routeParams ? route.matchesParams(routeParams) : true;
|
|
38115
38135
|
if (!matchingBranch && matching && paramsMatching) {
|
|
38116
38136
|
matchingBranch = branch;
|
|
38137
|
+
if (!routeParams) {
|
|
38138
|
+
// The params are part of the page this branch shows: /games/a and
|
|
38139
|
+
// /games/b are two pages on one branch, and the container renders
|
|
38140
|
+
// between them so the second is announced like any other (see
|
|
38141
|
+
// publishRouteRender) — a movement between the two waits on it.
|
|
38142
|
+
// eslint-disable-next-line no-unused-expressions
|
|
38143
|
+
route.paramsSignal.value;
|
|
38144
|
+
}
|
|
38117
38145
|
}
|
|
38118
38146
|
}
|
|
38119
38147
|
};
|
|
@@ -38178,6 +38206,59 @@ const RouteUI = ({
|
|
|
38178
38206
|
return element;
|
|
38179
38207
|
};
|
|
38180
38208
|
|
|
38209
|
+
/*
|
|
38210
|
+
* What ONE navigation asks of a route transition, worn by the element being
|
|
38211
|
+
* pressed: `<Link routeTransition>`, `<Button routeTransition>`, or the
|
|
38212
|
+
* attribute by hand on any anchor. A type travels as its name — all most
|
|
38213
|
+
* presses have to say — and anything more (a way round, a pace) as the same
|
|
38214
|
+
* object navTo() takes, written as JSON.
|
|
38215
|
+
*
|
|
38216
|
+
* Apart from route_transition.jsx, which plays the request: the press handlers
|
|
38217
|
+
* and the --navi-nav-to command read it too, and importing the transition
|
|
38218
|
+
* machinery there would pull it into an application that defines no
|
|
38219
|
+
* transition.
|
|
38220
|
+
*/
|
|
38221
|
+
|
|
38222
|
+
const ROUTE_TRANSITION_REQUEST_ATTRIBUTE = "data-navi-route-transition-request";
|
|
38223
|
+
|
|
38224
|
+
// The attributes to spread on the element. Nothing when nothing is asked, so
|
|
38225
|
+
// that the attribute written by hand on the same element is left standing.
|
|
38226
|
+
const writeRouteTransitionRequest = (routeTransition) => {
|
|
38227
|
+
if (routeTransition === undefined || routeTransition === null) {
|
|
38228
|
+
return null;
|
|
38229
|
+
}
|
|
38230
|
+
return {
|
|
38231
|
+
[ROUTE_TRANSITION_REQUEST_ATTRIBUTE]:
|
|
38232
|
+
typeof routeTransition === "string"
|
|
38233
|
+
? routeTransition
|
|
38234
|
+
: JSON.stringify(routeTransition),
|
|
38235
|
+
};
|
|
38236
|
+
};
|
|
38237
|
+
|
|
38238
|
+
// The request as navTo() takes it — a type name or the object — and undefined
|
|
38239
|
+
// when the element asks nothing.
|
|
38240
|
+
const readRouteTransitionRequest = (element) => {
|
|
38241
|
+
const asked = element.getAttribute(ROUTE_TRANSITION_REQUEST_ATTRIBUTE);
|
|
38242
|
+
if (asked === null) {
|
|
38243
|
+
return undefined;
|
|
38244
|
+
}
|
|
38245
|
+
const value = asked.trim();
|
|
38246
|
+
if (value === "") {
|
|
38247
|
+
return undefined;
|
|
38248
|
+
}
|
|
38249
|
+
if (value[0] !== "{") {
|
|
38250
|
+
return value;
|
|
38251
|
+
}
|
|
38252
|
+
try {
|
|
38253
|
+
return JSON.parse(value);
|
|
38254
|
+
} catch {
|
|
38255
|
+
console.warn(
|
|
38256
|
+
`${ROUTE_TRANSITION_REQUEST_ATTRIBUTE} is neither a type name nor JSON: ${value}`,
|
|
38257
|
+
);
|
|
38258
|
+
return undefined;
|
|
38259
|
+
}
|
|
38260
|
+
};
|
|
38261
|
+
|
|
38181
38262
|
/**
|
|
38182
38263
|
* Where a route movement is heading, said before its first picture is taken.
|
|
38183
38264
|
*
|
|
@@ -39629,10 +39710,6 @@ const TRANSITION_COVERED_ATTRIBUTE = "data-navi-route-transition-covered";
|
|
|
39629
39710
|
// right for a page that IS the whole viewport.
|
|
39630
39711
|
const TRANSITION_AREA_ATTRIBUTE = "data-navi-route-transition-area";
|
|
39631
39712
|
const TRANSITION_TARGET_ATTRIBUTE = "data-navi-route-transition-target";
|
|
39632
|
-
// What ONE navigation asks for, over whatever the relations say: worn by the
|
|
39633
|
-
// link being pressed (see <Link routeTransition>), or handed to navTo(). It answers
|
|
39634
|
-
// for that navigation and for no other — the next one is back to the relations.
|
|
39635
|
-
const TRANSITION_REQUEST_ATTRIBUTE = "data-navi-route-transition-request";
|
|
39636
39713
|
// What a history entry remembers of the crossing that created it, in the
|
|
39637
39714
|
// entry's own state: `{ from, type, direction, duration }` (see recordCrossing).
|
|
39638
39715
|
const CROSSING_STATE_KEY = "jsenv_route_transition";
|
|
@@ -40173,13 +40250,32 @@ const defineRouteTransition = (from, to, transition) => {
|
|
|
40173
40250
|
* "before" the other — so give it a movement that does not need one:
|
|
40174
40251
|
* `"cross-fade"`, or a custom type whose CSS is keyed on the type alone.
|
|
40175
40252
|
*
|
|
40176
|
-
*
|
|
40177
|
-
*
|
|
40178
|
-
*
|
|
40253
|
+
* Unless the history says it: `{ type: "slide-x", direction: "history" }` is
|
|
40254
|
+
* the grammar of a navigation stack, where every link goes one level deeper
|
|
40255
|
+
* and every back one level up. A push plays forward, a traversal retraces its
|
|
40256
|
+
* crossing or, with none remembered, plays back when it lands lower in the
|
|
40257
|
+
* history and forward when it lands higher, and a replace — the same level —
|
|
40258
|
+
* plays nothing. It plays only when the page changes: a push that opens a
|
|
40259
|
+
* layer over the page keeps the page. The relations written still answer
|
|
40260
|
+
* first, and a page written from anywhere then answers for its way out only
|
|
40261
|
+
* on a back — a link out of it is a push like any other (see findRelation).
|
|
40262
|
+
*
|
|
40263
|
+
* @param {string|{type?: string, duration?: number|string, direction?: "history"}} transition -
|
|
40264
|
+
* same forms as defineRouteTransition's. `"none"` (or removing the default)
|
|
40265
|
+
* puts the silence back.
|
|
40179
40266
|
* @returns {() => void} remove this default.
|
|
40180
40267
|
*/
|
|
40181
40268
|
const defineRouteDefaultTransition = transition => {
|
|
40182
|
-
const
|
|
40269
|
+
const {
|
|
40270
|
+
direction
|
|
40271
|
+
} = typeof transition === "object" && transition !== null ? transition : {};
|
|
40272
|
+
if (direction !== undefined && direction !== "history") {
|
|
40273
|
+
throw new TypeError(`defineRouteDefaultTransition takes direction: "history" or no direction, not ${JSON.stringify(direction)}: a default is about pages no relation orders, and "history" is the one thing that orders them — the depth of the entries the navigation goes between.`);
|
|
40274
|
+
}
|
|
40275
|
+
const value = {
|
|
40276
|
+
...normalizeTransition(transition),
|
|
40277
|
+
readsHistory: direction === "history"
|
|
40278
|
+
};
|
|
40183
40279
|
defaultTransition = value;
|
|
40184
40280
|
installRouteTransitionCss();
|
|
40185
40281
|
return () => {
|
|
@@ -40232,29 +40328,8 @@ const readNavigationRequest = ({
|
|
|
40232
40328
|
return normalizeRequest(routeTransition);
|
|
40233
40329
|
}
|
|
40234
40330
|
if (element && element.getAttribute) {
|
|
40235
|
-
const asked = element
|
|
40236
|
-
|
|
40237
|
-
return null;
|
|
40238
|
-
}
|
|
40239
|
-
const value = asked.trim();
|
|
40240
|
-
if (value === "") {
|
|
40241
|
-
return null;
|
|
40242
|
-
}
|
|
40243
|
-
// A type is a name, and a name is all most links have to say. Anything
|
|
40244
|
-
// more — a way round, a pace — is the same object the API takes
|
|
40245
|
-
// everywhere else, written as JSON so that it travels on an attribute
|
|
40246
|
-
// (and so that a plain <a> can say it too).
|
|
40247
|
-
if (value[0] === "{") {
|
|
40248
|
-
let parsed;
|
|
40249
|
-
try {
|
|
40250
|
-
parsed = JSON.parse(value);
|
|
40251
|
-
} catch {
|
|
40252
|
-
console.warn(`${TRANSITION_REQUEST_ATTRIBUTE} is neither a type name nor JSON: ${value}`);
|
|
40253
|
-
return null;
|
|
40254
|
-
}
|
|
40255
|
-
return normalizeRequest(parsed);
|
|
40256
|
-
}
|
|
40257
|
-
return normalizeRequest(value);
|
|
40331
|
+
const asked = readRouteTransitionRequest(element);
|
|
40332
|
+
return asked === undefined ? null : normalizeRequest(asked);
|
|
40258
40333
|
}
|
|
40259
40334
|
return null;
|
|
40260
40335
|
};
|
|
@@ -40340,6 +40415,31 @@ const crossingRecordedOn = state => {
|
|
|
40340
40415
|
}
|
|
40341
40416
|
return crossing;
|
|
40342
40417
|
};
|
|
40418
|
+
|
|
40419
|
+
/**
|
|
40420
|
+
* Which way the history says a navigation goes, for a default that reads it
|
|
40421
|
+
* (see defineRouteDefaultTransition): a push is one level deeper, a traversal
|
|
40422
|
+
* goes where the depth of the entry it lands on puts it — back when that is
|
|
40423
|
+
* not known, as in readTraversalReplay —, and anything else (a replace) stays
|
|
40424
|
+
* on its level: null.
|
|
40425
|
+
*/
|
|
40426
|
+
const readHistoryDirection = (navigationType, {
|
|
40427
|
+
state,
|
|
40428
|
+
fromState
|
|
40429
|
+
}) => {
|
|
40430
|
+
if (navigationType === "push") {
|
|
40431
|
+
return "forward";
|
|
40432
|
+
}
|
|
40433
|
+
if (navigationType !== "traverse") {
|
|
40434
|
+
return null;
|
|
40435
|
+
}
|
|
40436
|
+
const depthIn = navDepthOf(state);
|
|
40437
|
+
const depthOut = navDepthOf(fromState);
|
|
40438
|
+
if (depthIn !== undefined && depthOut !== undefined && depthIn > depthOut) {
|
|
40439
|
+
return "forward";
|
|
40440
|
+
}
|
|
40441
|
+
return "back";
|
|
40442
|
+
};
|
|
40343
40443
|
const navDepthOf = state => {
|
|
40344
40444
|
if (state && typeof state[NAV_DEPTH_STATE_KEY] === "number") {
|
|
40345
40445
|
return state[NAV_DEPTH_STATE_KEY];
|
|
@@ -40523,6 +40623,10 @@ let navigationAnimated = false;
|
|
|
40523
40623
|
// "push", "replace", "traverse", … — a push is the one navigation that creates
|
|
40524
40624
|
// the entry a crossing is recorded on.
|
|
40525
40625
|
let navigationType = null;
|
|
40626
|
+
// Which way the history says this navigation goes — "forward", "back", or null
|
|
40627
|
+
// for a replace — when the default reads it (see readHistoryDirection), and
|
|
40628
|
+
// undefined when nothing does.
|
|
40629
|
+
let navigationHistoryDirection;
|
|
40526
40630
|
// What was decided for the navigation now landing — a movement, or "none" —
|
|
40527
40631
|
// which is what its entry remembers (see recordCrossing). Null while nothing
|
|
40528
40632
|
// has been decided, and for a navigation nothing was said about.
|
|
@@ -40540,14 +40644,19 @@ observeBeforeRouting(details => {
|
|
|
40540
40644
|
navigationType = details.navigationType;
|
|
40541
40645
|
navigationUrl = details.url;
|
|
40542
40646
|
navigationFromUrl = documentUrlSignal.peek();
|
|
40543
|
-
// A traversal has no element and no call to ask anything: what it asks is
|
|
40544
|
-
// the crossing it retraces — reversed for a back, as it was for a forward.
|
|
40545
40647
|
// Read before the document state moves, so the state peeked is the entry
|
|
40546
40648
|
// being left.
|
|
40649
|
+
const fromState = documentStateSignal.peek();
|
|
40650
|
+
// A traversal has no element and no call to ask anything: what it asks is
|
|
40651
|
+
// the crossing it retraces — reversed for a back, as it was for a forward.
|
|
40547
40652
|
navigationRequest = navigationType === "traverse" ? readTraversalReplay(details, {
|
|
40548
40653
|
fromUrl: navigationFromUrl,
|
|
40549
|
-
fromState
|
|
40654
|
+
fromState
|
|
40550
40655
|
}) : readNavigationRequest(details);
|
|
40656
|
+
navigationHistoryDirection = defaultTransition && defaultTransition.readsHistory ? readHistoryDirection(navigationType, {
|
|
40657
|
+
state: details.state,
|
|
40658
|
+
fromState
|
|
40659
|
+
}) : undefined;
|
|
40551
40660
|
if (relations.length === 0 && !defaultTransition && !navigationRequest) {
|
|
40552
40661
|
return;
|
|
40553
40662
|
}
|
|
@@ -40565,17 +40674,24 @@ observeAfterRouting(() => {
|
|
|
40565
40674
|
const url = navigationUrl;
|
|
40566
40675
|
const fromUrl = navigationFromUrl;
|
|
40567
40676
|
const type = navigationType;
|
|
40677
|
+
const historyDirection = navigationHistoryDirection;
|
|
40568
40678
|
// Read here and dropped here: a request answers for the navigation it was
|
|
40569
40679
|
// made on, and the next one is back to the relations.
|
|
40570
40680
|
navigationRequest = null;
|
|
40571
40681
|
navigationUrl = null;
|
|
40572
40682
|
navigationFromUrl = null;
|
|
40573
40683
|
navigationType = null;
|
|
40574
|
-
|
|
40684
|
+
navigationHistoryDirection = undefined;
|
|
40685
|
+
// A default reading the history plays between two pages a level apart: not
|
|
40686
|
+
// on a replace, and not on a navigation that keeps the page — a push
|
|
40687
|
+
// opening a layer over it moves the layer, not the page (see
|
|
40688
|
+
// page_change.js).
|
|
40689
|
+
const base = defaultTransition && (!defaultTransition.readsHistory || historyDirection !== null && isRenderingPageChange()) ? defaultTransition : null;
|
|
40690
|
+
if (!navigationAnimated && (request || base)) {
|
|
40575
40691
|
const {
|
|
40576
40692
|
type,
|
|
40577
40693
|
duration
|
|
40578
|
-
} = resolveTransition(request,
|
|
40694
|
+
} = resolveTransition(request, base);
|
|
40579
40695
|
if (type === "none") {
|
|
40580
40696
|
navigationDecision = {
|
|
40581
40697
|
type: "none"
|
|
@@ -40588,11 +40704,12 @@ observeAfterRouting(() => {
|
|
|
40588
40704
|
// A default has no direction: nothing says which of two arbitrary
|
|
40589
40705
|
// pages is before the other, and the attribute is then worn empty —
|
|
40590
40706
|
// present for whoever keys on "one of ours is playing", silent on the
|
|
40591
|
-
// way. A request is the other case: a
|
|
40592
|
-
// press that names the movement means
|
|
40593
|
-
// otherwise — and a movement of navi's is
|
|
40594
|
-
// so left empty it would play nothing at
|
|
40595
|
-
|
|
40707
|
+
// way — unless it reads the history. A request is the other case: a
|
|
40708
|
+
// navigation IS a way round, so a press that names the movement means
|
|
40709
|
+
// forward unless it says otherwise — and a movement of navi's is
|
|
40710
|
+
// written on the direction, so left empty it would play nothing at
|
|
40711
|
+
// all.
|
|
40712
|
+
direction: request && request.direction !== undefined ? request.direction : request && request.typeSaid ? "forward" : base && base.readsHistory ? historyDirection : "",
|
|
40596
40713
|
type,
|
|
40597
40714
|
duration
|
|
40598
40715
|
});
|
|
@@ -40708,6 +40825,12 @@ const findRelation = (fromPage, toPage) => {
|
|
|
40708
40825
|
};
|
|
40709
40826
|
}
|
|
40710
40827
|
}
|
|
40828
|
+
// Leaving such a page plays back because leaving it is assumed to be
|
|
40829
|
+
// closing it. With the default reading the history, that is known instead:
|
|
40830
|
+
// a link out of it is a push, one level deeper, and the default answers.
|
|
40831
|
+
if (navigationHistoryDirection !== undefined && navigationHistoryDirection !== "back") {
|
|
40832
|
+
return null;
|
|
40833
|
+
}
|
|
40711
40834
|
for (const relation of relations) {
|
|
40712
40835
|
if (relation.from) {
|
|
40713
40836
|
continue;
|
|
@@ -41621,7 +41744,11 @@ const RouteTravel = ({
|
|
|
41621
41744
|
// a travel is between two of them, and by the time anything renders the first
|
|
41622
41745
|
// one is already gone. Written after each render (below), so a subscriber
|
|
41623
41746
|
// reading it — they all run before Preact flushes — reads the one being left.
|
|
41624
|
-
|
|
41747
|
+
// The page and not its place in the row: a row given again around the page
|
|
41748
|
+
// on screen (a window over a list, read anew around it) puts that page at
|
|
41749
|
+
// another index without anything having moved.
|
|
41750
|
+
const currentPage = currentIndex === -1 ? null : pages[currentIndex];
|
|
41751
|
+
const currentPageRef = useRef(currentPage);
|
|
41625
41752
|
|
|
41626
41753
|
// Where a page is asked for, whoever asks: a page is a route AND the params
|
|
41627
41754
|
// that say which of its tabs, and a caller told only the route would send the
|
|
@@ -41817,11 +41944,13 @@ const RouteTravel = ({
|
|
|
41817
41944
|
if (index === -1) {
|
|
41818
41945
|
return;
|
|
41819
41946
|
}
|
|
41820
|
-
|
|
41821
|
-
|
|
41822
|
-
//
|
|
41823
|
-
//
|
|
41824
|
-
|
|
41947
|
+
const page = pages[index];
|
|
41948
|
+
if (samePage(page, currentPageRef.current)) {
|
|
41949
|
+
// Where the row already was — the first reading of all, a row given
|
|
41950
|
+
// again around the page on screen, and any move this box has already
|
|
41951
|
+
// taken note of (a render writes it too). What it was still waiting
|
|
41952
|
+
// for is here nonetheless, so the wait is called off.
|
|
41953
|
+
if (samePage(pageAskedForRef.current, page)) {
|
|
41825
41954
|
pageAskedForRef.current = null;
|
|
41826
41955
|
}
|
|
41827
41956
|
return;
|
|
@@ -41830,13 +41959,12 @@ const RouteTravel = ({
|
|
|
41830
41959
|
// between two of them is a page change the path does not show (see
|
|
41831
41960
|
// page_change.js).
|
|
41832
41961
|
notePageChange();
|
|
41833
|
-
const page = pages[index];
|
|
41834
41962
|
// A page this box asked for itself — a travel's own navigation, or one
|
|
41835
41963
|
// it had given up waiting on: what arrives here is the answer to a
|
|
41836
41964
|
// question already answered, not somebody going somewhere.
|
|
41837
41965
|
if (samePage(pageAskedForRef.current, page)) {
|
|
41838
41966
|
pageAskedForRef.current = null;
|
|
41839
|
-
|
|
41967
|
+
currentPageRef.current = page;
|
|
41840
41968
|
return;
|
|
41841
41969
|
}
|
|
41842
41970
|
// Somewhere else arrived first: whatever this box was still waiting for
|
|
@@ -41848,15 +41976,15 @@ const RouteTravel = ({
|
|
|
41848
41976
|
// flight is the answer, aimed somewhere else. Starting a second one on
|
|
41849
41977
|
// top would leave this one's pictures to be dropped mid-slide.
|
|
41850
41978
|
if (travelRef.current) {
|
|
41851
|
-
|
|
41979
|
+
currentPageRef.current = page;
|
|
41852
41980
|
retargetTravel(travelRef.current, page);
|
|
41853
41981
|
return;
|
|
41854
41982
|
}
|
|
41855
|
-
const fromIndex =
|
|
41856
|
-
|
|
41857
|
-
if (fromIndex === -1
|
|
41858
|
-
// Arriving from outside this row
|
|
41859
|
-
//
|
|
41983
|
+
const fromIndex = pageIndexOf(pages, currentPageRef.current);
|
|
41984
|
+
currentPageRef.current = page;
|
|
41985
|
+
if (fromIndex === -1) {
|
|
41986
|
+
// Arriving from outside this row: there is no pair of pages to show,
|
|
41987
|
+
// so there is nothing to travel between.
|
|
41860
41988
|
return;
|
|
41861
41989
|
}
|
|
41862
41990
|
beginTravel({
|
|
@@ -41891,8 +42019,8 @@ const RouteTravel = ({
|
|
|
41891
42019
|
// What the next announcement will compare itself against: written after the
|
|
41892
42020
|
// render that shows it, so it is always the page one is looking at.
|
|
41893
42021
|
useLayoutEffect(() => {
|
|
41894
|
-
|
|
41895
|
-
}, [
|
|
42022
|
+
currentPageRef.current = currentPage;
|
|
42023
|
+
}, [currentPage]);
|
|
41896
42024
|
|
|
41897
42025
|
// Let go of far enough: the movement carries on from under the finger, at its
|
|
41898
42026
|
// own pace, to the end.
|
|
@@ -44905,13 +45033,15 @@ const navToCommand = (source, event, { argument }) => {
|
|
|
44905
45033
|
return {
|
|
44906
45034
|
target,
|
|
44907
45035
|
// Which way there is worn by the source, as a link wears it (see
|
|
44908
|
-
// link_replace.js, link_return.js, link_open.js
|
|
45036
|
+
// link_replace.js, link_return.js, link_open.js,
|
|
45037
|
+
// route_transition_request.js):
|
|
44909
45038
|
// `<Button command="--navi-nav-to:/done" replace>`.
|
|
44910
45039
|
implementation: () =>
|
|
44911
45040
|
navTo(argument, {
|
|
44912
45041
|
replace: linkAsksForReplace(source),
|
|
44913
45042
|
asReturn: linkAsksForReturn(source),
|
|
44914
45043
|
open: linkAsksToOpen(source),
|
|
45044
|
+
routeTransition: readRouteTransitionRequest(source),
|
|
44915
45045
|
}),
|
|
44916
45046
|
};
|
|
44917
45047
|
};
|
|
@@ -58012,10 +58142,8 @@ const LinkPlain = props => {
|
|
|
58012
58142
|
|
|
58013
58143
|
// What this link asks of a route transition, worn as an attribute so that
|
|
58014
58144
|
// the navigation reads it off the element being pressed (see
|
|
58015
|
-
//
|
|
58016
|
-
|
|
58017
|
-
// writes it by hand.
|
|
58018
|
-
const routeTransitionRequest = routeTransition === undefined || routeTransition === null ? undefined : typeof routeTransition === "string" ? routeTransition : JSON.stringify(routeTransition);
|
|
58145
|
+
// route_transition_request.js, which owns the name and does the reading).
|
|
58146
|
+
const routeTransitionRequest = writeRouteTransitionRequest(routeTransition);
|
|
58019
58147
|
|
|
58020
58148
|
// Which way this link goes to the place it aims at, worn as an attribute so
|
|
58021
58149
|
// that whoever answers the press reads it off the anchor (see
|
|
@@ -58106,7 +58234,7 @@ const LinkPlain = props => {
|
|
|
58106
58234
|
open: undefined,
|
|
58107
58235
|
document: undefined,
|
|
58108
58236
|
prefetch: undefined,
|
|
58109
|
-
|
|
58237
|
+
...routeTransitionRequest,
|
|
58110
58238
|
...(pressableDuringRouteTransition ? {
|
|
58111
58239
|
[PRESSABLE_ATTRIBUTE]: ""
|
|
58112
58240
|
} : null),
|
|
@@ -62816,6 +62944,7 @@ const ButtonUI = props => {
|
|
|
62816
62944
|
asReturn,
|
|
62817
62945
|
open,
|
|
62818
62946
|
document: isDocument,
|
|
62947
|
+
routeTransition,
|
|
62819
62948
|
pressableDuringRouteTransition,
|
|
62820
62949
|
prefetch = true,
|
|
62821
62950
|
// visual
|
|
@@ -62873,6 +63002,11 @@ const ButtonUI = props => {
|
|
|
62873
63002
|
[LINK_DOCUMENT_ATTRIBUTE]: ""
|
|
62874
63003
|
} : null;
|
|
62875
63004
|
|
|
63005
|
+
// What this press asks of a route transition (see
|
|
63006
|
+
// route_transition_request.js): read off the anchor by the navigation, off
|
|
63007
|
+
// the source by --navi-nav-to.
|
|
63008
|
+
const routeTransitionRequest = writeRouteTransitionRequest(routeTransition);
|
|
63009
|
+
|
|
62876
63010
|
// Worn as an attribute too, and read at the document by whoever catches the
|
|
62877
63011
|
// press a movement would have swallowed (see transition_press.js).
|
|
62878
63012
|
const pressableRequest = pressableDuringRouteTransition ? {
|
|
@@ -62929,6 +63063,8 @@ const ButtonUI = props => {
|
|
|
62929
63063
|
...openRequest,
|
|
62930
63064
|
document: undefined,
|
|
62931
63065
|
...documentRequest,
|
|
63066
|
+
routeTransition: undefined,
|
|
63067
|
+
...routeTransitionRequest,
|
|
62932
63068
|
pressableDuringRouteTransition: undefined,
|
|
62933
63069
|
...pressableRequest,
|
|
62934
63070
|
prefetch: undefined
|
|
@@ -63599,6 +63735,7 @@ const COMMAND_DEFAULT_PROPS_FACTORIES = {
|
|
|
63599
63735
|
* replace?: boolean,
|
|
63600
63736
|
* asReturn?: boolean,
|
|
63601
63737
|
* open?: string | { id: string, type?: "push" | "replace" },
|
|
63738
|
+
* routeTransition?: string | { type?: string, duration?: number | string, direction?: "forward" | "back" },
|
|
63602
63739
|
* document?: boolean,
|
|
63603
63740
|
* actionStandalone?: boolean,
|
|
63604
63741
|
* actionAbortable?: boolean,
|
|
@@ -63647,6 +63784,11 @@ const COMMAND_DEFAULT_PROPS_FACTORIES = {
|
|
|
63647
63784
|
* @param {string|{id: string, type?: "push"|"replace"}} [open] Lands with one
|
|
63648
63785
|
* of the destination's popups open, named the way its `navState` names it:
|
|
63649
63786
|
* what `<Link open>` says, for a press drawn as a button.
|
|
63787
|
+
* @param {string|{type?: string, duration?: number|string, direction?: "forward"|"back"}} [routeTransition]
|
|
63788
|
+
* What the press asks of a route transition, for that one navigation — a
|
|
63789
|
+
* type name, or an object to also say the pace or which way it plays, over
|
|
63790
|
+
* what the pair's relation says: what `<Link routeTransition>` says, read
|
|
63791
|
+
* off an `href`, a `route` or a `--navi-nav-to` command.
|
|
63650
63792
|
* @param {boolean} [document] The `href` is ANOTHER DOCUMENT of this origin —
|
|
63651
63793
|
* an admin panel, a status page, anything built as its own entry point — so
|
|
63652
63794
|
* the press is left to the browser and loads that page, instead of being
|