Sage100/plugins/vite-plugin-iframe-route-restoration.js
2026-01-20 11:04:04 +03:00

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'
}
];
}
};
}