@@ -14,6 +14,7 @@ for (let i = latestMinor + 1; i > latestMinor - 4; i--) {
1414---
1515
1616<script >
17+
1718 enum _DocType {
1819 TYPE = "Type",
1920 CONDITION = "Condition",
@@ -36,52 +37,134 @@ for (let i = latestMinor + 1; i > latestMinor - 4; i--) {
3637 "Structures": _DocType.STRUCTURE
3738 }
3839
39- function toggle<T>(array: Array<T>, value: T) {
40- const index = array.indexOf(value);
41-
42- if (index === -1) {
43- array.push(value);
44- } else {
45- array.splice(index, 1);
46- }
47- }
48-
40+ /**
41+ * The things to filter on.
42+ */
4943 export interface Filter {
5044 types: string[];
5145 supported: string;
5246 changed: string;
5347 }
5448
49+ /**
50+ * The current filter settings.
51+ */
5552 let filter: Filter = {
5653 types: [],
5754 supported: "",
5855 changed: "",
5956 };
6057
58+ /**
59+ * Deletes a query parameter from the URL.
60+ * @param key The key of the query parameter to delete.
61+ */
62+ function deleteParams(key: string) {
63+ const params = new URLSearchParams(window.location.search);
64+ params.delete(key);
65+
66+ // if params is empty, remove ?
67+ if (params.toString() === "") {
68+ window.history.pushState({}, '', window.location.pathname);
69+ return;
70+ }
71+
72+ const newUrl = window.location.pathname + '?' + params.toString();
73+ window.history.pushState({}, '', newUrl);
74+ }
75+
76+ /**
77+ * Adds a query parameter to the URL.
78+ * @param key The key of the query parameter to add.
79+ * @param value The value of the query parameter to add.
80+ */
81+ function addParams(key: string, value: string) {
82+ const params = new URLSearchParams(window.location.search);
83+ params.set(key, value);
84+ const newUrl = window.location.pathname + '?' + params.toString();
85+ window.history.pushState({}, '', newUrl);
86+ }
87+
88+ /**
89+ * Clears all query parameters from the URL.
90+ */
91+ function clearParams() {
92+ window.history.pushState({}, '', window.location.pathname);
93+ }
94+
95+ /**
96+ * Applies the current filters found in the URL to the filter object.
97+ */
98+ function applyParams() {
99+ const params = new URLSearchParams(window.location.search);
100+
101+ let types = params.get("types");
102+ if (types === null) {
103+ filter.types = [];
104+ } else {
105+ filter.types = decodeURIComponent(types).split(",") || [];
106+ }
107+ filter.supported = decodeURIComponent(params.get("supported") || "");
108+ filter.changed = decodeURIComponent(params.get("changed") || "");
109+ }
110+
111+ function toggle(array: Array<string>, value: string) {
112+ const index = array.indexOf(value);
113+
114+ if (index === -1) {
115+ array.push(value);
116+ } else {
117+ array.splice(index, 1);
118+ }
119+ }
120+
121+ /**
122+ * Handles a click event on a filter button.
123+ * @param button The button element that was clicked.
124+ */
61125 function handleClick(button: HTMLButtonElement) {
62126 const text = button.textContent!!.trim();
63127 const attribute = button.getAttribute("data-type")!!;
64128
129+ // update filter variable
65130 switch (attribute) {
66131 case "type":
67132 toggle(filter.types, text);
133+
134+ if (filter.types.length === 0) {
135+ deleteParams("types");
136+ } else {
137+ addParams("types", encodeURIComponent(filter.types.join(",")));
138+ }
68139 break;
69140 case "supported":
70141 if (text === filter.supported) {
71142 filter.supported = "";
72143 filter.changed = "";
144+
145+ deleteParams("supported");
146+ deleteParams("changed");
73147 } else {
74148 filter.supported = text;
75149 filter.changed = "";
150+
151+ addParams("supported", encodeURIComponent(text));
152+ deleteParams("changed");
76153 }
77154 break;
78155 case "changed":
79156 if (text === filter.changed) {
80157 filter.changed = "";
81158 filter.supported = "";
159+
160+ deleteParams("supported");
161+ deleteParams("changed");
82162 } else {
83163 filter.changed = text;
84164 filter.supported = "";
165+
166+ deleteParams("supported");
167+ addParams("changed", encodeURIComponent(text));
85168 }
86169 break;
87170 default:
@@ -178,6 +261,9 @@ for (let i = latestMinor + 1; i > latestMinor - 4; i--) {
178261 });
179262 }
180263
264+ /**
265+ * Reset all filter buttons to their default state.
266+ */
181267 function resetButtons() {
182268 const buttons = document.querySelectorAll("#filters .filter-button");
183269 buttons.forEach(button => {
@@ -187,14 +273,6 @@ for (let i = latestMinor + 1; i > latestMinor - 4; i--) {
187273 });
188274 }
189275
190- document.addEventListener("DOMContentLoaded", () => {
191- const buttons = document.querySelectorAll("#filters .filter-button");
192- buttons.forEach(button => {
193- button.addEventListener("click", () => handleClick(button as HTMLButtonElement));
194- });
195- resetButtons();
196- });
197-
198276 const expand = document.getElementById("filter-expand-button")!!;
199277 const expandIcon = document.getElementById("filter-expand-icon")!!;
200278 const filterElements = document.getElementById("filter-expand-area")!!;
@@ -204,6 +282,7 @@ for (let i = latestMinor + 1; i > latestMinor - 4; i--) {
204282 filterElements.classList.toggle("flex");
205283 expandIcon.querySelector("svg")!!.classList.toggle("rotate-90");
206284 resetButtons();
285+ clearParams();
207286 });
208287
209288 expand.addEventListener("click", () => {
@@ -216,6 +295,8 @@ for (let i = latestMinor + 1; i > latestMinor - 4; i--) {
216295 expand.click();
217296 }
218297
298+ // === POSITIONS ===
299+
219300 const filters = document.getElementById("filters")!!;
220301 function updatePosition() {
221302 // Update position of filters to be below the nav bar,
@@ -224,13 +305,28 @@ for (let i = latestMinor + 1; i > latestMinor - 4; i--) {
224305 }
225306
226307 updatePosition();
308+
227309 window.addEventListener("DOMContentLoaded", () => {
228310 updatePosition();
229311 filters.classList.remove("fixed"); // fix layout shift on load
230312 filters.classList.add("sticky"); // fix layout shift on load
231313 });
232314
233315 window.addEventListener("resize", updatePosition);
316+
317+ // === ON LOAD ===
318+
319+ window.addEventListener("DOMContentLoaded", () => {
320+ applyParams();
321+
322+ const buttons = document.querySelectorAll("#filters .filter-button");
323+ buttons.forEach(button => {
324+ button.addEventListener("click", () => handleClick(button as HTMLButtonElement));
325+ });
326+
327+ (buttons[0] as HTMLButtonElement).click();
328+ (buttons[0] as HTMLButtonElement).click();
329+ });
234330</script >
235331
236332<div id =" filters" class =" fixed right-0 top-[35px] sm:top-[118px]
0 commit comments