1
0
forked from sent/waves
This commit is contained in:
𓍼 2025-04-21 19:05:11 -05:00
parent 6b4ec8b1ae
commit a21cb430a3
5 changed files with 382 additions and 385 deletions

View File

@ -8,7 +8,7 @@
<meta property="og:image" content="/assets/images/icons/favicon.ico"/> <meta property="og:image" content="/assets/images/icons/favicon.ico"/>
<meta name="theme-color" content="#ffffff"/> <meta name="theme-color" content="#ffffff"/>
<meta name="msapplication-TileColor" content="#ffffff"/> <meta name="msapplication-TileColor" content="#ffffff"/>
<title>Waves</title> <title>Waves.</title>
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico"> <link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico">
<link rel="stylesheet" href="/assets/css/$.css"> <link rel="stylesheet" href="/assets/css/$.css">
<link rel="stylesheet" href="/assets/css/settings.css"> <link rel="stylesheet" href="/assets/css/settings.css">

View File

@ -8,7 +8,7 @@
<meta property="og:image" content="/assets/images/icons/favicon.ico"/> <meta property="og:image" content="/assets/images/icons/favicon.ico"/>
<meta name="theme-color" content="#ffffff"/> <meta name="theme-color" content="#ffffff"/>
<meta name="msapplication-TileColor" content="#ffffff"/> <meta name="msapplication-TileColor" content="#ffffff"/>
<title>Waves</title> <title>Waves.</title>
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico"> <link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico">
<link rel="stylesheet" href="/assets/css/$.css"> <link rel="stylesheet" href="/assets/css/$.css">
<link rel="stylesheet" href="/assets/css/settings.css"> <link rel="stylesheet" href="/assets/css/settings.css">

View File

@ -8,7 +8,7 @@
<meta property="og:image" content="/assets/images/icons/favicon.ico"/> <meta property="og:image" content="/assets/images/icons/favicon.ico"/>
<meta name="theme-color" content="#ffffff"/> <meta name="theme-color" content="#ffffff"/>
<meta name="msapplication-TileColor" content="#ffffff"/> <meta name="msapplication-TileColor" content="#ffffff"/>
<title>Waves</title> <title>Waves.</title>
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico"> <link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico">
<link rel="stylesheet" href="/assets/css/$.css"> <link rel="stylesheet" href="/assets/css/$.css">
<link rel="stylesheet" href="/assets/css/settings.css"> <link rel="stylesheet" href="/assets/css/settings.css">

View File

