125 lines
3.9 KiB
JavaScript
125 lines
3.9 KiB
JavaScript
export default function iframeRouteRestorationPlugin() {
|
|
return {
|
|
name: 'vite:iframe-route-restoration',
|
|
apply: 'serve',
|
|
transformIndexHtml() {
|
|
const script = `
|
|
const ALLOWED_PARENT_ORIGINS = [
|
|
"https://horizons.hostinger.com",
|
|
"https://horizons.hostinger.dev",
|
|
"https://horizons-frontend-local.hostinger.dev",
|
|
];
|
|
|
|
// Check to see if the page is in an iframe
|
|
if (window.self !== window.top) {
|
|
const STORAGE_KEY = 'horizons-iframe-saved-route';
|
|
|
|
const getCurrentRoute = () => location.pathname + location.search + location.hash;
|
|
|
|
const save = () => {
|
|
try {
|
|
const currentRoute = getCurrentRoute();
|
|
sessionStorage.setItem(STORAGE_KEY, currentRoute);
|
|
window.parent.postMessage({message: 'route-changed', route: currentRoute}, '*');
|
|
} catch {}
|
|
};
|
|
|
|
const replaceHistoryState = (url) => {
|
|
try {
|
|
history.replaceState(null, '', url);
|
|
window.dispatchEvent(new PopStateEvent('popstate', { state: history.state }));
|
|
return true;
|
|
} catch {}
|
|
return false;
|
|
};
|
|
|
|
const restore = () => {
|
|
try {
|
|
const saved = sessionStorage.getItem(STORAGE_KEY);
|
|
if (!saved) return;
|
|
|
|
if (!saved.startsWith('/')) {
|
|
sessionStorage.removeItem(STORAGE_KEY);
|
|
return;
|
|
}
|
|
|
|
const current = getCurrentRoute();
|
|
if (current !== saved) {
|
|
if (!replaceHistoryState(saved)) {
|
|
replaceHistoryState('/');
|
|
}
|
|
|
|
requestAnimationFrame(() => setTimeout(() => {
|
|
try {
|
|
const text = (document.body?.innerText || '').trim();
|
|
|
|
// If the restored route results in too little content, assume it is invalid and navigate home
|
|
if (text.length < 50) {
|
|
replaceHistoryState('/');
|
|
}
|
|
} catch {}
|
|
}, 1000));
|
|
}
|
|
} catch {}
|
|
};
|
|
|
|
const originalPushState = history.pushState;
|
|
history.pushState = function(...args) {
|
|
originalPushState.apply(this, args);
|
|
save();
|
|
};
|
|
|
|
const originalReplaceState = history.replaceState;
|
|
history.replaceState = function(...args) {
|
|
originalReplaceState.apply(this, args);
|
|
save();
|
|
};
|
|
|
|
const getParentOrigin = () => {
|
|
if (
|
|
window.location.ancestorOrigins &&
|
|
window.location.ancestorOrigins.length > 0
|
|
) {
|
|
return window.location.ancestorOrigins[0];
|
|
}
|
|
|
|
if (document.referrer) {
|
|
try {
|
|
return new URL(document.referrer).origin;
|
|
} catch (e) {
|
|
console.warn("Invalid referrer URL:", document.referrer);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
window.addEventListener('popstate', save);
|
|
window.addEventListener('hashchange', save);
|
|
window.addEventListener("message", function (event) {
|
|
const parentOrigin = getParentOrigin();
|
|
|
|
if (event.data?.type === "redirect-home" && parentOrigin && ALLOWED_PARENT_ORIGINS.includes(parentOrigin)) {
|
|
const saved = sessionStorage.getItem(STORAGE_KEY);
|
|
|
|
if(saved && saved !== '/') {
|
|
replaceHistoryState('/')
|
|
}
|
|
}
|
|
});
|
|
|
|
restore();
|
|
}
|
|
`;
|
|
|
|
return [
|
|
{
|
|
tag: 'script',
|
|
attrs: { type: 'module' },
|
|
children: script,
|
|
injectTo: 'head'
|
|
}
|
|
];
|
|
}
|
|
};
|
|
}
|