@canopy-iiif/app 1.12.2 → 1.12.3
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/lib/components/navigation.js +49 -9
- package/package.json +1 -1
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {
|
|
2
|
+
fs,
|
|
3
|
+
path,
|
|
4
|
+
CONTENT_DIR,
|
|
5
|
+
rootRelativeHref,
|
|
6
|
+
canonicalizeLocaleCode,
|
|
7
|
+
} = require("../common");
|
|
2
8
|
const mdx = require("../build/mdx.js");
|
|
3
9
|
const {getPageContext} = require("../page-context");
|
|
4
10
|
|
|
@@ -38,6 +44,33 @@ function slugFromRelative(relativePath) {
|
|
|
38
44
|
return {slug, segments, isIndex};
|
|
39
45
|
}
|
|
40
46
|
|
|
47
|
+
// Returns true when the segment is a configured (non-default) locale code that
|
|
48
|
+
// prefixes content routes, e.g. "fr" for content/fr/...
|
|
49
|
+
function isLocaleSegment(segment) {
|
|
50
|
+
if (!segment) return false;
|
|
51
|
+
try {
|
|
52
|
+
return !!canonicalizeLocaleCode(segment);
|
|
53
|
+
} catch (_) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Depth (number of leading segments) that identifies a navigation section root
|
|
59
|
+
// for a page. Locale-prefixed routes root at <locale>/<section>; everything else
|
|
60
|
+
// roots at <section>.
|
|
61
|
+
function rootDepthForSegments(segments) {
|
|
62
|
+
if (!Array.isArray(segments) || !segments.length) return 0;
|
|
63
|
+
if (segments.length > 1 && isLocaleSegment(segments[0])) return 2;
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Slug of the section root for a page's segments (locale-aware).
|
|
68
|
+
function rootSegmentForSegments(segments) {
|
|
69
|
+
const depth = rootDepthForSegments(segments);
|
|
70
|
+
if (!depth) return "";
|
|
71
|
+
return segments.slice(0, depth).join("/");
|
|
72
|
+
}
|
|
73
|
+
|
|
41
74
|
function pageSortKey(relativePath) {
|
|
42
75
|
const normalized = normalizeRelativePath(relativePath).toLowerCase();
|
|
43
76
|
if (!normalized) return "";
|
|
@@ -210,7 +243,11 @@ function getNavigationCache() {
|
|
|
210
243
|
|
|
211
244
|
const roots = new Map();
|
|
212
245
|
for (const node of nodes.values()) {
|
|
213
|
-
|
|
246
|
+
// A section root is either a top-level node (<section>) or, for
|
|
247
|
+
// locale-prefixed content, a <locale>/<section> node. Rooting a
|
|
248
|
+
// locale-prefixed sidebar at the locale segment alone would list every
|
|
249
|
+
// section under that locale instead of just the current one.
|
|
250
|
+
if (rootDepthForSegments(node.segments) === node.segments.length) {
|
|
214
251
|
roots.set(node.slug, node);
|
|
215
252
|
}
|
|
216
253
|
}
|
|
@@ -266,7 +303,7 @@ function getPageInfo(relativePath) {
|
|
|
266
303
|
slug: page.slug,
|
|
267
304
|
segments: page.segments.slice(),
|
|
268
305
|
relativePath: page.relativePath,
|
|
269
|
-
rootSegment: page.segments
|
|
306
|
+
rootSegment: rootSegmentForSegments(page.segments),
|
|
270
307
|
isIndex: page.isIndex,
|
|
271
308
|
};
|
|
272
309
|
}
|
|
@@ -278,7 +315,7 @@ function getPageInfo(relativePath) {
|
|
|
278
315
|
slug,
|
|
279
316
|
segments,
|
|
280
317
|
relativePath: normalized,
|
|
281
|
-
rootSegment: segments
|
|
318
|
+
rootSegment: rootSegmentForSegments(segments),
|
|
282
319
|
isIndex: false,
|
|
283
320
|
};
|
|
284
321
|
}
|
|
@@ -289,10 +326,12 @@ function buildNavigationForFile(relativePath) {
|
|
|
289
326
|
const page = cache.pagesByRelative.get(normalized);
|
|
290
327
|
const fallback = slugFromRelative(normalized);
|
|
291
328
|
const slug = page ? page.slug : fallback.slug;
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
329
|
+
const segments = page ? page.segments : fallback.segments;
|
|
330
|
+
const rootSegment = rootSegmentForSegments(segments);
|
|
331
|
+
// The section name is the last segment of the root (the segment after an
|
|
332
|
+
// optional locale prefix), e.g. "works" for both "works" and "fr/works".
|
|
333
|
+
const sectionName = rootSegment.split("/").pop() || "";
|
|
334
|
+
if (!slug || !rootSegment || EXCLUDED_ROOTS.has(sectionName)) {
|
|
296
335
|
return null;
|
|
297
336
|
}
|
|
298
337
|
const rootNode = cache.roots.get(rootSegment);
|
|
@@ -312,7 +351,8 @@ function buildNavigationRoots(currentSlug) {
|
|
|
312
351
|
const result = {};
|
|
313
352
|
const normalizedSlug = typeof currentSlug === "string" ? currentSlug : "";
|
|
314
353
|
for (const [segment, rootNode] of cache.roots.entries()) {
|
|
315
|
-
|
|
354
|
+
const sectionName = segment.split("/").pop() || "";
|
|
355
|
+
if (!segment || EXCLUDED_ROOTS.has(sectionName)) continue;
|
|
316
356
|
const shouldExpand =
|
|
317
357
|
normalizedSlug &&
|
|
318
358
|
(normalizedSlug === segment || normalizedSlug.startsWith(segment + "/"));
|