Navigator refactor (#648)

Navigation refactor
This commit is contained in:
Zef Hemel
2024-01-24 11:58:33 +01:00
committed by GitHub
parent 9fa52e43e0
commit aaacec6d61
25 changed files with 360 additions and 263 deletions
+24
View File
@@ -0,0 +1,24 @@
import { encodePageRef, parsePageRef } from "$sb/lib/page.ts";
import { assertEquals } from "../../test_deps.ts";
Deno.test("Page utility functions", () => {
// Base cases
assertEquals(parsePageRef("foo"), { page: "foo" });
assertEquals(parsePageRef("[[foo]]"), { page: "foo" });
assertEquals(parsePageRef("foo@1"), { page: "foo", pos: 1 });
assertEquals(parsePageRef("foo$bar"), { page: "foo", anchor: "bar" });
assertEquals(parsePageRef("foo$bar@1"), {
page: "foo",
anchor: "bar",
pos: 1,
});
// Edge cases
assertEquals(parsePageRef(""), { page: "" });
assertEquals(parsePageRef("user@domain.com"), { page: "user@domain.com" });
// Encoding
assertEquals(encodePageRef({ page: "foo" }), "foo");
assertEquals(encodePageRef({ page: "foo", pos: 10 }), "foo@10");
assertEquals(encodePageRef({ page: "foo", anchor: "bar" }), "foo$bar");
});
+40 -6
View File
@@ -6,13 +6,47 @@ export function validatePageName(name: string) {
if (name.startsWith(".")) {
throw new Error("Page name cannot start with a '.'");
}
if (name.includes("@")) {
throw new Error("Page name cannot contain '@'");
}
if (name.includes("$")) {
throw new Error("Page name cannot contain '$'");
}
if (/\.[a-zA-Z]+$/.test(name)) {
throw new Error("Page name can not end with a file extension");
}
}
export type PageRef = {
page: string;
pos?: number;
anchor?: string;
};
const posRegex = /@(\d+)$/;
// Should be kept in sync with the regex in index.plug.yaml
const anchorRegex = /\$([a-zA-Z\.\-\/]+[\w\.\-\/]*)$/;
export function parsePageRef(name: string): PageRef {
// Normalize the page name
if (name.startsWith("[[") && name.endsWith("]]")) {
name = name.slice(2, -2);
}
const pageRef: PageRef = { page: name };
const posMatch = pageRef.page.match(posRegex);
if (posMatch) {
pageRef.pos = parseInt(posMatch[1]);
pageRef.page = pageRef.page.replace(posRegex, "");
}
const anchorMatch = pageRef.page.match(anchorRegex);
if (anchorMatch) {
pageRef.anchor = anchorMatch[1];
pageRef.page = pageRef.page.replace(anchorRegex, "");
}
return pageRef;
}
export function encodePageRef(pageRef: PageRef): string {
let name = pageRef.page;
if (pageRef.pos) {
name += `@${pageRef.pos}`;
}
if (pageRef.anchor) {
name += `$${pageRef.anchor}`;
}
return name;
}