@ -1,320 +1,315 @@
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const historyStack = []; const historyStack = []
let currentIndex = -1; let currentIndex = -1
const refreshIcon = document.getElementById('refreshIcon'); const refreshIcon = document.getElementById('refreshIcon')
const fullscreenIcon = document.getElementById('fullscreenIcon'); const fullscreenIcon = document.getElementById('fullscreenIcon')
const backIcon = document.getElementById('backIcon'); const backIcon = document.getElementById('backIcon')
const forwardIcon = document.getElementById('forwardIcon'); const forwardIcon = document.getElementById('forwardIcon')
const iframe = document.getElementById('cool-iframe'); const iframe = document.getElementById('cool-iframe')
const erudaLoadingScreen = document.getElementById('erudaLoadingScreen'); const erudaLoadingScreen = document.getElementById('erudaLoadingScreen')
if (!refreshIcon || !fullscreenIcon || !backIcon || !forwardIcon || !iframe) return; if (!refreshIcon || !fullscreenIcon || !backIcon || !forwardIcon || !iframe) return
let loadingHidden = false;
const originalTitle = document.title
let loadingHidden = false
function showLoadingScreen(withToast = true, showEruda = false) { function showLoadingScreen(withToast = true, showEruda = false) {
loadingHidden = false; loadingHidden = false
NProgress.start(); NProgress.start()
if (withToast) { document.title = 'Loading... <3'
showToast( if (withToast) {
'Consider joining our <a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link">Discord</a>&nbsp;<3', showToast(
'success', 'Consider joining our <a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link">Discord</a>&nbsp;<3',
'heart' 'success',
); 'heart'
} )
}
} }
function hideLoadingScreen() { function hideLoadingScreen() {
if (loadingHidden) return; if (loadingHidden) return
loadingHidden = true; loadingHidden = true
NProgress.done(); NProgress.done()
document.title = originalTitle
} }
refreshIcon.addEventListener('click', () => { refreshIcon.addEventListener('click', () => {
refreshIcon.classList.add('spin'); refreshIcon.classList.add('spin')
if (iframe.tagName === 'IFRAME') { if (iframe.tagName === 'IFRAME') {
const currentUrl = iframe.contentWindow.location.href; const currentUrl = iframe.contentWindow.location.href
if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) { if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) {
addToHistory(currentUrl); addToHistory(currentUrl)
}
iframe.contentWindow.location.reload(true)
} }
iframe.contentWindow.location.reload(true); setTimeout(() => refreshIcon.classList.remove('spin'), 300)
} })
setTimeout(() => refreshIcon.classList.remove('spin'), 300);
});
fullscreenIcon.addEventListener('click', () => { fullscreenIcon.addEventListener('click', () => {
if (iframe.requestFullscreen) iframe.requestFullscreen(); if (iframe.requestFullscreen) iframe.requestFullscreen()
else if (iframe.mozRequestFullScreen) iframe.mozRequestFullScreen(); else if (iframe.mozRequestFullScreen) iframe.mozRequestFullScreen()
else if (iframe.webkitRequestFullscreen) iframe.webkitRequestFullscreen(); else if (iframe.webkitRequestFullscreen) iframe.webkitRequestFullscreen()
else if (iframe.msRequestFullscreen) iframe.msRequestFullscreen(); else if (iframe.msRequestFullscreen) iframe.msRequestFullscreen()
}); })
backIcon.addEventListener('click', () => { backIcon.addEventListener('click', () => {
if (currentIndex > 0) { if (currentIndex > 0) {
currentIndex--; currentIndex--
iframe.src = historyStack[currentIndex]; iframe.src = historyStack[currentIndex]
showLoadingScreen(false, false); showLoadingScreen(false, false)
updateNavButtons(); updateNavButtons()
updateDecodedSearchInput(); updateDecodedSearchInput()
} }
}); })
forwardIcon.addEventListener('click', () => { forwardIcon.addEventListener('click', () => {
if (currentIndex < historyStack.length - 1) { if (currentIndex < historyStack.length - 1) {
currentIndex++; currentIndex++
iframe.src = historyStack[currentIndex]; iframe.src = historyStack[currentIndex]
showLoadingScreen(false, false); showLoadingScreen(false, false)
updateNavButtons(); updateNavButtons()
updateDecodedSearchInput(); updateDecodedSearchInput()
} }
}); })
function normalizeUrl(urlStr) { function normalizeUrl(urlStr) {
try { try {
const url = new URL(urlStr); const url = new URL(urlStr)
url.searchParams.delete('ia'); url.searchParams.delete('ia')
return url.toString(); return url.toString()
} catch (e) { } catch (e) {
return urlStr; return urlStr
} }
} }
function addToHistory(url) { function addToHistory(url) {
const normalized = normalizeUrl(url); const normalized = normalizeUrl(url)
if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return; if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return
if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1); if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1)
historyStack.push(url); historyStack.push(url)
currentIndex++; currentIndex++
updateNavButtons(); updateNavButtons()
updateDecodedSearchInput(); updateDecodedSearchInput()
} }
function updateNavButtons() { function updateNavButtons() {
backIcon.disabled = currentIndex <= 0; backIcon.disabled = currentIndex <= 0
forwardIcon.disabled = currentIndex >= historyStack.length - 1; forwardIcon.disabled = currentIndex >= historyStack.length - 1
backIcon.classList.toggle('disabled', currentIndex <= 0); backIcon.classList.toggle('disabled', currentIndex <= 0)
forwardIcon.classList.toggle('disabled', currentIndex >= historyStack.length - 1); forwardIcon.classList.toggle('disabled', currentIndex >= historyStack.length - 1)
} }
function updateDecodedSearchInput() { function updateDecodedSearchInput() {
const searchInput2 = document.getElementById('searchInputt'); const searchInput2 = document.getElementById('searchInputt')
if (!searchInput2) return; if (!searchInput2) return
let url = ''; let url = ''
if (currentIndex >= 0 && historyStack[currentIndex]) { if (currentIndex >= 0 && historyStack[currentIndex]) {
url = historyStack[currentIndex]; url = historyStack[currentIndex]
} else if (iframe.src) { } else if (iframe.src) {
url = iframe.src; url = iframe.src
} }
searchInput2.value = decodeUrl(url); searchInput2.value = decodeUrl(url)
const lockIcon = document.getElementById('lockIcon'); const lockIcon = document.getElementById('lockIcon')
if (lockIcon) { if (lockIcon) {
lockIcon.className = decodeUrl(url).startsWith('https://') lockIcon.className = decodeUrl(url).startsWith('https://') ?
? 'fa-regular fa-lock' 'fa-regular fa-lock' :
: 'fa-regular fa-lock-open'; 'fa-regular fa-lock-open'
lockIcon.style.color = ''; lockIcon.style.color = ''
} }
} }
iframe.addEventListener('load', () => { iframe.addEventListener('load', () => {
try { hideLoadingScreen(); } try {
catch (error) { hideLoadingScreen()
console.error('Error during iframe load:', error); } catch {
hideLoadingScreen(); hideLoadingScreen()
} finally { } finally {
if (erudaLoadingScreen) erudaLoadingScreen.style.display = 'none'; if (erudaLoadingScreen) erudaLoadingScreen.style.display = 'none'
} }
}); })
iframe.addEventListener('error', () => { iframe.addEventListener('error', () => {
console.error('Error loading iframe content.'); hideLoadingScreen()
hideLoadingScreen(); })
});
iframe.addEventListener('loadstart', () => { iframe.addEventListener('loadstart', () => {
if (navbarToggle && navbarToggle.checked && navBar) { const navBar = document.querySelector('.navbar')
navBar.style.display = 'block'; const navbarToggle = document.getElementById('navbar-toggle')
} if (navbarToggle && navbarToggle.checked && navBar) navBar.style.display = 'block'
showLoadingScreen(false, false); showLoadingScreen(false, false)
}); })
const navBar = document.querySelector('.navbar'); const navBar = document.querySelector('.navbar')
const topBar = document.querySelector('.topbar'); const topBar = document.querySelector('.topbar')
const searchInput1 = document.getElementById('searchInput'); const searchInput1 = document.getElementById('searchInput')
const searchInput2 = document.getElementById('searchInputt'); const searchInput2 = document.getElementById('searchInputt')
const movies = document.getElementById('movies'); const movies = document.getElementById('movies')
const ai = document.getElementById('ai'); const ai = document.getElementById('ai')
const navbarToggle = document.getElementById('navbar-toggle'); const navbarToggle = document.getElementById('navbar-toggle')
if (navbarToggle && navBar) { if (navbarToggle && navBar) {
const savedNavbarState = localStorage.getItem('navbarToggled'); const savedNavbarState = localStorage.getItem('navbarToggled')
navbarToggle.checked = savedNavbarState === null ? true : savedNavbarState === 'true'; navbarToggle.checked = savedNavbarState === null ? true : savedNavbarState === 'true'
navBar.style.display = navBar.style.display = iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none'
iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none'; navbarToggle.addEventListener('change', () => {
navbarToggle.addEventListener('change', () => { localStorage.setItem('navbarToggled', navbarToggle.checked)
localStorage.setItem('navbarToggled', navbarToggle.checked); navBar.style.display = iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none'
navBar.style.display = })
iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none';
});
} }
iframe.style.display = 'none'; iframe.style.display = 'none'
window.addEventListener('load', hideLoadingScreen); window.addEventListener('load', hideLoadingScreen)
;
[searchInput1, searchInput2].forEach(input => { [searchInput1, searchInput2].forEach(input => {
if (input) { if (input) {
input.addEventListener('keyup', e => { input.addEventListener('keyup', e => {
if (e.key === 'Enter') handleSearch(input.value); if (e.key === 'Enter') handleSearch(input.value)
}); })
} }
}); })
if (movies) movies.addEventListener('click', e => { e.preventDefault(); handleSearch('https://movies.usewaves.site/'); });
if (ai) ai.addEventListener('click', e => { e.preventDefault(); handleSearch('https://ai.usewaves.site/'); }); if (movies) movies.addEventListener('click', e => {
e.preventDefault();
handleSearch('https://movies.usewaves.site/')
})
if (ai) ai.addEventListener('click', e => {
e.preventDefault();
handleSearch('https://ai.usewaves.site/')
})
function clearBackground() { function clearBackground() {
const preserved = [ const preserved = [
document.querySelector('.navbar'), document.querySelector('.navbar'),
document.getElementById('cool-iframe'), document.getElementById('cool-iframe'),
document.querySelector('.loading-screen'), document.querySelector('.loading-screen'),
erudaLoadingScreen erudaLoadingScreen
]; ]
Array.from(document.body.children).forEach(child => { Array.from(document.body.children).forEach(child => {
if (!preserved.includes(child)) child.remove(); if (!preserved.includes(child)) child.remove()
}); })
} }
async function handleSearch(query) { async function handleSearch(query) {
clearBackground(); clearBackground()
let searchURL
let searchURL;
if ( if (
query.startsWith('/assets/g/') || query.startsWith('/assets/g/') ||
query.startsWith(window.location.origin + '/assets/g/') query.startsWith(window.location.origin + '/assets/g/')
) { ) {
searchURL = query; searchURL = query
} else { } else {
searchURL = generateSearchUrl(query); searchURL = generateSearchUrl(query)
} }
if (searchInput2) searchInput2.value = searchURL
if (searchInput2) searchInput2.value = searchURL; historyStack.length = 0
currentIndex = -1
historyStack.length = 0; showLoadingScreen(true, false)
currentIndex = -1; iframe.style.display = 'block'
showLoadingScreen(true, false); if (topBar) topBar.style.display = 'none'
iframe.style.display = 'block'; backIcon.disabled = forwardIcon.disabled = true
if (topBar) topBar.style.display = 'none'; let finalUrl
backIcon.disabled = forwardIcon.disabled = true;
let finalUrl;
try { try {
const u = new URL(searchURL, window.location.origin); const u = new URL(searchURL, window.location.origin)
if (u.origin === window.location.origin && u.pathname.startsWith('/assets/g/')) { if (u.origin === window.location.origin && u.pathname.startsWith('/assets/g/')) {
finalUrl = u.href; finalUrl = u.href
} else { } else {
finalUrl = await getUrl(searchURL); finalUrl = await getUrl(searchURL)
} }
} catch (err) { } catch {
console.error('Error parsing URL, proxying by default:', err); finalUrl = await getUrl(searchURL)
finalUrl = await getUrl(searchURL);
} }
iframe.src = finalUrl
iframe.src = finalUrl;
iframe.onload = () => { iframe.onload = () => {
hideLoadingScreen(); hideLoadingScreen()
if (navbarToggle && navbarToggle.checked && navBar) navBar.style.display = 'block'; if (navbarToggle && navbarToggle.checked && navBar) navBar.style.display = 'block'
generateSubject(); generateSubject()
updateDecodedSearchInput(); updateDecodedSearchInput()
}; }
iframe.onerror = () => { iframe.onerror = () => {
console.error('Failed to load content.'); hideLoadingScreen()
hideLoadingScreen(); }
}; }
}
window.handleSearch = handleSearch; window.handleSearch = handleSearch
function generateSearchUrl(query) { function generateSearchUrl(query) {
try {
return new URL(query).toString();
} catch {
try { try {
const u = new URL(`https://${query}`); return new URL(query).toString()
if (u.hostname.includes('.')) return u.toString(); } catch {
} catch {} try {
} const u = new URL(`https://${query}`)
return `https://duckduckgo.com/?q=${encodeURIComponent(query)}&ia=web`; if (u.hostname.includes('.')) return u.toString()
} catch {}
}
return `https://duckduckgo.com/?q=${encodeURIComponent(query)}&ia=web`
} }
function showToast(message, type = 'success', iconType = 'check') { function showToast(message, type = 'success', iconType = 'check') {
const toast = document.createElement('div'); const toast = document.createElement('div')
toast.className = `toast show ${type}`; toast.className = `toast show ${type}`
const icons = { const icons = {
success: '<i class="fa-regular fa-check-circle" style="margin-right: 8px;"></i>', success: '<i class="fa-regular fa-check-circle" style="margin-right: 8px;"></i>',
error: '<i class="fa-regular fa-times-circle" style="margin-right: 8px;"></i>', error: '<i class="fa-regular fa-times-circle" style="margin-right: 8px;"></i>',
info: '<i class="fa-regular fa-info-circle" style="margin-right: 8px;"></i>', info: '<i class="fa-regular fa-info-circle" style="margin-right: 8px;"></i>',
warning: '<i class="fa-regular fa-exclamation-triangle" style="margin-right: 8px;"></i>', warning: '<i class="fa-regular fa-exclamation-triangle" style="margin-right: 8px;"></i>',
heart: '<i class="fa-regular fa-heart" style="margin-right: 8px;"></i>' heart: '<i class="fa-regular fa-heart" style="margin-right: 8px;"></i>'
}; }
const icon = icons[iconType] || icons.heart; const icon = icons[iconType] || icons.heart
toast.innerHTML = `${icon}${message} `; toast.innerHTML = `${icon}${message} `
const progressBar = document.createElement('div'); const progressBar = document.createElement('div')
progressBar.className = 'progress-bar'; progressBar.className = 'progress-bar'
toast.appendChild(progressBar); toast.appendChild(progressBar)
const closeBtn = document.createElement('button'); const closeBtn = document.createElement('button')
closeBtn.className = 'toast-close'; closeBtn.className = 'toast-close'
closeBtn.innerHTML = '<i class="fa-solid fa-xmark" style="margin-left: 8px; font-size: 0.8em;"></i>'; closeBtn.innerHTML = '<i class="fa-solid fa-xmark" style="margin-left: 8px; font-size: 0.8em;"></i>'
closeBtn.addEventListener('click', () => { closeBtn.addEventListener('click', () => {
toast.classList.add('hide'); toast.classList.add('hide')
setTimeout(() => toast.remove(), 500); setTimeout(() => toast.remove(), 500)
}); })
toast.appendChild(closeBtn); toast.appendChild(closeBtn)
document.body.appendChild(toast); document.body.appendChild(toast)
setTimeout(() => { setTimeout(() => {
toast.classList.add('hide'); toast.classList.add('hide')
setTimeout(() => toast.remove(), 500); setTimeout(() => toast.remove(), 500)
}, 3000); }, 3000)
} }
function preloadResources(url) { function preloadResources(url) {
if (!url) { if (!url) return
console.error('Preload failed: URL is undefined or empty.');
return;
}
try { try {
const link = document.createElement('link'); const link = document.createElement('link')
link.rel = 'preload'; link.rel = 'preload'
link.href = url; link.href = url
link.as = 'fetch'; link.as = 'fetch'
link.crossOrigin = 'anonymous'; link.crossOrigin = 'anonymous'
document.head.appendChild(link); document.head.appendChild(link)
console.log(`Resource preloaded: ${url}`); } catch {}
} catch (error) {
console.error('Error preloading resource:', error);
}
} }
function getUrl(url) { function getUrl(url) {
return Promise.resolve(__uv$config.prefix + __uv$config.encodeUrl(url)); return Promise.resolve(__uv$config.prefix + __uv$config.encodeUrl(url))
} }
function generateSubject() { function generateSubject() {
const subjects = ['math', 'science', 'history', 'art', 'programming', 'philosophy']; const subjects = ['math', 'science', 'history', 'art', 'programming', 'philosophy']
const random = subjects[Math.floor(Math.random() * subjects.length)]; const random = subjects[Math.floor(Math.random() * subjects.length)]
history.replaceState({}, '', '/learning?subject=' + random); history.replaceState({}, '', '/learning?subject=' + random)
} }
function decodeUrl(enc) { function decodeUrl(enc) {
try { try {
const o = new URL(enc, window.location.origin); const o = new URL(enc, window.location.origin)
const p = (__uv$config && __uv$config.prefix) || '/wa/a/'; const p = (__uv$config && __uv$config.prefix) || '/wa/a/'
if (o.pathname.startsWith(p)) { if (o.pathname.startsWith(p)) {
const part = o.pathname.slice(p.length); const part = o.pathname.slice(p.length)
return (__uv$config.decodeUrl ? __uv$config.decodeUrl(part) : decodeURIComponent(part)); return (__uv$config.decodeUrl ? __uv$config.decodeUrl(part) : decodeURIComponent(part))
} }
} catch {} } catch {}
return enc; return enc
} }
window.decodeUrl = decodeUrl; window.decodeUrl = decodeUrl
window.addToHistory = addToHistory; window.addToHistory = addToHistory
window.updateDecodedSearchInput = updateDecodedSearchInput; window.updateDecodedSearchInput = updateDecodedSearchInput
window.normalizeUrl = normalizeUrl; window.normalizeUrl = normalizeUrl
}); })

