summaryrefslogtreecommitdiff
path: root/js/navigation.ts
blob: 4a83be66c0138c1c49e854371f6858380c025141 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
async function loadPage(page_name: string, anchor?: string) {
	console.log(`loading page \`${page_name}\``);

	let url = `/html/${page_name}.html`;
	console.log(`note: page is at "${url}"`);

	window.history.pushState(page_name, "", url);

	let response = await fetch(url);

	if (!response.ok) {
		throw new Error(`unable to load page: \"${response.status}\"`);
	}

	let markup = await response.text();

	let parser = new DOMParser();
	let dom = parser.parseFromString(markup, "text/html");

	let titles = document.getElementsByTagName("title");
	let bodies = document.getElementsByTagName("body");
	let page   = document.getElementById("page")!;

	if (titles.length < 0x1) {
		throw new Error("unable to find title");
	}

	if (bodies.length < 0x1) {
		throw new Error("unable to find body");
	}

	if (!page) {
		throw new Error("unable to find page element");
	}

	let newTitles = dom.getElementsByTagName("title");
	let newPage   = dom.getElementById("page");

	if (newTitles.length < 0x1) {
		throw new Error("unable to find new title");
	}

	if (!newPage) {
		throw new Error("unable to find new page element");
	}

	titles[0x0].replaceWith(newTitles[0x0]);
	bodies[0x0].setAttribute("data-page", page_name);
	page.replaceWith(newPage);

	initImages();

	if (anchor) {
		console.log(`going to anchor \`${anchor}\``);

		anchor = `anchor.${anchor}`;

		console.log(`note: anchor has id "${anchor}"`);

		let anchor_element = document.getElementById(anchor);

		if (!anchor_element) {
			throw new Error(`unable to find anchor "${anchor}"`);
		}

		anchor_element.scrollIntoView({
			behavior: "smooth",
		});
	}
}

function toggleSideMenu() {
	scrollToTop();

	let sideMenu = document.getElementById("sideMenu");
	let navBar   = document.getElementById("navBar");
	let glyph    = document.getElementById("glyph");

	if (!sideMenu) {
		throw new Error("unable to find sideMenu");
	}

	if (!navBar) {
		throw new Error("unable to find navigation bar");
	}

	if (!glyph) {
		throw new Error("unable to find glyph");
	}

	sideMenu.classList.toggle("visible");
	glyph.classList.toggle("hidden");

	for (let link of navBar.getElementsByTagName("a")) {
		link.classList.toggle("hidden");
	}
}

async function scrollToTop() {
	window.scroll({
		top:      0,
		left:     0,
		behavior: "smooth",
	});
}

function initImages() {
	let page = document.getElementById("page");

	if (!page) {
		throw new Error("unable to find page");
	}

	let imageList = Array.from(page.getElementsByTagName("x-image"));

	for (let image of imageList) {
		let file = image.getAttribute("data-file");

		if (!file) {
			throw new Error("file not set for image element")
		}

		console.log("initialising image that links to \"" + file + "\"");

		let sourceUrl    = "/image/source/" + file + ".webp";
		let thumbnailUrl = "/image/thumbnail/" + file + ".avif";

		let blurElement = document.createElement("img");
		blurElement.setAttribute("class", "blur");
		blurElement.setAttribute("src",   thumbnailUrl);

		let hyperlinkElement = document.createElement("a");
		hyperlinkElement.setAttribute("href",   sourceUrl);
		hyperlinkElement.setAttribute("rel",    "noopener noreferrer");
		hyperlinkElement.setAttribute("target", "_blank");

		let image_element = document.createElement("img");
		image_element.setAttribute("src", thumbnailUrl);

		hyperlinkElement.appendChild(image_element);

		image.appendChild(blurElement);
		image.appendChild(hyperlinkElement);
	}
}