@ascribed/astro 0.2.1-next.12 → 0.2.1-next.14

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.
@@ -0,0 +1,59 @@
1
+ ---
2
+ // For a site's not-found page: on an address under the permalinks' path, it
3
+ // says the link came from a product that expected a section of these docs
4
+ // there, and that these docs don't have it. Anywhere else it shows nothing. A
5
+ // static host serves one not-found page for every missing address, so its
6
+ // script decides from the address, and without a script it stays hidden.
7
+ //
8
+ // import MissingPermalink from "@ascribed/astro/MissingPermalink.astro";
9
+ // <MissingPermalink />
10
+ //
11
+ // `home` is where it sends the reader: by default the root of the project whose
12
+ // permalinks it explains, which with several projects is the first that has
13
+ // any. Children replace its last paragraph, which offers the home page and
14
+ // searching.
15
+ import { home as root, permalinks } from "virtual:ascribe/site";
16
+ import { servedList } from "@ascribed/astro/permalinks";
17
+
18
+ interface Props {
19
+ home?: string;
20
+ }
21
+
22
+ const served = servedList(permalinks);
23
+ const { home = served?.home ?? root } = Astro.props;
24
+ const path = served?.path;
25
+ ---
26
+
27
+ {
28
+ path !== undefined && (
29
+ <section data-permalinks={path} hidden>
30
+ <p>
31
+ This address is a permalink, <code />: a name a product links to for a section of its
32
+ documentation. These docs have no section by that name. The link may come from a newer or
33
+ older version of the product than they describe.
34
+ </p>
35
+ <slot>
36
+ <p>Start from the <a href={home}>home page</a>, or search the docs for what you need.</p>
37
+ </slot>
38
+ </section>
39
+ )
40
+ }
41
+
42
+ <script>
43
+ for (const section of document.querySelectorAll<HTMLElement>("section[data-permalinks]")) {
44
+ const path = section.dataset["permalinks"] ?? "";
45
+ let address: string;
46
+ try {
47
+ address = decodeURIComponent(location.pathname);
48
+ } catch {
49
+ continue;
50
+ }
51
+ if (!address.startsWith(path)) continue;
52
+ // One segment after the path, as every permalink's address has.
53
+ const name = address.slice(path.length).replace(/\/$/, "");
54
+ if (name === "" || name.includes("/")) continue;
55
+ const code = section.querySelector("code");
56
+ if (code !== null) code.textContent = name;
57
+ section.hidden = false;
58
+ }
59
+ </script>
@@ -0,0 +1,78 @@
1
+ ---
2
+ // A permalink's address: a page that sends the reader on to the heading it
3
+ // names, wherever that is now. The integration adds it as a route at
4
+ // `<path>[id]`, one page for each entry of the site output's
5
+ // `_ascribe/permalinks.json`. It forwards without a script, links to the same
6
+ // place for a browser that doesn't follow, and isn't indexed. Its script
7
+ // first takes the reader's choices from the address's parameters
8
+ // (`?platform=macos`), as if they'd picked those tabs, then forwards.
9
+ //
10
+ // A retired permalink with nowhere to lead gets a page that says what was
11
+ // here was removed, gives the reason as its authors wrote it, as text, and
12
+ // links to the docs' home: the root of the project whose list named it.
13
+ import { home as root, permalinks } from "virtual:ascribe/site";
14
+ import { forwardingPaths, type Forwarding } from "@ascribed/astro/permalinks";
15
+
16
+ export function getStaticPaths() {
17
+ return forwardingPaths(permalinks);
18
+ }
19
+
20
+ const props = Astro.props as Forwarding;
21
+ const to = "to" in props ? props.to : undefined;
22
+ const dimensions = "to" in props ? props.dimensions : {};
23
+ const reason = "reason" in props ? props.reason : undefined;
24
+ const home = ("reason" in props ? props.home : undefined) ?? root;
25
+ const canonical =
26
+ to === undefined || Astro.site === undefined ? to : new URL(to, Astro.site).href;
27
+ ---
28
+
29
+ <!doctype html>
30
+ <html lang="en">
31
+ <head>
32
+ <meta charset="utf-8" />
33
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
34
+ {to === undefined ? <title>Removed from these docs</title> : <title>Redirecting to {to}</title>}
35
+ <meta name="robots" content="noindex" />
36
+ {to !== undefined && <meta http-equiv="refresh" content={`0;url=${to}`} />}
37
+ {canonical !== undefined && <link rel="canonical" href={canonical} />}
38
+ </head>
39
+ <body>
40
+ {
41
+ to === undefined ? (
42
+ <main>
43
+ <h1>Removed from these docs</h1>
44
+ <p>What this link led to was removed from these docs.</p>
45
+ <p data-reason>{reason}</p>
46
+ <p>
47
+ <a href={home}>Go to the docs' home page</a>
48
+ </p>
49
+ </main>
50
+ ) : (
51
+ <p>
52
+ This link leads to <a href={to} data-dimensions={JSON.stringify(dimensions)}>{to}</a>.
53
+ </p>
54
+ )
55
+ }
56
+ <script>
57
+ import { choose } from "@ascribed/elements";
58
+
59
+ // A parameter that names one of the content model's dimensions, with one of
60
+ // its values, is the reader's choice for it. Anything else is ignored, so a
61
+ // product sends what it knows without asking what the docs accept.
62
+ const link = document.querySelector<HTMLAnchorElement>("a[data-dimensions]");
63
+ if (link !== null) {
64
+ const dimensions = JSON.parse(link.dataset["dimensions"] ?? "{}") as Record<string, string[]>;
65
+ const chosen = new Set<string>();
66
+ for (const [name, value] of new URLSearchParams(location.search)) {
67
+ if (chosen.has(name) || !Object.hasOwn(dimensions, name)) continue;
68
+ if (dimensions[name]?.includes(value)) {
69
+ chosen.add(name);
70
+ choose(name, value);
71
+ }
72
+ }
73
+ // Sooner than the refresh, which waits for the page to load.
74
+ location.replace(link.href);
75
+ }
76
+ </script>
77
+ </body>
78
+ </html>