@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/jsenv_navi.js
CHANGED
|
@@ -36560,7 +36560,8 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
36560
36560
|
hold: leavingPagesHold,
|
|
36561
36561
|
startRef: createRef(),
|
|
36562
36562
|
endRef: createRef(),
|
|
36563
|
-
hidden: false
|
|
36563
|
+
hidden: false,
|
|
36564
|
+
observer: null
|
|
36564
36565
|
});
|
|
36565
36566
|
leavingPagesHold.containers.add(rerender);
|
|
36566
36567
|
// Keyed apart from the page it takes the place of, which is still there.
|
|
@@ -36600,20 +36601,22 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
36600
36601
|
}
|
|
36601
36602
|
entry.hidden = true;
|
|
36602
36603
|
entry.page.leavingSignal.value = true;
|
|
36603
|
-
|
|
36604
|
-
|
|
36605
|
-
|
|
36606
|
-
|
|
36607
|
-
|
|
36608
|
-
|
|
36609
|
-
|
|
36610
|
-
|
|
36611
|
-
|
|
36612
|
-
focusedElement.blur();
|
|
36613
|
-
}
|
|
36604
|
+
hideNodesBetween(start, end);
|
|
36605
|
+
// The page renders on its own while kept (a component reading a signal
|
|
36606
|
+
// the address moved), never through this container: a top node it
|
|
36607
|
+
// replaces lands between the markers unmarked. Its mutation is heard
|
|
36608
|
+
// before the next frame.
|
|
36609
|
+
const observer = new MutationObserver(() => {
|
|
36610
|
+
if (entry.hold.released) {
|
|
36611
|
+
observer.disconnect();
|
|
36612
|
+
return;
|
|
36614
36613
|
}
|
|
36615
|
-
|
|
36616
|
-
}
|
|
36614
|
+
hideNodesBetween(start, end);
|
|
36615
|
+
});
|
|
36616
|
+
observer.observe(start.parentNode, {
|
|
36617
|
+
childList: true
|
|
36618
|
+
});
|
|
36619
|
+
entry.observer = observer;
|
|
36617
36620
|
}
|
|
36618
36621
|
});
|
|
36619
36622
|
// Also run when a Suspense boundary above parks this container — a page
|
|
@@ -36625,6 +36628,7 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
36625
36628
|
return () => {
|
|
36626
36629
|
for (const entry of leavingRef.current) {
|
|
36627
36630
|
entry.hold.containers.delete(rerender);
|
|
36631
|
+
entry.observer?.disconnect();
|
|
36628
36632
|
}
|
|
36629
36633
|
leavingRef.current = [];
|
|
36630
36634
|
};
|
|
@@ -36652,6 +36656,22 @@ const useContentKeepingLeavingPages = (branch, readShownBranch, parentPage) => {
|
|
|
36652
36656
|
};
|
|
36653
36657
|
};
|
|
36654
36658
|
const countRenders = count => count + 1;
|
|
36659
|
+
const hideNodesBetween = (start, end) => {
|
|
36660
|
+
const focusedElement = document.activeElement;
|
|
36661
|
+
let node = start.nextSibling;
|
|
36662
|
+
while (node && node !== end) {
|
|
36663
|
+
if (node.nodeType === Node.ELEMENT_NODE && !node.hasAttribute(LEAVING_ATTRIBUTE)) {
|
|
36664
|
+
node.setAttribute(LEAVING_ATTRIBUTE, "");
|
|
36665
|
+
// What the keyboard held in it goes where the page's removal would
|
|
36666
|
+
// have sent it: a hidden element keeps the focus, and would go on
|
|
36667
|
+
// receiving the keys pressed during the movement.
|
|
36668
|
+
if (node.contains(focusedElement)) {
|
|
36669
|
+
focusedElement.blur();
|
|
36670
|
+
}
|
|
36671
|
+
}
|
|
36672
|
+
node = node.nextSibling;
|
|
36673
|
+
}
|
|
36674
|
+
};
|
|
36655
36675
|
// The page a container renders, as RoutePageContext hands it over (see
|
|
36656
36676
|
// route_page_context.js). Shown while the container would pick its branch, or
|
|
36657
36677
|
// a branch rendering the same element (it is then carried over), and while the
|
|
@@ -36863,6 +36883,14 @@ const collectBranches = (children, path = "") => {
|
|
|
36863
36883
|
const paramsMatching = routeParams ? route.matchesParams(routeParams) : true;
|
|
36864
36884
|
if (!matchingBranch && matching && paramsMatching) {
|
|
36865
36885
|
matchingBranch = branch;
|
|
36886
|
+
if (!routeParams) {
|
|
36887
|
+
// The params are part of the page this branch shows: /games/a and
|
|
36888
|
+
// /games/b are two pages on one branch, and the container renders
|
|
36889
|
+
// between them so the second is announced like any other (see
|
|
36890
|
+
// publishRouteRender) — a movement between the two waits on it.
|
|
36891
|
+
// eslint-disable-next-line no-unused-expressions
|
|
36892
|
+
route.paramsSignal.value;
|
|
36893
|
+
}
|
|
36866
36894
|
}
|
|
36867
36895
|
}
|
|
36868
36896
|
};
|
|
@@ -36927,6 +36955,59 @@ const RouteUI = ({
|
|
|
36927
36955
|
return element;
|
|
36928
36956
|
};
|
|
36929
36957
|
|
|
36958
|
+
/*
|
|
36959
|
+
* What ONE navigation asks of a route transition, worn by the element being
|
|
36960
|
+
* pressed: `<Link routeTransition>`, `<Button routeTransition>`, or the
|
|
36961
|
+
* attribute by hand on any anchor. A type travels as its name — all most
|
|
36962
|
+
* presses have to say — and anything more (a way round, a pace) as the same
|
|
36963
|
+
* object navTo() takes, written as JSON.
|
|
36964
|
+
*
|
|
36965
|
+
* Apart from route_transition.jsx, which plays the request: the press handlers
|
|
36966
|
+
* and the --navi-nav-to command read it too, and importing the transition
|
|
36967
|
+
* machinery there would pull it into an application that defines no
|
|
36968
|
+
* transition.
|
|
36969
|
+
*/
|
|
36970
|
+
|
|
36971
|
+
const ROUTE_TRANSITION_REQUEST_ATTRIBUTE = "data-navi-route-transition-request";
|
|
36972
|
+
|
|
36973
|
+
// The attributes to spread on the element. Nothing when nothing is asked, so
|
|
36974
|
+
// that the attribute written by hand on the same element is left standing.
|
|
36975
|
+
const writeRouteTransitionRequest = (routeTransition) => {
|
|
36976
|
+
if (routeTransition === undefined || routeTransition === null) {
|
|
36977
|
+
return null;
|
|
36978
|
+
}
|
|
36979
|
+
return {
|
|
36980
|
+
[ROUTE_TRANSITION_REQUEST_ATTRIBUTE]:
|
|
36981
|
+
typeof routeTransition === "string"
|
|
36982
|
+
? routeTransition
|
|
36983
|
+
: JSON.stringify(routeTransition),
|
|
36984
|
+
};
|
|
36985
|
+
};
|
|
36986
|
+
|
|
36987
|
+
// The request as navTo() takes it — a type name or the object — and undefined
|
|
36988
|
+
// when the element asks nothing.
|
|
36989
|
+
const readRouteTransitionRequest = (element) => {
|
|
36990
|
+
const asked = element.getAttribute(ROUTE_TRANSITION_REQUEST_ATTRIBUTE);
|
|
36991
|
+
if (asked === null) {
|
|
36992
|
+
return undefined;
|
|
36993
|
+
}
|
|
36994
|
+
const value = asked.trim();
|
|
36995
|
+
if (value === "") {
|
|
36996
|
+
return undefined;
|
|
36997
|
+
}
|
|
36998
|
+
if (value[0] !== "{") {
|
|
36999
|
+
return value;
|
|
37000
|
+
}
|
|
37001
|
+
try {
|
|
37002
|
+
return JSON.parse(value);
|
|
37003
|
+
} catch {
|
|
37004
|
+
console.warn(
|
|
37005
|
+
`${ROUTE_TRANSITION_REQUEST_ATTRIBUTE} is neither a type name nor JSON: ${value}`,
|
|
37006
|
+
);
|
|
37007
|
+
return undefined;
|
|
37008
|
+
}
|
|
37009
|
+
};
|
|
37010
|
+
|
|
36930
37011
|
/**
|
|
36931
37012
|
* Where a route movement is heading, said before its first picture is taken.
|
|
36932
37013
|
*
|
|
@@ -38338,10 +38419,6 @@ const TRANSITION_COVERED_ATTRIBUTE = "data-navi-route-transition-covered";
|
|
|
38338
38419
|
// right for a page that IS the whole viewport.
|
|
38339
38420
|
const TRANSITION_AREA_ATTRIBUTE = "data-navi-route-transition-area";
|
|
38340
38421
|
const TRANSITION_TARGET_ATTRIBUTE = "data-navi-route-transition-target";
|
|
38341
|
-
// What ONE navigation asks for, over whatever the relations say: worn by the
|
|
38342
|
-
// link being pressed (see <Link routeTransition>), or handed to navTo(). It answers
|
|
38343
|
-
// for that navigation and for no other — the next one is back to the relations.
|
|
38344
|
-
const TRANSITION_REQUEST_ATTRIBUTE = "data-navi-route-transition-request";
|
|
38345
38422
|
// What a history entry remembers of the crossing that created it, in the
|
|
38346
38423
|
// entry's own state: `{ from, type, direction, duration }` (see recordCrossing).
|
|
38347
38424
|
const CROSSING_STATE_KEY = "jsenv_route_transition";
|
|
@@ -38882,13 +38959,32 @@ const defineRouteTransition = (from, to, transition) => {
|
|
|
38882
38959
|
* "before" the other — so give it a movement that does not need one:
|
|
38883
38960
|
* `"cross-fade"`, or a custom type whose CSS is keyed on the type alone.
|
|
38884
38961
|
*
|
|
38885
|
-
*
|
|
38886
|
-
*
|
|
38887
|
-
*
|
|
38962
|
+
* Unless the history says it: `{ type: "slide-x", direction: "history" }` is
|
|
38963
|
+
* the grammar of a navigation stack, where every link goes one level deeper
|
|
38964
|
+
* and every back one level up. A push plays forward, a traversal retraces its
|
|
38965
|
+
* crossing or, with none remembered, plays back when it lands lower in the
|
|
38966
|
+
* history and forward when it lands higher, and a replace — the same level —
|
|
38967
|
+
* plays nothing. It plays only when the page changes: a push that opens a
|
|
38968
|
+
* layer over the page keeps the page. The relations written still answer
|
|
38969
|
+
* first, and a page written from anywhere then answers for its way out only
|
|
38970
|
+
* on a back — a link out of it is a push like any other (see findRelation).
|
|
38971
|
+
*
|
|
38972
|
+
* @param {string|{type?: string, duration?: number|string, direction?: "history"}} transition -
|
|
38973
|
+
* same forms as defineRouteTransition's. `"none"` (or removing the default)
|
|
38974
|
+
* puts the silence back.
|
|
38888
38975
|
* @returns {() => void} remove this default.
|
|
38889
38976
|
*/
|
|
38890
38977
|
const defineRouteDefaultTransition = transition => {
|
|
38891
|
-
const
|
|
38978
|
+
const {
|
|
38979
|
+
direction
|
|
38980
|
+
} = typeof transition === "object" && transition !== null ? transition : {};
|
|
38981
|
+
if (direction !== undefined && direction !== "history") {
|
|
38982
|
+
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.`);
|
|
38983
|
+
}
|
|
38984
|
+
const value = {
|
|
38985
|
+
...normalizeTransition(transition),
|
|
38986
|
+
readsHistory: direction === "history"
|
|
38987
|
+
};
|
|
38892
38988
|
defaultTransition = value;
|
|
38893
38989
|
installRouteTransitionCss();
|
|
38894
38990
|
return () => {
|
|
@@ -38941,29 +39037,8 @@ const readNavigationRequest = ({
|
|
|
38941
39037
|
return normalizeRequest(routeTransition);
|
|
38942
39038
|
}
|
|
38943
39039
|
if (element && element.getAttribute) {
|
|
38944
|
-
const asked = element
|
|
38945
|
-
|
|
38946
|
-
return null;
|
|
38947
|
-
}
|
|
38948
|
-
const value = asked.trim();
|
|
38949
|
-
if (value === "") {
|
|
38950
|
-
return null;
|
|
38951
|
-
}
|
|
38952
|
-
// A type is a name, and a name is all most links have to say. Anything
|
|
38953
|
-
// more — a way round, a pace — is the same object the API takes
|
|
38954
|
-
// everywhere else, written as JSON so that it travels on an attribute
|
|
38955
|
-
// (and so that a plain <a> can say it too).
|
|
38956
|
-
if (value[0] === "{") {
|
|
38957
|
-
let parsed;
|
|
38958
|
-
try {
|
|
38959
|
-
parsed = JSON.parse(value);
|
|
38960
|
-
} catch {
|
|
38961
|
-
console.warn(`${TRANSITION_REQUEST_ATTRIBUTE} is neither a type name nor JSON: ${value}`);
|
|
38962
|
-
return null;
|
|
38963
|
-
}
|
|
38964
|
-
return normalizeRequest(parsed);
|
|
38965
|
-
}
|
|
38966
|
-
return normalizeRequest(value);
|
|
39040
|
+
const asked = readRouteTransitionRequest(element);
|
|
39041
|
+
return asked === undefined ? null : normalizeRequest(asked);
|
|
38967
39042
|
}
|
|
38968
39043
|
return null;
|
|
38969
39044
|
};
|
|
@@ -39049,6 +39124,31 @@ const crossingRecordedOn = state => {
|
|
|
39049
39124
|
}
|
|
39050
39125
|
return crossing;
|
|
39051
39126
|
};
|
|
39127
|
+
|
|
39128
|
+
/**
|
|
39129
|
+
* Which way the history says a navigation goes, for a default that reads it
|
|
39130
|
+
* (see defineRouteDefaultTransition): a push is one level deeper, a traversal
|
|
39131
|
+
* goes where the depth of the entry it lands on puts it — back when that is
|
|
39132
|
+
* not known, as in readTraversalReplay —, and anything else (a replace) stays
|
|
39133
|
+
* on its level: null.
|
|
39134
|
+
*/
|
|
39135
|
+
const readHistoryDirection = (navigationType, {
|
|
39136
|
+
state,
|
|
39137
|
+
fromState
|
|
39138
|
+
}) => {
|
|
39139
|
+
if (navigationType === "push") {
|
|
39140
|
+
return "forward";
|
|
39141
|
+
}
|
|
39142
|
+
if (navigationType !== "traverse") {
|
|
39143
|
+
return null;
|
|
39144
|
+
}
|
|
39145
|
+
const depthIn = navDepthOf(state);
|
|
39146
|
+
const depthOut = navDepthOf(fromState);
|
|
39147
|
+
if (depthIn !== undefined && depthOut !== undefined && depthIn > depthOut) {
|
|
39148
|
+
return "forward";
|
|
39149
|
+
}
|
|
39150
|
+
return "back";
|
|
39151
|
+
};
|
|
39052
39152
|
const navDepthOf = state => {
|
|
39053
39153
|
if (state && typeof state[NAV_DEPTH_STATE_KEY] === "number") {
|
|
39054
39154
|
return state[NAV_DEPTH_STATE_KEY];
|
|
@@ -39232,6 +39332,10 @@ let navigationAnimated = false;
|
|
|
39232
39332
|
// "push", "replace", "traverse", … — a push is the one navigation that creates
|
|
39233
39333
|
// the entry a crossing is recorded on.
|
|
39234
39334
|
let navigationType = null;
|
|
39335
|
+
// Which way the history says this navigation goes — "forward", "back", or null
|
|
39336
|
+
// for a replace — when the default reads it (see readHistoryDirection), and
|
|
39337
|
+
// undefined when nothing does.
|
|
39338
|
+
let navigationHistoryDirection;
|
|
39235
39339
|
// What was decided for the navigation now landing — a movement, or "none" —
|
|
39236
39340
|
// which is what its entry remembers (see recordCrossing). Null while nothing
|
|
39237
39341
|
// has been decided, and for a navigation nothing was said about.
|
|
@@ -39249,14 +39353,19 @@ observeBeforeRouting(details => {
|
|
|
39249
39353
|
navigationType = details.navigationType;
|
|
39250
39354
|
navigationUrl = details.url;
|
|
39251
39355
|
navigationFromUrl = documentUrlSignal.peek();
|
|
39252
|
-
// A traversal has no element and no call to ask anything: what it asks is
|
|
39253
|
-
// the crossing it retraces — reversed for a back, as it was for a forward.
|
|
39254
39356
|
// Read before the document state moves, so the state peeked is the entry
|
|
39255
39357
|
// being left.
|
|
39358
|
+
const fromState = documentStateSignal.peek();
|
|
39359
|
+
// A traversal has no element and no call to ask anything: what it asks is
|
|
39360
|
+
// the crossing it retraces — reversed for a back, as it was for a forward.
|
|
39256
39361
|
navigationRequest = navigationType === "traverse" ? readTraversalReplay(details, {
|
|
39257
39362
|
fromUrl: navigationFromUrl,
|
|
39258
|
-
fromState
|
|
39363
|
+
fromState
|
|
39259
39364
|
}) : readNavigationRequest(details);
|
|
39365
|
+
navigationHistoryDirection = defaultTransition && defaultTransition.readsHistory ? readHistoryDirection(navigationType, {
|
|
39366
|
+
state: details.state,
|
|
39367
|
+
fromState
|
|
39368
|
+
}) : undefined;
|
|
39260
39369
|
if (relations.length === 0 && !defaultTransition && !navigationRequest) {
|
|
39261
39370
|
return;
|
|
39262
39371
|
}
|
|
@@ -39274,17 +39383,24 @@ observeAfterRouting(() => {
|
|
|
39274
39383
|
const url = navigationUrl;
|
|
39275
39384
|
const fromUrl = navigationFromUrl;
|
|
39276
39385
|
const type = navigationType;
|
|
39386
|
+
const historyDirection = navigationHistoryDirection;
|
|
39277
39387
|
// Read here and dropped here: a request answers for the navigation it was
|
|
39278
39388
|
// made on, and the next one is back to the relations.
|
|
39279
39389
|
navigationRequest = null;
|
|
39280
39390
|
navigationUrl = null;
|
|
39281
39391
|
navigationFromUrl = null;
|
|
39282
39392
|
navigationType = null;
|
|
39283
|
-
|
|
39393
|
+
navigationHistoryDirection = undefined;
|
|
39394
|
+
// A default reading the history plays between two pages a level apart: not
|
|
39395
|
+
// on a replace, and not on a navigation that keeps the page — a push
|
|
39396
|
+
// opening a layer over it moves the layer, not the page (see
|
|
39397
|
+
// page_change.js).
|
|
39398
|
+
const base = defaultTransition && (!defaultTransition.readsHistory || historyDirection !== null && isRenderingPageChange()) ? defaultTransition : null;
|
|
39399
|
+
if (!navigationAnimated && (request || base)) {
|
|
39284
39400
|
const {
|
|
39285
39401
|
type,
|
|
39286
39402
|
duration
|
|
39287
|
-
} = resolveTransition(request,
|
|
39403
|
+
} = resolveTransition(request, base);
|
|
39288
39404
|
if (type === "none") {
|
|
39289
39405
|
navigationDecision = {
|
|
39290
39406
|
type: "none"
|
|
@@ -39297,11 +39413,12 @@ observeAfterRouting(() => {
|
|
|
39297
39413
|
// A default has no direction: nothing says which of two arbitrary
|
|
39298
39414
|
// pages is before the other, and the attribute is then worn empty —
|
|
39299
39415
|
// present for whoever keys on "one of ours is playing", silent on the
|
|
39300
|
-
// way. A request is the other case: a
|
|
39301
|
-
// press that names the movement means
|
|
39302
|
-
// otherwise — and a movement of navi's is
|
|
39303
|
-
// so left empty it would play nothing at
|
|
39304
|
-
|
|
39416
|
+
// way — unless it reads the history. A request is the other case: a
|
|
39417
|
+
// navigation IS a way round, so a press that names the movement means
|
|
39418
|
+
// forward unless it says otherwise — and a movement of navi's is
|
|
39419
|
+
// written on the direction, so left empty it would play nothing at
|
|
39420
|
+
// all.
|
|
39421
|
+
direction: request && request.direction !== undefined ? request.direction : request && request.typeSaid ? "forward" : base && base.readsHistory ? historyDirection : "",
|
|
39305
39422
|
type,
|
|
39306
39423
|
duration
|
|
39307
39424
|
});
|
|
@@ -39417,6 +39534,12 @@ const findRelation = (fromPage, toPage) => {
|
|
|
39417
39534
|
};
|
|
39418
39535
|
}
|
|
39419
39536
|
}
|
|
39537
|
+
// Leaving such a page plays back because leaving it is assumed to be
|
|
39538
|
+
// closing it. With the default reading the history, that is known instead:
|
|
39539
|
+
// a link out of it is a push, one level deeper, and the default answers.
|
|
39540
|
+
if (navigationHistoryDirection !== undefined && navigationHistoryDirection !== "back") {
|
|
39541
|
+
return null;
|
|
39542
|
+
}
|
|
39420
39543
|
for (const relation of relations) {
|
|
39421
39544
|
if (relation.from) {
|
|
39422
39545
|
continue;
|
|
@@ -40330,7 +40453,11 @@ const RouteTravel = ({
|
|
|
40330
40453
|
// a travel is between two of them, and by the time anything renders the first
|
|
40331
40454
|
// one is already gone. Written after each render (below), so a subscriber
|
|
40332
40455
|
// reading it — they all run before Preact flushes — reads the one being left.
|
|
40333
|
-
|
|
40456
|
+
// The page and not its place in the row: a row given again around the page
|
|
40457
|
+
// on screen (a window over a list, read anew around it) puts that page at
|
|
40458
|
+
// another index without anything having moved.
|
|
40459
|
+
const currentPage = currentIndex === -1 ? null : pages[currentIndex];
|
|
40460
|
+
const currentPageRef = useRef(currentPage);
|
|
40334
40461
|
|
|
40335
40462
|
// Where a page is asked for, whoever asks: a page is a route AND the params
|
|
40336
40463
|
// that say which of its tabs, and a caller told only the route would send the
|
|
@@ -40526,11 +40653,13 @@ const RouteTravel = ({
|
|
|
40526
40653
|
if (index === -1) {
|
|
40527
40654
|
return;
|
|
40528
40655
|
}
|
|
40529
|
-
|
|
40530
|
-
|
|
40531
|
-
//
|
|
40532
|
-
//
|
|
40533
|
-
|
|
40656
|
+
const page = pages[index];
|
|
40657
|
+
if (samePage(page, currentPageRef.current)) {
|
|
40658
|
+
// Where the row already was — the first reading of all, a row given
|
|
40659
|
+
// again around the page on screen, and any move this box has already
|
|
40660
|
+
// taken note of (a render writes it too). What it was still waiting
|
|
40661
|
+
// for is here nonetheless, so the wait is called off.
|
|
40662
|
+
if (samePage(pageAskedForRef.current, page)) {
|
|
40534
40663
|
pageAskedForRef.current = null;
|
|
40535
40664
|
}
|
|
40536
40665
|
return;
|
|
@@ -40539,13 +40668,12 @@ const RouteTravel = ({
|
|
|
40539
40668
|
// between two of them is a page change the path does not show (see
|
|
40540
40669
|
// page_change.js).
|
|
40541
40670
|
notePageChange();
|
|
40542
|
-
const page = pages[index];
|
|
40543
40671
|
// A page this box asked for itself — a travel's own navigation, or one
|
|
40544
40672
|
// it had given up waiting on: what arrives here is the answer to a
|
|
40545
40673
|
// question already answered, not somebody going somewhere.
|
|
40546
40674
|
if (samePage(pageAskedForRef.current, page)) {
|
|
40547
40675
|
pageAskedForRef.current = null;
|
|
40548
|
-
|
|
40676
|
+
currentPageRef.current = page;
|
|
40549
40677
|
return;
|
|
40550
40678
|
}
|
|
40551
40679
|
// Somewhere else arrived first: whatever this box was still waiting for
|
|
@@ -40557,15 +40685,15 @@ const RouteTravel = ({
|
|
|
40557
40685
|
// flight is the answer, aimed somewhere else. Starting a second one on
|
|
40558
40686
|
// top would leave this one's pictures to be dropped mid-slide.
|
|
40559
40687
|
if (travelRef.current) {
|
|
40560
|
-
|
|
40688
|
+
currentPageRef.current = page;
|
|
40561
40689
|
retargetTravel(travelRef.current, page);
|
|
40562
40690
|
return;
|
|
40563
40691
|
}
|
|
40564
|
-
const fromIndex =
|
|
40565
|
-
|
|
40566
|
-
if (fromIndex === -1
|
|
40567
|
-
// Arriving from outside this row
|
|
40568
|
-
//
|
|
40692
|
+
const fromIndex = pageIndexOf(pages, currentPageRef.current);
|
|
40693
|
+
currentPageRef.current = page;
|
|
40694
|
+
if (fromIndex === -1) {
|
|
40695
|
+
// Arriving from outside this row: there is no pair of pages to show,
|
|
40696
|
+
// so there is nothing to travel between.
|
|
40569
40697
|
return;
|
|
40570
40698
|
}
|
|
40571
40699
|
beginTravel({
|
|
@@ -40600,8 +40728,8 @@ const RouteTravel = ({
|
|
|
40600
40728
|
// What the next announcement will compare itself against: written after the
|
|
40601
40729
|
// render that shows it, so it is always the page one is looking at.
|
|
40602
40730
|
useLayoutEffect(() => {
|
|
40603
|
-
|
|
40604
|
-
}, [
|
|
40731
|
+
currentPageRef.current = currentPage;
|
|
40732
|
+
}, [currentPage]);
|
|
40605
40733
|
|
|
40606
40734
|
// Let go of far enough: the movement carries on from under the finger, at its
|
|
40607
40735
|
// own pace, to the end.
|
|
@@ -43563,13 +43691,15 @@ const navToCommand = (source, event, { argument }) => {
|
|
|
43563
43691
|
return {
|
|
43564
43692
|
target,
|
|
43565
43693
|
// Which way there is worn by the source, as a link wears it (see
|
|
43566
|
-
// link_replace.js, link_return.js, link_open.js
|
|
43694
|
+
// link_replace.js, link_return.js, link_open.js,
|
|
43695
|
+
// route_transition_request.js):
|
|
43567
43696
|
// `<Button command="--navi-nav-to:/done" replace>`.
|
|
43568
43697
|
implementation: () =>
|
|
43569
43698
|
navTo(argument, {
|
|
43570
43699
|
replace: linkAsksForReplace(source),
|
|
43571
43700
|
asReturn: linkAsksForReturn(source),
|
|
43572
43701
|
open: linkAsksToOpen(source),
|
|
43702
|
+
routeTransition: readRouteTransitionRequest(source),
|
|
43573
43703
|
}),
|
|
43574
43704
|
};
|
|
43575
43705
|
};
|
|
@@ -56466,10 +56596,8 @@ const LinkPlain = props => {
|
|
|
56466
56596
|
|
|
56467
56597
|
// What this link asks of a route transition, worn as an attribute so that
|
|
56468
56598
|
// the navigation reads it off the element being pressed (see
|
|
56469
|
-
//
|
|
56470
|
-
|
|
56471
|
-
// writes it by hand.
|
|
56472
|
-
const routeTransitionRequest = routeTransition === undefined || routeTransition === null ? undefined : typeof routeTransition === "string" ? routeTransition : JSON.stringify(routeTransition);
|
|
56599
|
+
// route_transition_request.js, which owns the name and does the reading).
|
|
56600
|
+
const routeTransitionRequest = writeRouteTransitionRequest(routeTransition);
|
|
56473
56601
|
|
|
56474
56602
|
// Which way this link goes to the place it aims at, worn as an attribute so
|
|
56475
56603
|
// that whoever answers the press reads it off the anchor (see
|
|
@@ -56560,7 +56688,7 @@ const LinkPlain = props => {
|
|
|
56560
56688
|
open: undefined,
|
|
56561
56689
|
document: undefined,
|
|
56562
56690
|
prefetch: undefined,
|
|
56563
|
-
|
|
56691
|
+
...routeTransitionRequest,
|
|
56564
56692
|
...(pressableDuringRouteTransition ? {
|
|
56565
56693
|
[PRESSABLE_ATTRIBUTE]: ""
|
|
56566
56694
|
} : null),
|
|
@@ -61270,6 +61398,7 @@ const ButtonUI = props => {
|
|
|
61270
61398
|
asReturn,
|
|
61271
61399
|
open,
|
|
61272
61400
|
document: isDocument,
|
|
61401
|
+
routeTransition,
|
|
61273
61402
|
pressableDuringRouteTransition,
|
|
61274
61403
|
prefetch = true,
|
|
61275
61404
|
// visual
|
|
@@ -61327,6 +61456,11 @@ const ButtonUI = props => {
|
|
|
61327
61456
|
[LINK_DOCUMENT_ATTRIBUTE]: ""
|
|
61328
61457
|
} : null;
|
|
61329
61458
|
|
|
61459
|
+
// What this press asks of a route transition (see
|
|
61460
|
+
// route_transition_request.js): read off the anchor by the navigation, off
|
|
61461
|
+
// the source by --navi-nav-to.
|
|
61462
|
+
const routeTransitionRequest = writeRouteTransitionRequest(routeTransition);
|
|
61463
|
+
|
|
61330
61464
|
// Worn as an attribute too, and read at the document by whoever catches the
|
|
61331
61465
|
// press a movement would have swallowed (see transition_press.js).
|
|
61332
61466
|
const pressableRequest = pressableDuringRouteTransition ? {
|
|
@@ -61383,6 +61517,8 @@ const ButtonUI = props => {
|
|
|
61383
61517
|
...openRequest,
|
|
61384
61518
|
document: undefined,
|
|
61385
61519
|
...documentRequest,
|
|
61520
|
+
routeTransition: undefined,
|
|
61521
|
+
...routeTransitionRequest,
|
|
61386
61522
|
pressableDuringRouteTransition: undefined,
|
|
61387
61523
|
...pressableRequest,
|
|
61388
61524
|
prefetch: undefined
|
|
@@ -62039,6 +62175,7 @@ const COMMAND_DEFAULT_PROPS_FACTORIES = {
|
|
|
62039
62175
|
* replace?: boolean,
|
|
62040
62176
|
* asReturn?: boolean,
|
|
62041
62177
|
* open?: string | { id: string, type?: "push" | "replace" },
|
|
62178
|
+
* routeTransition?: string | { type?: string, duration?: number | string, direction?: "forward" | "back" },
|
|
62042
62179
|
* document?: boolean,
|
|
62043
62180
|
* actionStandalone?: boolean,
|
|
62044
62181
|
* actionAbortable?: boolean,
|
|
@@ -62087,6 +62224,11 @@ const COMMAND_DEFAULT_PROPS_FACTORIES = {
|
|
|
62087
62224
|
* @param {string|{id: string, type?: "push"|"replace"}} [open] Lands with one
|
|
62088
62225
|
* of the destination's popups open, named the way its `navState` names it:
|
|
62089
62226
|
* what `<Link open>` says, for a press drawn as a button.
|
|
62227
|
+
* @param {string|{type?: string, duration?: number|string, direction?: "forward"|"back"}} [routeTransition]
|
|
62228
|
+
* What the press asks of a route transition, for that one navigation — a
|
|
62229
|
+
* type name, or an object to also say the pace or which way it plays, over
|
|
62230
|
+
* what the pair's relation says: what `<Link routeTransition>` says, read
|
|
62231
|
+
* off an `href`, a `route` or a `--navi-nav-to` command.
|
|
62090
62232
|
* @param {boolean} [document] The `href` is ANOTHER DOCUMENT of this origin —
|
|
62091
62233
|
* an admin panel, a status page, anything built as its own entry point — so
|
|
62092
62234
|
* the press is left to the browser and loads that page, instead of being
|