Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
QuiteAFancyEmerald
GitHub Repository: QuiteAFancyEmerald/Holy-Unblocker
Path: blob/master/views/assets/js/loader.js
5247 views
1
(() => {
2
const _addEventListener = addEventListener,
3
windowEventListeners = [],
4
documentEventListeners = [],
5
loadedModules = [];
6
_addEventListener('keydown', (event) => {
7
if (event.ctrlKey && event.code === 'KeyM' && event.isTrusted) {
8
if (localStorage.getItem('{{hu-lts}}-loader-key') !== navigator.userAgent)
9
localStorage.setItem('{{hu-lts}}-loader-key', navigator.userAgent);
10
else localStorage.removeItem('{{hu-lts}}-loader-key');
11
location.reload();
12
}
13
});
14
Window.prototype.addEventListener = (...args) => {
15
windowEventListeners.push([...args]);
16
return _addEventListener(...args);
17
};
18
Document.prototype.addEventListener = (...args) => {
19
documentEventListeners.push([...args]);
20
return _addEventListener.bind(document)(...args);
21
};
22
const displayErrorPage = (overwrite = false) => {
23
document.body.removeAttribute('style');
24
if (overwrite) document.body.replaceWith(document.createElement('body'));
25
document.body.insertAdjacentHTML(
26
'afterbegin',
27
'<center><h1>403 Forbidden</h1></center><center>You don’t have permission to access this page.</center><hr><center>nginx</center>'
28
);
29
let head = document.createElement('head'),
30
title = document.createElement('title');
31
title.textContent = '500 Internal Server Error';
32
head.appendChild(title);
33
document.head.replaceWith(head);
34
if (document.currentScript) document.currentScript.remove();
35
};
36
if (localStorage.getItem('{{hu-lts}}-loader-key') !== navigator.userAgent)
37
return displayErrorPage();
38
const lastUpdated = '{{cacheVal}}',
39
retrieveUrl = (pathname) => {
40
let capturedUrl = new URL(pathname, location),
41
capturedParams = new URLSearchParams(capturedUrl.search);
42
capturedParams.set('cache', lastUpdated);
43
capturedUrl.search = capturedParams.toString();
44
return capturedUrl;
45
};
46
47
const loadPage =
48
(destination = location, pushState = true) =>
49
() => {
50
fetch(
51
retrieveUrl(
52
destination.pathname.replace(/\/+/g, '/').replace(/\/$/, '') + '.ico'
53
),
54
{ mode: 'same-origin' }
55
)
56
.then((response) => {
57
let i = windowEventListeners.length - 1;
58
for (; i >= 0; i--) {
59
removeEventListener(...windowEventListeners[i]);
60
windowEventListeners.pop();
61
}
62
for (i = documentEventListeners.length - 1; i >= 0; i--) {
63
document.removeEventListener(...documentEventListeners[i]);
64
documentEventListeners.pop();
65
}
66
if (destination !== location && pushState) {
67
console.clear();
68
if (response.status === 200) {
69
history.pushState({}, '', retrieveUrl(destination));
70
} else return location.assign(new URL(destination, location));
71
}
72
response.blob().then((blob) => {
73
new Response(
74
blob.stream().pipeThrough(new DecompressionStream('gzip'))
75
)
76
.text()
77
.then((text) => {
78
((currentDoc, newDoc) => {
79
const deferScripts = [],
80
syncScripts = [];
81
let reachedEnd = false,
82
waitForHead = false,
83
headScripts = 0;
84
const bodyLoader = () => {
85
headScripts--;
86
if (waitForHead && headScripts <= 0) {
87
waitForHead = false;
88
currentDoc.body.replaceWith(recursiveClone(newDoc.body));
89
if (reachedEnd) loadNextScript(false)();
90
}
91
return waitForHead;
92
};
93
const loadNextScript = (isDefer, currentScript) => () => {
94
if (
95
!isDefer &&
96
currentScript &&
97
'head' ===
98
currentScript.parentElement.tagName.toLowerCase()
99
)
100
bodyLoader();
101
let nextScript = [...currentDoc.scripts].find(
102
(script) =>
103
script.getAttribute('itemprop') === 'script-insert' &&
104
script.defer === isDefer
105
);
106
if (nextScript) {
107
const replacement = isDefer
108
? deferScripts.shift()
109
: syncScripts.shift();
110
nextScript.replaceWith(replacement);
111
if (replacement.childNodes.length > 0)
112
loadNextScript(isDefer, replacement)();
113
} else if (!isDefer && !waitForHead) loadNextScript(true)();
114
else reachedEnd = true;
115
};
116
const recursiveClone = (node) => {
117
if (node.nodeType !== Node.ELEMENT_NODE) return node;
118
const nodeName = node.tagName.toLowerCase();
119
let src = { pathname: node.src || '' };
120
if (
121
node.src &&
122
'./'.indexOf(node.getAttribute('src')[0]) >= 0
123
) {
124
src = retrieveUrl(node.src);
125
node.setAttribute(
126
'src',
127
src.pathname + src.search + src.hash
128
);
129
}
130
if (['svg', 'xml'].includes(nodeName))
131
return node.cloneNode(1);
132
let elementCopy = currentDoc.createElement(nodeName);
133
let j = 0,
134
nodeList = [...node.attributes];
135
for (; j < nodeList.length; j++) {
136
let attrName = nodeList[j].nodeName;
137
let attrValue = nodeList[j].nodeValue;
138
elementCopy.setAttribute(attrName, attrValue || '');
139
if (attrName.toLowerCase() === 'href')
140
try {
141
new URL(attrValue);
142
} catch (e) {
143
if ('./?'.indexOf(attrValue[0]) !== -1)
144
if (
145
nodeName === 'a' &&
146
attrValue.indexOf('#') === -1
147
)
148
elementCopy.addEventListener('click', (event) => {
149
event.preventDefault();
150
if (attrValue === '{{route}}{{/}}')
151
attrValue = '{{route}}{{/index}}';
152
loadPage(new URL(attrValue, location))();
153
});
154
else if (nodeName === 'link') {
155
src = retrieveUrl(node.href);
156
elementCopy.setAttribute(
157
'href',
158
src.pathname + src.search + src.hash
159
);
160
}
161
}
162
}
163
nodeList = [...node.childNodes];
164
for (j = 0; j < nodeList.length; j++)
165
elementCopy.appendChild(recursiveClone(nodeList[j]));
166
if ('script' === nodeName) {
167
if (
168
node.async ||
169
'module' === node.type.toLowerCase() ||
170
node.hasAttribute('data-module')
171
) {
172
if (
173
loadedModules.includes(
174
src.pathname || node.textContent
175
)
176
)
177
return currentDoc.createElement('script');
178
loadedModules.push(src.pathname || node.textContent);
179
if (node.async) return elementCopy;
180
}
181
const isDefer =
182
node.defer || 'module' === node.type.toLowerCase();
183
let replacement = currentDoc.createElement('script');
184
if (isDefer) replacement.setAttribute('defer', '');
185
replacement.setAttribute('itemprop', 'script-insert');
186
if (node.childNodes.length <= 0) {
187
elementCopy.addEventListener(
188
'load',
189
loadNextScript(isDefer, elementCopy)
190
);
191
elementCopy.addEventListener(
192
'error',
193
loadNextScript(isDefer, elementCopy)
194
);
195
}
196
if (isDefer) deferScripts.push(elementCopy);
197
else {
198
syncScripts.push(elementCopy);
199
if ('head' === node.parentElement.tagName.toLowerCase())
200
headScripts++;
201
}
202
return replacement;
203
} else if (['style', 'link'].includes(nodeName)) {
204
if (
205
'link' === nodeName &&
206
!/^stylesheet$/i.test(node.rel)
207
)
208
return elementCopy;
209
else if (node.childNodes.length <= 0) {
210
elementCopy.addEventListener('load', bodyLoader);
211
elementCopy.addEventListener('error', bodyLoader);
212
if ('head' === node.parentElement.tagName.toLowerCase())
213
headScripts++;
214
}
215
}
216
return elementCopy;
217
};
218
let currentType = currentDoc.doctype,
219
newType = newDoc.doctype,
220
currentDocNode = currentDoc.documentElement,
221
newDocNode = newDoc.documentElement;
222
if (currentType)
223
if (newType) currentType.replaceWith(newType);
224
else currentType.remove();
225
else if (newType) currentDoc.prepend(newType);
226
if (currentDocNode)
227
if (newDocNode) {
228
if (
229
currentDocNode.tagName === newDocNode.tagName &&
230
currentDoc.head &&
231
newDoc.head &&
232
currentDoc.body &&
233
newDoc.body
234
) {
235
[...currentDocNode.attributes].forEach((attribute) => {
236
currentDocNode.removeAttribute(attribute.nodeName);
237
});
238
[...newDocNode.attributes].forEach((attribute) => {
239
currentDocNode.setAttribute(
240
attribute.nodeName,
241
attribute.nodeValue || ''
242
);
243
});
244
waitForHead = true;
245
currentDoc.head.replaceWith(
246
recursiveClone(newDoc.head)
247
);
248
} else
249
currentDocNode.replaceWith(recursiveClone(newDocNode));
250
} else currentDocNode.remove();
251
else if (newDocNode)
252
currentDocNode.appendChild(recursiveClone(newDocNode));
253
254
loadNextScript(false)();
255
})(
256
document,
257
new DOMParser().parseFromString(text, 'text/html')
258
);
259
});
260
});
261
})
262
.catch((error) => {
263
console.log(error);
264
displayErrorPage(true);
265
});
266
};
267
if (document.readyState === 'complete') loadPage()();
268
else addEventListener('load', loadPage());
269
_addEventListener('popstate', () => {
270
if (location.href.includes('#')) return;
271
console.clear();
272
loadPage(location, false)();
273
});
274
})();
275
276