@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/dev/jsenv_navi.js
CHANGED
|
@@ -7325,6 +7325,16 @@ const positionCallout = (
|
|
|
7325
7325
|
}
|
|
7326
7326
|
return;
|
|
7327
7327
|
}
|
|
7328
|
+
if (!calloutElement.isConnected) {
|
|
7329
|
+
// The callout is drawn inside the anchor's subtree (calloutContainer),
|
|
7330
|
+
// so it leaves the document with it — a Suspense boundary parking
|
|
7331
|
+
// the screen while an action re-runs keeps the subtree mounted, refs
|
|
7332
|
+
// intact, but detached. showPopover() throws on a detached element,
|
|
7333
|
+
// and leaving the document already took it out of the top layer, so
|
|
7334
|
+
// there is nothing to hide either: same as ancestorClosed, wait for
|
|
7335
|
+
// the next check, which shows it again once the subtree is back.
|
|
7336
|
+
return;
|
|
7337
|
+
}
|
|
7328
7338
|
if (!calloutElement.matches(":popover-open")) {
|
|
7329
7339
|
if (debug) {
|
|
7330
7340
|
debug(event, "showing callout because anchor is visible again");
|
|
@@ -24214,10 +24224,16 @@ const createRoutePattern = (
|
|
|
24214
24224
|
// search params are updated. When buildMostPreciseUrl performs an ancestor
|
|
24215
24225
|
// optimisation (e.g. "/map/isochrone/compare" → "/map/isochrone") it is trusted
|
|
24216
24226
|
// as-is because the built pathname will differ from the route's own base pathname.
|
|
24217
|
-
//
|
|
24218
|
-
//
|
|
24219
|
-
//
|
|
24220
|
-
|
|
24227
|
+
// A weak param is never inherited from its signal by a url built for a link
|
|
24228
|
+
// (see readSignalForUrlBuild). A url amended in place is another matter: the
|
|
24229
|
+
// route is matching, so the signal IS this visit's state, kept in step with
|
|
24230
|
+
// the address by every routing pass — and what it holds is carried over, so
|
|
24231
|
+
// that changing another param does not end the visit this one qualifies.
|
|
24232
|
+
// Read from the signal, not from the url being amended: several signals
|
|
24233
|
+
// written in one batch flush one url write at a time, and the routing pass
|
|
24234
|
+
// of the first would take the others for gone — and reset them — if the url
|
|
24235
|
+
// it wrote did not already carry what they hold.
|
|
24236
|
+
const carryOverWeakParams = (params) => {
|
|
24221
24237
|
let paramsWithWeak = params;
|
|
24222
24238
|
for (const connection of connections) {
|
|
24223
24239
|
const { paramName } = connection;
|
|
@@ -24225,17 +24241,13 @@ const createRoutePattern = (
|
|
|
24225
24241
|
continue;
|
|
24226
24242
|
}
|
|
24227
24243
|
const currentValue = connection.signal.peek();
|
|
24228
|
-
if (currentValue
|
|
24229
|
-
continue;
|
|
24230
|
-
}
|
|
24231
|
-
const currentParams = applyOn(currentUrl);
|
|
24232
|
-
if (!currentParams || currentParams[paramName] === undefined) {
|
|
24244
|
+
if (connection.isDefaultValue(currentValue)) {
|
|
24233
24245
|
continue;
|
|
24234
24246
|
}
|
|
24235
24247
|
if (paramsWithWeak === params) {
|
|
24236
24248
|
paramsWithWeak = { ...params };
|
|
24237
24249
|
}
|
|
24238
|
-
paramsWithWeak[paramName] =
|
|
24250
|
+
paramsWithWeak[paramName] = currentValue;
|
|
24239
24251
|
}
|
|
24240
24252
|
return paramsWithWeak;
|
|
24241
24253
|
};
|
|
@@ -24271,7 +24283,7 @@ const createRoutePattern = (
|
|
|
24271
24283
|
};
|
|
24272
24284
|
|
|
24273
24285
|
const buildUrlPreservingPath = (currentUrl, params = {}) => {
|
|
24274
|
-
params = carryOverWeakParams(
|
|
24286
|
+
params = carryOverWeakParams(params);
|
|
24275
24287
|
if (currentUrl) {
|
|
24276
24288
|
params = carryOverPathParams(currentUrl, params);
|
|
24277
24289
|
}
|
|
@@ -27188,20 +27200,28 @@ const setupBrowserIntegrationViaHistory = ({
|
|
|
27188
27200
|
// traversal to another document is a full page load, which no press on a
|
|
27189
27201
|
// link asked for — the entries that are ours are recorded as they are
|
|
27190
27202
|
// created, starting with the one this document was loaded into.
|
|
27203
|
+
//
|
|
27204
|
+
// The presence of window.navigation says nothing about the entry: the spec
|
|
27205
|
+
// makes currentEntry null in a document that is not fully active, and iOS
|
|
27206
|
+
// Safari answers null in a document that plainly is (a booted app, minutes
|
|
27207
|
+
// into a session). Nothing can be done about it; an entry that cannot be
|
|
27208
|
+
// read is treated as a browser without the API, which only costs the
|
|
27209
|
+
// adjacency.
|
|
27191
27210
|
const sameDocumentEntryKeys = new Set();
|
|
27192
27211
|
const rememberEntryIsOfThisDocument = () => {
|
|
27193
|
-
|
|
27194
|
-
|
|
27212
|
+
const currentEntry = window.navigation?.currentEntry;
|
|
27213
|
+
if (currentEntry) {
|
|
27214
|
+
sameDocumentEntryKeys.add(currentEntry.key);
|
|
27195
27215
|
}
|
|
27196
27216
|
};
|
|
27197
27217
|
rememberEntryIsOfThisDocument();
|
|
27198
27218
|
const adjacentEntryDelta = (url) => {
|
|
27199
|
-
const
|
|
27200
|
-
if (!
|
|
27219
|
+
const currentEntry = window.navigation?.currentEntry;
|
|
27220
|
+
if (!currentEntry) {
|
|
27201
27221
|
return 0;
|
|
27202
27222
|
}
|
|
27203
|
-
const entries = navigation.entries();
|
|
27204
|
-
const index =
|
|
27223
|
+
const entries = window.navigation.entries();
|
|
27224
|
+
const index = currentEntry.index;
|
|
27205
27225
|
// Behind first: when the same page stands on both sides (A, B, A and one
|
|
27206
27226
|
// is on B), a link to it reads as going back.
|
|
27207
27227
|
for (const delta of [-1, 1]) {
|
|
@@ -36819,7 +36839,7 @@ const useUIStateController = (
|
|
|
36819
36839
|
// reach until that popup opens. Letting it block interaction would make
|
|
36820
36840
|
// a picker whose content is loading impossible to open at all.
|
|
36821
36841
|
getInteractionBlockingControls: () => [],
|
|
36822
|
-
onUIAction: (e, { skipCommand } = {}) => {
|
|
36842
|
+
onUIAction: (e, { skipCommand, skipBoundSignal } = {}) => {
|
|
36823
36843
|
if (controlType === "button" && controller.controlHostProps.name) {
|
|
36824
36844
|
const buttonName = controller.controlHostProps.name;
|
|
36825
36845
|
const parentController = controller.parentUIStateController;
|
|
@@ -36849,7 +36869,9 @@ const useUIStateController = (
|
|
|
36849
36869
|
}
|
|
36850
36870
|
// Trigger uiAction/command side effects without changing UI state.
|
|
36851
36871
|
const currentUIState = controller.uiState;
|
|
36852
|
-
|
|
36872
|
+
if (!skipBoundSignal) {
|
|
36873
|
+
writeBoundSignal(currentUIState);
|
|
36874
|
+
}
|
|
36853
36875
|
s.uiActionInternal?.(currentUIState, e);
|
|
36854
36876
|
if (s.uiAction) {
|
|
36855
36877
|
debugUIState(`calling uiAction for ${controlType}`, currentUIState);
|
|
@@ -37075,7 +37097,15 @@ const useUIStateController = (
|
|
|
37075
37097
|
// sync, but do NOT fire the command and do NOT notify the parent —
|
|
37076
37098
|
// both would cause an infinite loop when a parent cascades state
|
|
37077
37099
|
// down to its children (child command would re-trigger the cascade).
|
|
37078
|
-
|
|
37100
|
+
// A control following what it was given (state_prop_change) does
|
|
37101
|
+
// not write its bound signal either: the signal is what it
|
|
37102
|
+
// follows. The one write that would change it is an emptied
|
|
37103
|
+
// signal refilled with the suggestion the control fell back on —
|
|
37104
|
+
// a state the app just took back, put back by the control.
|
|
37105
|
+
controller.onUIAction(e, {
|
|
37106
|
+
skipCommand: true,
|
|
37107
|
+
skipBoundSignal: e.type === "state_prop_change",
|
|
37108
|
+
});
|
|
37079
37109
|
}
|
|
37080
37110
|
if (
|
|
37081
37111
|
e.type === "facade_propagate_up" ||
|
|
@@ -74967,8 +74997,11 @@ const Spin = ({
|
|
|
74967
74997
|
// elsewhere on the page — and the control follows it. A control seeded from a
|
|
74968
74998
|
// signal only writes back into it (see resolveInputProps), which is enough
|
|
74969
74999
|
// for a field one only ever types into and not for a value that is also moved
|
|
74970
|
-
// from outside.
|
|
74971
|
-
// the
|
|
75000
|
+
// from outside. A signal holding nothing is left alone: the control goes back
|
|
75001
|
+
// to the suggestion it started on by itself (see resolveValueState), and
|
|
75002
|
+
// asking it to reset would be an act of its own, written into the signal —
|
|
75003
|
+
// the signal could then never hold nothing while a spin is bound to it, and a
|
|
75004
|
+
// day the app took back would come back as today.
|
|
74972
75005
|
const signalValue = signalProp ? signalProp.value : undefined;
|
|
74973
75006
|
// The value as of the render this effect belongs to, and not one the closure
|
|
74974
75007
|
// captured a while ago: a step writes the signal, the signal brings us back
|
|
@@ -74982,7 +75015,6 @@ const Spin = ({
|
|
|
74982
75015
|
return;
|
|
74983
75016
|
}
|
|
74984
75017
|
if (signalValue === undefined) {
|
|
74985
|
-
dispatchRequestResetUIState(controlEl);
|
|
74986
75018
|
return;
|
|
74987
75019
|
}
|
|
74988
75020
|
if (signalValue !== valueRef.current) {
|