@jsenv/navi 0.29.26 → 0.29.27
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/jsenv_navi.js +81 -1
- package/dist/jsenv_navi.js.map +2 -2
- package/docs/navigation.md +41 -0
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -2775,6 +2775,32 @@ const createRoutePattern = (pattern, { searchParams = {} } = {}) => {
|
|
|
2775
2775
|
return false;
|
|
2776
2776
|
}
|
|
2777
2777
|
|
|
2778
|
+
// Descending into a child path param means "this URL keeps the value you
|
|
2779
|
+
// are on" — right for a param that QUALIFIES a position (a tab, a mode),
|
|
2780
|
+
// wrong for one that NAMES a page. Two things must both hold for it to be
|
|
2781
|
+
// a name:
|
|
2782
|
+
//
|
|
2783
|
+
// - literal routes are declared for its other values ("/games/me/done").
|
|
2784
|
+
// Declaring them is the developer saying these values are places; a tab
|
|
2785
|
+
// nobody named a route after stays a qualifier;
|
|
2786
|
+
// - it has a default value, which makes THIS url the url of that default:
|
|
2787
|
+
// "/games/me" IS section=a-venir. Descending would leave the default
|
|
2788
|
+
// unaddressable — two states, one url. Without a default ("/map" is not
|
|
2789
|
+
// a panel, it is the absence of one) this url means nothing yet and
|
|
2790
|
+
// stays free to remember where you were.
|
|
2791
|
+
const thisUrlAlreadyMeansAParamValue = (connection) => {
|
|
2792
|
+
if (connection.paramType !== "path") {
|
|
2793
|
+
return false;
|
|
2794
|
+
}
|
|
2795
|
+
if (pathConnectionMap.has(connection.paramName)) {
|
|
2796
|
+
return false; // we carry that param ourselves, we are not its default
|
|
2797
|
+
}
|
|
2798
|
+
if (!connection.namedByLiteralRoutes) {
|
|
2799
|
+
return false;
|
|
2800
|
+
}
|
|
2801
|
+
return connection.getDefaultValue() !== undefined;
|
|
2802
|
+
};
|
|
2803
|
+
|
|
2778
2804
|
// Check if child has active non-default signal values
|
|
2779
2805
|
let hasActiveParams = false;
|
|
2780
2806
|
const childParams = { ...compatibility.childParams };
|
|
@@ -2801,7 +2827,10 @@ const createRoutePattern = (pattern, { searchParams = {} } = {}) => {
|
|
|
2801
2827
|
if (signalValue !== undefined) {
|
|
2802
2828
|
// No explicit override - use signal value
|
|
2803
2829
|
childParams[paramName] = signalValue;
|
|
2804
|
-
if (
|
|
2830
|
+
if (
|
|
2831
|
+
connection.isCustomValue(signalValue) &&
|
|
2832
|
+
!thisUrlAlreadyMeansAParamValue(connection)
|
|
2833
|
+
) {
|
|
2805
2834
|
hasActiveParams = true;
|
|
2806
2835
|
}
|
|
2807
2836
|
}
|
|
@@ -5323,6 +5352,57 @@ const setupRoutePatterns = (routePatterns) => {
|
|
|
5323
5352
|
collectDescendantPathSignals(routePattern);
|
|
5324
5353
|
routePattern.descendantPathSignals = descendantPathSignalsByIndex;
|
|
5325
5354
|
}
|
|
5355
|
+
// Phase 5b: Flag path params whose values are ALSO declared as literal routes
|
|
5356
|
+
// ("/games/me/done" next to "/games/me/:section"). That declaration is the
|
|
5357
|
+
// only reliable statement that the param names pages rather than qualifying
|
|
5358
|
+
// one — read by shouldUseChildRoute to decide whether an ancestor url may
|
|
5359
|
+
// descend into it.
|
|
5360
|
+
for (const routePattern of routePatternSet) {
|
|
5361
|
+
for (const connection of routePattern.connections) {
|
|
5362
|
+
if (connection.paramType !== "path") {
|
|
5363
|
+
continue;
|
|
5364
|
+
}
|
|
5365
|
+
const paramSegment = routePattern.pattern.segments.find(
|
|
5366
|
+
(seg) => seg.type === "param" && seg.name === connection.paramName,
|
|
5367
|
+
);
|
|
5368
|
+
if (!paramSegment) {
|
|
5369
|
+
continue;
|
|
5370
|
+
}
|
|
5371
|
+
const { index } = paramSegment;
|
|
5372
|
+
const sharesPathUpTo = (otherSegments) => {
|
|
5373
|
+
for (let i = 0; i < index; i++) {
|
|
5374
|
+
const seg = routePattern.pattern.segments[i];
|
|
5375
|
+
const otherSeg = otherSegments[i];
|
|
5376
|
+
if (!otherSeg) {
|
|
5377
|
+
return false;
|
|
5378
|
+
}
|
|
5379
|
+
if (seg.type === "literal" && otherSeg.type === "literal") {
|
|
5380
|
+
if (seg.value !== otherSeg.value) {
|
|
5381
|
+
return false;
|
|
5382
|
+
}
|
|
5383
|
+
} else if (seg.type !== otherSeg.type) {
|
|
5384
|
+
return false;
|
|
5385
|
+
}
|
|
5386
|
+
}
|
|
5387
|
+
return true;
|
|
5388
|
+
};
|
|
5389
|
+
for (const otherPattern of routePatternSet) {
|
|
5390
|
+
if (otherPattern === routePattern) {
|
|
5391
|
+
continue;
|
|
5392
|
+
}
|
|
5393
|
+
const otherSegments = otherPattern.pattern.segments;
|
|
5394
|
+
const otherSegment = otherSegments[index];
|
|
5395
|
+
if (!otherSegment || otherSegment.type !== "literal") {
|
|
5396
|
+
continue;
|
|
5397
|
+
}
|
|
5398
|
+
if (!sharesPathUpTo(otherSegments)) {
|
|
5399
|
+
continue;
|
|
5400
|
+
}
|
|
5401
|
+
connection.namedByLiteralRoutes = true;
|
|
5402
|
+
break;
|
|
5403
|
+
}
|
|
5404
|
+
}
|
|
5405
|
+
}
|
|
5326
5406
|
// Phase 6: Calculate depths for all patterns
|
|
5327
5407
|
for (const routePattern of routePatternSet) {
|
|
5328
5408
|
calculatePatternDepth(routePattern);
|