@jsenv/navi 0.29.327 → 0.29.329
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 +55 -23
- package/dist/dev/jsenv_navi.js.map +6 -6
- package/dist/jsenv_navi.js +55 -23
- package/dist/jsenv_navi.js.map +6 -6
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -7071,6 +7071,16 @@ const positionCallout = (
|
|
|
7071
7071
|
}
|
|
7072
7072
|
return;
|
|
7073
7073
|
}
|
|
7074
|
+
if (!calloutElement.isConnected) {
|
|
7075
|
+
// The callout is drawn inside the anchor's subtree (calloutContainer),
|
|
7076
|
+
// so it leaves the document with it — a Suspense boundary parking
|
|
7077
|
+
// the screen while an action re-runs keeps the subtree mounted, refs
|
|
7078
|
+
// intact, but detached. showPopover() throws on a detached element,
|
|
7079
|
+
// and leaving the document already took it out of the top layer, so
|
|
7080
|
+
// there is nothing to hide either: same as ancestorClosed, wait for
|
|
7081
|
+
// the next check, which shows it again once the subtree is back.
|
|
7082
|
+
return;
|
|
7083
|
+
}
|
|
7074
7084
|
if (!calloutElement.matches(":popover-open")) {
|
|
7075
7085
|
if (debug) {
|
|
7076
7086
|
debug(event, "showing callout because anchor is visible again");
|
|
@@ -23516,10 +23526,16 @@ const createRoutePattern = (
|
|
|
23516
23526
|
// search params are updated. When buildMostPreciseUrl performs an ancestor
|
|
23517
23527
|
// optimisation (e.g. "/map/isochrone/compare" → "/map/isochrone") it is trusted
|
|
23518
23528
|
// as-is because the built pathname will differ from the route's own base pathname.
|
|
23519
|
-
//
|
|
23520
|
-
//
|
|
23521
|
-
//
|
|
23522
|
-
|
|
23529
|
+
// A weak param is never inherited from its signal by a url built for a link
|
|
23530
|
+
// (see readSignalForUrlBuild). A url amended in place is another matter: the
|
|
23531
|
+
// route is matching, so the signal IS this visit's state, kept in step with
|
|
23532
|
+
// the address by every routing pass — and what it holds is carried over, so
|
|
23533
|
+
// that changing another param does not end the visit this one qualifies.
|
|
23534
|
+
// Read from the signal, not from the url being amended: several signals
|
|
23535
|
+
// written in one batch flush one url write at a time, and the routing pass
|
|
23536
|
+
// of the first would take the others for gone — and reset them — if the url
|
|
23537
|
+
// it wrote did not already carry what they hold.
|
|
23538
|
+
const carryOverWeakParams = (params) => {
|
|
23523
23539
|
let paramsWithWeak = params;
|
|
23524
23540
|
for (const connection of connections) {
|
|
23525
23541
|
const { paramName } = connection;
|
|
@@ -23527,17 +23543,13 @@ const createRoutePattern = (
|
|
|
23527
23543
|
continue;
|
|
23528
23544
|
}
|
|
23529
23545
|
const currentValue = connection.signal.peek();
|
|
23530
|
-
if (currentValue
|
|
23531
|
-
continue;
|
|
23532
|
-
}
|
|
23533
|
-
const currentParams = applyOn(currentUrl);
|
|
23534
|
-
if (!currentParams || currentParams[paramName] === undefined) {
|
|
23546
|
+
if (connection.isDefaultValue(currentValue)) {
|
|
23535
23547
|
continue;
|
|
23536
23548
|
}
|
|
23537
23549
|
if (paramsWithWeak === params) {
|
|
23538
23550
|
paramsWithWeak = { ...params };
|
|
23539
23551
|
}
|
|
23540
|
-
paramsWithWeak[paramName] =
|
|
23552
|
+
paramsWithWeak[paramName] = currentValue;
|
|
23541
23553
|
}
|
|
23542
23554
|
return paramsWithWeak;
|
|
23543
23555
|
};
|
|
@@ -23573,7 +23585,7 @@ const createRoutePattern = (
|
|
|
23573
23585
|
};
|
|
23574
23586
|
|
|
23575
23587
|
const buildUrlPreservingPath = (currentUrl, params = {}) => {
|
|
23576
|
-
params = carryOverWeakParams(
|
|
23588
|
+
params = carryOverWeakParams(params);
|
|
23577
23589
|
if (currentUrl) {
|
|
23578
23590
|
params = carryOverPathParams(currentUrl, params);
|
|
23579
23591
|
}
|
|
@@ -26438,20 +26450,28 @@ const setupBrowserIntegrationViaHistory = ({
|
|
|
26438
26450
|
// traversal to another document is a full page load, which no press on a
|
|
26439
26451
|
// link asked for — the entries that are ours are recorded as they are
|
|
26440
26452
|
// created, starting with the one this document was loaded into.
|
|
26453
|
+
//
|
|
26454
|
+
// The presence of window.navigation says nothing about the entry: the spec
|
|
26455
|
+
// makes currentEntry null in a document that is not fully active, and iOS
|
|
26456
|
+
// Safari answers null in a document that plainly is (a booted app, minutes
|
|
26457
|
+
// into a session). Nothing can be done about it; an entry that cannot be
|
|
26458
|
+
// read is treated as a browser without the API, which only costs the
|
|
26459
|
+
// adjacency.
|
|
26441
26460
|
const sameDocumentEntryKeys = new Set();
|
|
26442
26461
|
const rememberEntryIsOfThisDocument = () => {
|
|
26443
|
-
|
|
26444
|
-
|
|
26462
|
+
const currentEntry = window.navigation?.currentEntry;
|
|
26463
|
+
if (currentEntry) {
|
|
26464
|
+
sameDocumentEntryKeys.add(currentEntry.key);
|
|
26445
26465
|
}
|
|
26446
26466
|
};
|
|
26447
26467
|
rememberEntryIsOfThisDocument();
|
|
26448
26468
|
const adjacentEntryDelta = (url) => {
|
|
26449
|
-
const
|
|
26450
|
-
if (!
|
|
26469
|
+
const currentEntry = window.navigation?.currentEntry;
|
|
26470
|
+
if (!currentEntry) {
|
|
26451
26471
|
return 0;
|
|
26452
26472
|
}
|
|
26453
|
-
const entries = navigation.entries();
|
|
26454
|
-
const index =
|
|
26473
|
+
const entries = window.navigation.entries();
|
|
26474
|
+
const index = currentEntry.index;
|
|
26455
26475
|
// Behind first: when the same page stands on both sides (A, B, A and one
|
|
26456
26476
|
// is on B), a link to it reads as going back.
|
|
26457
26477
|
for (const delta of [-1, 1]) {
|
|
@@ -35880,7 +35900,7 @@ const useUIStateController = (
|
|
|
35880
35900
|
// reach until that popup opens. Letting it block interaction would make
|
|
35881
35901
|
// a picker whose content is loading impossible to open at all.
|
|
35882
35902
|
getInteractionBlockingControls: () => [],
|
|
35883
|
-
onUIAction: (e, { skipCommand } = {}) => {
|
|
35903
|
+
onUIAction: (e, { skipCommand, skipBoundSignal } = {}) => {
|
|
35884
35904
|
if (controlType === "button" && controller.controlHostProps.name) {
|
|
35885
35905
|
const buttonName = controller.controlHostProps.name;
|
|
35886
35906
|
const parentController = controller.parentUIStateController;
|
|
@@ -35906,7 +35926,9 @@ const useUIStateController = (
|
|
|
35906
35926
|
}
|
|
35907
35927
|
// Trigger uiAction/command side effects without changing UI state.
|
|
35908
35928
|
const currentUIState = controller.uiState;
|
|
35909
|
-
|
|
35929
|
+
if (!skipBoundSignal) {
|
|
35930
|
+
writeBoundSignal(currentUIState);
|
|
35931
|
+
}
|
|
35910
35932
|
s.uiActionInternal?.(currentUIState, e);
|
|
35911
35933
|
if (s.uiAction) {
|
|
35912
35934
|
s.uiAction(currentUIState, e);
|
|
@@ -36128,7 +36150,15 @@ const useUIStateController = (
|
|
|
36128
36150
|
// sync, but do NOT fire the command and do NOT notify the parent —
|
|
36129
36151
|
// both would cause an infinite loop when a parent cascades state
|
|
36130
36152
|
// down to its children (child command would re-trigger the cascade).
|
|
36131
|
-
|
|
36153
|
+
// A control following what it was given (state_prop_change) does
|
|
36154
|
+
// not write its bound signal either: the signal is what it
|
|
36155
|
+
// follows. The one write that would change it is an emptied
|
|
36156
|
+
// signal refilled with the suggestion the control fell back on —
|
|
36157
|
+
// a state the app just took back, put back by the control.
|
|
36158
|
+
controller.onUIAction(e, {
|
|
36159
|
+
skipCommand: true,
|
|
36160
|
+
skipBoundSignal: e.type === "state_prop_change",
|
|
36161
|
+
});
|
|
36132
36162
|
}
|
|
36133
36163
|
if (
|
|
36134
36164
|
e.type === "facade_propagate_up" ||
|
|
@@ -73060,8 +73090,11 @@ const Spin = ({
|
|
|
73060
73090
|
// elsewhere on the page — and the control follows it. A control seeded from a
|
|
73061
73091
|
// signal only writes back into it (see resolveInputProps), which is enough
|
|
73062
73092
|
// for a field one only ever types into and not for a value that is also moved
|
|
73063
|
-
// from outside.
|
|
73064
|
-
// the
|
|
73093
|
+
// from outside. A signal holding nothing is left alone: the control goes back
|
|
73094
|
+
// to the suggestion it started on by itself (see resolveValueState), and
|
|
73095
|
+
// asking it to reset would be an act of its own, written into the signal —
|
|
73096
|
+
// the signal could then never hold nothing while a spin is bound to it, and a
|
|
73097
|
+
// day the app took back would come back as today.
|
|
73065
73098
|
const signalValue = signalProp ? signalProp.value : undefined;
|
|
73066
73099
|
// The value as of the render this effect belongs to, and not one the closure
|
|
73067
73100
|
// captured a while ago: a step writes the signal, the signal brings us back
|
|
@@ -73075,7 +73108,6 @@ const Spin = ({
|
|
|
73075
73108
|
return;
|
|
73076
73109
|
}
|
|
73077
73110
|
if (signalValue === undefined) {
|
|
73078
|
-
dispatchRequestResetUIState(controlEl);
|
|
73079
73111
|
return;
|
|
73080
73112
|
}
|
|
73081
73113
|
if (signalValue !== valueRef.current) {
|