diff --git a/public/assets/js/script-extra.js b/public/assets/js/script-extra.js index 512c392..1ee8021 100644 --- a/public/assets/js/script-extra.js +++ b/public/assets/js/script-extra.js @@ -91,30 +91,28 @@ newHead.querySelectorAll('style').forEach(s => head.appendChild(s.cloneNode(true))); } - document.addEventListener('click', (event) => { - const link = event.target.closest('a'); - if (!link || link.hasAttribute('download')) return; + let abortController = null; - const url = new URL(link.href, location.href); - if (url.origin !== location.origin) return; - if (link.target || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return; - - if (url.hash && url.pathname === location.pathname) { - event.preventDefault(); - const target = document.querySelector(url.hash); - if (target) { - target.scrollIntoView({ behavior: 'smooth', block: 'start' }); - history.pushState(null, '', url.hash); - } - return; - } - - event.preventDefault(); + async function navigate(url) { + if (abortController) abortController.abort(); + const ac = new AbortController(); + abortController = ac; document.startViewTransition(async () => { - const response = await fetch(url.href, { - headers: { 'X-Requested-With': 'view-transition' } - }); + let response; + try { + response = await fetch(url.href, { + headers: { 'X-Requested-With': 'view-transition' }, + signal: ac.signal + }); + } catch (err) { + if (err.name === 'AbortError') return; + location.href = url.href; + return; + } + + if (ac.signal.aborted) return; + const html = await response.text(); const doc = new DOMParser().parseFromString(html, 'text/html'); @@ -145,6 +143,35 @@ window.__cursorReinit(); } }); + } + + window.__navigate = function (href) { + let url; + try { url = new URL(href, location.href); } catch (_) { location.href = href; return; } + if (url.origin !== location.origin) { location.href = href; return; } + navigate(url); + }; + + document.addEventListener('click', (event) => { + const link = event.target.closest('a'); + if (!link || link.hasAttribute('download')) return; + + const url = new URL(link.href, location.href); + if (url.origin !== location.origin) return; + if (link.target || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return; + + if (url.hash && url.pathname === location.pathname) { + event.preventDefault(); + const target = document.querySelector(url.hash); + if (target) { + target.scrollIntoView({ behavior: 'smooth', block: 'start' }); + history.pushState(null, '', url.hash); + } + return; + } + + event.preventDefault(); + navigate(url); }); window.addEventListener('popstate', () => location.reload()); diff --git a/public/index.html b/public/index.html index 219bd75..b85fa2a 100644 --- a/public/index.html +++ b/public/index.html @@ -46,14 +46,14 @@ function onTap() { tapCount++; - if (tapCount >= 10) { + if (tapCount >= 3) { clearTimeout(tapTimer); tapCount = 0; - location.href = '/qr-code/'; + typeof window.__navigate === 'function' ? window.__navigate('/qr-code/') : (location.href = '/qr-code/'); return; } clearTimeout(tapTimer); - tapTimer = setTimeout(() => { tapCount = 0; }, 1500); + tapTimer = setTimeout(() => { tapCount = 0; }, 400); } el.addEventListener('touchend', (e) => { @@ -63,7 +63,7 @@ }, { passive: false }); el.addEventListener('click', () => { - if (Date.now() - lastTouch < 1400) return; + if (Date.now() - lastTouch < 300) return; onTap(); }); })(); diff --git a/public/tools/tls-test/assets/tls-test.js b/public/tools/tls-test/assets/tls-test.js index a7eb5ec..731db97 100644 --- a/public/tools/tls-test/assets/tls-test.js +++ b/public/tools/tls-test/assets/tls-test.js @@ -94,7 +94,9 @@ (msg.entries || []).forEach((e) => appendRow(e.phase, e.detail, "", e.severity)); if (msg.status === "done") { closedByDone = true; - location.replace(init.resultsUrl); + typeof window.__navigate === 'function' + ? window.__navigate(init.resultsUrl) + : location.replace(init.resultsUrl); } return; } @@ -118,7 +120,12 @@ if (msg.type === "done") { closedByDone = true; markDone(msg.rank, msg.score); - setTimeout(() => location.replace(msg.redirect || init.resultsUrl), 300); + setTimeout(() => { + const target = msg.redirect || init.resultsUrl; + typeof window.__navigate === 'function' + ? window.__navigate(target) + : location.replace(target); + }, 300); return; } if (msg.type === "error") {