View File

@ -10,13 +10,14 @@ document.head.appendChild(style);
const historyStack = []; const historyStack = [];
let currentIndex = -1; let currentIndex = -1;
const elements = { const elements = {
refreshIcon: document.getElementById('refreshIcon'), refreshIcon: document.getElementById('refreshIcon'),
fullscreenIcon: document.getElementById('fullscreenIcon'), fullscreenIcon: document.getElementById('fullscreenIcon'),
backIcon: document.getElementById('backIcon'), backIcon: document.getElementById('backIcon'),
forwardIcon: document.getElementById('forwardIcon'), forwardIcon: document.getElementById('forwardIcon'),
searchInput2: document.getElementById('searchInputt'), searchInput2: document.getElementById('searchInputt'),
iframe: document.getElementById('cool-iframe') iframe: document.getElementById('cool-iframe')
}; };
const originalTitle = document.title;
let loadingFallbackTimeout; let loadingFallbackTimeout;
elements.refreshIcon.addEventListener('click', handleRefresh); elements.refreshIcon.addEventListener('click', handleRefresh);
@ -25,99 +26,106 @@ elements.backIcon.addEventListener('click', handleBack);
elements.forwardIcon.addEventListener('click', handleForward); elements.forwardIcon.addEventListener('click', handleForward);
function showLoadingScreen() { function showLoadingScreen() {
if (typeof NProgress !== 'undefined') NProgress.start(); if (typeof NProgress !== 'undefined') {
NProgress.start();
document.title = 'Loading... <3';
setTimeout(() => {
if (typeof NProgress !== 'undefined') NProgress.done();
}, 10000);
}
} }
function hideLoadingScreen() { function hideLoadingScreen() {
if (typeof NProgress !== 'undefined') NProgress.done(); if (typeof NProgress !== 'undefined') NProgress.done();
document.title = originalTitle;
} }
function handleRefresh() { function handleRefresh() {
elements.refreshIcon.classList.add('spin'); elements.refreshIcon.classList.add('spin');
const iframe = elements.iframe; const iframe = elements.iframe;
const currentUrl = iframe.contentWindow.location.href; const currentUrl = iframe.contentWindow.location.href;
if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) { if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) {
addToHistory(currentUrl); addToHistory(currentUrl);
} }
iframe.contentWindow.location.reload(true); iframe.contentWindow.location.reload(true);
setTimeout(() => elements.refreshIcon.classList.remove('spin'), 300); setTimeout(() => elements.refreshIcon.classList.remove('spin'), 300);
} }
function handleFullscreen() { function handleFullscreen() {
const iframe = elements.iframe; const iframe = elements.iframe;
if (iframe && iframe.tagName === 'IFRAME') iframe.requestFullscreen(); if (iframe && iframe.tagName === 'IFRAME') iframe.requestFullscreen();
} }
function handleBack() { function handleBack() {
toggleButtonAnimation(elements.backIcon, 'button-animate-back'); toggleButtonAnimation(elements.backIcon, 'button-animate-back');
if (currentIndex > 0) { if (currentIndex > 0) {
currentIndex--; currentIndex--;
updateIframeSrc(); updateIframeSrc();
} }
} }
function handleForward() { function handleForward() {
toggleButtonAnimation(elements.forwardIcon, 'button-animate-forward'); toggleButtonAnimation(elements.forwardIcon, 'button-animate-forward');
if (currentIndex < historyStack.length - 1) { if (currentIndex < historyStack.length - 1) {
currentIndex++; currentIndex++;
updateIframeSrc(); updateIframeSrc();
} }
} }
function toggleButtonAnimation(button, animationClass) { function toggleButtonAnimation(button, animationClass) {
button.classList.add(animationClass); button.classList.add(animationClass);
setTimeout(() => button.classList.remove(animationClass), 200); setTimeout(() => button.classList.remove(animationClass), 200);
} }
function normalizeUrl(urlStr) { function normalizeUrl(urlStr) {
try { try {
const url = new URL(urlStr); const url = new URL(urlStr);
url.searchParams.delete('ia'); url.searchParams.delete('ia');
return url.toString(); return url.toString();
} catch (e) { } catch (e) {
return urlStr; return urlStr;
} }
} }
function addToHistory(url) { function addToHistory(url) {
const normalized = normalizeUrl(url); const normalized = normalizeUrl(url);
if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return; if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return;
if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1); if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1);
historyStack.push(url); historyStack.push(url);
currentIndex++; currentIndex++;
updateNavButtons(); updateNavButtons();
updateDecodedSearchInput(); updateDecodedSearchInput();
} }
function updateIframeSrc() { function updateIframeSrc() {
showLoadingScreen(); showLoadingScreen();
elements.iframe.src = historyStack[currentIndex]; elements.iframe.src = historyStack[currentIndex];
updateNavButtons(); updateNavButtons();
updateDecodedSearchInput(); updateDecodedSearchInput();
} }
function updateNavButtons() { function updateNavButtons() {
const isAtStart = currentIndex <= 0; const isAtStart = currentIndex <= 0;
const isAtEnd = currentIndex >= historyStack.length - 1; const isAtEnd = currentIndex >= historyStack.length - 1;
elements.backIcon.disabled = isAtStart; elements.backIcon.disabled = isAtStart;
elements.forwardIcon.disabled = isAtEnd; elements.forwardIcon.disabled = isAtEnd;
elements.backIcon.classList.toggle('disabled', isAtStart); elements.backIcon.classList.toggle('disabled', isAtStart);
elements.forwardIcon.classList.toggle('disabled', isAtEnd); elements.forwardIcon.classList.toggle('disabled', isAtEnd);
} }
function updateDecodedSearchInput() { function updateDecodedSearchInput() {
if (elements.searchInput2) { if (elements.searchInput2) {
const url = historyStack[currentIndex] || elements.iframe.src; const url = historyStack[currentIndex] || elements.iframe.src;
elements.searchInput2.value = decodeUrl(url); elements.searchInput2.value = decodeUrl(url);
} }
} }
function decodeUrl(url) { function decodeUrl(url) {
try { try {
return decodeURIComponent(url); return decodeURIComponent(url);
} catch (e) { } catch (e) {
return url; return url;
} }
} }
window.addToHistory = addToHistory; window.addToHistory = addToHistory;
@ -125,57 +133,51 @@ window.updateDecodedSearchInput = updateDecodedSearchInput;
window.normalizeUrl = normalizeUrl; window.normalizeUrl = normalizeUrl;
function detectIframeNavigation() { function detectIframeNavigation() {
try { try {
const iframeWindow = elements.iframe.contentWindow; const iframeWindow = elements.iframe.contentWindow;
const pushState = iframeWindow.history.pushState; const pushState = iframeWindow.history.pushState;
const replaceState = iframeWindow.history.replaceState; const replaceState = iframeWindow.history.replaceState;
iframeWindow.history.pushState = function() { iframeWindow.history.pushState = function() {
pushState.apply(this, arguments); pushState.apply(this, arguments);
handleIframeNavigation(iframeWindow.location.href); handleIframeNavigation(iframeWindow.location.href);
}; };
iframeWindow.history.replaceState = function() { iframeWindow.history.replaceState = function() {
replaceState.apply(this, arguments); replaceState.apply(this, arguments);
handleIframeNavigation(iframeWindow.location.href); handleIframeNavigation(iframeWindow.location.href);
}; };
iframeWindow.addEventListener('popstate', () => handleIframeNavigation(iframeWindow.location.href)); iframeWindow.addEventListener('popstate', () => handleIframeNavigation(iframeWindow.location.href));
iframeWindow.addEventListener('hashchange', () => handleIframeNavigation(iframeWindow.location.href)); iframeWindow.addEventListener('hashchange', () => handleIframeNavigation(iframeWindow.location.href));
} catch (error) {} } catch (error) {}
} }
function handleIframeNavigation(rawUrl) { function handleIframeNavigation(rawUrl) {
let urlStr = rawUrl; let urlStr = rawUrl;
try { try {
urlStr = decodeUrl(rawUrl); urlStr = decodeUrl(rawUrl);
} catch {} } catch {}
try {
try { const u = new URL(urlStr);
const u = new URL(urlStr); if (u.hostname.endsWith('duckduckgo.com')) {
if (u.hostname.endsWith('duckduckgo.com')) { if (typeof NProgress !== 'undefined') NProgress.done();
if (typeof NProgress !== 'undefined') NProgress.done(); return;
return; }
} } catch (e) {}
} catch (e) { if (normalizeUrl(urlStr) !== normalizeUrl(historyStack[currentIndex] || '')) {
} showLoadingScreen();
addToHistory(urlStr);
if (normalizeUrl(urlStr) !== normalizeUrl(historyStack[currentIndex] || '')) { } else {
showLoadingScreen(); hideLoadingScreen();
addToHistory(urlStr); }
} else { }
hideLoadingScreen();
}
}
elements.iframe.addEventListener('load', () => { elements.iframe.addEventListener('load', () => {
try { try {
detectIframeNavigation(); detectIframeNavigation();
if (historyStack.length === 0) { if (historyStack.length === 0) {
addToHistory(elements.iframe.contentWindow.location.href); addToHistory(elements.iframe.contentWindow.location.href);
} else { } else {
handleIframeNavigation(elements.iframe.contentWindow.location.href); handleIframeNavigation(elements.iframe.contentWindow.location.href);
} }
} catch (error) { } catch (error) {}
console.error('Error during iframe load handling:', error); hideLoadingScreen();
} finally {
hideLoadingScreen();
}
}); });