initial commit
This commit is contained in:
125
plugins/vite-plugin-iframe-route-restoration.js
Normal file
125
plugins/vite-plugin-iframe-route-restoration.js
Normal file
@@ -0,0 +1,125 @@
|
||||
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'
|
||||
}
|
||||
];
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user