Repository navigation
Expand file tree
/
Copy pathutils.js
More file actions
139 lines (122 loc) · 4.39 KB
/
Copy pathutils.js
File metadata and controls
139 lines (122 loc) · 4.39 KB
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
/**
* Appends the provided template to the node with the id contentId
* @param {*} template The HTML to render
* @param {string} contentId
*/
export function renderHtml(template, contentId) {
const content = document.getElementById(contentId)
if (!content) {
throw Error("No Element found for provided content id")
}
content.innerHTML = ""
content.append(template)
}
/**
* Loads an external file with an div with the class "template", adds it to the body of your page, and returns
* the div
* @param {string} page - Path to the file containing the template ('/templates/template.html')
* @return {Promise<*>} On succesfull resolvement, the HtmlTemplate found in the file
*/
export async function loadHtml(page) {
const resHtml = await fetch(page).then(r => {
if (!r.ok) {
throw new Error(`Failed to load the page: '${page}' `)
}
return r.text()
});
const parser = new DOMParser()
const content = parser.parseFromString(resHtml, "text/html")
const div = content.querySelector(".template")
if (!div) {
throw new Error(`No outer div with class 'template' found in file '${page}'`)
}
return div
}
/**
* Only meant for when Navigo is set to use Hash based routing (Always this semester)
* If users try to enter your site with only "/", it will change this to "/#/" as required
* for Hash based routing
* Call it before you start using the router (add the specific routes)
*/
export function adjustForMissingHash() {
let path = window.location.hash
if (path == "") { //Do this only for hash
path = "#/"
window.history.pushState({}, path, window.location.href + path);
}
}
/**
* Sets active element on a div (or similar) containing a-tags (with data-navigo attributes ) used as a "menu"
* Meant to be called in a before-hook with Navigo
* @param topnav - Id for the element that contains the "navigation structure"
* @param activeUrl - The URL which are the "active" one
*/
export function setActiveLink(topnav, activeUrl) {
const links = document.getElementById(topnav).querySelectorAll("a");
links.forEach(child => {
child.classList.remove("active")
//remove leading '/' if any
if (child.getAttribute("href").replace(/\//, "") === activeUrl) {
child.classList.add("active")
}
})
}
/**
* Small utility function to use in the first "then()" when fetching data from a REST API that supply error-responses as JSON
*
* Use like this--> const responseData = await fetch(URL,{..}).then(handleHttpErrors)
*/
export async function handleHttpErrors(res) {
if (!res.ok) {
const errorResponse = await res.json();
const error = new Error(errorResponse.message)
// @ts-ignore
error.fullResponse = errorResponse
throw error
}
return res.json()
}
/**
* HINT --> USE DOMPurify.santitize(..) to sanitize a full string of tags to be inserted
* via innerHTLM
* Tablerows are required to be inside a table tag, so use this small utility function to
* santitize a string with TableRows only (made from data with map)
* DOMPurify is available here, because it's imported in index.html, and as so available in all
* your JavaScript files
*/
export function sanitizeStringWithTableRows(tableRows) {
let secureRows = DOMPurify.sanitize("<table>" + tableRows + "</table>")
secureRows = secureRows.replace("<table>", "").replace("</table>", "")
return secureRows
}
export function sanitizeStringWithSpan(span) {
let secureRows = DOMPurify.sanitize("<span>" + span + "</span>")
secureRows = secureRows.replace("<span>", "").replace("</span>", "")
return secureRows
}
export function makeOptionsToken(method, body, addToken) {
const opts = {
method: method,
headers: {
"Content-type": "application/json",
"Accept": "application/json"
}
}
if (body) {
opts.body = JSON.stringify(body);
}
if (addToken && localStorage.getItem("token")) {
opts.headers.Authorization = "Bearer " + localStorage.getItem("token")
}
return opts;
}
//Utility function you can use to escape "untrusted" data inputs
//Ref: https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
export function encode(str) {
str = str.replace(/&/g, "&");
str = str.replace(/>/g, ">");
str = str.replace(/</g, "<");
str = str.replace(/"/g, """);
str = str.replace(/'/g, "'");
return str;
}