|
1 | 1 | (() => { |
2 | | - const _addEventListener = addEventListener, |
3 | | - windowEventListeners = [], |
| 2 | + const windowEventListeners = [], |
4 | 3 | documentEventListeners = [], |
5 | 4 | loadedModules = []; |
| 5 | + let _addEventListener = addEventListener, |
| 6 | + _document = document, |
| 7 | + _window = window, |
| 8 | + origin = location; |
6 | 9 | _addEventListener('keydown', (event) => { |
7 | 10 | if (event.ctrlKey && event.code === 'KeyM' && event.isTrusted) { |
8 | 11 | if (localStorage.getItem('{{hu-lts}}-loader-key') !== navigator.userAgent) |
9 | 12 | localStorage.setItem('{{hu-lts}}-loader-key', navigator.userAgent); |
10 | 13 | else localStorage.removeItem('{{hu-lts}}-loader-key'); |
11 | | - location.reload(); |
| 14 | + _window.location.reload(); |
12 | 15 | } |
13 | 16 | }); |
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); |
| 17 | + const setListeners = () => { |
| 18 | + const currentWindow = _window, |
| 19 | + currentDoc = _document; |
| 20 | + currentWindow.Window.prototype.addEventListener = (...args) => { |
| 21 | + windowEventListeners.push([...args]); |
| 22 | + return _addEventListener.bind(currentWindow)(...args); |
| 23 | + }; |
| 24 | + currentWindow.Document.prototype.addEventListener = (...args) => { |
| 25 | + documentEventListeners.push([...args]); |
| 26 | + return _addEventListener.bind(currentDoc)(...args); |
| 27 | + }; |
21 | 28 | }; |
22 | | - const displayErrorPage = (overwrite = false) => { |
23 | | - document.body.removeAttribute('style'); |
24 | | - if (overwrite) document.body.replaceWith(document.createElement('body')); |
25 | | - document.body.insertAdjacentHTML( |
| 29 | + setListeners(); |
| 30 | + const displayErrorPage = (overwrite = false, currentDoc = _document) => { |
| 31 | + currentDoc.body.removeAttribute('style'); |
| 32 | + if (overwrite) |
| 33 | + currentDoc.body.replaceWith(currentDoc.createElement('body')); |
| 34 | + currentDoc.body.insertAdjacentHTML( |
26 | 35 | 'afterbegin', |
27 | 36 | '<center><h1>403 Forbidden</h1></center><center>You don’t have permission to access this page.</center><hr><center>nginx</center>' |
28 | 37 | ); |
29 | | - let head = document.createElement('head'), |
30 | | - title = document.createElement('title'); |
| 38 | + let head = currentDoc.createElement('head'), |
| 39 | + title = currentDoc.createElement('title'); |
31 | 40 | title.textContent = '500 Internal Server Error'; |
32 | 41 | head.appendChild(title); |
33 | | - document.head.replaceWith(head); |
34 | | - if (document.currentScript) document.currentScript.remove(); |
| 42 | + currentDoc.head.replaceWith(head); |
| 43 | + if (currentDoc.currentScript) currentDoc.currentScript.remove(); |
35 | 44 | }; |
36 | | - if (localStorage.getItem('{{hu-lts}}-loader-key') !== navigator.userAgent) |
| 45 | + if ( |
| 46 | + _window.localStorage.getItem('{{hu-lts}}-loader-key') !== |
| 47 | + navigator.userAgent |
| 48 | + ) |
37 | 49 | return displayErrorPage(); |
38 | 50 | const lastUpdated = '{{cacheVal}}', |
39 | 51 | retrieveUrl = (pathname) => { |
40 | | - let capturedUrl = new URL(pathname, location), |
| 52 | + let capturedUrl = new URL(pathname, origin), |
41 | 53 | capturedParams = new URLSearchParams(capturedUrl.search); |
42 | 54 | capturedParams.set('cache', lastUpdated); |
43 | 55 | capturedUrl.search = capturedParams.toString(); |
44 | 56 | return capturedUrl; |
45 | 57 | }; |
46 | 58 |
|
| 59 | + const loadAttachments = () => { |
| 60 | + if (_document.readyState === 'complete') loadPage()(); |
| 61 | + else addEventListener('load', loadPage()); |
| 62 | + _addEventListener('popstate', () => { |
| 63 | + if (_window.location.href.includes('#')) return; |
| 64 | + _window.console.clear(); |
| 65 | + loadPage(location, false)(); |
| 66 | + }); |
| 67 | + }; |
| 68 | + |
47 | 69 | const loadPage = |
48 | | - (destination = location, pushState = true) => |
| 70 | + (destination = origin, pushState = true) => |
49 | 71 | () => { |
50 | | - fetch( |
51 | | - retrieveUrl( |
52 | | - destination.pathname.replace(/\/+/g, '/').replace(/\/$/, '') + '.ico' |
53 | | - ), |
54 | | - { mode: 'same-origin' } |
55 | | - ) |
| 72 | + _window |
| 73 | + .fetch( |
| 74 | + retrieveUrl( |
| 75 | + destination.pathname.replace(/\/+/g, '/').replace(/\/$/, '') + |
| 76 | + '.ico' |
| 77 | + ), |
| 78 | + { mode: 'same-origin' } |
| 79 | + ) |
56 | 80 | .then((response) => { |
57 | 81 | let i = windowEventListeners.length - 1; |
58 | 82 | for (; i >= 0; i--) { |
59 | | - removeEventListener(...windowEventListeners[i]); |
| 83 | + _window.removeEventListener(...windowEventListeners[i]); |
60 | 84 | windowEventListeners.pop(); |
61 | 85 | } |
62 | 86 | for (i = documentEventListeners.length - 1; i >= 0; i--) { |
63 | | - document.removeEventListener(...documentEventListeners[i]); |
| 87 | + _document.removeEventListener(...documentEventListeners[i]); |
64 | 88 | documentEventListeners.pop(); |
65 | 89 | } |
66 | | - if (destination !== location && pushState) { |
67 | | - console.clear(); |
| 90 | + if (destination !== _window.location && pushState) { |
| 91 | + _window.console.clear(); |
68 | 92 | if (response.status === 200) { |
69 | | - history.pushState({}, '', retrieveUrl(destination)); |
70 | | - } else return location.assign(new URL(destination, location)); |
| 93 | + if (_window === window) |
| 94 | + _window.history.pushState({}, '', retrieveUrl(destination)); |
| 95 | + } else return _window.location.assign(new URL(destination, origin)); |
71 | 96 | } |
72 | 97 | response.blob().then((blob) => { |
73 | | - new Response( |
74 | | - blob.stream().pipeThrough(new DecompressionStream('gzip')) |
| 98 | + new _window.Response( |
| 99 | + blob.stream().pipeThrough(new _window.DecompressionStream('gzip')) |
75 | 100 | ) |
76 | 101 | .text() |
77 | 102 | .then((text) => { |
|
111 | 136 | if (replacement.childNodes.length > 0) |
112 | 137 | loadNextScript(isDefer, replacement)(); |
113 | 138 | } else if (!isDefer && !waitForHead) loadNextScript(true)(); |
114 | | - else reachedEnd = true; |
| 139 | + else { |
| 140 | + reachedEnd = true; |
| 141 | + if (waitForHead) return; |
| 142 | + [ |
| 143 | + ...windowEventListeners, |
| 144 | + ...documentEventListeners, |
| 145 | + ].forEach((listenerParams) => { |
| 146 | + if (listenerParams[0] === 'DOMContentLoaded') |
| 147 | + listenerParams[1]( |
| 148 | + new _window.Event('DOMContentLoaded') |
| 149 | + ); |
| 150 | + }); |
| 151 | + windowEventListeners.forEach((listenerParams) => { |
| 152 | + if (listenerParams[0] === 'load') |
| 153 | + listenerParams[1](new _window.Event('load')); |
| 154 | + }); |
| 155 | + } |
115 | 156 | }; |
116 | 157 | const recursiveClone = (node) => { |
117 | 158 | if (node.nodeType !== Node.ELEMENT_NODE) return node; |
|
149 | 190 | event.preventDefault(); |
150 | 191 | if (attrValue === '{{route}}{{/}}') |
151 | 192 | attrValue = '{{route}}{{/index}}'; |
152 | | - loadPage(new URL(attrValue, location))(); |
| 193 | + loadPage(new URL(attrValue, origin))(); |
153 | 194 | }); |
154 | 195 | else if (nodeName === 'link') { |
155 | 196 | src = retrieveUrl(node.href); |
|
213 | 254 | headScripts++; |
214 | 255 | } |
215 | 256 | } |
| 257 | + /* |
| 258 | + if (node.id === 'newtab') |
| 259 | + elementCopy.addEventListener('click', () => { |
| 260 | + origin = new URL(location.href); |
| 261 | + _window = open(); |
| 262 | + _addEventListener = _addEventListener.bind(_window); |
| 263 | + _document = _window.document; |
| 264 | + setListeners(); |
| 265 | + loadAttachments(); |
| 266 | + }); |
| 267 | + */ |
216 | 268 | return elementCopy; |
217 | 269 | }; |
218 | 270 | let currentType = currentDoc.doctype, |
|
253 | 305 |
|
254 | 306 | loadNextScript(false)(); |
255 | 307 | })( |
256 | | - document, |
257 | | - new DOMParser().parseFromString(text, 'text/html') |
| 308 | + _document, |
| 309 | + new _window.DOMParser().parseFromString(text, 'text/html') |
258 | 310 | ); |
259 | 311 | }); |
260 | 312 | }); |
261 | 313 | }) |
262 | 314 | .catch((error) => { |
263 | | - console.log(error); |
| 315 | + _window.console.log(error); |
264 | 316 | displayErrorPage(true); |
265 | 317 | }); |
266 | 318 | }; |
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 | | - }); |
| 319 | + loadAttachments(); |
274 | 320 | })(); |
0 commit comments